From 6801b2e86cfb08ed6f1687c74a5c3d64e97e9541 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Thu, 21 May 2026 09:41:38 +0700 Subject: [PATCH] first commit --- .gitignore | 33 ++++++++++++++++++++++ README.md | 42 ++++++++++++++++++++++++++++ __init__.py | 1 + __manifest__.py | 19 +++++++++++++ models/__init__.py | 2 ++ models/pos_order.py | 33 ++++++++++++++++++++++ models/pos_payment.py | 23 +++++++++++++++ views/pos_order_views.xml | 59 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 212 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 __init__.py create mode 100644 __manifest__.py create mode 100644 models/__init__.py create mode 100644 models/pos_order.py create mode 100644 models/pos_payment.py create mode 100644 views/pos_order_views.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5537e00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Editors and IDEs +.idea/ +.vscode/ +*.swp +*.swo +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..62a9c38 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# POS Edit Payment Method + +An Odoo 19 module designed to allow **POS Managers** to safely edit the payment method used in Point of Sale Orders under specific conditions, while maintaining strict control over other financial fields (like nominal amount and date). + +## Key Features + +- 👤 **Access Limitation**: Only users belonging to the **POS Manager** group (`point_of_sale.group_pos_manager`) can edit the payment method. For standard POS Users, the fields remain completely read-only. +- 🔒 **Dynamic Checks & Rules**: Editing is only permitted if: + - The POS Session of the order is **not closed**. + - The POS Order state is **not Done or Cancelled**. + - The order **does not have a posted invoice**. + - None of the payments in the order have a **posted accounting journal entry**. +- 🚫 **Tamper Prevention**: Other financial fields, such as **amount (nominal)**, **date**, and **card details** are strictly read-only and cannot be manually edited. Standard creation or deletion of payments from the backend list view is disabled (`create="0"` and `delete="0"`). +- 💬 **Odoo Chatter Integration**: Seamlessly leverages Odoo's native change tracking system to automatically log changes in the POS Order chatter (e.g., *• BCA changed to BTN for Rp 17,001.00*). + +## Installation + +1. Place the `pos_edit_payment_method` directory inside your custom Odoo addons path. +2. Restart your Odoo server instance. +3. Log in to your Odoo database as an Administrator. +4. Activate **Developer Mode** (Settings -> Activate the developer mode). +5. Navigate to the **Apps** menu and click **Update Apps List**. +6. Search for `POS Edit Payment Method` in the Apps search bar. +7. Click **Activate** (or **Install**). + +## Usage Guide + +1. Go to **Point of Sale** -> **Orders** -> **Orders**. +2. Open a POS order whose session is still in progress (not closed). +3. Under the **Payments** tab, double-click or inline-edit the **Payment Method** field. Note that other fields (like **Amount** and **Date**) are strictly locked. +4. Save the order. +5. Review the **Chatter** on the right to see the automatic change log entry. +6. Test using an order whose session has already been closed. Verify that the payment method field is locked and cannot be edited. +7. Test logging in as a standard POS User (non-manager). Verify that all fields in the payments tab are locked. + +## Technical Details + +- **Dependencies**: `point_of_sale` +- **Category**: `Point of Sale` +- **License**: `LGPL-3` +- **Author**: `Suherdy Yacob` +- **Version**: `19.0.1.0.0` diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..a05c881 --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,19 @@ +{ + 'name': 'POS Edit Payment Method', + 'version': '19.0.1.0.0', + 'category': 'Point of Sale', + 'summary': 'Allows editing the payment method of a POS Order under specific conditions', + 'description': """ + This module allows users to edit the payment method used in POS orders: + - Only editable if the POS session is not closed and the accounting journal/entry is not posted. + - Other payment fields (like amount/nominal) remain strictly read-only. + - Log payment method changes in the POS Order's chatter. + """, + 'author': 'Suherdy Yacob', + 'depends': ['point_of_sale'], + 'data': [ + 'views/pos_order_views.xml', + ], + 'installable': True, + 'license': 'LGPL-3', +} diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..57f9330 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_order +from . import pos_payment diff --git a/models/pos_order.py b/models/pos_order.py new file mode 100644 index 0000000..1386136 --- /dev/null +++ b/models/pos_order.py @@ -0,0 +1,33 @@ +from odoo import models, fields, api + +class PosOrder(models.Model): + _inherit = 'pos.order' + + is_payment_editable = fields.Boolean( + compute='_compute_is_payment_editable', + string='Is Payment Editable' + ) + + @api.depends('session_id.state', 'state', 'account_move', 'payment_ids.account_move_id.state') + def _compute_is_payment_editable(self): + is_manager = self.env.user.has_group('point_of_sale.group_pos_manager') + for order in self: + # Only POS Managers can edit + if not is_manager: + order.is_payment_editable = False + # 1. POS session must not be closed + elif order.session_id.state == 'closed': + order.is_payment_editable = False + # 2. POS order state must not be done or cancel + elif order.state in ('done', 'cancel'): + order.is_payment_editable = False + # 3. Order must not have a posted invoice + elif order.account_move and order.account_move.state == 'posted': + order.is_payment_editable = False + else: + # 4. None of the payments must have a posted accounting journal entry (account_move_id) + is_any_payment_posted = any( + p.account_move_id and p.account_move_id.state == 'posted' + for p in order.payment_ids + ) + order.is_payment_editable = not is_any_payment_posted diff --git a/models/pos_payment.py b/models/pos_payment.py new file mode 100644 index 0000000..5c4bbf0 --- /dev/null +++ b/models/pos_payment.py @@ -0,0 +1,23 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + +class PosPayment(models.Model): + _inherit = 'pos.payment' + + def write(self, vals): + if 'payment_method_id' in vals: + # Check if current user is not a POS Manager + if not self.env.user.has_group('point_of_sale.group_pos_manager'): + raise ValidationError(_( + "Only POS Managers are allowed to edit payment methods." + )) + + for payment in self: + # Enforce the validation rules + if not payment.pos_order_id.is_payment_editable: + raise ValidationError(_( + "You cannot edit the payment method because the POS session is closed " + "or the accounting journal has already been posted." + )) + + return super(PosPayment, self).write(vals) diff --git a/views/pos_order_views.xml b/views/pos_order_views.xml new file mode 100644 index 0000000..a36d40b --- /dev/null +++ b/views/pos_order_views.xml @@ -0,0 +1,59 @@ + + + + pos.order.form.inherit.edit.payment + pos.order + + + + + + + + + + not is_payment_editable + + + + + + 0 + 0 + bottom + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + +