Browse Source
Merge pull request #52 from coopiteasy/12.0-migration-emc-website-portal
Merge pull request #52 from coopiteasy/12.0-migration-emc-website-portal
[MIG] migrate module. comply with new portal.pull/56/head
Houssine BAKKALI
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 426 additions and 699 deletions
-
351easy_my_coop/models/partner.py
-
13easy_my_coop_website/views/subscription_template.xml
-
12easy_my_coop_website_portal/__manifest__.py
-
191easy_my_coop_website_portal/controllers/main.py
-
218easy_my_coop_website_portal/views/easy_my_coop_website_portal_templates.xml
-
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
@ -1,170 +1,181 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2019 Coop IT Easy SCRL fs |
|||
# Houssine Bakkali <houssine@coopiteasy.be> |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|||
|
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ResPartner(models.Model): |
|||
_inherit = 'res.partner' |
|||
|
|||
@api.multi |
|||
def _invoice_total(self): |
|||
account_invoice_report = self.env['account.invoice.report'] |
|||
if not self.ids: |
|||
self.total_invoiced = 0.0 |
|||
return True |
|||
|
|||
all_partners_and_children = {} |
|||
all_partner_ids = [] |
|||
for partner in self: |
|||
# price_total is in the company currency |
|||
all_partners_and_children[partner] = self.search([('id', 'child_of', partner.id)]).ids |
|||
all_partner_ids += all_partners_and_children[partner] |
|||
|
|||
# searching account.invoice.report via the orm is comparatively |
|||
# expensive (generates queries "id in []" forcing to build the |
|||
# full table). |
|||
# In simple cases where all invoices are in the same currency than |
|||
# the user's company access directly these elements |
|||
|
|||
# generate where clause to include multicompany rules |
|||
where_query = account_invoice_report._where_calc([ |
|||
('partner_id', 'in', all_partner_ids), |
|||
('state', 'not in', ['draft', 'cancel']), |
|||
('company_id', '=', self.env.user.company_id.id), |
|||
('type', 'in', ('out_invoice', 'out_refund')), |
|||
('release_capital_request', '=', False), |
|||
]) |
|||
account_invoice_report._apply_ir_rules(where_query, 'read') |
|||
from_clause, where_clause, where_clause_params = where_query.get_sql() |
|||
|
|||
# price_total is in the company currency |
|||
query = """ |
|||
SELECT SUM(price_total) as total, partner_id |
|||
FROM account_invoice_report account_invoice_report |
|||
WHERE %s |
|||
GROUP BY partner_id |
|||
""" % where_clause |
|||
self.env.cr.execute(query, where_clause_params) |
|||
price_totals = self.env.cr.dictfetchall() |
|||
for partner, child_ids in all_partners_and_children.items(): |
|||
partner.total_invoiced = sum(price['total'] for price in price_totals if price['partner_id'] in child_ids) |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_effective_date(self): |
|||
# TODO change it to compute it from the share register |
|||
for partner in self: |
|||
if partner.share_ids: |
|||
partner.effective_date = partner.share_ids[0].effective_date |
|||
|
|||
@api.multi |
|||
def _get_share_type(self): |
|||
shares = ( |
|||
self.env['product.product'] |
|||
.search([('is_share', '=', True)]) |
|||
) |
|||
share_types = [(share.default_code, share.short_name) for share in shares] |
|||
return [('', '')] + share_types |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_cooperator_type(self): |
|||
for partner in self: |
|||
share_type = '' |
|||
for line in partner.share_ids: |
|||
share_type = line.share_product_id.default_code |
|||
if share_type: |
|||
partner.cooperator_type = share_type |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_share_info(self): |
|||
for partner in self: |
|||
number_of_share = 0 |
|||
total_value = 0.0 |
|||
for line in partner.share_ids: |
|||
number_of_share += line.share_number |
|||
total_value += line.share_unit_price * line.share_number |
|||
partner.number_of_share = number_of_share |
|||
partner.total_value = total_value |
|||
|
|||
cooperator = fields.Boolean(string='Cooperator', |
|||
help="Check this box if this contact is a" |
|||
" cooperator (effective or not).") |
|||
member = fields.Boolean(string='Effective cooperator', |
|||
help="Check this box if this cooperator" |
|||
" is an effective member.") |
|||
coop_candidate = fields.Boolean(string="Cooperator candidate", |
|||
compute="_compute_coop_candidate", |
|||
store=True, |
|||
readonly=True) |
|||
old_member = fields.Boolean(string='Old cooperator', |
|||
help="Check this box if this cooperator is" |
|||
" no more an effective member.") |
|||
# todo use oca partner_contact_gender |
|||
gender = fields.Selection([('male', 'Male'), |
|||
('female', 'Female'), |
|||
('other', 'Other')], |
|||
string='Gender') |
|||
share_ids = fields.One2many('share.line', |
|||
'partner_id', |
|||
string='Share Lines') |
|||
cooperator_register_number = fields.Integer(string='Cooperator Number') |
|||
number_of_share = fields.Integer(compute="_compute_share_info", |
|||
multi='share', |
|||
string='Number of share', |
|||
readonly=True) |
|||
total_value = fields.Float(compute="_compute_share_info", |
|||
multi='share', |
|||
string='Total value of shares', |
|||
readonly=True) |
|||
company_register_number = fields.Char(string='Company Register Number') |
|||
cooperator_type = fields.Selection(selection='_get_share_type', |
|||
compute=_compute_cooperator_type, |
|||
string='Cooperator Type', |
|||
store=True) |
|||
effective_date = fields.Date(sting="Effective Date", |
|||
compute=_compute_effective_date, |
|||
store=True) |
|||
representative = fields.Boolean(string="Legal Representative") |
|||
subscription_request_ids = fields.One2many('subscription.request', |
|||
'partner_id', |
|||
string="Subscription request") |
|||
legal_form = fields.Selection([('', '')], |
|||
string="Legal form") |
|||
data_policy_approved = fields.Boolean(string="Approved Data Policy") |
|||
internal_rules_approved = fields.Boolean(string="Approved Internal Rules") |
|||
|
|||
@api.multi |
|||
@api.depends('subscription_request_ids.state') |
|||
def _compute_coop_candidate(self): |
|||
for partner in self: |
|||
if partner.member: |
|||
is_candidate = False |
|||
else: |
|||
if len(partner.subscription_request_ids.filtered(lambda record: record.state == 'done')) > 0: |
|||
is_candidate = True |
|||
else: |
|||
is_candidate = False |
|||
|
|||
partner.coop_candidate = is_candidate |
|||
|
|||
def has_representative(self): |
|||
if self.child_ids.filtered('representative'): |
|||
return True |
|||
return False |
|||
|
|||
def get_representative(self): |
|||
return self.child_ids.filtered('representative') |
|||
|
|||
def get_cooperator_from_email(self, email): |
|||
return self.search([('cooperator', '=', True), |
|||
('email', '=', email)]) |
|||
|
|||
def get_cooperator_from_crn(self, company_register_number): |
|||
return self.search([('cooperator', '=', True), |
|||
('company_register_number', '=', company_register_number)]) |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2019 Coop IT Easy SCRL fs |
|||
# Houssine Bakkali <houssine@coopiteasy.be> |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|||
|
|||
|
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class ResPartner(models.Model): |
|||
_inherit = 'res.partner' |
|||
|
|||
@api.multi |
|||
def _get_report_base_filename(self): |
|||
self.ensure_one() |
|||
if self.member: |
|||
return "Cooperator Certificate - %s" % self.name |
|||
else: |
|||
return 'unknown' |
|||
|
|||
@api.multi |
|||
def _invoice_total(self): |
|||
account_invoice_report = self.env['account.invoice.report'] |
|||
if not self.ids: |
|||
self.total_invoiced = 0.0 |
|||
return True |
|||
|
|||
all_partners_and_children = {} |
|||
all_partner_ids = [] |
|||
for partner in self: |
|||
# price_total is in the company currency |
|||
all_partners_and_children[partner] = self.search([('id', 'child_of', partner.id)]).ids |
|||
all_partner_ids += all_partners_and_children[partner] |
|||
|
|||
# searching account.invoice.report via the orm is comparatively |
|||
# expensive (generates queries "id in []" forcing to build the |
|||
# full table). |
|||
# In simple cases where all invoices are in the same currency than |
|||
# the user's company access directly these elements |
|||
|
|||
# generate where clause to include multicompany rules |
|||
where_query = account_invoice_report._where_calc([ |
|||
('partner_id', 'in', all_partner_ids), |
|||
('state', 'not in', ['draft', 'cancel']), |
|||
('company_id', '=', self.env.user.company_id.id), |
|||
('type', 'in', ('out_invoice', 'out_refund')), |
|||
('release_capital_request', '=', False), |
|||
]) |
|||
account_invoice_report._apply_ir_rules(where_query, 'read') |
|||
from_clause, where_clause, where_clause_params = where_query.get_sql() |
|||
|
|||
# price_total is in the company currency |
|||
query = """ |
|||
SELECT SUM(price_total) as total, partner_id |
|||
FROM account_invoice_report account_invoice_report |
|||
WHERE %s |
|||
GROUP BY partner_id |
|||
""" % where_clause |
|||
self.env.cr.execute(query, where_clause_params) |
|||
price_totals = self.env.cr.dictfetchall() |
|||
for partner, child_ids in all_partners_and_children.items(): |
|||
partner.total_invoiced = sum(price['total'] for price in price_totals if price['partner_id'] in child_ids) |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_effective_date(self): |
|||
# TODO change it to compute it from the share register |
|||
for partner in self: |
|||
if partner.share_ids: |
|||
partner.effective_date = partner.share_ids[0].effective_date |
|||
|
|||
@api.multi |
|||
def _get_share_type(self): |
|||
shares = ( |
|||
self.env['product.product'] |
|||
.search([('is_share', '=', True)]) |
|||
) |
|||
share_types = [(share.default_code, share.short_name) for share in shares] |
|||
return [('', '')] + share_types |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_cooperator_type(self): |
|||
for partner in self: |
|||
share_type = '' |
|||
for line in partner.share_ids: |
|||
share_type = line.share_product_id.default_code |
|||
if share_type: |
|||
partner.cooperator_type = share_type |
|||
|
|||
@api.multi |
|||
@api.depends('share_ids') |
|||
def _compute_share_info(self): |
|||
for partner in self: |
|||
number_of_share = 0 |
|||
total_value = 0.0 |
|||
for line in partner.share_ids: |
|||
number_of_share += line.share_number |
|||
total_value += line.share_unit_price * line.share_number |
|||
partner.number_of_share = number_of_share |
|||
partner.total_value = total_value |
|||
|
|||
cooperator = fields.Boolean(string='Cooperator', |
|||
help="Check this box if this contact is a" |
|||
" cooperator (effective or not).") |
|||
member = fields.Boolean(string='Effective cooperator', |
|||
help="Check this box if this cooperator" |
|||
" is an effective member.") |
|||
coop_candidate = fields.Boolean(string="Cooperator candidate", |
|||
compute="_compute_coop_candidate", |
|||
store=True, |
|||
readonly=True) |
|||
old_member = fields.Boolean(string='Old cooperator', |
|||
help="Check this box if this cooperator is" |
|||
" no more an effective member.") |
|||
# todo use oca partner_contact_gender |
|||
gender = fields.Selection([('male', 'Male'), |
|||
('female', 'Female'), |
|||
('other', 'Other')], |
|||
string='Gender') |
|||
share_ids = fields.One2many('share.line', |
|||
'partner_id', |
|||
string='Share Lines') |
|||
cooperator_register_number = fields.Integer(string='Cooperator Number') |
|||
number_of_share = fields.Integer(compute="_compute_share_info", |
|||
multi='share', |
|||
string='Number of share', |
|||
readonly=True) |
|||
total_value = fields.Float(compute="_compute_share_info", |
|||
multi='share', |
|||
string='Total value of shares', |
|||
readonly=True) |
|||
company_register_number = fields.Char(string='Company Register Number') |
|||
cooperator_type = fields.Selection(selection='_get_share_type', |
|||
compute=_compute_cooperator_type, |
|||
string='Cooperator Type', |
|||
store=True) |
|||
effective_date = fields.Date(sting="Effective Date", |
|||
compute=_compute_effective_date, |
|||
store=True) |
|||
representative = fields.Boolean(string="Legal Representative") |
|||
subscription_request_ids = fields.One2many('subscription.request', |
|||
'partner_id', |
|||
string="Subscription request") |
|||
legal_form = fields.Selection([('', '')], |
|||
string="Legal form") |
|||
data_policy_approved = fields.Boolean(string="Approved Data Policy") |
|||
internal_rules_approved = fields.Boolean(string="Approved Internal Rules") |
|||
|
|||
@api.multi |
|||
@api.depends('subscription_request_ids.state') |
|||
def _compute_coop_candidate(self): |
|||
for partner in self: |
|||
if partner.member: |
|||
is_candidate = False |
|||
else: |
|||
sub_requests = partner.subscription_request_ids.filtered( |
|||
lambda record: record.state == 'done') |
|||
is_candidate = bool(sub_requests) |
|||
|
|||
partner.coop_candidate = is_candidate |
|||
|
|||
@api.multi |
|||
def has_representative(self): |
|||
self.ensure_one() |
|||
if self.child_ids.filtered('representative'): |
|||
return True |
|||
return False |
|||
|
|||
@api.multi |
|||
def get_representative(self): |
|||
self.ensure_one() |
|||
return self.child_ids.filtered('representative') |
|||
|
|||
def get_cooperator_from_email(self, email): |
|||
return self.env['res.partner'].search([('cooperator', '=', True), |
|||
('email', '=', email)]) |
|||
|
|||
def get_cooperator_from_crn(self, company_register_number): |
|||
return self.env['res.partner'].search([('cooperator', '=', True), |
|||
('company_register_number', '=', company_register_number)]) |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf8 -*- |
|||
import controllers |
@ -1,31 +0,0 @@ |
|||
# -*- 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', |
|||
] |
|||
} |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import main |
@ -1,188 +0,0 @@ |
|||
# -*- 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 |
@ -1,117 +0,0 @@ |
|||
<?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