From d9c7ff69a4cb815e98b5b92e88404871bb8c4829 Mon Sep 17 00:00:00 2001 From: "Valeriya(vchu)" Date: Thu, 13 Apr 2023 10:15:32 +0200 Subject: [PATCH] [IMP] website_sale, base: use invoice address at checkout at checkout use the invoice address as billing address instead of main address if the invoice one is defined. Add the functionality to add new billings addresses at checkout. task-3258835 Part-of: odoo/odoo#118428 --- addons/website_sale/controllers/main.py | 178 ++++++++++++------ addons/website_sale/models/sale_order.py | 6 + addons/website_sale/models/website.py | 12 +- .../static/src/js/website_sale.js | 25 ++- .../static/src/scss/website_sale.scss | 2 +- .../tests/tours/website_sale_complete_flow.js | 2 +- .../website_sale/tests/test_sale_process.py | 62 +++++- addons/website_sale/views/templates.xml | 129 +++++++------ .../views/templates.xml | 2 +- odoo/addons/base/models/ir_ui_view.py | 4 +- odoo/addons/base/tests/test_views.py | 2 +- 11 files changed, 288 insertions(+), 136 deletions(-) diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index cffcc1acee9..b17a2cedb48 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -959,12 +959,11 @@ class WebsiteSale(payment_portal.PaymentPortal): # ------------------------------------------------------ def checkout_check_address(self, order): - billing_fields_required = self._get_mandatory_fields_billing(order.partner_id.country_id.id) - if not all(order.partner_id.read(billing_fields_required)[0].values()): - return request.redirect('/shop/address?partner_id=%d' % order.partner_id.id) + partner_invoice = order.partner_invoice_id + if not self._check_billing_partner_mandatory_fields(partner_invoice): + return request.redirect('/shop/address?partner_id=%d&is_invoice=1' % partner_invoice.id) - shipping_fields_required = self._get_mandatory_fields_shipping(order.partner_shipping_id.country_id.id) - if not all(order.partner_shipping_id.read(shipping_fields_required)[0].values()): + if not self._check_shipping_partner_mandatory_fields(order.partner_shipping_id): return request.redirect('/shop/address?partner_id=%d' % order.partner_shipping_id.id) def checkout_redirection(self, order): @@ -987,29 +986,49 @@ class WebsiteSale(payment_portal.PaymentPortal): def checkout_values(self, **kw): order = request.website.sale_get_order(force_create=True) - shippings = [] + bill_partners = [] + ship_partners = [] if order.partner_id != request.website.user_id.sudo().partner_id: Partner = order.partner_id.with_context(show_address=1).sudo() - shippings = Partner.search([ - ("id", "child_of", order.partner_id.commercial_partner_id.ids), - '|', ("type", "in", ["delivery", "other"]), ("id", "=", order.partner_id.commercial_partner_id.id) + commercial_partner = order.partner_id.commercial_partner_id + bill_partners = Partner.search([ + ("id", "child_of", commercial_partner.ids), + '|', ("type", "in", ["invoice", "other"]), ("id", "=", commercial_partner.id) ], order='id desc') - if shippings: - if kw.get('partner_id') or 'use_billing' in kw: - if 'use_billing' in kw: - partner_id = order.partner_id.id - else: - partner_id = int(kw.get('partner_id')) - if partner_id in shippings.mapped('id'): - order.partner_shipping_id = partner_id + ship_partners = Partner.search([ + ("id", "child_of", commercial_partner.ids), + '|', ("type", "in", ["delivery", "other"]), ("id", "=", commercial_partner.id) + ], order='id desc') + + # do not show commercial_partner_id if its mandatory fields are not complete to children + # as children can not edit (fill) the commercial_partner_id + if commercial_partner != order.partner_id: + if not self._check_billing_partner_mandatory_fields(commercial_partner): + bill_partners = bill_partners.filtered(lambda p: p.id != commercial_partner.id) + + if not self._check_shipping_partner_mandatory_fields(commercial_partner): + ship_partners = ship_partners.filtered(lambda p: p.id != commercial_partner.id) + + partner_id = int(kw.get('partner_id', 0)) + if partner_id: + if 'is_invoice' in kw and bill_partners and partner_id in bill_partners.mapped('id'): + order.partner_invoice_id = partner_id + elif ship_partners and partner_id in ship_partners.mapped('id'): + order.partner_shipping_id = partner_id values = { 'order': order, - 'shippings': shippings, + 'shippings': ship_partners, + 'billings': bill_partners, 'only_services': order and order.only_services or False } return values + def _check_billing_partner_mandatory_fields(self, partner_id): + ''' return True if all mandatory fields for billing address are complete ''' + billing_fields_required = self._get_mandatory_fields_billing(partner_id.country_id.id) + return all(partner_id.read(billing_fields_required)[0].values()) + def _get_mandatory_fields_billing(self, country_id=False): req = ["name", "email", "street", "city", "country_id"] if country_id: @@ -1020,6 +1039,11 @@ class WebsiteSale(payment_portal.PaymentPortal): req += ['zip'] return req + def _check_shipping_partner_mandatory_fields(self, partner_id): + ''' return True if all mandatory fields for shipping address are complete ''' + shipping_fields_required = self._get_mandatory_fields_shipping(partner_id.country_id.id) + return all(partner_id.read(shipping_fields_required)[0].values()) + def _get_mandatory_fields_shipping(self, country_id=False): req = ["name", "street", "city", "country_id"] if country_id: @@ -1037,13 +1061,16 @@ class WebsiteSale(payment_portal.PaymentPortal): error = dict() error_message = [] - if data.get('partner_id'): + if mode == ('edit', 'billing') and data.get('partner_id'): partner_su = request.env['res.partner'].sudo().browse(int(data['partner_id'])).exists() - name_change = partner_su and 'name' in data and data['name'] != partner_su.name - email_change = partner_su and 'email' in data and data['email'] != partner_su.email + name_change = partner_su and partner_su.name and 'name' in data and data['name'] != partner_su.name + email_change = partner_su and 'email' in data and data['email'] != partner_su.email and partner_su.email + invoices = request.env['account.move'].sudo().search( + [('partner_id', '=', partner_su.id)], limit=1 + ) if partner_su else False # Prevent changing the billing partner name if invoices have been issued. - if mode[1] == 'billing' and name_change and not partner_su.can_edit_vat(): + if name_change and not partner_su.can_edit_vat() and invoices: error['name'] = 'error' error_message.append(_( "Changing your name is not allowed once documents have been issued for your" @@ -1151,20 +1178,23 @@ class WebsiteSale(payment_portal.PaymentPortal): if request.website.specific_user_account: new_values['website_id'] = request.website.id + commercial_partner_id = order.partner_id.commercial_partner_id if mode[0] == 'new': + lang = request.lang.code if request.lang.code in request.website.mapped('language_ids.code') else None + if lang: + new_values['lang'] = lang new_values['company_id'] = request.website.company_id.id new_values['team_id'] = request.website.salesteam_id and request.website.salesteam_id.id new_values['user_id'] = request.website.salesperson_id.id - - lang = request.lang.code if request.lang.code in request.website.mapped('language_ids.code') else None - if lang: - new_values['lang'] = lang - if mode == ('edit', 'billing') and order.partner_id.type == 'contact': - new_values['type'] = 'other' - if mode[1] == 'shipping': - new_values['parent_id'] = order.partner_id.commercial_partner_id.id - new_values['type'] = 'delivery' - + # define type of the new partner + if mode[1] == 'billing': + new_values['type'] = 'other' if 'use_same' in values else 'invoice' + # for public user avoid linking to default archived 'Public user' partner + if commercial_partner_id.active: + new_values['parent_id'] = commercial_partner_id.id + elif mode[1] == 'shipping': + new_values['type'] = 'delivery' + new_values['parent_id'] = commercial_partner_id.id return new_values, errors, error_msg @http.route(['/shop/address'], type='http', methods=['GET', 'POST'], auth="public", website=True, sitemap=False) @@ -1176,35 +1206,36 @@ class WebsiteSale(payment_portal.PaymentPortal): if redirection: return redirection - mode = (False, False) can_edit_vat = False values, errors = {}, {} partner_id = int(kw.get('partner_id', -1)) - # IF PUBLIC ORDER - if order.partner_id.id == request.website.user_id.sudo().partner_id.id: + if order._is_public_order(): mode = ('new', 'billing') can_edit_vat = True - # IF ORDER LINKED TO A PARTNER - else: + else: # IF ORDER LINKED TO A PARTNER if partner_id > 0: - if partner_id == order.partner_id.id: - mode = ('edit', 'billing') - can_edit_vat = order.partner_id.can_edit_vat() + partners = Partner.search( + [('id', 'child_of', order.partner_id.commercial_partner_id.ids)] + ) + if 'is_invoice' in kw: + bill_partners_ids = partners.filtered(lambda p: p.type != 'delivery').ids + if partner_id in bill_partners_ids or order.partner_id.id == partner_id: + mode = ('edit', 'billing') + can_edit_vat = order.partner_id.can_edit_vat() + else: + return Forbidden() else: - shippings = Partner.search([('id', 'child_of', order.partner_id.commercial_partner_id.ids)]) - if order.partner_id.commercial_partner_id.id == partner_id: - mode = ('new', 'shipping') - partner_id = -1 - elif partner_id in shippings.mapped('id'): + ship_partners_ids = partners.filtered(lambda p: p.type != 'invoice').ids + if partner_id in ship_partners_ids: mode = ('edit', 'shipping') else: return Forbidden() if mode and partner_id != -1: values = Partner.browse(partner_id) elif partner_id == -1: - mode = ('new', 'shipping') + mode = ('new', 'billing') if 'is_invoice' in kw else ('new', 'shipping') else: # no mode - refresh without post? return request.redirect('/shop/checkout') @@ -1218,29 +1249,53 @@ class WebsiteSale(payment_portal.PaymentPortal): errors['error_message'] = error_msg values = kw else: + update_mode, address_mode = mode partner_id = self._checkout_form_save(mode, post, kw) # We need to validate _checkout_form_save return, because when partner_id not in shippings # it returns Forbidden() instead the partner_id if isinstance(partner_id, Forbidden): return partner_id + fpos_before = order.fiscal_position_id - if mode[1] == 'billing': - order.partner_id = partner_id - # This is the *only* thing that the front end user will see/edit anyway when choosing billing address - order.partner_invoice_id = partner_id - if not kw.get('use_same'): - kw['callback'] = kw.get('callback') or \ - (not order.only_services and (mode[0] == 'edit' and '/shop/checkout' or '/shop/address')) - # We need to update the pricelist(by the one selected by the customer), because onchange_partner reset it - # We only need to update the pricelist when it is not redirected to /confirm_order - if kw.get('callback', False) != '/shop/confirm_order': - request.website.sale_get_order(update_pricelist=True) - elif mode[1] == 'shipping': - order.partner_shipping_id = partner_id + update_values = {} + if update_mode == 'new': # New address + if order._is_public_order(): + update_values['partner_id'] = partner_id + + if address_mode == 'billing': + update_values['partner_invoice_id'] = partner_id + if kw.get('use_same'): + update_values['partner_shipping_id'] = partner_id + elif not kw.get('callback') and not order.only_services: + # Now that the billing is set, if shipping is necessary + # request the user to fill the shipping address + kw['callback'] = '/shop/address' + elif address_mode == 'shipping': + update_values['partner_shipping_id'] = partner_id + elif update_mode == 'edit': # Updating an existing address + if order.partner_id.id == partner_id: + # Editing the main partner of the SO --> also trigger a partner update to + # recompute fpos & any partner-related fields + update_values['partner_id'] = partner_id + + if address_mode == 'billing': + update_values['partner_invoice_id'] = partner_id + if not kw.get('callback') and not order.only_services: + kw['callback'] = '/shop/checkout' + elif address_mode == 'shipping': + update_values['partner_shipping_id'] = partner_id + + order.write(update_values) if order.fiscal_position_id != fpos_before: + # Recompute taxes on fpos change + # TODO recompute all prices too to correctly manage price_include taxes ? order._recompute_taxes() + if 'partner_id' in update_values: + # Force recomputation of pricelist on main customer address update + request.website.sale_get_order(update_pricelist=True) + # TDE FIXME: don't ever do this # -> TDE: you are the guy that did what we should never do in commit e6f038a order.message_partner_ids = [(4, partner_id), (3, request.website.partner_id.id)] @@ -1438,8 +1493,7 @@ class WebsiteSale(payment_portal.PaymentPortal): order = render_values['website_sale_order'] def_country_id = order.partner_id.country_id - # IF PUBLIC ORDER - if order.partner_id.id == request.website.user_id.sudo().partner_id.id: + if order._is_public_order(): if request.geoip.country_code: def_country_id = request.env['res.country'].search([('code', '=', request.geoip.country_code)], limit=1) else: @@ -1463,7 +1517,7 @@ class WebsiteSale(payment_portal.PaymentPortal): if redirection: return redirection - if order.partner_id.id == request.website.user_id.sudo().partner_id.id: + if order._is_public_order(): return request.redirect('/shop/address') redirection = self.checkout_check_address(order) diff --git a/addons/website_sale/models/sale_order.py b/addons/website_sale/models/sale_order.py index 471fa23f940..0292afdb2d0 100644 --- a/addons/website_sale/models/sale_order.py +++ b/addons/website_sale/models/sale_order.py @@ -622,3 +622,9 @@ class SaleOrder(models.Model): ]).available_carriers( self.partner_shipping_id ).filtered(_is_carrier_available) + + #=== TOOLING ===# + + def _is_public_order(self): + self.ensure_one() + return self.partner_id.id == request.website.user_id.sudo().partner_id.id diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py index fb401b48712..61c524db31a 100644 --- a/addons/website_sale/models/website.py +++ b/addons/website_sale/models/website.py @@ -393,7 +393,6 @@ class Website(models.Model): # change the partner, and trigger the computes (fpos) sale_order_sudo.write({ 'partner_id': partner_sudo.id, - 'partner_invoice_id': partner_sudo.id, 'payment_term_id': self.sale_get_payment_term(partner_sudo), # Must be specified to ensure it is not recomputed when it shouldn't 'pricelist_id': pricelist_id, @@ -418,7 +417,7 @@ class Website(models.Model): def _prepare_sale_order_values(self, partner_sudo): self.ensure_one() - addr = partner_sudo.address_get(['delivery']) + addr = partner_sudo.address_get(['delivery', 'invoice']) if not request.website.is_public_user(): # FIXME VFE why not use last_website_so_id field ? last_sale_order = self.env['sale.order'].sudo().search( @@ -426,8 +425,11 @@ class Website(models.Model): limit=1, order="date_order desc, id desc", ) - if last_sale_order and last_sale_order.partner_shipping_id.active: # first = me - addr['delivery'] = last_sale_order.partner_shipping_id.id + if last_sale_order: + if last_sale_order.partner_shipping_id.active: # first = me + addr['delivery'] = last_sale_order.partner_shipping_id.id + if last_sale_order.partner_invoice_id.active: + addr['invoice'] = last_sale_order.partner_invoice_id.id affiliate_id = request.session.get('affiliate_id') salesperson_user_sudo = self.env['res.users'].sudo().browse(affiliate_id).exists() @@ -439,7 +441,7 @@ class Website(models.Model): 'fiscal_position_id': self.fiscal_position_id.id, 'partner_id': partner_sudo.id, - 'partner_invoice_id': partner_sudo.id, + 'partner_invoice_id': addr['invoice'], 'partner_shipping_id': addr['delivery'], 'pricelist_id': self.pricelist_id.id, diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index 10ded89a840..84fb00cd83c 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -796,6 +796,7 @@ publicWidget.registry.WebsiteSaleLayout = publicWidget.Widget.extend({ publicWidget.registry.websiteSaleCart = publicWidget.Widget.extend({ selector: '.oe_website_sale .oe_cart', events: { + 'click .js_change_billing': '_onClickChangeBilling', 'click .js_change_shipping': '_onClickChangeShipping', 'click .js_edit_address': '_onClickEditAddress', 'click .js_delete_product': '_onClickDeleteProduct', @@ -805,19 +806,33 @@ publicWidget.registry.websiteSaleCart = publicWidget.Widget.extend({ // Handlers //-------------------------------------------------------------------------- + /** + * @private + * @param {Event} ev + */ + _onClickChangeBilling: function (ev) { + this._onClickChangeAddress(ev, 'all_billing', 'js_change_billing'); + }, /** * @private * @param {Event} ev */ _onClickChangeShipping: function (ev) { - var $old = $('.all_shipping').find('.card.border.border-primary'); - $old.find('.btn-ship').toggle(); - $old.addClass('js_change_shipping'); + this._onClickChangeAddress(ev, 'all_shipping', 'js_change_shipping'); + }, + /** + * @private + * @param {Event} ev + */ + _onClickChangeAddress: function (ev, rowAddrClass, cardClass) { + var $old = $(`.${rowAddrClass}`).find('.card.border.border-primary'); + $old.find('.btn-addr').toggle(); + $old.addClass(cardClass); $old.removeClass('border border-primary'); var $new = $(ev.currentTarget).parent('div.one_kanban').find('.card'); - $new.find('.btn-ship').toggle(); - $new.removeClass('js_change_shipping'); + $new.find('.btn-addr').toggle(); + $new.removeClass(cardClass); $new.addClass('border border-primary'); var $form = $(ev.currentTarget).parent('div.one_kanban').find('form.d-none'); diff --git a/addons/website_sale/static/src/scss/website_sale.scss b/addons/website_sale/static/src/scss/website_sale.scss index fadff7e17eb..a2a178f6a95 100644 --- a/addons/website_sale/static/src/scss/website_sale.scss +++ b/addons/website_sale/static/src/scss/website_sale.scss @@ -464,7 +464,7 @@ tr#empty { display: none; } -.js_change_shipping { +.js_change_shipping, .js_change_billing { cursor: pointer; } diff --git a/addons/website_sale/static/tests/tours/website_sale_complete_flow.js b/addons/website_sale/static/tests/tours/website_sale_complete_flow.js index a2f158f036a..42cd6347d20 100644 --- a/addons/website_sale/static/tests/tours/website_sale_complete_flow.js +++ b/addons/website_sale/static/tests/tours/website_sale_complete_flow.js @@ -239,7 +239,7 @@ }, { content: "Add new shipping address", - trigger: '.one_kanban form[action^="/shop/address"] .btn', + trigger: '.all_shipping .one_kanban form[action^="/shop/address"] .btn', }, { content: "Fulfill shipping address form", diff --git a/addons/website_sale/tests/test_sale_process.py b/addons/website_sale/tests/test_sale_process.py index a718e4b29cd..212dfd0dbda 100644 --- a/addons/website_sale/tests/test_sale_process.py +++ b/addons/website_sale/tests/test_sale_process.py @@ -146,6 +146,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs 'name': 'a res.partner address', 'email': 'email@email.email', 'street': 'ooo', 'city': 'ooo', 'zip': '1200', 'country_id': self.country_id, 'submitted': 1, } + self.default_billing_address_values = self.default_address_values | {'is_invoice': 1} def _create_so(self, partner_id=None, company_id=None): values = { @@ -165,7 +166,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs return self.env['sale.order'].create(values) def _get_last_address(self, partner): - ''' Useful to retrieve the last created shipping address ''' + """ Useful to retrieve the last created address (shipping or billing) """ return partner.child_ids.sorted('id', reverse=True)[0] # TEST WEBSITE @@ -233,7 +234,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs # 2. Logged in user/internal user, should not edit name or email address of billing self.default_address_values['partner_id'] = self.demo_partner.id - self.WebsiteSaleController.address(**self.default_address_values) + self.WebsiteSaleController.address(**self.default_billing_address_values) self.assertEqual(self.demo_partner.company_id, self.company_c, "Logged in user edited billing (the partner itself) should not get its company modified.") self.assertNotEqual(self.demo_partner.name, self.default_address_values['name'], "Employee cannot change their name during the checkout process.") self.assertNotEqual(self.demo_partner.email, self.default_address_values['email'], "Employee cannot change their email during the checkout process.") @@ -257,7 +258,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs # 2. Public user, edit billing self.default_address_values['partner_id'] = new_partner.id - self.WebsiteSaleController.address(**self.default_address_values) + self.WebsiteSaleController.address(**self.default_billing_address_values) self.assertEqual(new_partner.company_id, self.website.company_id, "Public user edited billing (the partner itself) should not get its company modified.") def test_04_apply_empty_pl(self): @@ -353,7 +354,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs # 2. Portal user, edit billing self.default_address_values['partner_id'] = self.portal_partner.id - self.WebsiteSaleController.address(**self.default_address_values) + self.WebsiteSaleController.address(**self.default_billing_address_values) # Name cannot be changed if there are issued invoices self.assertNotEqual(self.portal_partner.name, self.default_address_values['name'], "Portal User should not be able to change the name if they have invoices under their name.") @@ -383,7 +384,7 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs {'name': 'Tax 20% excl', 'amount': 20, 'price_include': False}, {'name': 'Tax 15% incl', 'amount': 15, 'price_include': True}, ]) - self.env['account.fiscal.position'].create([ + fpos_be, fpos_nl = self.env['account.fiscal.position'].create([ { 'sequence': 1, 'name': 'BE', @@ -426,13 +427,64 @@ class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo, HttpCaseWithUs req.httprequest.method = "POST" self.WebsiteSaleController.address(**be_address_POST) + self.assertEqual( + so.fiscal_position_id, + fpos_be, + ) self.assertEqual( [so.amount_untaxed, so.amount_tax, so.amount_total], [90.91, 18.18, 109.09] # (100 : (1 + 10%)) * (1 + 20%) = 109.09 ) self.WebsiteSaleController.address(**nl_address_POST) + self.assertEqual( + so.fiscal_position_id, + fpos_nl, + ) self.assertEqual( [so.amount_untaxed, so.amount_tax, so.amount_total], [90.91, 13.64, 104.55] # (100 : (1 + 10%)) * (1 + 15%) = 104.55 ) + + def test_08_new_user_address_state(self): + ''' Test the billing and shipping addresses creation values. ''' + self._setUp_multicompany_env() + so = self._create_so(self.demo_partner.id) + + env = api.Environment(self.env.cr, self.demo_user.id, {}) + # change also website env for `sale_get_order` to not change order partner_id + with MockRequest(env, website=self.website.with_env(env), sale_order_id=so.id) as req: + req.httprequest.method = "POST" + + # check the default values + self.assertEqual(self.demo_partner, so.partner_invoice_id) + self.assertEqual(self.demo_partner, so.partner_shipping_id) + + # 1. Logged-in user, new shipping + self.WebsiteSaleController.address(**self.default_address_values) + new_shipping = self._get_last_address(self.demo_partner) + msg = "New shipping address should have its type set as 'delivery'" + self.assertTrue(new_shipping.type == 'delivery', msg) + + # 2. Logged-in user, new billing + self.WebsiteSaleController.address(**self.default_billing_address_values) + new_billing = self._get_last_address(self.demo_partner) + msg = "New billing should have its type set as 'invoice'" + self.assertTrue(new_billing.type == 'invoice', msg) + self.assertNotEqual(new_billing, self.demo_partner) + + # 3. Check that invoice/shipping address of so changed + self.assertEqual(new_billing, so.partner_invoice_id) + self.assertEqual(new_shipping, so.partner_shipping_id) + + # 4. Logged-in user, new billing use same + use_same = self.default_billing_address_values | {'use_same': 1} + self.WebsiteSaleController.address(**use_same) + new_billing_use_same = self._get_last_address(self.demo_partner) + msg = "New billing use same should have its type set as 'other'" + self.assertTrue(new_billing_use_same.type == 'other', msg) + self.assertNotEqual(new_billing, self.demo_partner) + + # 5. Check that invoice/shipping address of so changed + self.assertEqual(new_billing_use_same, so.partner_invoice_id) + self.assertEqual(new_billing_use_same, so.partner_shipping_id) diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 2b35acc5cec..44d6c1cfb3e 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1735,7 +1735,7 @@
- +
@@ -1752,47 +1752,23 @@

Billing Address

-
- - - - - - -
+ + + + +

Shipping Address

-
-
-
- - -
- - - - - - - -
-
-
-
-
+ + + + + - + -