Skip to content

Commit

Permalink
[MIG] portal_addresses: Migration to 18.0
Browse files Browse the repository at this point in the history
  • Loading branch information
docker-odoo authored and cem-adhoc committed Dec 23, 2024
1 parent 5456ead commit cfbd2a4
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 108 deletions.
9 changes: 7 additions & 2 deletions portal_addresses/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
##############################################################################
{
'name': 'Portal Addresses',
'version': "17.0.1.0.0",
'version': "18.0.1.0.0",
'category': 'Tools',
'complexity': 'easy',
'author': 'ADHOC SA, Odoo Community Association (OCA)',
Expand All @@ -35,6 +35,11 @@
'views/portal_templates.xml',
'views/templates.xml',
],
'installable': False,
'installable': True,
'auto_install': True,
'assets': {
'web.assets_frontend': [
'/portal_addresses/static/src/js/address.js'
]
}
}
131 changes: 39 additions & 92 deletions portal_addresses/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,104 +4,53 @@
##############################################################################
from odoo import http
from odoo.http import request
from werkzeug.exceptions import Forbidden
from odoo.addons.website_sale.controllers.main import WebsiteSale


class WebsiteSalePortal(WebsiteSale):
@http.route(
'/portal/address', type='http', methods=['GET'], auth='public', website=True, sitemap=False
)
def shop_address(
self, partner_id=None, address_type='billing', use_delivery_as_billing=None, **query_params
):
""" Display the address form.
A partner and/or an address type can be given through the query string params to specify
which address to update or create, and its type.
@http.route(['/portal/address'], type='http', methods=['GET', 'POST'],
auth="public", website=True)
def portal_address(self, **kw):
Partner = request.env['res.partner'].with_context(show_address=1).sudo()
order = request.env['sale.order'].new({
'partner_id': request.env.user.partner_id.commercial_partner_id.id
})

mode = (False, False)
values, errors = {}, {}
partner_id = int(kw.get('partner_id', -1))
:param str partner_id: The partner whose address to update with the address form, if any.
:param str address_type: The type of the address: 'billing' or 'delivery'.
:param str use_delivery_as_billing: Whether the provided address should be used as both the
delivery and the billing address. 'true' or 'false'.
:param dict query_params: The additional query string parameters forwarded to
`_prepare_address_form_values`.
:return: The rendered address form.
:rtype: str
"""
partner_id = partner_id and int(partner_id)
order_sudo = request.website.sale_get_order()

if partner_id > 0:
partner_type = request.env['res.partner'].browse(partner_id).type
values = Partner.browse(partner_id)
if partner_type == 'invoice':
mode = ('edit', 'billing')
else:
mode = ('edit', 'shipping')
elif partner_id == -1:
mode = ('new', kw.get('mode') or 'shipping')
else: # no mode - refresh without post?
return request.redirect('/portal/addresses')
# Retrieve the partner whose address to update, if any, and its address type.
partner_sudo, address_type = self._prepare_address_update(
order_sudo, partner_id=partner_id, address_type=address_type
)

# IF POSTED
if 'submitted' in kw:
pre_values = self.values_preprocess(kw)
errors, error_msg = self.checkout_form_validate(mode, kw, pre_values)
post, errors, error_msg = self.values_postprocess(order, mode, pre_values, errors, error_msg)
if errors:
errors['error_message'] = error_msg
values = kw
else:
partner_id = self._portal_address_form_save(mode, post, kw)
if isinstance(partner_id, Forbidden):
return partner_id
if mode[1] == 'billing':
order.partner_id = partner_id
elif mode[1] == 'shipping':
order.partner_shipping_id = partner_id
if partner_sudo: # If editing an existing partner.
use_delivery_as_billing = (
order_sudo.partner_shipping_id == order_sudo.partner_invoice_id
)

order.message_partner_ids = [(4, partner_id), (3, request.website.partner_id.id)]
if not errors:
return request.redirect(kw.get('callback') or '/portal/addresses')
# Render the address form.
address_form_values = self._prepare_address_form_values(
order_sudo,
partner_sudo,
address_type=address_type,
use_delivery_as_billing=use_delivery_as_billing,
**query_params
)
return request.render('portal_addresses.portal_address', address_form_values)

render_values = {
'website_sale_order': order,
'partner_id': partner_id,
'mode': mode,
'checkout': values,
'error': errors,
'callback': kw.get('callback'),
'only_services': order and order.only_services,
'account_on_checkout': request.website.account_on_checkout,
'is_public_user': request.website.is_public_user()
}
# para evitar modulo puente con l10n_ar_website_sale lo hacemos asi
if request.env['ir.module.module'].sudo().search([
('name', '=', 'l10n_ar_website_sale'),
('state', '=', 'installed')], limit=1):
document_categories = request.env[
'l10n_latam.document.type'].sudo().search([])
afip_responsabilities = request.env[
'l10n_ar.afip.responsibility.type'].sudo().search([])
uid = request.session.uid or request.env.ref('base.public_user').id
Partner = request.env['res.users'].browse(uid).partner_id
Partner = Partner.with_context(show_address=1).sudo()
render_values.update({
'document_categories': document_categories,
'afip_responsabilities': afip_responsabilities,
'partner': Partner,
})
render_values.update(self._get_country_related_render_values(kw, render_values))
return request.render("portal_addresses.portal_address", render_values)

def _portal_address_form_save(self, mode, checkout, all_values):
Partner = request.env['res.partner']
if mode[0] == 'new':
partner_id = Partner.sudo().create(checkout).id
elif mode[0] == 'edit':
partner_id = int(all_values.get('partner_id', 0))
if partner_id:
# double check
partner = request.env.user.partner_id
shippings = Partner.sudo().search(
[("id", "child_of", partner.commercial_partner_id.ids)])
if partner_id not in shippings.mapped('id') and \
partner_id != partner.id:
return Forbidden()
Partner.browse(partner_id).sudo().write(checkout)
return partner_id

@http.route(['/portal/addresses'],
type='http', auth="public", website=True)
Expand All @@ -110,8 +59,6 @@ def portal_addresses(self, **post):
order = request.env['sale.order'].new(
{'partner_id':
request.env.user.partner_id.commercial_partner_id.id})
order.pricelist_id = order.partner_id.property_product_pricelist \
and order.partner_id.property_product_pricelist.id or False
Partner = order.partner_id.with_context(show_address=1).sudo()
shippings = Partner.search(
[("id", "child_of", order.partner_id.commercial_partner_id.ids),
Expand All @@ -126,8 +73,8 @@ def portal_addresses(self, **post):
values = {
'order': order,
'website_sale_order': order,
'shippings': shippings,
'billings': billings
'delivery_addresses': shippings,
'billing_addresses': billings
}
# Avoid useless rendering if called in ajax
if post.get('xhr'):
Expand Down
67 changes: 67 additions & 0 deletions portal_addresses/static/src/js/address.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/** @odoo-module **/

import publicWidget from "@web/legacy/js/public/public_widget";

const websiteSaleAddress = publicWidget.registry.websiteSaleAddress;


websiteSaleAddress.include({

// @override
_onSaveAddress: async function (ev) {
if (!this.addressForm.reportValidity()) {
return
}

const submitButton = ev.currentTarget;
if (!ev.defaultPrevented && !submitButton.disabled) {
ev.preventDefault();
if(ev.currentTarget.closest('form').action.includes('portal/address') ){
debugger;
submitButton.disabled = true;
const spinner = document.createElement('span');
spinner.classList.add('fa', 'fa-cog', 'fa-spin');
submitButton.appendChild(spinner);

const result = await this.http.post(
'/shop/address/submit',
new FormData(this.addressForm),
)
if (result.successUrl) {
debugger;
window.location = '/portal/addresses';
} else {
// Highlight missing/invalid form values
document.querySelectorAll('.is-invalid').forEach(element => {
if (!result.invalid_fields.includes(element.name)) {
element.classList.remove('is-invalid');
}
})
result.invalid_fields.forEach(
fieldName => this.addressForm[fieldName].classList.add('is-invalid')
);

// Display the error messages
// NOTE: setCustomValidity is not used as we would have to reset the error msg on
// input update, which is not worth catching for the rare cases where the
// server-side validation will catch validation issues (now that required inputs
// are also handled client-side)
const newErrors = result.messages.map(message => {
const errorHeader = document.createElement('h5');
errorHeader.classList.add('text-danger');
errorHeader.appendChild(document.createTextNode(message));
return errorHeader;
});

this.errorsDiv.replaceChildren(...newErrors);

// Re-enable button and remove spinner
submitButton.disabled = false;
spinner.remove();
}
} else {
this._super(...arguments);
}
}
}
})
41 changes: 27 additions & 14 deletions portal_addresses/views/templates.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<odoo>
<template id="addresses" inherit_id="website_sale.checkout" primary="True">
<t t-if="order._has_deliverable_products()" position="replace">
<t t-call="portal_addresses.portal_delivery_address_row">
<t t-set="addresses" t-value="delivery_addresses"/>
</t>
</t>
<t t-call="website_sale.checkout_layout" position="attributes">
<attribute name="t-call">portal_addresses.portal_checkout_layout</attribute>
</t>
<t t-call="website_sale.row_addresses" position="attributes">
<attribute name="t-call">portal_addresses.portal_row_addresses</attribute>
</t>
<t t-call="website_sale.row_addresses" position="attributes">
<attribute name="t-call">portal_addresses.portal_row_addresses</attribute>
<t t-call="website_sale.billing_address_row" position="attributes">
<attribute name="t-call">portal_addresses.portal_billing_address_row</attribute>
</t>
</template>

Expand All @@ -18,16 +20,27 @@
<t t-call="website_sale.navigation_buttons" position="replace"/>
</template>

<template id="portal_row_addresses" inherit_id="website_sale.row_addresses" primary="True">
<template id="portal_delivery_address_row" inherit_id="website_sale.delivery_address_row" primary="True">
<t t-call="website_sale.address_row" position="attributes">
<attribute name="t-call">portal_addresses.portal_address_row</attribute>
</t>
</template>

<template id="portal_billing_address_row" inherit_id="website_sale.billing_address_row" primary="True">
<t t-call="website_sale.address_row" position="attributes">
<attribute name="t-call">portal_addresses.portal_address_row</attribute>
</t>
</template>

<template id="portal_address_row" inherit_id="website_sale.address_row" primary="True">
<t t-if="is_invoice" position="replace">
<t t-if="is_invoice">
<t t-set="new_address_href" t-valuef="/portal/address?mode=billing"/>
<t t-set="new_address_href" t-valuef="/portal/address?address_type=billing"/>
</t>
</t>
<t t-else="" position="replace">
<t t-else="">
<t t-set="new_address_href" t-valuef="/portal/address?mode=shipping"/>
<t t-set="new_address_href" t-valuef="/portal/address?address_type=delivery"/>
</t>
</t>
<t t-call="website_sale.address_kanban" position="attributes">
Expand All @@ -49,14 +62,14 @@
<a role="button" t-att-href="'/portal/addresses'" class="btn btn-outline-secondary w-100 w-md-auto order-md-1 order-3">
<i class="fw-light fa fa-angle-left me-2"/> Discard
</a>
</xpath>
<xpath expr="//a[hasclass('a-submit')]" position="replace">
<a role="button" href="#" class="a-submit a-submit-disable a-submit-loading btn btn-primary w-100 w-md-auto order-1 order-md-3">
</xpath>
<xpath expr="//button[@id='save_address']" position="replace">
<button id="save_address" class="btn btn-primary w-100 w-md-auto order-1 order-md-3">
Save address <i class="fw-light fa fa-angle-right ms-2"/>
</a>
</button>
</xpath>
<form action="/shop/address" position="attributes">
<attribute name="action">/portal/address</attribute>
<form action="/shop/address/submit" position="attributes">
<attribute name="action">/portal/address/submit</attribute>
</form>
</template>

Expand Down

0 comments on commit cfbd2a4

Please sign in to comment.