Usando el módulo website_forms
Crear formularios de edición/creación en el website puede llegar a ser una tarea titánica para el desarrollador de Odoo. Por la sencilla razón que puede llegar a involucrar no solo el desarrollo de módulos web, sino ademas el utilizar un lenguaje muchas veces desconocido para el como es el caso de Javascript y la librería jQuery. Para mitigar esta situación, Odoo provee en su versión community un módulo muy util llamado website_form que permite crear formularios sin necesidad de usar Javascript. Esto no se debe confundir con el módulo que brinda la interface gráfica, el Website Form Builder que se provee en la versión Enterprise.
El módulo website_form es tan importante... que el módulo website_sale esta desarrollado con el. No solo eso, sino el website_hr_recruitment, el website_crm... entre otros. Ahora se encuentra poco documentado. Yo encontré documentación en el excelente libro de Daniel Resis, "Odoo Development Essentials" para la versión 10.0 de Odoo. Pero despues no hay más documentación, es por eso que voy a documentar mi experiencia con este desconocido pero muy potente módulo para el desarrollador (usando el módulo sale a modo de ejemplo).
Primero y como era de esperarse, debemos agregar al __manifest__,py el módulo website_form.
# any module necessary for this one to work correctly
'depends': ['website','website_form','sale'],
El segundo paso (y esto no es menor) se debe agregar un atributo al modelo, indicando que el mismo será modificable por el módulo website_form. Esto lo haremos con un archivo de datos que tambien se agrega en el __manifest__.py.
<record id="sale.model_sale_order" model="ir.model">
<field name="website_form_access">True</field>
</record>
El tercer paso es ya modificar el template con el que vamos a trabajar, agregando el form en si mismo.
<div class="row">
<section id="forms">
<form class="s_website_form container-fluid form-horizontal"
action="/website_form/"
data-model_name="sale.order"
data-force_action="form.submit.custom"
data-success_page="/my" enctype="multipart/form-data" >
Como podran ver, el form tiene los atributos data_success_page (que es donde se redireccionará al clickear "Submit"); data-model_name donde se indica con que modelo se trabajará, action que apunta a /website_form debido a que es el controller que se encargará de procesar el formulario y da de alta el registro; data-success_page que indica la página a mostrar en el momento de submitir el formulario; y por último data-force_action que indica un controller que opcionalmente puede procesar los datos del formulario en el caso que se desee modificar el registro.
Ahora pasemos a agregar los campos a actualizar (en este caso los campos confirmation_date) y el botón para guardar el formulario:
<div class="form-group form-field">
<div class="row">
<div class="col-md-3 col-sm-4 text-right">
<label class="control-label" for="name">Sales Price Net</label>
</div>
<div class="col-md-7 col-sm-8">
<input name="sales_price_net" type="number" required="True" class="o_website_from_input form-control" />
</div>
</div>
</div>
<!-- Submit button -->
<div class="form-group">
<div class="col-md-offset-3 col-md-7 col-sm-offset-4 col-sm-8">
<a class="o_website_form_send btn btn-primary btn-lg">
Save
</a>
<span id="o_website_form_result"></span>
</div>
</div>
Entonces, cuando el usuario clickee Save Odoo intentará crear un registro con los datos ingresados en el formulario. Si se fijan en el módulo website_crm, es así como funciona. Ahora supongamos que necesitamos (como siempre) agregar validaciones y campos extras a nuestro registro, eso lo podemos hacer en el modelo mismo, por medio de la función website_form_input_filter donde podemos definir cada uno de los valores con los que se creará el registro:
def website_form_input_filter(self, request, values):
user = self.env['res.users'].browse(request.env.uid)
partner = user.partner_id
params = dict(request.params)
fields = ['confirmation_date']
for field in fields:
if field in params:
values[field] = params[field]
values['partner_id'] = partner.parent_id.id
values['pricelist_id'] = partner.sudo().property_product_pricelist.id
return values
Por último, y esto no es menor se puede invocar un controller al momento de hacer el Submit del formulario (por medio del atributo daata-force_action. Y allí podemos definir un controller similar a este:
class WebsitePortalForm(WebsiteForm):
@http.route('/website_form/form.submit.custom', type='http', auth="public", methods=['POST'], website=True)
def form_submit_custom(self, **kwargs):
model_record = request.env['sale.order']
sale_order_id = request.session.get('sale_order',0)
sale_order = model_record.browse(service_order_id)
sale_order.write({'confirmation_date': kwargs['confirmation_date']})
return json.dumps({})
En este último ejemplo, procedemos a modificar un registro de sale.order que se encuentra seteado en la sesión (que se lo hace en el controller que invoca el formulario).
Bueno, si tienen que trabajar con formularios de Odoo les recomiendo echar una mirada al módulo website_form. Sobre todo ver como funciona en el código, debido a que en el mismo se cuenta con ejemplos de su funcionamiento. Esto les va a ahorrar mucho tiempo.
|
Acerca de:
Gustavo Orrillo
Passionate about programming, he has implemented Odoo for different types of businesses since 2010. In Moldeo Interactive he is a founding Partner and Programmer; In addition to writing on the Blog about different topics related to the developments he makes.