Skip to content

Commit

Permalink
[16.0][NEW] pos_order_to_sale_order_delivery: Add new module to allow…
Browse files Browse the repository at this point in the history
… set delivery method before create sale order
  • Loading branch information
GabbasovDinar committed Aug 16, 2023
1 parent 15397e4 commit 7b5a3d7
Show file tree
Hide file tree
Showing 25 changed files with 499 additions and 0 deletions.
1 change: 1 addition & 0 deletions pos_order_to_sale_order_delivery/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO :)
1 change: 1 addition & 0 deletions pos_order_to_sale_order_delivery/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
22 changes: 22 additions & 0 deletions pos_order_to_sale_order_delivery/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "PoS Order To Sale Order: Delivery",
"version": "16.0.1.0.0",
"category": "Sales/Point of Sale",
"summary": "Compatibility of pos_order_to_sale_order and delivery modules",
"depends": ["pos_order_to_sale_order", "delivery"],
"website": "https://github.com/OCA/pos",
"author": "Cetmix,Odoo Community Association (OCA)",
"maintainers": ["GabbasovDinar", "CetmixGitDrone"],
"data": [
"views/res_config_settings_view.xml",
],
"installable": True,
"assets": {
"point_of_sale.assets": [
"pos_order_to_sale_order_delivery/static/src/css/pos.css",
"pos_order_to_sale_order_delivery/static/src/js/**/*.js",
"pos_order_to_sale_order_delivery/static/src/xml/**/*.xml",
],
},
"license": "AGPL-3",
}
4 changes: 4 additions & 0 deletions pos_order_to_sale_order_delivery/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import delivery_carrier
from . import pos_config
from . import res_config_settings
from . import sale_order
73 changes: 73 additions & 0 deletions pos_order_to_sale_order_delivery/models/delivery_carrier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from odoo import api, models


class DeliveryCarrier(models.Model):
_inherit = "delivery.carrier"

@api.model
def get_pos_choose_delivery_fields(self):
"""
Return fields names of `choose.delivery.fields` model to read for PoS
"""
return [

Check warning on line 12 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L12

Added line #L12 was not covered by tests
"carrier_id",
"delivery_type",
"delivery_price",
"display_price",
"currency_id",
"delivery_message",
]

@api.model
def get_pos_delivery_carriers(self, order_data, config_id):
"""
Return available delivery carrier data for PoS
"""
config = self.env["pos.config"].browse(config_id)
delivery_carriers = config.iface_sale_order_delivery_carrier_ids

Check warning on line 27 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L26-L27

Added lines #L26 - L27 were not covered by tests
if not config.iface_sale_order_allow_delivery or not delivery_carriers:
return False

Check warning on line 29 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L29

Added line #L29 was not covered by tests

sale_order_obj = self.env["sale.order"]
order_vals = sale_order_obj._prepare_from_pos(order_data)
sale_order = sale_order_obj.new(order_vals)

Check warning on line 33 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L31-L33

Added lines #L31 - L33 were not covered by tests

available_carriers = delivery_carriers.available_carriers(

Check warning on line 35 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L35

Added line #L35 was not covered by tests
sale_order.partner_shipping_id
)
if not available_carriers:
return False

Check warning on line 39 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L39

Added line #L39 was not covered by tests

choose_delivery_carriers = choose_delivery_carrier_obj = self.env[

Check warning on line 41 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L41

Added line #L41 was not covered by tests
"choose.delivery.carrier"
]
sale_order_id = sale_order.id

Check warning on line 44 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L44

Added line #L44 was not covered by tests
for carrier in available_carriers:
choose = choose_delivery_carrier_obj.new(

Check warning on line 46 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L46

Added line #L46 was not covered by tests
{
"order_id": sale_order_id,
"carrier_id": carrier.id,
}
)
choose._get_shipment_rate()
choose_delivery_carriers |= choose

Check warning on line 53 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L52-L53

Added lines #L52 - L53 were not covered by tests

base_model_obj = models.BaseModel
fields_to_read = self.get_pos_choose_delivery_fields()

Check warning on line 56 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L55-L56

Added lines #L55 - L56 were not covered by tests

choose_delivery_carrier_list = [
{
field_name: (
[
getattr(choose, field_name).id,
getattr(choose, field_name).display_name,
]
if isinstance(getattr(choose, field_name), base_model_obj)
else getattr(choose, field_name)
)
for field_name in fields_to_read
}
for choose in choose_delivery_carriers
]

return choose_delivery_carrier_list

Check warning on line 73 in pos_order_to_sale_order_delivery/models/delivery_carrier.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/delivery_carrier.py#L73

Added line #L73 was not covered by tests
15 changes: 15 additions & 0 deletions pos_order_to_sale_order_delivery/models/pos_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import fields, models


class PosConfig(models.Model):
_inherit = "pos.config"

iface_sale_order_allow_delivery = fields.Boolean(default=True)
iface_sale_order_delivery_carrier_ids = fields.Many2many(
comodel_name="delivery.carrier",
relation="delivery_carrier_pos_config_rel",
column1="pos_config_id",
column2="delivery_carrier_id",
string="Shipping Methods",
check_company=True,
)
15 changes: 15 additions & 0 deletions pos_order_to_sale_order_delivery/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

pos_iface_sale_order_allow_delivery = fields.Boolean(
related="pos_config_id.iface_sale_order_allow_delivery",
readonly=False,
)
pos_iface_sale_order_delivery_carrier_ids = fields.Many2many(
related="pos_config_id.iface_sale_order_delivery_carrier_ids",
comodel_name="delivery.carrier",
readonly=False,
)
38 changes: 38 additions & 0 deletions pos_order_to_sale_order_delivery/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from odoo import api, models


class SaleOrder(models.Model):
_inherit = "sale.order"

@api.model
def create_order_from_pos(self, order_data, action):
if order_data.get("delivery_carrier"):
return super(

Check warning on line 10 in pos_order_to_sale_order_delivery/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/sale_order.py#L10

Added line #L10 was not covered by tests
SaleOrder,
self.with_context(
with_pos_delivery_carrier=order_data["delivery_carrier"]
),
).create_order_from_pos(order_data, action)
return super().create_order_from_pos(order_data, action)

@api.model_create_multi
def create(self, vals_list):
orders = super().create(vals_list)
carrier_data = self.env.context.get("with_pos_delivery_carrier")
if carrier_data:
orders.set_pos_delivery_carrier(carrier_data)

Check warning on line 23 in pos_order_to_sale_order_delivery/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/sale_order.py#L23

Added line #L23 was not covered by tests
return orders

def set_pos_delivery_carrier(self, carrier_data):
"""
Set delivery carrier for current Sale Order from POS data
"""
self.ensure_one()
delivery_carrier = self.env["delivery.carrier"].browse(carrier_data["id"])
self.set_delivery_line(delivery_carrier, carrier_data["delivery_price"])
self.write(

Check warning on line 33 in pos_order_to_sale_order_delivery/models/sale_order.py

View check run for this annotation

Codecov / codecov/patch

pos_order_to_sale_order_delivery/models/sale_order.py#L30-L33

Added lines #L30 - L33 were not covered by tests
{
"recompute_delivery_price": False,
"delivery_message": carrier_data["delivery_message"],
}
)
2 changes: 2 additions & 0 deletions pos_order_to_sale_order_delivery/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Select PoS > Configuration > Settings > Inventory > enable flag "Allow Delivery Carrier" > specify "Shipping Methods":
.. image:: ../static/img/pos_config.png
2 changes: 2 additions & 0 deletions pos_order_to_sale_order_delivery/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Dinar Gabbasov <https://github.com/GabbasovDinar>
* Cetmix <https://cetmix.com/>
6 changes: 6 additions & 0 deletions pos_order_to_sale_order_delivery/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This module extends the functionality of the pos_order_to_sale_order module
by allowing you to create sales orders specifying a delivery method from
the Point of Sale.

It is enough to specify that you want to add a shipping method during the
creation of a sales order in the Point of Sale.
16 changes: 16 additions & 0 deletions pos_order_to_sale_order_delivery/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

* Open your Point of sale
* Create a new order and select products
* Select a customer
* Click on the "Create Order" button
* Click on the "Add a shipping method" button

.. figure:: ../static/img/pos_add_shipping.png

* Click Create Sale order button

Before creating a sales order, a popup will open where you can specify the shipping method

.. figure:: ../static/img/pos_select_shipping.png

* Click on the "Confirm" button to add the selected method during the sales order creation process
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions pos_order_to_sale_order_delivery/static/src/css/pos.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.pos .js_class_add_shipping_method {
margin-right: 0px !important;
line-height: initial !important;
padding: 5px;
}
.pos .delivery-carrier-popup .details {
text-align: left;
}
.pos .delivery-carrier-popup .cost {
padding: 10px 0;
}
.pos .delivery-carrier-popup .alert-info {
clear: both;
color: #0e616e;
background-color: #d1ecf1;
border-color: #b9e3ea;
position: relative;
padding: 1rem 1rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-top-color: transparent;
border-top-width: 1px;
border-right-color: transparent;
border-right-width: 1px;
border-bottom-color: transparent;
border-bottom-width: 1px;
border-left-color: transparent;
border-left-width: 1px;
border-radius: 0.25rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/** @odoo-module **/

import AbstractAwaitablePopup from "point_of_sale.AbstractAwaitablePopup";
import Registries from "point_of_sale.Registries";
import {_lt} from "@web/core/l10n/translation";

const {useState} = owl;

class ChooseDeliveryCarrierPopup extends AbstractAwaitablePopup {
setup() {
super.setup();
this.state = useState({choose: this.props.chooses[0]});
}
onChange(carrierId) {
const selected = this.props.chooses.find(
(item) => parseInt(carrierId) === item.carrier_id[0]
);
this.state.choose = selected;
}
getPayload() {
return this.props.chooses.find((item) => this.state.choose === item);
}
}

ChooseDeliveryCarrierPopup.template = "ChooseDeliveryCarrierPopup";
ChooseDeliveryCarrierPopup.defaultProps = {
confirmText: _lt("Confirm"),
cancelText: _lt("Cancel"),
title: _lt("Add a shipping method"),
body: "",
list: [],
confirmKey: false,
};

Registries.Component.add(ChooseDeliveryCarrierPopup);

export default ChooseDeliveryCarrierPopup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/** @odoo-module **/

import CreateOrderPopup from "point_of_sale.CreateOrderPopup";
import Registries from "point_of_sale.Registries";

const {useState} = owl;

const PosDeliveryCarrierCreateOrderPopup = (CreateOrderPopup) =>
class extends CreateOrderPopup {
// @override
setup() {
super.setup();
this.state = useState({addDeliveryCarrier: false});
}
get currentOrder() {
return this.env.pos.get_order();
}
onClickToShipping() {
this.state.addDeliveryCarrier = !this.state.addDeliveryCarrier;
}
// @override
async _actionCreateSaleOrder(order_state) {
const addDeliveryCarrier = this.state.addDeliveryCarrier;
if (addDeliveryCarrier) {
const response = await this.rpc({
model: "delivery.carrier",
method: "get_pos_delivery_carriers",
args: [this.currentOrder.export_as_JSON(), this.env.pos.config.id],
}).catch(function (error) {
throw error;
});
if (response) {
const {confirmed, payload} = await this._chooseDeliveryCarrier(
response
);
if (confirmed) {
await this.currentOrder.set_delivery_carrier(
this._prepareDeliveryCarrierData(payload)
);
if (this.currentOrder.get_delivery_carrier()) {
return await super._actionCreateSaleOrder(order_state);
}
}
return await this.cancel();
}
return await this.showPopup("ErrorPopup", {
title: this.env._t("Error"),
body: this.env._t("Not Found Shipping Methods."),
});
}
return await super._actionCreateSaleOrder(order_state);
}
async _chooseDeliveryCarrier(choose_delivery_carriers) {
return await this.showPopup("ChooseDeliveryCarrierPopup", {
chooses: choose_delivery_carriers,
});
}
_prepareDeliveryCarrierData(choose_delivery_carrier) {
return {
id: choose_delivery_carrier.carrier_id[0],
delivery_price: choose_delivery_carrier.delivery_price,
delivery_message: choose_delivery_carrier.delivery_message,
delivery_type: choose_delivery_carrier.delivery_type,
};
}
};

Registries.Component.extend(CreateOrderPopup, PosDeliveryCarrierCreateOrderPopup);
31 changes: 31 additions & 0 deletions pos_order_to_sale_order_delivery/static/src/js/models.esm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/** @odoo-module **/

import {Order} from "point_of_sale.models";
import Registries from "point_of_sale.Registries";

const PosOrderToSaleOrderDeliveryOrder = (Order) =>
class PosOrderToSaleOrderDeliveryOrder extends Order {
constructor() {
super(...arguments);
this.delivery_carrier = false;
}
get_delivery_carrier() {
return this.delivery_carrier;
}
set_delivery_carrier(delivery_carrier) {
this.delivery_carrier = delivery_carrier;
}
export_as_JSON() {
const result = super.export_as_JSON(...arguments);
result.delivery_carrier = this.get_delivery_carrier();
return result;
}
init_from_JSON(json) {
super.init_from_JSON(...arguments);
this.set_delivery_carrier(json.delivery_carrier || false);
}
};

Registries.Model.extend(Order, PosOrderToSaleOrderDeliveryOrder);

export default PosOrderToSaleOrderDeliveryOrder;
Loading

0 comments on commit 7b5a3d7

Please sign in to comment.