-
151pos_order_to_sale_order/README.rst
-
1pos_order_to_sale_order/__init__.py
-
12pos_order_to_sale_order/__manifest__.py
-
7pos_order_to_sale_order/demo/res_groups.xml
-
181pos_order_to_sale_order/i18n/fr.po
-
108pos_order_to_sale_order/i18n/pos_order_to_sale_order.pot
-
2pos_order_to_sale_order/models/__init__.py
-
21pos_order_to_sale_order/models/pos_config.py
-
109pos_order_to_sale_order/models/sale_order.py
-
23pos_order_to_sale_order/models/sale_order_line.py
-
2pos_order_to_sale_order/readme/CONFIGURE.rst
-
38pos_order_to_sale_order/readme/DESCRIPTION.rst
-
11pos_order_to_sale_order/readme/ROADMAP.rst
-
23pos_order_to_sale_order/readme/USAGE.rst
-
BINpos_order_to_sale_order/static/description/pos_config_form.png
-
BINpos_order_to_sale_order/static/description/pos_create_picking_confirm.png
-
BINpos_order_to_sale_order/static/description/pos_create_picking_option_1.png
-
BINpos_order_to_sale_order/static/description/pos_create_picking_option_2.png
-
BINpos_order_to_sale_order/static/description/pos_create_picking_option_3.png
-
BINpos_order_to_sale_order/static/description/pos_frontend_buttons.png
-
BINpos_order_to_sale_order/static/description/pos_frontend_order.png
-
12pos_order_to_sale_order/static/src/css/pos_order_to_sale_order.css
-
225pos_order_to_sale_order/static/src/js/pos_order_to_sale_order.js
-
163pos_order_to_sale_order/static/src/js/screens.js
-
38pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml
-
11pos_order_to_sale_order/views/assets.xml
-
14pos_order_to_sale_order/views/pos_order_to_sale_order.xml
-
68pos_order_to_sale_order/views/view_pos_config.xml
@ -1,2 +1 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,22 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) |
|||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
{ |
|||
"name": "PoS Order To Sale Order", |
|||
"version": "8.0.3.0.0", |
|||
"version": "12.0.1.0.0", |
|||
"author": "GRAP,Odoo Community Association (OCA)", |
|||
"category": "Point Of Sale", |
|||
"license": "AGPL-3", |
|||
"depends": ["point_of_sale",], |
|||
"depends": ["point_of_sale"], |
|||
"maintainers": ["legalsylvain"], |
|||
"development_status": "Production/Stable", |
|||
"website": "https://odoo-community.org/", |
|||
"website": "https://github.com/OCA/pos", |
|||
"data": [ |
|||
"views/view_pos_config.xml", |
|||
"views/pos_order_to_sale_order.xml", |
|||
"views/assets.xml", |
|||
], |
|||
"demo": ["demo/res_groups.xml",], |
|||
"qweb": ["static/src/xml/pos_order_to_sale_order.xml",], |
|||
"qweb": ["static/src/xml/pos_order_to_sale_order.xml"], |
|||
} |
@ -1,7 +0,0 @@ |
|||
<openerp><data> |
|||
|
|||
<record id="sale.group_discount_per_so_line" model="res.groups"> |
|||
<field name="users" eval="[(4, ref('base.user_root'))]"/> |
|||
</record> |
|||
|
|||
</data></openerp> |
@ -1,3 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import sale_order |
|||
from . import sale_order_line |
|||
from . import pos_config |
@ -1,90 +1,61 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) |
|||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from openerp import models, api, _ |
|||
from odoo import _, api, models |
|||
|
|||
|
|||
class SaleOrder(models.Model): |
|||
_inherit = "sale.order" |
|||
|
|||
@api.model |
|||
def _prepare_order_field_from_pos(self, order_data): |
|||
session_obj = self.env["pos.session"] |
|||
session = session_obj.browse(order_data["pos_session_id"]) |
|||
res = self.onchange_partner_id(order_data["partner_id"])["value"] |
|||
res.update( |
|||
{ |
|||
"partner_id": order_data["partner_id"] or False, |
|||
"origin": _("Point of Sale %s") % (session.name), |
|||
"client_order_ref": order_data["name"], |
|||
"user_id": order_data["user_id"] or False, |
|||
"order_line": [], |
|||
} |
|||
) |
|||
if self.env.context.get("is_pos_pricelist"): |
|||
res.update( |
|||
{"pricelist_id": order_data["pricelist_id"],} |
|||
) |
|||
for line_data in order_data["lines"]: |
|||
res["order_line"].append( |
|||
[ |
|||
0, |
|||
False, |
|||
self._prepare_order_line_field_from_pos(line_data[2], res), |
|||
] |
|||
) |
|||
return res |
|||
def _prepare_from_pos(self, order_data): |
|||
PosSession = self.env["pos.session"] |
|||
session = PosSession.browse(order_data["pos_session_id"]) |
|||
return { |
|||
"partner_id": order_data["partner_id"], |
|||
"origin": _("Point of Sale %s") % (session.name), |
|||
"client_order_ref": order_data["name"], |
|||
"user_id": order_data["user_id"], |
|||
"pricelist_id": order_data["pricelist_id"], |
|||
"fiscal_position_id": order_data["fiscal_position_id"], |
|||
} |
|||
|
|||
@api.model |
|||
def _prepare_order_line_field_from_pos(self, line_data, sale_order_data): |
|||
line_obj = self.env["sale.order.line"] |
|||
res = line_obj.product_id_change( |
|||
sale_order_data["pricelist_id"], |
|||
line_data["product_id"], |
|||
qty=line_data["qty"], |
|||
partner_id=sale_order_data["partner_id"], |
|||
)["value"] |
|||
res.update( |
|||
{ |
|||
"product_id": line_data["product_id"], |
|||
"product_uom_qty": line_data["qty"], |
|||
"discount": line_data["discount"], |
|||
"tax_id": [(6, False, res["tax_id"])], |
|||
} |
|||
) |
|||
if self.env.context.get("is_pos_pricelist"): |
|||
res.update( |
|||
{ |
|||
"price_unit": line_data["price_unit"], |
|||
"tax_id": line_data["tax_ids"], |
|||
} |
|||
) |
|||
return res |
|||
def create_order_from_pos(self, order_data, action): |
|||
SaleOrderLine = self.env["sale.order.line"] |
|||
|
|||
@api.model |
|||
def create_order_from_pos(self, order_data): |
|||
is_pos_pricelist = len( |
|||
self.env["ir.module.module"].search( |
|||
[("name", "=", "pos_pricelist"), ("state", "=", "installed")] |
|||
) |
|||
) |
|||
# Create Draft Sale order |
|||
sale_order = self.create( |
|||
self.with_context( |
|||
is_pos_pricelist=is_pos_pricelist |
|||
)._prepare_order_field_from_pos(order_data) |
|||
) |
|||
order_vals = self._prepare_from_pos(order_data) |
|||
sale_order = self.create(order_vals.copy()) |
|||
sale_order.onchange_partner_id() |
|||
# we rewrite data, because onchange could alter some |
|||
# custom data (like pricelist) |
|||
sale_order.write(order_vals) |
|||
|
|||
# create Sale order lines |
|||
for order_line_data in order_data["lines"]: |
|||
# Create Sale order lines |
|||
order_line_vals = SaleOrderLine._prepare_from_pos( |
|||
sale_order, order_line_data[2]) |
|||
sale_order_line = SaleOrderLine.create( |
|||
order_line_vals.copy()) |
|||
sale_order_line.product_id_change() |
|||
# we rewrite data, because onchange could alter some |
|||
# data (like quantity, or price) |
|||
sale_order_line.write(order_line_vals) |
|||
|
|||
# Confirm Sale Order |
|||
if order_data["sale_order_state"] in ["confirmed", "delivered"]: |
|||
sale_order.action_button_confirm() |
|||
if action in ["confirmed", "delivered"]: |
|||
sale_order.action_confirm() |
|||
|
|||
# mark picking as delivered |
|||
if order_data["sale_order_state"] == "delivered": |
|||
sale_order.picking_ids.force_assign() |
|||
sale_order.picking_ids.do_transfer() |
|||
if action == "delivered": |
|||
# Mark all moves are delivered |
|||
for move in sale_order.mapped( |
|||
"picking_ids.move_ids_without_package"): |
|||
move.quantity_done = move.product_uom_qty |
|||
sale_order.mapped("picking_ids").button_validate() |
|||
|
|||
return { |
|||
"sale_order_id": sale_order.id, |
|||
|
@ -0,0 +1,23 @@ |
|||
# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) |
|||
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from odoo import api, models |
|||
|
|||
|
|||
class SaleOrderLine(models.Model): |
|||
_inherit = "sale.order.line" |
|||
|
|||
@api.model |
|||
def _prepare_from_pos(self, sale_order, order_line_data): |
|||
ProductProduct = self.env["product.product"] |
|||
product = ProductProduct.browse(order_line_data["product_id"]) |
|||
return { |
|||
"order_id": sale_order.id, |
|||
"product_id": order_line_data["product_id"], |
|||
"name": product.name, |
|||
"product_uom_qty": order_line_data["qty"], |
|||
"discount": order_line_data["discount"], |
|||
"price_unit": order_line_data["price_unit"], |
|||
"tax_id": order_line_data["tax_ids"], |
|||
} |
@ -1,11 +0,0 @@ |
|||
* Because of the poor design of the Odoo Point of Sale, some basic features |
|||
are not available by default, like pricelist, fiscal position, etc ... |
|||
For that reason, unit price will be recomputed by default, when creating the |
|||
sale order, and the unit price of the current bill will not be used. |
|||
|
|||
Note that this problem is fixed if ``pos_pricelist`` is installed. |
|||
(same repository) In that cases, the pricelist, the unit prices and the taxes |
|||
will be the same in the order, as in the displayed bill. |
|||
|
|||
.. figure:: ../static/description/pos_create_picking_confirm.png |
|||
:width: 800 px |
@ -0,0 +1,23 @@ |
|||
* Open your Point of sale |
|||
* create a new order and select products |
|||
* select a customer |
|||
|
|||
* then, click on the "Create Sale Order" button |
|||
|
|||
.. figure:: ../static/description/pos_frontend_order.png |
|||
:width: 800 px |
|||
|
|||
Three options are available: |
|||
|
|||
* **Create a draft Order** |
|||
A new sale order in a draft mode will be created that can be changed later. |
|||
|
|||
* **Create a Confirmed Order** |
|||
A new sale order will be created and confirmed. |
|||
|
|||
* **Create Delivered Picking** (by default) |
|||
A new sale order will be created and confirmed. the associated picking |
|||
will be marked as delivered. |
|||
|
|||
.. figure:: ../static/description/pos_frontend_buttons.png |
|||
:width: 800 px |
Before Width: 841 | Height: 427 | Size: 38 KiB After Width: 990 | Height: 414 | Size: 37 KiB |
Before Width: 513 | Height: 423 | Size: 28 KiB |
Before Width: 420 | Height: 277 | Size: 20 KiB |
Before Width: 415 | Height: 274 | Size: 21 KiB |
Before Width: 422 | Height: 279 | Size: 20 KiB |
After Width: 585 | Height: 346 | Size: 18 KiB |
After Width: 435 | Height: 332 | Size: 36 KiB |
@ -1,12 +0,0 @@ |
|||
/* |
|||
Copyright (C) 2018 - Today: GRAP (http://www.grap.coop) |
|||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain) |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
*/ |
|||
|
|||
/*Redefine here, the style defined in web module (base.css), because this file |
|||
is not loaded in the point of sale.*/ |
|||
.blockUI.blockOverlay { |
|||
background-color: black; |
|||
opacity: 0.6; |
|||
} |
@ -1,225 +0,0 @@ |
|||
/* *************************************************************************** |
|||
Copyright (C) 2017 - Today: GRAP (http://www.grap.coop)
|
|||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|||
**************************************************************************** */ |
|||
|
|||
openerp.pos_order_to_sale_order = function (instance) { |
|||
|
|||
"use strict"; |
|||
|
|||
var module = instance.point_of_sale; |
|||
var _t = instance.web._t; |
|||
|
|||
/* ************************************************************************ |
|||
New Widget CreateSaleOrderButtonWidget |
|||
************************************************************************ */ |
|||
module.CreateSaleOrderButtonWidget = module.PosBaseWidget.extend({ |
|||
template: 'CreateSaleOrderButtonWidget', |
|||
|
|||
/** |
|||
* Define all the confirmation messages. |
|||
*/ |
|||
init: function (parent, options) { |
|||
this._super(parent, options); |
|||
this.sale_order_state = options.sale_order_state; |
|||
if (this.sale_order_state === 'draft') { |
|||
this.display_text = _t("Create Draft Order"); |
|||
this.confirmation_message = _t( |
|||
'Create Draft Sale Order and discard the current' + |
|||
' PoS Order?'); |
|||
this.confirmation_comment = _t( |
|||
"This operation will permanently discard the current PoS" + |
|||
" Order and create a draft Sale Order, based on the" + |
|||
" current order lines."); |
|||
} else if (options.sale_order_state === 'confirmed') { |
|||
this.display_text = _t("Create Confirmed Order"); |
|||
this.confirmation_message = _t( |
|||
'Create Confirmed Sale Order and discard the current' + |
|||
' PoS Order?'); |
|||
this.confirmation_comment = _t( |
|||
"This operation will permanently discard the current PoS" + |
|||
" Order and create a confirmed Sale Order, based on the" + |
|||
" current order lines."); |
|||
} else if (options.sale_order_state === 'delivered') { |
|||
this.display_text = _t("Create Delivered Order"); |
|||
this.confirmation_message = _t( |
|||
'Create Delivered Sale Order and discard the current' + |
|||
' PoS Order?'); |
|||
this.confirmation_comment = _t( |
|||
"This operation will permanently discard the current PoS" + |
|||
" Order and create a confirmed Sale Order, based on the" + |
|||
" current order lines. The according picking will be" + |
|||
" marked as delivered."); |
|||
} |
|||
if (! this.pos.pricelist_engine) { |
|||
this.confirmation_comment += _t( |
|||
"\nNote if you have manually changed unit prices for" + |
|||
" some products, this changes will not been taken into" + |
|||
" account in the sale order.") |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Define onclick function when the button to create sale order is |
|||
* clicked. |
|||
* - On click, check if there is a customer defined, |
|||
* - ask confirmation call server to create sale order, and delete |
|||
* the current order. |
|||
*/ |
|||
renderElement: function () { |
|||
var self = this; |
|||
this._super(); |
|||
this.$el.click(function () { |
|||
var current_order = self.pos.get('selectedOrder'); |
|||
// Prevent empty delivery order
|
|||
if (current_order.get('orderLines').length === 0) { |
|||
self.pos_widget.screen_selector.show_popup('error', { |
|||
'message': _t('Empty Order'), |
|||
'comment': _t( |
|||
'There must be at least one product in your' + |
|||
' order to create Sale Order.'), |
|||
}); |
|||
return; |
|||
} |
|||
// Check Customer
|
|||
if (!current_order.get('client')) { |
|||
self.pos_widget.screen_selector.show_popup('error', { |
|||
'message': _t('No customer defined'), |
|||
'comment': _t( |
|||
'You should select a customer in order to create' + |
|||
' a Sale Order. Please select one by clicking' + |
|||
' the order tab.'), |
|||
}); |
|||
return; |
|||
} |
|||
self.pos.pos_widget.screen_selector.show_popup('confirm', { |
|||
message: self.confirmation_message, |
|||
comment: self.confirmation_comment, |
|||
confirm: function () { |
|||
var SaleOrderModel = |
|||
new instance.web.Model('sale.order'); |
|||
current_order.sale_order_state = self.sale_order_state; |
|||
instance.web.blockUI(); |
|||
SaleOrderModel.call('create_order_from_pos', [ |
|||
self.prepare_create_sale_order(current_order)] |
|||
).then(function (result) { |
|||
instance.web.unblockUI(); |
|||
self.hook_create_sale_order_success(result); |
|||
}).fail(function (error, event) { |
|||
instance.web.unblockUI(); |
|||
self.hook_create_sale_order_error(error, event); |
|||
}); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* Overloadable function to send custom sale order data to server |
|||
*/ |
|||
prepare_create_sale_order: function (order) { |
|||
var res = order.export_as_JSON(); |
|||
res.sale_order_state = this.sale_order_state; |
|||
return res; |
|||
}, |
|||
|
|||
/** |
|||
* Overloadable function to make custom action after Sale order |
|||
* Creation succeeded |
|||
*/ |
|||
hook_create_sale_order_success: function (result) { |
|||
this.pos.get('selectedOrder').destroy(); |
|||
}, |
|||
|
|||
/** |
|||
* Overloadable function to make custom action after Sale order |
|||
* Creation failed |
|||
*/ |
|||
hook_create_sale_order_error: function (error, event) { |
|||
event.preventDefault(); |
|||
if (error.code === 200) { |
|||
// Business Logic Error, not a connection problem
|
|||
this.pos_widget.screen_selector.show_popup('error-traceback', { |
|||
message: error.data.message, |
|||
comment: error.data.debug, |
|||
}); |
|||
} else { |
|||
// Connexion problem
|
|||
this.pos_widget.screen_selector.show_popup('error', { |
|||
message: _t('The order could not be sent'), |
|||
comment: _t( |
|||
'Check your internet connection and try again.'), |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
|
|||
|
|||
/* ************************************************************************ |
|||
Extend PosWidget: |
|||
************************************************************************ */ |
|||
module.PosWidget = module.PosWidget.extend({ |
|||
|
|||
/** |
|||
* Overload build_widgets(), to create new buttons, depending of the |
|||
* configuration |
|||
*/ |
|||
build_widgets: function () { |
|||
this._super(); |
|||
if (this.pos.config.iface_create_draft_sale_order) { |
|||
this.create_draft_sale_order_button = |
|||
new module.CreateSaleOrderButtonWidget( |
|||
this, {'sale_order_state': 'draft'}); |
|||
this.create_draft_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines')); |
|||
} |
|||
if (this.pos.config.iface_create_confirmed_sale_order) { |
|||
this.create_confirmed_sale_order_button = |
|||
new module.CreateSaleOrderButtonWidget( |
|||
this, {'sale_order_state': 'confirmed'}); |
|||
this.create_confirmed_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines')); |
|||
} |
|||
if (this.pos.config.iface_create_delivered_sale_order) { |
|||
this.create_delivered_sale_order_button = |
|||
new module.CreateSaleOrderButtonWidget( |
|||
this, {'sale_order_state': 'delivered'}); |
|||
this.create_delivered_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines')); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
|
|||
/* ************************************************************************ |
|||
Extend OrderWidget |
|||
************************************************************************ */ |
|||
module.OrderWidget = module.OrderWidget.extend({ |
|||
|
|||
/** |
|||
* Overload renderElement(), to display buttons when the order change. |
|||
*/ |
|||
renderElement: function (scrollbottom) { |
|||
this._super(scrollbottom); |
|||
if (this.pos_widget.create_draft_sale_order_button) { |
|||
this.pos_widget.create_draft_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines') |
|||
); |
|||
} |
|||
if (this.pos_widget.create_confirmed_sale_order_button) { |
|||
this.pos_widget.create_confirmed_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines') |
|||
); |
|||
} |
|||
if (this.pos_widget.create_delivered_sale_order_button) { |
|||
this.pos_widget.create_delivered_sale_order_button.appendTo( |
|||
this.pos_widget.$('ul.orderlines') |
|||
); |
|||
} |
|||
|
|||
}, |
|||
}); |
|||
|
|||
}; |
@ -0,0 +1,163 @@ |
|||
/** *************************************************************************** |
|||
Copyright (C) 2017 - Today: GRAP (http://www.grap.coop)
|
|||
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
|
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|||
******************************************************************************/ |
|||
|
|||
odoo.define('pos_order_to_sale_order.screens', function (require) { |
|||
"use strict"; |
|||
|
|||
var screens = require('point_of_sale.screens'); |
|||
var gui = require('point_of_sale.gui'); |
|||
var core = require('web.core'); |
|||
var framework = require('web.framework'); |
|||
var rpc = require('web.rpc'); |
|||
var _t = core._t; |
|||
|
|||
/** ********************************************************************** |
|||
New Widget CreateSaleOrderButtonWidget: |
|||
* On click, display a new screen to select the action to do |
|||
*/ |
|||
var CreateSaleOrderButtonWidget = screens.ActionButtonWidget.extend({ |
|||
template: 'CreateSaleOrderButtonWidget', |
|||
|
|||
button_click: function () { |
|||
if (this.pos.get_order().get_client()) { |
|||
this.gui.show_screen('create_sale_order'); |
|||
} else { |
|||
this.gui.show_popup('error', { |
|||
'title': _t('No customer defined'), |
|||
'body': _t( |
|||
'You should select a customer in order to create' + |
|||
' a Sale Order.'), |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
is_visible: function () { |
|||
return this.pos.get_order().orderlines.length > 0; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
screens.define_action_button({ |
|||
'name': 'create_sale_order', |
|||
'widget': CreateSaleOrderButtonWidget, |
|||
'condition': function () { |
|||
return this.pos.config.iface_create_sale_order; |
|||
}, |
|||
}); |
|||
|
|||
screens.OrderWidget.include({ |
|||
update_summary: function () { |
|||
this._super(); |
|||
if (this.getParent().action_buttons && |
|||
this.getParent().action_buttons.create_sale_order) { |
|||
this.getParent().action_buttons.create_sale_order.renderElement(); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
/** ********************************************************************** |
|||
New ScreenWidget CreateSaleOrderScreenWidget: |
|||
* On show, display all buttons, depending on the pos configuration |
|||
*/ |
|||
var CreateSaleOrderScreenWidget = screens.ScreenWidget.extend({ |
|||
template: 'CreateSaleOrderScreenWidget', |
|||
auto_back: true, |
|||
|
|||
|
|||
show: function(){ |
|||
var self = this; |
|||
this._super(); |
|||
|
|||
this.renderElement(); |
|||
|
|||
this.$('.back').click(function(){ |
|||
self.gui.back(); |
|||
}); |
|||
|
|||
if (!this.pos.config.iface_create_draft_sale_order) { |
|||
this.$('#button-create-draft-order').addClass('oe_hidden'); |
|||
} |
|||
if (!this.pos.config.iface_create_confirmed_sale_order) { |
|||
this.$('#button-create-confirmed-order').addClass('oe_hidden'); |
|||
} |
|||
if (!this.pos.config.iface_create_delivered_sale_order) { |
|||
this.$('#button-create-delivered-order').addClass('oe_hidden'); |
|||
} |
|||
|
|||
this.$('.paymentmethod').click(function(event){ |
|||
self.click_sale_order_button(event.currentTarget.attributes.action.nodeValue); |
|||
}); |
|||
}, |
|||
|
|||
click_sale_order_button: function(action) { |
|||
var self = this; |
|||
console.log("click_sale_order_button : " + action); |
|||
|
|||
this.gui.show_popup('confirm', { |
|||
'title': _t( |
|||
'Create Sale Order and discard the current' + |
|||
' PoS Order?'), |
|||
'body': _t( |
|||
"This operation will permanently discard the current PoS" + |
|||
" Order and create a Sale Order, based on the" + |
|||
" current order lines."), |
|||
confirm: function(){ |
|||
framework.blockUI(); |
|||
rpc.query({ |
|||
model: 'sale.order', |
|||
method: 'create_order_from_pos', |
|||
args: [self.pos.get('selectedOrder').export_as_JSON(), action], |
|||
}).then(function (result) { |
|||
self.hook_create_sale_order_success(result); |
|||
}).fail(function (error, event) { |
|||
self.hook_create_sale_order_error(error, event); |
|||
}); |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* Overloadable function to make custom action after Sale order |
|||
* Creation succeeded |
|||
*/ |
|||
hook_create_sale_order_success: function (result) { |
|||
framework.unblockUI(); |
|||
this.pos.get('selectedOrder').destroy(); |
|||
}, |
|||
|
|||
/** |
|||
* Overloadable function to make custom action after Sale order |
|||
* Creation failed |
|||
*/ |
|||
hook_create_sale_order_error: function (error, event) { |
|||
framework.unblockUI(); |
|||
event.preventDefault(); |
|||
if (error.code === 200) { |
|||
// Business Logic Error, not a connection problem
|
|||
this.gui.show_popup('error-traceback', { |
|||
'title': error.data.message, |
|||
'body': error.data.debug, |
|||
}); |
|||
} else { |
|||
// Connexion problem
|
|||
this.gui.show_popup('error', { |
|||
'title': _t('The order could not be sent'), |
|||
'body': _t('Check your internet connection and try again.'), |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
}); |
|||
|
|||
gui.define_screen({ |
|||
'name': 'create_sale_order', |
|||
'widget': CreateSaleOrderScreenWidget, |
|||
'condition': function () { |
|||
return this.pos.config.iface_create_sale_order; |
|||
}, |
|||
}); |
|||
|
|||
}); |
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<odoo> |
|||
|
|||
<template id="assets" inherit_id="point_of_sale.assets"> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/pos_order_to_sale_order/static/src/js/screens.js"></script> |
|||
</xpath> |
|||
</template> |
|||
|
|||
</odoo> |
@ -1,14 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<openerp><data> |
|||
|
|||
<template id="assets_backend" name="pos_order_to_sale_order assets" inherit_id="point_of_sale.index"> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/pos_order_to_sale_order/static/src/js/pos_order_to_sale_order.js"></script> |
|||
</xpath> |
|||
<xpath expr="//link[@id='pos-stylesheet']" position="after"> |
|||
<link rel="stylesheet" href="/pos_order_to_sale_order/static/src/css/pos_order_to_sale_order.css"/> |
|||
</xpath> |
|||
</template> |
|||
|
|||
</data></openerp> |
@ -1,16 +1,66 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp><data> |
|||
<odoo> |
|||
|
|||
<record id="view_pos_config_form" model="ir.ui.view"> |
|||
<record id="view_pos_config_form" model="ir.ui.view"> |
|||
<field name="model">pos.config</field> |
|||
<field name="inherit_id" ref="point_of_sale.view_pos_config_form"/> |
|||
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/> |
|||
<field name="arch" type="xml"> |
|||
<field name="iface_invoicing" position="after"> |
|||
<field name="iface_create_draft_sale_order" /> |
|||
<field name="iface_create_confirmed_sale_order" /> |
|||
<field name="iface_create_delivered_sale_order" /> |
|||
</field> |
|||
|
|||
<xpath expr="//h2[@name='order']" position="before"> |
|||
|
|||
<h2 name="create_sale_order">Sale Order Creations</h2> |
|||
<div class="row mt16 o_settings_container"> |
|||
<div class="col-12 col-lg-6 o_setting_box"> |
|||
<div class="o_setting_left_pane"> |
|||
<field name="iface_create_draft_sale_order"/> |
|||
</div> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="iface_create_draft_sale_order"/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-12 col-lg-6 o_setting_box"> |
|||
<div class="o_setting_left_pane"> |
|||
<field name="iface_create_confirmed_sale_order"/> |
|||
</div> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="iface_create_confirmed_sale_order"/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-12 col-lg-6 o_setting_box"> |
|||
<div class="o_setting_left_pane"> |
|||
<field name="iface_create_delivered_sale_order"/> |
|||
</div> |
|||
<div class="o_setting_right_pane"> |
|||
<label for="iface_create_delivered_sale_order"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
|||
|
|||
<!-- string="Create Delivered Sale Orders" --> |
|||
|
|||
|
|||
<!-- <div class="text-muted"> |
|||
Display pictures of product categories |
|||
</div> |
|||
|
|||
|
|||
<xpath expr="//field[@name='iface_cashdrawer']/.." position="after"> |
|||
<div class="row"> |
|||
<label string="Create Draft Sale Orders" for="iface_create_draft_sale_order" class="col-lg-3 o_light_label"/> |
|||
<field name="iface_create_draft_sale_order"/> |
|||
</div> |
|||
<div class="row"> |
|||
<label string="Create Confirmed Sale Orders" for="iface_create_confirmed_sale_order" class="col-lg-3 o_light_label"/> |
|||
<field name="iface_create_confirmed_sale_order"/> |
|||
</div> |
|||
<div class="row"> |
|||
<label string="Create Delivered Sale Orders" for="iface_create_delivered_sale_order" class="col-lg-3 o_light_label"/> |
|||
<field name="iface_create_delivered_sale_order"/> |
|||
</div> --> |
|||
|
|||
</data></openerp> |