[IMP] point_of_sale: Send ticket by email.
When you select a customer in the front end, you can send him an email with the receipt as an image. If you decided to send the mail and you'd like to print the receipt anyway, you have to click on the When you're offline, the order will be queued and the ticket printed. You'll receive an error message When invoicing, the invoice will be in attachment of the email. TASK-ID: 1922660 closes odoo/odoo#35812 Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,7 @@ from odoo.tools import float_is_zero
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.http import request
|
||||
from odoo.osv.expression import AND
|
||||
import base64
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -607,6 +608,34 @@ class PosOrder(models.Model):
|
||||
'target': 'current',
|
||||
}
|
||||
|
||||
@api.model
|
||||
def action_receipt_to_customer(self, name, client, ticket, invoice_id=False):
|
||||
template_obj = self.env['mail.mail']
|
||||
message = "<p>Dear %s,<br/>Here is your electronic ticket from the %s. </p>" % (client['name'], name)
|
||||
template_data = {
|
||||
'subject': 'Receipt %s' % name,
|
||||
'body_html': message + '<img src="data:image/jpeg;base64,%s"/>' % ticket,
|
||||
'email_from': self.env.company.email,
|
||||
'email_to': client['email']
|
||||
}
|
||||
|
||||
if invoice_id:
|
||||
report = self.env.ref('point_of_sale.pos_invoice_report').render_qweb_pdf(invoice_id)
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'name': name,
|
||||
'type': 'binary',
|
||||
'datas': base64.b64encode(report[0]),
|
||||
'datas_fname': name + '.pdf',
|
||||
'store_fname': name,
|
||||
'res_model': 'account.move',
|
||||
'res_id': invoice_id,
|
||||
'mimetype': 'application/x-pdf'
|
||||
})
|
||||
template_data['attachment_ids'] = attachment
|
||||
|
||||
template_id = template_obj.create(template_data)
|
||||
template_obj.send(template_id)
|
||||
|
||||
@api.model
|
||||
def remove_from_ui(self, server_ids):
|
||||
""" Remove orders from the frontend PoS application
|
||||
|
||||
@@ -890,7 +890,7 @@ exports.PosModel = Backbone.Model.extend({
|
||||
// on success, get the order id generated by the server
|
||||
transfer.then(function(order_server_id){
|
||||
// generate the pdf and download it
|
||||
if (order_server_id.length) {
|
||||
if (order_server_id.length && !order.is_to_email()) {
|
||||
self.chrome.do_action('point_of_sale.pos_invoice_report',{additional_context:{
|
||||
active_ids:order_server_id,
|
||||
}}).then(function () {
|
||||
@@ -900,6 +900,9 @@ exports.PosModel = Backbone.Model.extend({
|
||||
rejectInvoiced({code:401, message:'Backend Invoice', data:{order: order}});
|
||||
rejectDone();
|
||||
});
|
||||
} else if (order_server_id.length) {
|
||||
resolveInvoiced(order_server_id[0]);
|
||||
resolveDone();
|
||||
} else {
|
||||
// The order has been pushed separately in batch when
|
||||
// the connection came back.
|
||||
@@ -2218,6 +2221,7 @@ exports.Order = Backbone.Model.extend({
|
||||
this.temporary = options.temporary || false;
|
||||
this.creation_date = new Date();
|
||||
this.to_invoice = false;
|
||||
this.to_email = false;
|
||||
this.orderlines = new OrderlineCollection();
|
||||
this.paymentlines = new PaymentlineCollection();
|
||||
this.pos_session_id = this.pos.pos_session.id;
|
||||
@@ -2957,6 +2961,13 @@ exports.Order = Backbone.Model.extend({
|
||||
is_to_invoice: function(){
|
||||
return this.to_invoice;
|
||||
},
|
||||
/* ---- Email --- */
|
||||
set_to_email: function(to_email) {
|
||||
this.to_email = to_email;
|
||||
},
|
||||
is_to_email: function(){
|
||||
return this.to_email;
|
||||
},
|
||||
/* ---- Client / Customer --- */
|
||||
// the client related to the current order.
|
||||
set_client: function(client){
|
||||
|
||||
@@ -35,6 +35,7 @@ var rpc = require('web.rpc');
|
||||
var utils = require('web.utils');
|
||||
var field_utils = require('web.field_utils');
|
||||
var BarcodeEvents = require('barcodes.BarcodeEvents').BarcodeEvents;
|
||||
var Printer = require('point_of_sale.Printer').Printer;
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
@@ -1629,7 +1630,7 @@ var ReceiptScreenWidget = ScreenWidget.extend({
|
||||
this.handle_auto_print();
|
||||
},
|
||||
handle_auto_print: function() {
|
||||
if (this.should_auto_print()) {
|
||||
if (this.should_auto_print() && !this.pos.get_order().is_to_email()) {
|
||||
this.print();
|
||||
if (this.should_close_immediately()){
|
||||
this.click_next();
|
||||
@@ -2119,6 +2120,11 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
this.$('.js_invoice').removeClass('highlight');
|
||||
}
|
||||
},
|
||||
click_email: function(){
|
||||
var order = this.pos.get_order();
|
||||
order.set_to_email(!order.is_to_email());
|
||||
this.$('.js_email').toggleClass('highlight', order.is_to_email());
|
||||
},
|
||||
click_tip: function(){
|
||||
var self = this;
|
||||
var order = this.pos.get_order();
|
||||
@@ -2139,9 +2145,14 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
}
|
||||
});
|
||||
},
|
||||
toggle_email_button: function() {
|
||||
var client = this.pos.get_client();
|
||||
this.$('.js_email').removeClass('oe_hidden', client);
|
||||
},
|
||||
customer_changed: function() {
|
||||
var client = this.pos.get_client();
|
||||
this.$('.js_customer_name').text( client ? client.name : _t('Customer') );
|
||||
this.$('.js_customer_name').text( client ? client.name : _t('Customer') );
|
||||
this.toggle_email_button();
|
||||
},
|
||||
click_set_customer: function(){
|
||||
this.gui.show_screen('clientlist');
|
||||
@@ -2179,7 +2190,9 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
this.$('.js_invoice').click(function(){
|
||||
self.click_invoice();
|
||||
});
|
||||
|
||||
this.$('.js_email').click(function(){
|
||||
self.click_email();
|
||||
});
|
||||
this.$('.js_cashdrawer').click(function(){
|
||||
self.pos.proxy.printer.open_cashbox();
|
||||
});
|
||||
@@ -2269,6 +2282,17 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
}
|
||||
}
|
||||
|
||||
if (order.get_client && order.is_to_email() && !order.get_client().email) {
|
||||
this.gui.show_popup('confirm', {
|
||||
'title': _t('Please fill the Customer Email'),
|
||||
'body': _t('This customer does not have an email address, define one or do not send an email'),
|
||||
confirm: function () {
|
||||
this.gui.show_screen('clientlist');
|
||||
},
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the change is too large, it's probably an input error, make the user confirm.
|
||||
if (!force_validation && order.get_total_with_tax() > 0 && (order.get_total_with_tax() * 1000 < order.get_total_paid())) {
|
||||
this.gui.show_popup('confirm',{
|
||||
@@ -2310,13 +2334,32 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
|
||||
invoiced.catch(this._handleFailedPushForInvoice.bind(this, order, false));
|
||||
|
||||
invoiced.then(function () {
|
||||
invoiced.then(function (value) {
|
||||
self.invoicing = false;
|
||||
self.send_receipt_to_customer(value || false);
|
||||
self.gui.show_screen('receipt');
|
||||
});
|
||||
} else {
|
||||
this.pos.push_order(order);
|
||||
this.gui.show_screen('receipt');
|
||||
if (order.is_to_email()){
|
||||
var ordered = this.pos.push_order(order);
|
||||
ordered.then(function() {
|
||||
self.send_receipt_to_customer(false);
|
||||
self.gui.show_screen('receipt');
|
||||
});
|
||||
ordered.catch(function(value) {
|
||||
order.set_to_email(false);
|
||||
self.gui.show_screen('receipt');
|
||||
self.gui.show_popup('error',{
|
||||
'title': "Error: no internet connection",
|
||||
'body': "There is no internet connection, impossible to send the email.",
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.pos.push_order(order);
|
||||
self.gui.show_screen('receipt');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
@@ -2328,6 +2371,31 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
this.finalize_validation();
|
||||
}
|
||||
},
|
||||
|
||||
send_receipt_to_customer: function(invoice_server_id) {
|
||||
var order = this.pos.get_order();
|
||||
if(order.is_to_email()){
|
||||
var data = {
|
||||
widget: this,
|
||||
pos: order.pos,
|
||||
order: order,
|
||||
receipt: order.export_for_printing(),
|
||||
orderlines: order.get_orderlines(),
|
||||
paymentlines: order.get_paymentlines(),
|
||||
}
|
||||
|
||||
var receipt = QWeb.render('OrderReceipt', data);
|
||||
var printer = new Printer();
|
||||
|
||||
printer.htmlToImg(receipt).then(function(ticket) {
|
||||
rpc.query({
|
||||
model: 'pos.order',
|
||||
method: 'action_receipt_to_customer',
|
||||
args: [order.get_name(), order.get_client(), ticket, invoice_server_id],
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
gui.define_screen({name:'payment', widget: PaymentScreenWidget});
|
||||
|
||||
|
||||
@@ -824,6 +824,9 @@
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<div t-attf-class='button js_email #{widget.pos.get_client() ? "" : "oe_hidden"}'>
|
||||
<i class='fa fa-inbox' /> Email
|
||||
</div>
|
||||
<t t-if='widget.pos.config.tip_product_id'>
|
||||
<div class='button js_tip'>
|
||||
<i class='fa fa-heart' /> Tip
|
||||
|
||||
Reference in New Issue
Block a user