diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 6a6e84d2104..2c68e064f44 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -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 = "

Dear %s,
Here is your electronic ticket from the %s.

" % (client['name'], name) + template_data = { + 'subject': 'Receipt %s' % name, + 'body_html': message + '' % 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 diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 3e008db4347..1bfe646ebee 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -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){ diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index d22e9dd7f6a..c988db5cfdb 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -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}); diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 713aace77af..96529b384d5 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -824,6 +824,9 @@ +
+ Email +
Tip