Browse Source
[ADD] wsite_portal_ext: Correctly manage companies
[ADD] wsite_portal_ext: Correctly manage companies
Remove the usage of street2. The street is stored in the street attribute. And it found the name of the company in a parent_id if there is one. If the partner is a company. It shows information about the company. Namely, its name, its VAT number, its email, its phone, and its address. If the partner is a contact of a company. It shows informations about the company and about the contact. Namely, the name, the email and the phone of the contact, the name, the VAT and the address of the company. In fact the VAT and the address must be the same on the contact and on the company. This is the standard behaviour in Odoo. So when a partner became a contact of a company it lost his own address and VAT number. These two field are copied from the company. When the partner is a person. It shows information about this person. Namely, his or her name, email, phone, VAT (not required) and address. It also make the website portal easier to extend.pull/1/head
Rémy Taymans
7 years ago
5 changed files with 340 additions and 0 deletions
-
2website_portal_extend/__init__.py
-
31website_portal_extend/__openerp__.py
-
2website_portal_extend/controllers/__init__.py
-
188website_portal_extend/controllers/main.py
-
117website_portal_extend/views/portal_website_templates.xml
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf8 -*- |
|||
import controllers |
@ -0,0 +1,31 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
# Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
{ |
|||
'name': 'Website Portal Extend', |
|||
|
|||
'summary': """ |
|||
Extension of Website Portal that show correctly information about |
|||
companies |
|||
""", |
|||
'description': """ |
|||
""", |
|||
|
|||
'author': 'Rémy Taymans', |
|||
'license': 'AGPL-3', |
|||
'version': '9.0.1.0', |
|||
'website': "https://github.com/houssine78/vertical-cooperative", |
|||
|
|||
'category': 'Website', |
|||
|
|||
'depends': [ |
|||
'website', |
|||
'website_portal_v10', |
|||
], |
|||
|
|||
'data': [ |
|||
'views/portal_website_templates.xml', |
|||
] |
|||
} |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import main |
@ -0,0 +1,188 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
# Copyright 2017-2018 Rémy Taymans <remytaymans@gmail.com> |
|||
# Copyright 2018 Odoo SA |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
|
|||
from openerp import fields, models, http |
|||
from openerp.http import request |
|||
from openerp import tools |
|||
from openerp.tools.translate import _ |
|||
|
|||
from openerp.addons.website_portal_v10.controllers.main import WebsiteAccount |
|||
|
|||
|
|||
class ExtendWebsiteAccountController(WebsiteAccount): |
|||
|
|||
mandatory_billing_fields = [ |
|||
"name", |
|||
"phone", |
|||
"email", |
|||
"city", |
|||
"country_id", |
|||
"street", |
|||
] |
|||
optional_billing_fields = [ |
|||
"zipcode", |
|||
"state_id", |
|||
"vat", |
|||
] |
|||
|
|||
@http.route(['/my/account'], type='http', auth='user', website=True) |
|||
def details(self, redirect=None, **post): |
|||
partner = request.env['res.users'].browse(request.uid).partner_id |
|||
values = { |
|||
'error': {}, |
|||
'error_message': [] |
|||
} |
|||
|
|||
self._set_mandatory_fields(post) |
|||
self._set_optional_fields(post) |
|||
|
|||
all_fields = ( |
|||
self.mandatory_billing_fields |
|||
+ self.optional_billing_fields |
|||
) |
|||
|
|||
if post: |
|||
error, error_message = self.details_form_validate(post) |
|||
values.update({'error': error, 'error_message': error_message}) |
|||
values.update(post) |
|||
if not error: |
|||
# Change zipcode to zip as it is stored as zip in the |
|||
# partner |
|||
if 'zipcode' in all_fields: |
|||
post.update({'zip': post.pop('zipcode', '')}) |
|||
|
|||
if partner.type == "contact": |
|||
address_fields = {} |
|||
if 'city' in all_fields: |
|||
address_fields.update({ |
|||
'city': post.pop('city'), |
|||
}) |
|||
if 'street' in all_fields: |
|||
address_fields.update({ |
|||
'street': post.pop('street'), |
|||
}) |
|||
if 'vat' in all_fields: |
|||
address_fields.update({ |
|||
'vat': post['vat'], |
|||
}) |
|||
if 'zipcode' in all_fields: |
|||
address_fields.update({ |
|||
'zip': post.pop('zip'), |
|||
}) |
|||
if 'country_id' in all_fields: |
|||
address_fields.update({ |
|||
'country_id': post.pop('country_id'), |
|||
}) |
|||
if 'state_id' in all_fields: |
|||
address_fields.update({ |
|||
'state_id': post.pop('state_id') |
|||
}) |
|||
|
|||
company_fields = {} |
|||
if 'company_name' in all_fields: |
|||
company_fields.update({ |
|||
'name': post.pop('company_name'), |
|||
}) |
|||
if 'vat' in all_fields: |
|||
company_fields.update({ |
|||
# The VAT must be updated on the company and on |
|||
# the partner, so pop is not used. |
|||
'vat': post['vat'], |
|||
}) |
|||
|
|||
partner.commercial_partner_id.sudo().write(address_fields) |
|||
partner.commercial_partner_id.sudo().write(company_fields) |
|||
# Write the rest of the info in the partner |
|||
partner.sudo().write(post) |
|||
|
|||
if redirect: |
|||
return request.redirect(redirect) |
|||
return request.redirect('/my/home') |
|||
|
|||
countries = request.env['res.country'].sudo().search([]) |
|||
states = request.env['res.country.state'].sudo().search([]) |
|||
|
|||
values.update({ |
|||
'partner': partner, |
|||
'countries': countries, |
|||
'states': states, |
|||
'has_check_vat': hasattr(request.env['res.partner'], 'check_vat'), |
|||
'redirect': redirect, |
|||
}) |
|||
|
|||
return request.website.render("website_portal.details", values) |
|||
|
|||
def _set_mandatory_fields(self, data): |
|||
"""Change mandatory billing fields of the form. |
|||
Overwrite this function if mandatory fields must be changed |
|||
depending on the value of the data or any other value. |
|||
Here it mark the field 'company_name' as need or not depending |
|||
on the current user. |
|||
""" |
|||
partner = request.env['res.users'].browse(request.uid).partner_id |
|||
if (partner.parent_id |
|||
and 'company_name' not in self.mandatory_billing_fields): |
|||
self.mandatory_billing_fields.append('company_name') |
|||
if (not partner.parent_id |
|||
and 'company_name' in self.mandatory_billing_fields): |
|||
self.mandatory_billing_fields.remove('company_name') |
|||
|
|||
def _set_optional_fields(self, data): |
|||
"""Same as set_mandatory_fields but for optional ones. |
|||
Here this does nothing. |
|||
""" |
|||
pass |
|||
|
|||
def details_form_validate(self, data): |
|||
"""Validate the form""" |
|||
error = dict() |
|||
error_message = [] |
|||
|
|||
all_fields = ( |
|||
self.mandatory_billing_fields |
|||
+ self.optional_billing_fields |
|||
) |
|||
|
|||
# Validation |
|||
for field_name in self.mandatory_billing_fields: |
|||
if not data.get(field_name): |
|||
error[field_name] = 'missing' |
|||
|
|||
# email validation |
|||
if ('email' in all_fields |
|||
and data.get('email') |
|||
and not tools.single_email_re.match(data.get('email'))): |
|||
error["email"] = 'error' |
|||
error_message.append( |
|||
_('Invalid Email! Please enter a valid email address.') |
|||
) |
|||
|
|||
# vat validation |
|||
if ('vat' in all_fields |
|||
and data.get("vat") |
|||
and hasattr(request.env["res.partner"], "check_vat")): |
|||
if request.website.company_id.vat_check_vies: |
|||
# force full VIES online check |
|||
check_func = request.env["res.partner"].vies_vat_check |
|||
else: |
|||
# quick and partial off-line checksum validation |
|||
check_func = request.env["res.partner"].simple_vat_check |
|||
vat_country, vat_number = request.env["res.partner"]._split_vat( |
|||
data.get("vat") |
|||
) |
|||
if not check_func(vat_country, vat_number): # simple_vat_check |
|||
error["vat"] = 'error' |
|||
# error message for empty required fields |
|||
if [err for err in error.values() if err == 'missing']: |
|||
error_message.append(_('Some required fields are empty.')) |
|||
|
|||
unknown = [k for k in data.iterkeys() if k not in all_fields] |
|||
if unknown: |
|||
error['common'] = 'Unknown field' |
|||
error_message.append("Unknown field '%s'" % ','.join(unknown)) |
|||
|
|||
return error, error_message |
@ -0,0 +1,117 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
Copyright 2018 Rémy Taymans <remytaymans@gmail.com> |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
--> |
|||
<openerp> |
|||
|
|||
<!-- Modifying the form --> |
|||
<template |
|||
id="website_portal_details_form" |
|||
name="Website Portal Details Form" |
|||
inherit_id="website_portal.details"> |
|||
<xpath expr="//form" position="replace"> |
|||
|
|||
<form action="/my/account" method="post"> |
|||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/> |
|||
|
|||
<div class="row o_website_portal_details"> |
|||
<div class="col-md-8"> |
|||
<div class="row"> |
|||
|
|||
<div class="col-md-12"> |
|||
<div t-if="error_message" class="alert alert-danger"> |
|||
<t t-foreach="error_message" t-as="err"><t t-esc="err"/><br /></t> |
|||
</div> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('name') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="name">Your Name</label> |
|||
<input type="text" name="name" class="form-control" t-att-value="name or partner.name" /> |
|||
</div> |
|||
|
|||
<div class="clearfix" /> |
|||
|
|||
<div t-attf-class="form-group #{error.get('email') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="email">Email</label> |
|||
<input type="email" name="email" class="form-control" t-att-value="email or partner.email" /> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('phone') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="phone">Phone</label> |
|||
<input type="tel" name="phone" class="form-control" t-att-value="phone or partner.phone" /> |
|||
</div> |
|||
|
|||
<div class="clearfix" /> |
|||
|
|||
<div t-attf-class="form-group #{error.get('company_name') and 'has-error' or ''} col-lg-6" t-if="partner.parent_id"> |
|||
<label class="control-label" for="company_name">Company Name</label> |
|||
<input type="text" name="company_name" class="form-control" t-att-value="company_name or partner.parent_id.name"/> |
|||
</div> |
|||
|
|||
<div t-if="has_check_vat" t-attf-class="form-group #{error.get('vat') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label label-optional" for="vat">VAT Number</label> |
|||
<input type="text" name="vat" class="form-control" t-att-value="vat or partner.parent_id.vat" t-if="partner.parent_id"/> |
|||
<input type="text" name="vat" class="form-control" t-att-value="vat or partner.vat" t-if="not partner.parent_id"/> |
|||
</div> |
|||
|
|||
<div class="clearfix" /> |
|||
|
|||
<div t-attf-class="form-group #{error.get('street') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="street">Street</label> |
|||
<input type="text" name="street" class="form-control" t-att-value="street or partner.street" /> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('city') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="city">City</label> |
|||
<input type="text" name="city" class="form-control" t-att-value="city or partner.city" /> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('zip') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="zipcode">Zip / Postal Code</label> |
|||
<input type="text" name="zipcode" class="form-control" t-att-value="zipcode or partner.zip" /> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('country_id') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label" for="country_id">Country</label> |
|||
<select name="country_id" class="form-control"> |
|||
<option value="">Country...</option> |
|||
<t t-foreach="countries or []" t-as="country"> |
|||
<option t-att-value="country.id" t-att-selected="country.id == partner.country_id.id"> |
|||
<t t-esc="country.name" /> |
|||
</option> |
|||
</t> |
|||
</select> |
|||
</div> |
|||
|
|||
<div t-attf-class="form-group #{error.get('state_id') and 'has-error' or ''} col-lg-6"> |
|||
<label class="control-label label-optional" for="state_id">State / Province</label> |
|||
<select name="state_id" class="form-control"> |
|||
<option value="">select...</option> |
|||
<t t-foreach="states or []" t-as="state"> |
|||
<option t-att-value="state.id" style="display:none;" t-att-data-country_id="state.country_id.id" t-att-selected="state.id == partner.state_id.id"> |
|||
<t t-esc="state.name" /> |
|||
</option> |
|||
</t> |
|||
</select> |
|||
</div> |
|||
|
|||
<input type="hidden" name="redirect" t-att-value="redirect"/> |
|||
|
|||
</div> <!-- row --> |
|||
|
|||
<div class="clearfix"> |
|||
<button type="submit" class="btn btn-default btn-primary pull-right mb32 "> |
|||
Confirm |
|||
<span class="fa fa-long-arrow-right" /> |
|||
</button> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
</form> |
|||
|
|||
</xpath> |
|||
</template> |
|||
|
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue