This question has been flagged

I am trying to add a custom date input field to the Extra Info section on the eCommerce Website. I have the code below for a new module (the code in the view I copied from a date field using the Form Builder). It keeps giving me the error:

ValueError: time data '19/05/2022' does not match format '%Y-%m-%d'

when I submit the Extra Info page. If I remove the datepicker from the input field and enter it in manually in the %Y-%m-%d format (eg 2021-02-19) it works...How can I get the datepicker and input field working....I do not want to use type='date' due to browser compatibility issues.


Model

# -*- coding: utf-8 -*-

from odoo import models, fields, api

# Override the Customer Model to include Area Field
class WebsiteSaleOrderExtraInfo(models.Model):
_name = 'sale.order'
_inherit = ['sale.order']

x_website_delivery_date = fields.Date(string='Delivery Date', required=True)


Views

<odoo>
<data>

<!-- Override for Website Sale Addrees View -->
<template id="extra_info_custom" name="Checkout Extra Info with Delivery Date" inherit_id="website_sale.extra_info">
<xpath expr="//div[contains(@class,'s_website_form_submit')]" position="before">

<!-- Adding in Delivery Date at bottom of Form -->
<div class="form-group s_website_form_field col-12 s_website_form_custom" data-type="date" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label " style="width: 200px" for="x_website_delivery_date">
<span class="s_website_form_label_content">Delivery Date</span>
</label>
<div class="col-sm">
<div class="s_website_form_date input-group date" id="datepicker_x_website_delivery_date" data-target-input="nearest">
<input type="text"
class="form-control datetimepicker-input s_website_form_input"
data-target="#datepicker_x_website_delivery_date"
name="x_website_delivery_date"
placeholder=""
id="x_website_delivery_date"
required="1"
/>

<div class="input-group-append" data-target="#datepicker_x_website_delivery_date" data-toggle="datetimepicker" options="{'datepicker':{'minDate': 0}}">
<div class="input-group-text">
<i class="fa fa-calendar"></i>
</div>
</div>
</div>
</div>
</div>
</div>

</xpath>
</template>


<!-- Allow x_website_delivery_date to be whitelisted in web forms -->
<function model="ir.model.fields" name="formbuilder_whitelist">
<value>sale.order</value>
<value eval="[
'x_website_delivery_date'
]"/>
</function>

</data>
</odoo>






Avatar
Discard
Author

Follow up debugging:

The Extra Info Next button calls the /website_form/shop.sale.order route in website_sale. It is failing at the:

order.write(data['record']) line

where data['record'] = {'x_website_delivery_date': '20/04/2021'}

Author Best Answer

So I figured out how to do this...I'm hoping there might still be a better way. I created a controller that overrides the /website_form/shop.sale.order route. It seems that the website forms do not manage date fields well and it would be great if some helper/date handler was built in to the odoo base install.

# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSaleForm
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
import datetime

# Extend the WebsiteSale class
class WebsiteSaleExtraInfo(WebsiteSaleForm):
    @http.route('/website_form/shop.sale.order', type='http', auth="public", methods=['POST'], website=True)
    def website_form_saleorder(self, **kwargs):
        user_date_format = request.env['res.lang']._lang_get(request.env.user.lang).date_format
        # Loop through args and convert dates if required
        for k, v in kwargs.items():
            new_date = self.convert_date(v, user_date_format)
            if new_date:
                kwargs[k] = new_date
        res = super(WebsiteSaleExtraInfo, self).website_form_saleorder(**kwargs)
        return res
    # Helper function to convert a date from the user date format to the server date format
    def convert_date(self, custom_date, original_date_format, new_date_format=DEFAULT_SERVER_DATE_FORMAT):
        try:
            new_date = datetime.datetime.strptime(custom_date, original_date_format).strftime(new_date_format)
        except:
            return False
        return new_date
Avatar
Discard