diff options
| -rw-r--r-- | addons/payment/models/payment_acquirer.py | 2 | ||||
| -rw-r--r-- | addons/payment/views/payment_views.xml | 14 | ||||
| -rw-r--r-- | addons/payment_transfer/__manifest__.py | 1 | ||||
| -rw-r--r-- | addons/payment_transfer/models/payment.py | 7 | ||||
| -rw-r--r-- | addons/payment_transfer/views/payment_views.xml | 25 | ||||
| -rw-r--r-- | addons/website_sale/controllers/main.py | 110 | ||||
| -rw-r--r-- | addons/website_sale/models/sale_order.py | 11 | ||||
| -rw-r--r-- | addons/website_sale/static/src/js/website_sale_validate.js | 2 | ||||
| -rw-r--r-- | addons/website_sale/views/templates.xml | 96 | ||||
| -rw-r--r-- | addons/website_sale_delivery/controllers/main.py | 19 | ||||
| -rw-r--r-- | addons/website_sale_delivery/models/sale_order.py | 23 | ||||
| -rw-r--r-- | addons/website_sale_delivery/views/website_sale_delivery_templates.xml | 48 |
12 files changed, 167 insertions, 191 deletions
diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py index ae990799b38..535a56c2336 100644 --- a/addons/payment/models/payment_acquirer.py +++ b/addons/payment/models/payment_acquirer.py @@ -353,7 +353,7 @@ class PaymentAcquirer(models.Model): return True @api.multi - def toggle_enviroment_value(self): + def toggle_environment_value(self): prod = self.filtered(lambda acquirer: acquirer.environment == 'prod') prod.write({'environment': 'test'}) (self-prod).write({'environment': 'prod'}) diff --git a/addons/payment/views/payment_views.xml b/addons/payment/views/payment_views.xml index 510d22c5b97..bf703e89ece 100644 --- a/addons/payment/views/payment_views.xml +++ b/addons/payment/views/payment_views.xml @@ -30,13 +30,21 @@ <field name="module_id" invisible="1"/> <field name="module_state" invisible="1"/> <div class="oe_button_box" name="button_box" attrs="{'invisible': ['&', ('module_id', '!=', False), ('module_state', '!=', 'installed')]}"> - <button attrs="{'invisible': [('environment', '=', 'test')]}" class="oe_stat_button" name="toggle_enviroment_value" type="object" icon="fa-play"> + <!-- transfer referenced here due to view inheritance issue in current master (post-saas-16) --> + <button name="toggle_environment_value" + attrs="{'invisible': ['|', ('environment', '=', 'test'), ('provider', '=', 'transfer')]}" + class="oe_stat_button" + type="object" icon="fa-play"> <div class="o_stat_info o_field_widget"> <span class="text-success">Production</span> <span class="o_stat_text">Environment</span> </div> </button> - <button attrs="{'invisible': [('environment', '=', 'prod')]}" class="oe_stat_button" name="toggle_enviroment_value" type="object" icon="fa-stop"> + <!-- transfer referenced here due to view inheritance issue in current master (post-saas-16) --> + <button name="toggle_environment_value" + attrs="{'invisible': ['|', ('environment', '=', 'prod'), ('provider', '=', 'transfer')]}" + class="oe_stat_button" + type="object" icon="fa-stop"> <div class="o_stat_info o_field_widget"> <span class="o_warning_text">Test</span> <span class="o_stat_text">Environment</span> @@ -63,7 +71,7 @@ </group> </group> <notebook attrs="{'invisible': ['&', ('module_id', '!=', False), ('module_state', '!=', 'installed')]}"> - <page string="Credentials"> + <page string="Credentials" name="acquirer_credentials"> <group name="acquirer"> </group> </page> diff --git a/addons/payment_transfer/__manifest__.py b/addons/payment_transfer/__manifest__.py index d26949df288..9f8704467dc 100644 --- a/addons/payment_transfer/__manifest__.py +++ b/addons/payment_transfer/__manifest__.py @@ -8,6 +8,7 @@ 'description': """Transfer Payment Acquirer""", 'depends': ['payment'], 'data': [ + 'views/payment_views.xml', 'views/payment_transfer_templates.xml', 'data/payment_acquirer_data.xml', ], diff --git a/addons/payment_transfer/models/payment.py b/addons/payment_transfer/models/payment.py index 996294bf287..00a34ac0ad4 100644 --- a/addons/payment_transfer/models/payment.py +++ b/addons/payment_transfer/models/payment.py @@ -46,6 +46,13 @@ class TransferPaymentAcquirer(models.Model): values['post_msg'] = self._format_transfer_data() return super(TransferPaymentAcquirer, self).create(values) + @api.multi + def write(self, values): + """ Hook in write to create a default post_msg. See create(). """ + if all(not acquirer.post_msg and acquirer.provider != 'transfer' for acquirer in self) and values.get('provider') == 'transfer': + values['post_msg'] = self._format_transfer_data() + return super(TransferPaymentAcquirer, self).write(values) + class TransferPaymentTransaction(models.Model): _inherit = 'payment.transaction' diff --git a/addons/payment_transfer/views/payment_views.xml b/addons/payment_transfer/views/payment_views.xml new file mode 100644 index 00000000000..127ab7b1238 --- /dev/null +++ b/addons/payment_transfer/views/payment_views.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="payment_acquirer_view_form_inherit_transfer" model="ir.ui.view"> + <field name="name">payment.acquirer.view.form.inherit.transfer</field> + <field name="model">payment.acquirer</field> + <field name="inherit_id" ref="payment.acquirer_form"/> + <field name="arch" type="xml"> + <page name="acquirer_credentials" position="attributes"> + <attribute name="attrs">{'invisible': [('provider', '=', 'transfer')]}</attribute> + </page> + <field name="done_msg" position="attributes"> + <attribute name="attrs">{'invisible': [('provider', '=', 'transfer')]}</attribute> + </field> + <field name="cancel_msg" position="attributes"> + <attribute name="attrs">{'invisible': [('provider', '=', 'transfer')]}</attribute> + </field> + <field name="error_msg" position="attributes"> + <attribute name="attrs">{'invisible': [('provider', '=', 'transfer')]}</attribute> + </field> + <field name="auto_confirm" position="attributes"> + <attribute name="attrs">{'invisible': [('provider', '=', 'transfer')]}</attribute> + </field> + </field> + </record> +</odoo> diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 9ff71a4f1a0..4ea4f981320 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -696,6 +696,40 @@ class WebsiteSale(http.Controller): # Payment # ------------------------------------------------------ + def _get_shop_payment_values(self, order, **kwargs): + shipping_partner_id = False + if order: + shipping_partner_id = order.partner_shipping_id.id or order.partner_invoice_id.id + + values = dict( + website_sale_order=order, + errors=[], + partner=order.partner_id.id, + order=order, + payment_action_id=request.env.ref('payment.action_payment_acquirer').id, + ) + + acquirers = request.env['payment.acquirer'].search( + [('website_published', '=', True), ('company_id', '=', order.company_id.id)] + ) + values['acquirers'] = [] + for acquirer in acquirers: + acquirer_button = acquirer.with_context(submit_class='btn btn-primary', submit_txt=_('Pay Now')).sudo().render( + '/', + order.amount_total, + order.pricelist_id.currency_id.id, + values={ + 'return_url': '/shop/payment/validate', + 'partner_id': shipping_partner_id, + 'billing_partner_id': order.partner_invoice_id.id, + } + ) + acquirer.button = acquirer_button + values['acquirers'].append(acquirer) + values['tokens'] = request.env['payment.token'].search([('partner_id', '=', order.partner_id.id), ('acquirer_id', 'in', acquirers.ids)]) + + return values + @http.route(['/shop/payment'], type='http', auth="public", website=True) def payment(self, **post): """ Payment step. This page proposes several payment means based on available @@ -707,48 +741,18 @@ class WebsiteSale(http.Controller): did go to a payment.acquirer website but closed the tab without paying / canceling """ - SaleOrder = request.env['sale.order'] - order = request.website.sale_get_order() - redirection = self.checkout_redirection(order) if redirection: return redirection - shipping_partner_id = False - if order: - if order.partner_shipping_id.id: - shipping_partner_id = order.partner_shipping_id.id - else: - shipping_partner_id = order.partner_invoice_id.id + render_values = self._get_shop_payment_values(order, **post) - values = { - 'website_sale_order': order - } - values['errors'] = SaleOrder._get_errors(order) - values.update(SaleOrder._get_website_data(order)) - if not values['errors']: - acquirers = request.env['payment.acquirer'].search( - [('website_published', '=', True), ('company_id', '=', order.company_id.id)] - ) - values['acquirers'] = [] - for acquirer in acquirers: - acquirer_button = acquirer.with_context(submit_class='btn btn-primary', submit_txt=_('Pay Now')).sudo().render( - '/', - order.amount_total, - order.pricelist_id.currency_id.id, - values={ - 'return_url': '/shop/payment/validate', - 'partner_id': shipping_partner_id, - 'billing_partner_id': order.partner_invoice_id.id, - } - ) - acquirer.button = acquirer_button - values['acquirers'].append(acquirer) - - values['tokens'] = request.env['payment.token'].search([('partner_id', '=', order.partner_id.id), ('acquirer_id', 'in', acquirers.ids)]) - - return request.render("website_sale.payment", values) + if render_values['errors']: + render_values.pop('acquirers', '') + render_values.pop('tokens', '') + + return request.render("website_sale.payment", render_values) @http.route(['/shop/payment/transaction_token/confirm'], type='json', auth="public", website=True) def payment_transaction_token_confirm(self, tx, **kwargs): @@ -856,35 +860,15 @@ class WebsiteSale(http.Controller): @http.route('/shop/payment/get_status/<int:sale_order_id>', type='json', auth="public", website=True) def payment_get_status(self, sale_order_id, **post): - order = request.env['sale.order'].sudo().browse(sale_order_id) + order = request.env['sale.order'].sudo().browse(sale_order_id).exists() assert order.id == request.session.get('sale_last_order_id') - values = {} - flag = False - if not order: - values.update({'not_order': True, 'state': 'error'}) - else: - tx = request.env['payment.transaction'].sudo().search( - ['|', ('sale_order_id', '=', order.id), ('reference', '=', order.name)], limit=1 - ) - - if not tx: - if order.amount_total: - values.update({'tx_ids': False, 'state': 'error'}) - else: - values.update({'tx_ids': False, 'state': 'done', 'validation': None}) - else: - state = tx.state - flag = state == 'pending' - values.update({ - 'tx_ids': True, - 'state': state, - 'acquirer_id': tx.acquirer_id, - 'validation': tx.acquirer_id.auto_confirm == 'none', - 'tx_post_msg': tx.acquirer_id.post_msg or None - }) - - return {'recall': flag, 'message': request.env['ir.ui.view'].render_template("website_sale.order_state_message", values)} + return { + 'recall': order.payment_tx_id.state == 'pending', + 'message': request.env['ir.ui.view'].render_template("website_sale.payment_confirmation_status", { + 'order': order + }) + } @http.route('/shop/payment/validate', type='http', auth="public", website=True) def payment_validate(self, transaction_id=None, sale_order_id=None, **post): diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py index baf78e4c01b..355af951f61 100644 --- a/addons/website_sale/models/sale_order.py +++ b/addons/website_sale/models/sale_order.py @@ -31,17 +31,6 @@ class SaleOrder(models.Model): order.cart_quantity = int(sum(order.mapped('website_order_line.product_uom_qty'))) order.only_services = all(l.product_id.type in ('service', 'digital') for l in order.website_order_line) - @api.model - def _get_errors(self, order): - return [] - - @api.model - def _get_website_data(self, order): - return { - 'partner': order.partner_id.id, - 'order': order - } - @api.multi def _cart_find_product_line(self, product_id=None, line_id=None, **kwargs): self.ensure_one() diff --git a/addons/website_sale/static/src/js/website_sale_validate.js b/addons/website_sale/static/src/js/website_sale_validate.js index dce80543dc3..2518766f488 100644 --- a/addons/website_sale/static/src/js/website_sale_validate.js +++ b/addons/website_sale/static/src/js/website_sale_validate.js @@ -12,7 +12,7 @@ $(document).ready(function () { if (! order_node || order_node.data('order-id') === undefined) { return; } - var order_id = order_node.data('order-id'); + var order_id = parseInt(order_node.data('order-id')); return ajax.jsonRpc('/shop/payment/get_status/' + order_id, 'call', { }).then(function (result) { _poll_nbr += 1; diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 63bf22b2a8b..adc88e4a140 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1369,8 +1369,8 @@ <div class="clearfix" /> <div class="oe_structure" /> <div class="js_payment mb64 col-md-12 row" t-if="acquirers and website_sale_order.amount_total" id="payment_method"> - <div class="col-lg-5 col-sm-6"> - <h4>Payment Method:</h4> + <div class="col-lg-7 col-sm-8"> + <h4>Choose a payment method</h4> <ul class="list-unstyled"> <t t-set="payment_methods_available" t-value="False"/> <t t-set="partner_country" t-value="website_sale_order and website_sale_order.partner_invoice_id.country_id"/> @@ -1411,8 +1411,12 @@ </div> </li> </ul> + <a class="btn btn-default btn-block" + t-attf-href="/web#return_label=Website&action=#{payment_action_id}"> + <i class="fa fa-plus-square" aria-hidden="true"></i> Setup payment methods + </a> </div> - <div class="col-lg-5 col-lg-offset-2 col-sm-6 text-right"> + <div class="col-lg-5 col-sm-4 text-right"> <t t-foreach="acquirers or []" t-as="acquirer" id="acquirers_list"> <div t-att-data-id="acquirer.id" class="oe_sale_acquirer_button hidden pull-right"> <div t-raw="acquirer.button" /> @@ -1471,9 +1475,8 @@ <h1 class="mb32">Order <em t-field="order.name" /> Confirmed</h1> <div class="thanks_msg"> <h2>Thank you for your order. - <a class="btn btn-primary pull-right hidden-xs" href="/shop/print" target="_blank"><i class="fa fa-print"></i> Print - </a></h2> - <div class="oe_website_sale_tx_status" t-att-data-order-id="order.id"></div> + <a class="btn btn-primary pull-right hidden-xs" href="/shop/print" target="_blank"><i class="fa fa-print"></i> Print</a> + </h2> </div> </div> </div> @@ -1586,40 +1589,6 @@ </t> </template> - <template id="order_state_message" name="Order State Message"> - <t groups="base.group_system"> - <a class="btn btn-primary pull-right" target="_blank" t-att-href="'/web#model=%s&id=%s&action=%s&view_type=form' % ('payment.acquirer',acquirer_id.id, 'payment.action_payment_acquirer')"> - <i class="fa fa-cog"></i> Configure Transfer Details</a> - </t> - <t t-if="(not_order and state == 'error') or (not tx_ids and state == 'error')"> - <p>There seems to be an error with your request.</p> - </t> - <t t-if="not tx_ids and state == 'done'"> - <p>Your order has been confirmed, thank you for your loyalty.</p> - </t> - <t t-if="tx_ids and state == 'done'"> - <p>Your payment has been received.</p> - </t> - <t t-if="tx_ids and state == 'authorized'"> - <p>Your payment has been authorized.</p> - </t> - <t t-if="tx_ids and state == 'cancel'"> - <p>The payment seems to have been canceled.</p> - </t> - <t t-if="tx_ids and state == 'pending' and validation"> - <p>Your transaction is waiting a manual confirmation.</p> - <br /> - <t t-if="tx_post_msg"> - <div class="hidden-print"> - <t t-raw="tx_post_msg" /> - </div> - </t> - </t> - <t t-if="tx_ids and state not in ['done', 'cancel', 'pending', 'authorized']"> - <p>Your transaction is waiting confirmation.</p> - </t> - </template> - <template id="total"> <div id="cart_total" t-att-class="extra_class or ''" t-if="website_sale_order"> <div class="row" id="order_total_untaxed"> @@ -1644,36 +1613,31 @@ </template> <template id="payment_confirmation_status"> - <t t-if="order.payment_acquirer_id.auto_confirm == 'none'"> - <div class="panel panel-info"> - <div class="panel-heading" t-raw="order.payment_acquirer_id.pending_msg" /> + <div class="oe_website_sale_tx_status" t-att-data-order-id="order.id"> + <div t-att-class="' panel ' + (order.payment_tx_id.state == 'pending' and 'panel-info') or (order.payment_tx_id.state == 'done' and 'panel-success') or 'panel-danger'"> + <a groups="base.group_system" class="btn btn-primary pull-right" target="_blank" + t-att-href="'/web#model=%s&id=%s&action=%s&view_type=form' % ('payment.acquirer', order.payment_acquirer_id.id, 'payment.action_payment_acquirer')"> + <i class="fa fa-cog"></i> + </a> + <div class="panel-heading"> + <t t-if="order.payment_tx_id.state == 'pending'"> + <t t-raw="order.payment_acquirer_id.pending_msg"/> + </t> + <t t-if="order.payment_tx_id.state == 'done'"> + <t t-raw="order.payment_acquirer_id.done_msg"/> + </t> + <t t-if="order.payment_tx_id.state == 'cancel'"> + <t t-raw="order.payment_acquirer_id.cancel_msg"/> + </t> + <t t-if="order.payment_tx_id.state == 'error'"> + <t t-raw="order.payment_acquirer_id.error_msg"/> + </t> + </div> <div class="panel-body" t-if="order.payment_acquirer_id.post_msg"> <t t-raw="order.payment_acquirer_id.post_msg" /> </div> </div> - </t> - <t t-if="order.payment_acquirer_id.auto_confirm != 'none'"> - <t t-if="order.payment_tx_id.state == 'pending'"> - <div class="alert alert-info" role="alert"> - <t t-raw="order.payment_acquirer_id.pending_msg" /> - </div> - </t> - <t t-if="order.payment_tx_id.state == 'done'"> - <div class="alert alert-success" role="alert"> - <t t-raw="order.payment_acquirer_id.done_msg" /> - </div> - </t> - <t t-if="order.payment_tx_id.state == 'cancel'"> - <div class="alert alert-danger" role="alert"> - <t t-raw="order.payment_acquirer_id.cancel_msg" /> - </div> - </t> - <t t-if="order.payment_tx_id.state == 'error'"> - <div class="alert alert-danger" role="alert"> - <t t-raw="order.payment_acquirer_id.error_msg" /> - </div> - </t> - </t> + </div> </template> <template id="payment_token_form"> diff --git a/addons/website_sale_delivery/controllers/main.py b/addons/website_sale_delivery/controllers/main.py index 0e0f60aa70a..cbb456d7968 100644 --- a/addons/website_sale_delivery/controllers/main.py +++ b/addons/website_sale_delivery/controllers/main.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import http + +from odoo import http, _ from odoo.http import request from odoo.addons.website_sale.controllers.main import WebsiteSale @@ -32,3 +33,19 @@ class WebsiteSaleDelivery(WebsiteSale): if line.is_delivery: ret['transaction']['shipping'] = line.price_unit return ret + + def _get_shop_payment_values(self, order, **kwargs): + values = super(WebsiteSaleDelivery, self)._get_shop_payment_values(order, **kwargs) + if not order._get_delivery_methods(): + values['errors'].append( + (_('Sorry, we are unable to ship your order'), + _('No shipping method is available for your current order and shipping address. ' + 'Please contact us for more information.'))) + + has_stockable_products = any(line.product_id.type in ['consu', 'product'] for line in order.order_line) + if has_stockable_products: + delivery_carriers = order._get_delivery_methods() + values['deliveries'] = delivery_carriers.sudo().with_context(order_id=order.id) + + values['delivery_action_id'] = request.env.ref('delivery.action_delivery_carrier_form').id + return values diff --git a/addons/website_sale_delivery/models/sale_order.py b/addons/website_sale_delivery/models/sale_order.py index 279dd758711..9b3c98741f8 100644 --- a/addons/website_sale_delivery/models/sale_order.py +++ b/addons/website_sale_delivery/models/sale_order.py @@ -90,29 +90,6 @@ class SaleOrder(models.Model): _logger.debug("Carrier #%s removed from e-commerce carrier list. %s" % (carrier_id, e)) return available_carriers - @api.model - def _get_errors(self, order): - errors = super(SaleOrder, self)._get_errors(order) - if not order._get_delivery_methods(): - errors.append( - (_('Sorry, we are unable to ship your order'), - _('No shipping method is available for your current order and shipping address. ' - 'Please contact us for more information.'))) - return errors - - @api.model - def _get_website_data(self, order): - """ Override to add delivery-related website data. """ - values = super(SaleOrder, self)._get_website_data(order) - # We need a delivery only if we have stockable products - has_stockable_products = any(order.order_line.filtered(lambda line: line.product_id.type in ['consu', 'product'])) - if not has_stockable_products: - return values - - delivery_carriers = order._get_delivery_methods() - values['deliveries'] = delivery_carriers.sudo().with_context(order_id=order.id) - return values - @api.multi def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs): """ Override to update carrier quotation if quantity changed """ diff --git a/addons/website_sale_delivery/views/website_sale_delivery_templates.xml b/addons/website_sale_delivery/views/website_sale_delivery_templates.xml index d7f3a34dbb2..3714aab2230 100644 --- a/addons/website_sale_delivery/views/website_sale_delivery_templates.xml +++ b/addons/website_sale_delivery/views/website_sale_delivery_templates.xml @@ -23,29 +23,33 @@ <template id="payment_delivery" name="Delivery Costs" inherit_id="website_sale.payment"> <xpath expr="//div[@id='payment_method']" position="before"> - <div t-if="deliveries" class="row" id="delivery_carrier"> + <div t-if="deliveries" class="col-md-12 row" id="delivery_carrier"> <div class="col-lg-7 col-sm-8"> - <h4>Choose your Delivery Method</h4> - <ul class="list-unstyled"> - <li t-foreach="deliveries" t-as="delivery"> - <t t-if="delivery.available"> - <div id="delivery_method"> - <label> - <input t-att-value="delivery.id" type="radio" name="delivery_type" - t-att-checked="order.carrier_id and order.carrier_id.id == delivery.id and 'checked' or False"/> - <abbr t-att-title="delivery.website_description"><span t-field="delivery.name"/></abbr> - <span class="badge" t-field="delivery.price" - t-options='{ - "widget": "monetary", - "from_currency": delivery.product_id.company_id.currency_id, - "display_currency": website_sale_order.currency_id - }'/> - <div t-field="delivery.website_description" class="text-muted"/> - </label> - </div> - </t> - </li> - </ul> + <h4>Choose a delivery method</h4> + <ul class="list-unstyled"> + <li t-foreach="deliveries" t-as="delivery"> + <t t-if="delivery.available"> + <div id="delivery_method"> + <label> + <input t-att-value="delivery.id" type="radio" name="delivery_type" + t-att-checked="order.carrier_id and order.carrier_id.id == delivery.id and 'checked' or False"/> + <abbr t-att-title="delivery.website_description"><span t-field="delivery.name"/></abbr> + <span class="badge" t-field="delivery.price" + t-options='{ + "widget": "monetary", + "from_currency": delivery.product_id.company_id.currency_id, + "display_currency": website_sale_order.currency_id + }'/> + <div t-field="delivery.website_description" class="text-muted"/> + </label> + </div> + </t> + </li> + </ul> + <a class="btn btn-default btn-block" + t-attf-href="/web#return_label=Website&action=#{delivery_action_id}"> + <i class="fa fa-plus-square" aria-hidden="true"></i> Setup delivery methods + </a> </div> </div> </xpath> |
