Skip to content
Merged
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
6 changes: 6 additions & 0 deletions pos_sale_picking_keep/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ This module inhibits the manipulation that the point of sale mades over
the sales orders pickings, and the creation of new pickings under the
PoS picking type.

When settling a sale order in the PoS, the ordered quantities are loaded
even if the products were already delivered through the sale order
pickings, deducting only the quantities already invoiced. Without this
module, the PoS deducts the delivered quantities, which makes no sense
here, as the PoS is only used to charge the order, not to deliver it.

**Table of contents**

.. contents::
Expand Down
5 changes: 4 additions & 1 deletion pos_sale_picking_keep/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Keep sale pickings from PoS",
"version": "19.0.1.0.0",
"version": "19.0.1.1.0",
"category": "Point Of Sale",
"website": "https://github.com/OCA/pos",
"author": "Tecnativa, Odoo Community Association (OCA)",
Expand All @@ -11,6 +11,9 @@
"installable": True,
"depends": ["pos_sale", "sale_stock"],
"assets": {
"point_of_sale._assets_pos": [
"pos_sale_picking_keep/static/src/js/**/*",
],
"web.assets_tests": [
"pos_sale_picking_keep/static/tests/tours/**/*",
],
Expand Down
6 changes: 6 additions & 0 deletions pos_sale_picking_keep/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
This module inhibits the manipulation that the point of sale mades over the sales orders
pickings, and the creation of new pickings under the PoS picking type.

When settling a sale order in the PoS, the ordered quantities are loaded
even if the products were already delivered through the sale order pickings,
deducting only the quantities already invoiced. Without this module, the PoS
deducts the delivered quantities, which makes no sense here, as the PoS is
only used to charge the order, not to deliver it.
5 changes: 5 additions & 0 deletions pos_sale_picking_keep/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,11 @@ <h1>Keep sale pickings from PoS</h1>
<p>This module inhibits the manipulation that the point of sale mades over
the sales orders pickings, and the creation of new pickings under the
PoS picking type.</p>
<p>When settling a sale order in the PoS, the ordered quantities are loaded
even if the products were already delivered through the sale order
pickings, deducting only the quantities already invoiced. Without this
module, the PoS deducts the delivered quantities, which makes no sense
here, as the PoS is only used to charge the order, not to deliver it.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
Expand Down
24 changes: 24 additions & 0 deletions pos_sale_picking_keep/static/src/js/pos_order_line.esm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright 2026 Jarsa - Jesús Alan Ramos Rodríguez
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
import {PosOrderline} from "@point_of_sale/app/models/pos_order_line";
import {patch} from "@web/core/utils/patch";

patch(PosOrderline.prototype, {
/**
* The PoS deducts the already delivered quantity when settling a sale
* order, because it assumes it will deliver the remaining quantity
* itself. With this module the sale order pickings are kept and the PoS
* only charges the order, so the delivered quantity must not be
* deducted. Only the already invoiced quantity is deducted to avoid
* charging twice.
* @override
*/
async setQuantityFromSOL(saleOrderLine) {
if (this.product_id.type === "service") {
return super.setQuantityFromSOL(...arguments);
}
return this.setQuantity(
saleOrderLine.product_uom_qty - saleOrderLine.qty_invoiced
);
},
});
28 changes: 28 additions & 0 deletions pos_sale_picking_keep/tests/test_pos_sale_picking_keep.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,34 @@ def test_sale_order_pos_order_done(self):
self.assertEqual(so_picking.state, "done")
self.assertEqual(sol.qty_delivered, 1)

def test_settle_delivered_sale_order(self):
"""The ordered quantity is settled even if it was already delivered."""
self.env["stock.quant"]._update_available_quantity(
self.product, self.warehouse.lot_stock_id, 1
)
order_form = Form(self.env["sale.order"])
order_form.partner_id = self.customer
order_form.client_order_ref = "test_pos_sale_picking_keep"
with order_form.order_line.new() as line_form:
line_form.product_id = self.product
sale_order = order_form.save()
sale_order.action_confirm()
sale_order.picking_ids.move_ids.write({"picked": True})
sale_order.picking_ids.button_validate()
sol = sale_order.order_line
self.assertEqual(sol.qty_delivered, 1)
self.main_pos_config.open_ui()
# The tour checks that the line is loaded with quantity 1.00
self.start_tour(
f"/pos/ui?config_id={self.main_pos_config.id}",
"PosSalePickingKeep1",
login="accountman",
)
pos_order = sol.pos_order_line_ids.order_id
self.assertEqual(pos_order.state, "paid")
self.assertFalse(pos_order.picking_ids)
self.assertEqual(sale_order.picking_ids.state, "done")

def test_pos_order_flow(self):
self.main_pos_config.open_ui()
self.start_tour(
Expand Down
Loading