Skip to content

Commit b5b780b

Browse files
committed
[ADD] pos_order_workflow: Add Send to Pick button & backend picking workflow
- Added send to pick functionality in POS frontend to allow sending orders for picking - Created a new XML template to show the Send to Pick button on the POS product screen - Added a method check existing picking in pos order model to check if a picking exists for the order - Implemented create picking set shipping method to set the shipping date and create picking - Updated process saved order method to handle picking creation and shipping logic - Connected frontend and backend using RPC with order access token for identification This improves the POS workflow by linking order processing with the picking and delivery system
1 parent 996f642 commit b5b780b

File tree

6 files changed

+123
-0
lines changed

6 files changed

+123
-0
lines changed

pos_order_workflow/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

pos_order_workflow/__manifest__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
'name': 'POS Order Workflow',
3+
'version': '1.0',
4+
'summary': 'POS Order Workflow',
5+
'author': 'Raghav Agiwal',
6+
'depends': ['point_of_sale'],
7+
"assets": {
8+
"point_of_sale._assets_pos": [
9+
"pos_order_workflow/static/src/*",
10+
],
11+
},
12+
'installable': True,
13+
'application': True,
14+
'auto_install': True,
15+
'license': 'LGPL-3'
16+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import pos_order
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import logging
2+
from odoo import fields, models
3+
4+
_logger = logging.getLogger(__name__)
5+
6+
7+
class PosOrder(models.Model):
8+
_inherit = "pos.order"
9+
10+
def create_picking_set_shipping(self, order_id):
11+
order = self.browse(order_id)
12+
order.ensure_one()
13+
14+
if order.name == "/":
15+
order.name = order._compute_order_name()
16+
17+
if not order.shipping_date:
18+
order.shipping_date = fields.Date.today()
19+
20+
if not order.picking_ids:
21+
order._create_order_picking()
22+
23+
def check_existing_picking(self, order_id):
24+
order = self.search([('access_token', '=', order_id)], limit=1)
25+
return {
26+
'hasPicking': bool(order.picking_ids),
27+
'trackingNumber': order.tracking_number or 'N/A'
28+
}
29+
30+
def _process_saved_order(self, draft):
31+
self.ensure_one()
32+
if not draft:
33+
self.action_pos_order_paid()
34+
35+
if not self.picking_ids:
36+
self._create_order_picking()
37+
38+
self.picking_ids.scheduled_date = self.shipping_date
39+
self._compute_total_cost_in_real_time()
40+
41+
if self.to_invoice and self.state == 'paid':
42+
self._generate_pos_order_invoice()
43+
44+
return self.id
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { patch } from "@web/core/utils/patch";
2+
import { _t } from "@web/core/l10n/translation";
3+
import { useService } from "@web/core/utils/hooks";
4+
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
5+
6+
patch(ProductScreen.prototype, {
7+
setup() {
8+
super.setup(...arguments);
9+
this.orm = useService("orm");
10+
},
11+
12+
async checkOrderPickingStatus(order_id) {
13+
const result = await this.orm.call("pos.order","check_existing_picking",["pos.order", order_id]);
14+
return result;
15+
},
16+
17+
async sendToPick() {
18+
const currentOrder = this.pos.get_order();
19+
if (!currentOrder) {
20+
this.notification.add(_t("No active order found!"), { type: "warning" });
21+
return;
22+
}
23+
24+
const { hasPicking, trackingNumber } = await this.checkOrderPickingStatus(currentOrder.access_token);
25+
if (hasPicking) {
26+
this.notification.add(_t(`Order Already Processed. This order already has a picking associated with it.
27+
Tracking Number : (${trackingNumber})`), {
28+
type: "danger",
29+
})
30+
return;
31+
}
32+
33+
if (!currentOrder.partner_id) {
34+
this.notification.add(_t(`Select Customer`), {
35+
type: "warning",
36+
})
37+
return;
38+
}
39+
40+
if (!currentOrder.shipping_date) {
41+
const today = new Date().toISOString().split("T")[0];
42+
currentOrder.shipping_date = today;
43+
}
44+
45+
const syncOrderResult = await this.pos.push_single_order(currentOrder);
46+
47+
await this.orm.call("pos.order", "create_picking_set_shipping", ["pos.order" , syncOrderResult[0].id]);
48+
49+
this.notification.add(_t("Order Sent to Pick"), {
50+
type: "success",
51+
});
52+
},
53+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates id="send_to_pick_template" xml:space="preserve">
3+
<t t-name="pos_order.send_to_pick_button" t-inherit="point_of_sale.ProductScreen" t-inherit-mode="extension">
4+
<xpath expr="//Numpad" position="after">
5+
<button t-if="!currentOrder?.is_empty()" class="'button btn btn-primary btn-lg py-3 d-flex align-items-center justify-content-center flex-fill" t-on-click="sendToPick">Send To Pick</button>
6+
</xpath>
7+
</t>
8+
</templates>

0 commit comments

Comments
 (0)