[MERGE]trunk.
bzr revid: vme@tinyerp.com-20140324052106-8671bunhx2of7ysa
This commit is contained in:
@@ -30,7 +30,7 @@ from openerp import SUPERUSER_ID
|
||||
from openerp import tools
|
||||
from openerp.osv import fields, osv, expression
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools.float_utils import float_round
|
||||
from openerp.tools.float_utils import float_round as round
|
||||
|
||||
import openerp.addons.decimal_precision as dp
|
||||
|
||||
@@ -1937,15 +1937,15 @@ class account_tax(osv.osv):
|
||||
#
|
||||
'base_code_id': fields.many2one('account.tax.code', 'Account Base Code', help="Use this code for the tax declaration."),
|
||||
'tax_code_id': fields.many2one('account.tax.code', 'Account Tax Code', help="Use this code for the tax declaration."),
|
||||
'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
|
||||
'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
|
||||
'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1.", digits_compute=get_precision_tax()),
|
||||
'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1.", digits_compute=get_precision_tax()),
|
||||
|
||||
# Same fields for refund invoices
|
||||
|
||||
'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the tax declaration."),
|
||||
'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the tax declaration."),
|
||||
'ref_base_sign': fields.float('Refund Base Code Sign', help="Usually 1 or -1."),
|
||||
'ref_tax_sign': fields.float('Refund Tax Code Sign', help="Usually 1 or -1."),
|
||||
'ref_base_sign': fields.float('Refund Base Code Sign', help="Usually 1 or -1.", digits_compute=get_precision_tax()),
|
||||
'ref_tax_sign': fields.float('Refund Tax Code Sign', help="Usually 1 or -1.", digits_compute=get_precision_tax()),
|
||||
'include_base_amount': fields.boolean('Included in base amount', help="Indicates if the amount of tax must be included in the base amount for the computation of the next taxes"),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
'description': fields.char('Tax Code'),
|
||||
@@ -2143,7 +2143,7 @@ class account_tax(osv.osv):
|
||||
tax_compute_precision = precision
|
||||
if taxes and taxes[0].company_id.tax_calculation_rounding_method == 'round_globally':
|
||||
tax_compute_precision += 5
|
||||
totalin = totalex = float_round(price_unit * quantity, precision)
|
||||
totalin = totalex = round(price_unit * quantity, precision)
|
||||
tin = []
|
||||
tex = []
|
||||
for tax in taxes:
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<separator/>
|
||||
<filter string="Draft" icon="terp-document-new" domain="[('state','=','draft')]" help = "Draft Invoices"/>
|
||||
<filter string="Pro-forma" icon="terp-gtk-media-pause" domain="['|', ('state','=','proforma'),('state','=','proforma2')]" help = "Pro-forma Invoices"/>
|
||||
<filter string="Invoiced" name="current" icon="terp-check" domain="[('state','not in', ('draft','cancel'))]" help = "Open and Paid Invoices"/>
|
||||
<filter string="Invoiced" name="current" icon="terp-check" domain="[('state','not in', ('draft','cancel','proforma','proforma2'))]" help = "Open and Paid Invoices"/>
|
||||
<separator/>
|
||||
<filter icon="terp-personal" string="Customer" name="customer" domain="['|', ('type','=','out_invoice'),('type','=','out_refund')]" help="Customer Invoices And Refunds"/>
|
||||
<filter icon="terp-personal" string="Supplier" domain="['|', ('type','=','in_invoice'),('type','=','in_refund')]" help="Supplier Invoices And Refunds"/>
|
||||
|
||||
@@ -41,6 +41,23 @@ class account_voucher(osv.osv):
|
||||
'number': fields.char('Number', size=32),
|
||||
}
|
||||
|
||||
def _amount_to_text(self, cr, uid, amount, currency_id, context=None):
|
||||
# Currency complete name is not available in res.currency model
|
||||
# Exceptions done here (EUR, USD, BRL) cover 75% of cases
|
||||
# For other currencies, display the currency code
|
||||
currency = self.pool['res.currency'].browse(cr, uid, currency_id, context=context)
|
||||
if currency.name.upper() == 'EUR':
|
||||
currency_name = 'Euro'
|
||||
elif currency.name.upper() == 'USD':
|
||||
currency_name = 'Dollars'
|
||||
elif currency.name.upper() == 'BRL':
|
||||
currency_name = 'reais'
|
||||
else:
|
||||
currency_name = currency.name
|
||||
#TODO : generic amount_to_text is not ready yet, otherwise language (and country) and currency can be passed
|
||||
#amount_in_word = amount_to_text(amount, context=context)
|
||||
return amount_to_text(amount, currency=currency_name)
|
||||
|
||||
def onchange_amount(self, cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=None):
|
||||
""" Inherited - add amount_in_word and allow_check_writting in returned value dictionary """
|
||||
if not context:
|
||||
@@ -48,22 +65,7 @@ class account_voucher(osv.osv):
|
||||
default = super(account_voucher, self).onchange_amount(cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=context)
|
||||
if 'value' in default:
|
||||
amount = 'amount' in default['value'] and default['value']['amount'] or amount
|
||||
|
||||
# Currency complete name is not available in res.currency model
|
||||
# Exceptions done here (EUR, USD, BRL) cover 75% of cases
|
||||
# For other currencies, display the currency code
|
||||
currency = self.pool['res.currency'].browse(cr, uid, currency_id, context=context)
|
||||
if currency.name.upper() == 'EUR':
|
||||
currency_name = 'Euro'
|
||||
elif currency.name.upper() == 'USD':
|
||||
currency_name = 'Dollars'
|
||||
elif currency.name.upper() == 'BRL':
|
||||
currency_name = 'reais'
|
||||
else:
|
||||
currency_name = currency.name
|
||||
#TODO : generic amount_to_text is not ready yet, otherwise language (and country) and currency can be passed
|
||||
#amount_in_word = amount_to_text(amount, context=context)
|
||||
amount_in_word = amount_to_text(amount, currency=currency_name)
|
||||
amount_in_word = self._amount_to_text(cr, uid, amount, currency_id, context=context)
|
||||
default['value'].update({'amount_in_word':amount_in_word})
|
||||
if journal_id:
|
||||
allow_check_writing = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context).allow_check_writing
|
||||
@@ -92,6 +94,19 @@ class account_voucher(osv.osv):
|
||||
},
|
||||
'nodestroy': True
|
||||
}
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if vals.get('amount') and vals.get('journal_id') and 'amount_in_word' not in vals:
|
||||
vals['amount_in_word'] = self._amount_to_text(cr, uid, vals['amount'], vals.get('currency_id') or \
|
||||
self.pool['account.journal'].browse(cr, uid, vals['journal_id'], context=context).currency.id or \
|
||||
self.pool['res.company'].browse(cr, uid, vals['company_id']).currency_id.id, context=context)
|
||||
return super(account_voucher, self).create(cr, uid, vals, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if vals.get('amount') and vals.get('journal_id') and 'amount_in_word' not in vals:
|
||||
vals['amount_in_word'] = self._amount_to_text(cr, uid, vals['amount'], vals.get('currency_id') or \
|
||||
self.pool['account.journal'].browse(cr, uid, vals['journal_id'], context=context).currency.id or \
|
||||
self.pool['res.company'].browse(cr, uid, vals['company_id']).currency_id.id, context=context)
|
||||
return super(account_voucher, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
||||
"""
|
||||
|
||||
@@ -463,14 +463,12 @@ def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_val
|
||||
# if at least one modification has been found
|
||||
for model_id, resource_id in lines:
|
||||
line_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, model_id).model
|
||||
name = pool.get(line_model).name_get(cr, uid, [resource_id])[0][1]
|
||||
|
||||
vals = {
|
||||
'method': method,
|
||||
'object_id': model_id,
|
||||
'user_id': uid,
|
||||
'res_id': resource_id,
|
||||
'name': name,
|
||||
}
|
||||
if (model_id, resource_id) not in old_values and method not in ('copy', 'read'):
|
||||
# the resource was not existing so we are forcing the method to 'create'
|
||||
@@ -481,7 +479,11 @@ def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_val
|
||||
# the resource is not existing anymore so we are forcing the method to 'unlink'
|
||||
# (because it could also come with the value 'write' if we are deleting the
|
||||
# record through a one2many field)
|
||||
name = old_values[(model_id, resource_id)]['value'].get('name',False)
|
||||
vals.update({'method': 'unlink'})
|
||||
else :
|
||||
name = pool[line_model].name_get(cr, uid, [resource_id])[0][1]
|
||||
vals.update({'name': name})
|
||||
# create the audittrail log in super admin mode, only if a change has been detected
|
||||
if lines[(model_id, resource_id)]:
|
||||
log_id = pool.get('audittrail.log').create(cr, SUPERUSER_ID, vals)
|
||||
|
||||
+31
-22
@@ -456,7 +456,7 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||
bFound = False
|
||||
LastFound = False
|
||||
for one_date in self.pool.get('calendar.event').get_recurrent_date_by_event(cr, uid, curEvent, context=context):
|
||||
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S')
|
||||
in_date_format = one_date.replace(tzinfo=None)
|
||||
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
|
||||
if LastFound:
|
||||
for alert in LastFound:
|
||||
@@ -490,7 +490,7 @@ class calendar_alarm_manager(osv.AbstractModel):
|
||||
bFound = False
|
||||
LastFound = False
|
||||
for one_date in self.pool.get("calendar.event").get_recurrent_date_by_event(cr, uid, curEvent, context=context):
|
||||
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S')
|
||||
in_date_format = one_date.replace(tzinfo=None)
|
||||
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, ajax_check_every_seconds, after=partner.calendar_last_notif_ack, mail=False, context=context)
|
||||
if LastFound:
|
||||
for alert in LastFound:
|
||||
@@ -680,19 +680,23 @@ class calendar_event(osv.Model):
|
||||
return [d.astimezone(pytz.UTC) for d in rset1]
|
||||
|
||||
def _get_recurrency_end_date(self, data, context=None):
|
||||
if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')):
|
||||
data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S')
|
||||
if data.get('rrule_type') in ('daily', unicode('count')):
|
||||
rel_date = relativedelta(days=data.get('count') + 1)
|
||||
elif data.get('rrule_type') in ('weekly', unicode('weekly')):
|
||||
rel_date = relativedelta(days=(data.get('count') + 1) * 7)
|
||||
elif data.get('rrule_type') in ('monthly', unicode('monthly')):
|
||||
rel_date = relativedelta(months=data.get('count') + 1)
|
||||
elif data.get('rrule_type') in ('yearly', unicode('yearly')):
|
||||
rel_date = relativedelta(years=data.get('count') + 1)
|
||||
end_date = data_date_deadline + rel_date
|
||||
else:
|
||||
end_date = data.get('end_date')
|
||||
if not data.get('recurrency'):
|
||||
return False
|
||||
|
||||
end_type = data.get('end_type')
|
||||
end_date = data.get('end_date')
|
||||
|
||||
if end_type == 'count' and all(data.get(key) for key in ['count', 'rrule_type', 'date_deadline']):
|
||||
count = data['count'] + 1
|
||||
delay, mult = {
|
||||
'daily': ('days', 1),
|
||||
'weekly': ('days', 7),
|
||||
'monthly': ('months', 1),
|
||||
'yearly': ('years', 1),
|
||||
}[data['rrule_type']]
|
||||
|
||||
deadline = datetime.strptime(data['date_deadline'], tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
return deadline + relativedelta(**{delay: count * mult})
|
||||
return end_date
|
||||
|
||||
def _find_my_attendee(self, cr, uid, meeting_ids, context=None):
|
||||
@@ -774,7 +778,11 @@ class calendar_event(osv.Model):
|
||||
result[event] = ""
|
||||
return result
|
||||
|
||||
# retro compatibility function
|
||||
def _rrule_write(self, cr, uid, ids, field_name, field_value, args, context=None):
|
||||
return self._set_rulestring(self, cr, uid, ids, field_name, field_value, args, context=context)
|
||||
|
||||
def _set_rulestring(self, cr, uid, ids, field_name, field_value, args, context=None):
|
||||
if not isinstance(ids, list):
|
||||
ids = [ids]
|
||||
data = self._get_empty_rrule_data()
|
||||
@@ -812,7 +820,7 @@ class calendar_event(osv.Model):
|
||||
'class': fields.selection([('public', 'Public'), ('private', 'Private'), ('confidential', 'Public for Employees')], 'Privacy', states={'done': [('readonly', True)]}),
|
||||
'location': fields.char('Location', help="Location of Event", track_visibility='onchange', states={'done': [('readonly', True)]}),
|
||||
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Show Time as', states={'done': [('readonly', True)]}),
|
||||
'rrule': fields.function(_get_rulestring, type='char', fnct_inv=_rrule_write, store=True, string='Recurrent Rule'),
|
||||
'rrule': fields.function(_get_rulestring, type='char', fnct_inv=_set_rulestring, store=True, string='Recurrent Rule'),
|
||||
'rrule_type': fields.selection([('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')], 'Recurrency', states={'done': [('readonly', True)]}, help="Let the event automatically repeat at that interval"),
|
||||
'recurrency': fields.boolean('Recurrent', help="Recurrent Meeting"),
|
||||
'recurrent_id': fields.integer('Recurrent ID'),
|
||||
@@ -1169,7 +1177,7 @@ class calendar_event(osv.Model):
|
||||
#repeat monthly by nweekday ((weekday, weeknumber), )
|
||||
if r._bynweekday:
|
||||
data['week_list'] = day_list[r._bynweekday[0][0]].upper()
|
||||
data['byday'] = r._bynweekday[0][1]
|
||||
data['byday'] = str(r._bynweekday[0][1])
|
||||
data['month_by'] = 'day'
|
||||
data['rrule_type'] = 'monthly'
|
||||
|
||||
@@ -1423,7 +1431,7 @@ class calendar_event(osv.Model):
|
||||
# set end_date for calendar searching
|
||||
if values.get('recurrency', True) and values.get('end_type', 'count') in ('count', unicode('count')) and \
|
||||
(values.get('rrule_type') or values.get('count') or values.get('date') or values.get('date_deadline')):
|
||||
for data in self.read(cr, uid, ids, ['date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context):
|
||||
for data in self.read(cr, uid, ids, ['end_date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context):
|
||||
end_date = self._get_recurrency_end_date(data, context=context)
|
||||
super(calendar_event, self).write(cr, uid, [data['id']], {'end_date': end_date}, context=context)
|
||||
|
||||
@@ -1454,11 +1462,12 @@ class calendar_event(osv.Model):
|
||||
if not 'user_id' in vals: # Else bug with quick_create when we are filter on an other user
|
||||
vals['user_id'] = uid
|
||||
|
||||
if vals.get('recurrency', True) and vals.get('end_type', 'count') in ('count', unicode('count')) and \
|
||||
(vals.get('rrule_type') or vals.get('count') or vals.get('date') or vals.get('date_deadline')):
|
||||
vals['end_date'] = self._get_recurrency_end_date(vals, context=context)
|
||||
|
||||
res = super(calendar_event, self).create(cr, uid, vals, context=context)
|
||||
|
||||
data = self.read(cr, uid, [res], ['end_date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context)[0]
|
||||
end_date = self._get_recurrency_end_date(data, context=context)
|
||||
self.write(cr, uid, [res], {'end_date': end_date}, context=context)
|
||||
|
||||
self.create_attendees(cr, uid, [res], context=context)
|
||||
return res
|
||||
|
||||
|
||||
@@ -401,7 +401,7 @@
|
||||
</div>
|
||||
<div style="height: 50px;text-align: left;font-size : 14px;border-collapse: separate;margin-top:10px">
|
||||
<strong style="margin-left:12px">Dear ${object.cn}</strong> ,<br/>
|
||||
<p style="margin-left:12px">this it a reminder for the event below : </p>
|
||||
<p style="margin-left:12px">That is a reminder for the event below : </p>
|
||||
</div>
|
||||
<div style="height: auto;margin-left:12px;margin-top:30px;">
|
||||
<table>
|
||||
|
||||
@@ -65,3 +65,20 @@
|
||||
-
|
||||
!python {model: calendar.event}: |
|
||||
self.write(cr, uid, [ref("calendar_event_alldaytestevent0")], {'alarm_ids': [(6,0,[ref("res_alarm_daybeforeeventstarts0")])]})
|
||||
-
|
||||
I create a recuring rule for my event
|
||||
-
|
||||
!record {model: calendar.event, id: calendar.event_sprintreview1}:
|
||||
name: Begin of month meeting
|
||||
date: !eval time.strftime('%Y-%m-%d 12:00:00')
|
||||
recurrency: true
|
||||
rrule: FREQ=MONTHLY;INTERVAL=1;COUNT=12;BYDAY=1MO
|
||||
-
|
||||
I check that the attributes are set correctly
|
||||
-
|
||||
!assert {model: calendar.event, id: calendar.event_sprintreview1}:
|
||||
- rrule_type == 'monthly'
|
||||
- count == 12
|
||||
- month_by == 'day'
|
||||
- byday == '1'
|
||||
- week_list == 'MO'
|
||||
|
||||
@@ -313,7 +313,10 @@ class crm_lead(format_address, osv.osv):
|
||||
stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context=context)
|
||||
if not stage.on_change:
|
||||
return {'value': {}}
|
||||
return {'value': {'probability': stage.probability}}
|
||||
vals = {'probability': stage.probability}
|
||||
if stage.probability >= 100 or (stage.probability == 0 and stage.sequence > 1):
|
||||
vals['date_closed'] = fields.datetime.now()
|
||||
return {'value': vals}
|
||||
|
||||
def on_change_partner_id(self, cr, uid, ids, partner_id, context=None):
|
||||
values = {}
|
||||
@@ -407,7 +410,7 @@ class crm_lead(format_address, osv.osv):
|
||||
'probability = 0 %, select "Change Probability Automatically".\n'
|
||||
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
||||
for stage_id, lead_ids in stages_leads.items():
|
||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id, 'date_closed': fields.datetime.now()}, context=context)
|
||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id}, context=context)
|
||||
return True
|
||||
|
||||
def case_mark_won(self, cr, uid, ids, context=None):
|
||||
@@ -428,7 +431,7 @@ class crm_lead(format_address, osv.osv):
|
||||
'probability = 100 % and select "Change Probability Automatically".\n'
|
||||
'Create a specific stage or edit an existing one by editing columns of your opportunity pipe.'))
|
||||
for stage_id, lead_ids in stages_leads.items():
|
||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id, 'date_closed': fields.datetime.now()}, context=context)
|
||||
self.write(cr, uid, lead_ids, {'stage_id': stage_id}, context=context)
|
||||
return True
|
||||
|
||||
def case_escalate(self, cr, uid, ids, context=None):
|
||||
|
||||
@@ -95,7 +95,6 @@
|
||||
<form string="Leads Form" version="7.0">
|
||||
<header>
|
||||
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
|
||||
attrs="{'invisible': [('probability', '=', 100)]}"
|
||||
help="Convert to Opportunity" class="oe_highlight"/>
|
||||
<field name="stage_id" widget="statusbar" clickable="True"
|
||||
domain="['&', '|', ('case_default', '=', True), ('section_ids', '=', section_id), '|', ('type', '=', type), ('type', '=', 'both')]"
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
Salesman create a mass convert wizard and convert all the leads.
|
||||
-
|
||||
!python {model: crm.lead2opportunity.partner.mass}: |
|
||||
context.update({'active_model': 'crm.lead', 'active_ids': [ref("test_crm_lead_01"), ref("test_crm_lead_02"), ref("test_crm_lead_03"), ref("test_crm_lead_04"), ref("test_crm_lead_05"), ref("test_crm_lead_06")], 'active_id': ref("test_crm_lead_01"), 'no_force_assignation': False})
|
||||
id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('test_res_user_01'), ref('test_res_user_02'), ref('test_res_user_03'), ref('test_res_user_04')])], 'section_id': ref('crm.section_sales_department'), 'deduplicate': False}, context=context)
|
||||
context.update({'active_model': 'crm.lead', 'active_ids': [ref("test_crm_lead_01"), ref("test_crm_lead_02"), ref("test_crm_lead_03"), ref("test_crm_lead_04"), ref("test_crm_lead_05"), ref("test_crm_lead_06")], 'active_id': ref("test_crm_lead_01")})
|
||||
id = self.create(cr, uid, {'user_ids': [(6, 0, [ref('test_res_user_01'), ref('test_res_user_02'), ref('test_res_user_03'), ref('test_res_user_04')])], 'section_id': ref('crm.section_sales_department'), 'deduplicate': False, 'force_assignation': True}, context=context)
|
||||
self.mass_convert(cr, uid, [id], context=context)
|
||||
-
|
||||
The leads should now be opps with a salesman and a salesteam. Also, salesmen should have been assigned following a round-robin method.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools import email_split
|
||||
import re
|
||||
|
||||
class crm_lead2opportunity_partner(osv.osv_memory):
|
||||
@@ -42,20 +43,21 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
||||
return {'value': {'partner_id': False if action != 'exist' else self._find_matching_partner(cr, uid, context=context)}}
|
||||
|
||||
def _get_duplicated_leads(self, cr, uid, partner_id, email, context=None):
|
||||
"""
|
||||
Search for opportunities that have the same partner and that arent done or cancelled
|
||||
"""
|
||||
lead_obj = self.pool.get('crm.lead')
|
||||
results = []
|
||||
emails = set(email_split(email) + [email])
|
||||
final_stage_domain = [('stage_id.probability', '<', 100), '|', ('stage_id.probability', '>', 0), ('stage_id.sequence', '<=', 1)]
|
||||
partner_match_domain = []
|
||||
for email in emails:
|
||||
partner_match_domain.append(('email_from', '=ilike', email))
|
||||
if partner_id:
|
||||
# Search for opportunities that have the same partner and that arent done or cancelled
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), '|', ('stage_id.probability', '=', False), ('stage_id.probability', '<', '100')])
|
||||
for id in ids:
|
||||
results.append(id)
|
||||
email = re.findall(r'([^ ,<@]+@[^> ,]+)', email or '')
|
||||
if email:
|
||||
ids = lead_obj.search(cr, uid, [('email_from', '=ilike', email[0]), '|', ('stage_id.probability', '=', False), ('stage_id.probability', '<', '100')])
|
||||
for id in ids:
|
||||
results.append(id)
|
||||
return list(set(results))
|
||||
|
||||
partner_match_domain.append(('partner_id', '=', partner_id))
|
||||
partner_match_domain = ['|'] * (len(partner_match_domain) - 1) + partner_match_domain
|
||||
if not partner_match_domain:
|
||||
return []
|
||||
return lead_obj.search(cr, uid, partner_match_domain + final_stage_domain)
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
@@ -126,7 +128,7 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
||||
leads = lead.browse(cr, uid, lead_ids, context=context)
|
||||
for lead_id in leads:
|
||||
partner_id = self._create_partner(cr, uid, lead_id.id, data.action, lead_id.partner_id.id, context=context)
|
||||
res = lead.convert_opportunity(cr, uid, [lead_id.id], partner_id, [], team_id, context=context)
|
||||
res = lead.convert_opportunity(cr, uid, [lead_id.id], partner_id, [], False, context=context)
|
||||
user_ids = vals.get('user_ids', False)
|
||||
if context.get('no_force_assignation'):
|
||||
leads_to_allocate = [lead_id.id for lead_id in leads if not lead_id.user_id]
|
||||
@@ -195,8 +197,7 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
|
||||
('each_exist_or_create', 'Use existing partner or create'),
|
||||
('nothing', 'Do not link to a customer')
|
||||
], 'Related Customer', required=True),
|
||||
# Uncomment me in trunk
|
||||
# 'force_assignation': fields.boolean('Force assignation', help='If unchecked, this will leave the salesman of duplicated opportunities'),
|
||||
'force_assignation': fields.boolean('Force assignation', help='If unchecked, this will leave the salesman of duplicated opportunities'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -272,10 +273,7 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
|
||||
active_ids = active_ids.difference(merged_lead_ids)
|
||||
active_ids = active_ids.union(remaining_lead_ids)
|
||||
ctx['active_ids'] = list(active_ids)
|
||||
# Remove me in trunk
|
||||
ctx['no_force_assignation'] = ctx.get('no_force_assignation', True)
|
||||
# Uncomment me in trunk
|
||||
# ctx['no_force_assignation'] = not data.force_assignation
|
||||
ctx['no_force_assignation'] = not data.force_assignation
|
||||
return self.action_apply(cr, uid, ids, context=ctx)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
<div class="oe_title">
|
||||
<h3>
|
||||
<span class="oe_grey">( </span>
|
||||
<field name="partner_latitude" nolabel="1" readonly="1" class="oe_inline"/>
|
||||
<field name="partner_latitude" nolabel="1" class="oe_inline"/>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','<=',0)]}">N </span>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','>=',0)]}">S </span>
|
||||
<field name="partner_longitude" class="oe_inline" readonly="1" nolabel="1"/>
|
||||
<field name="partner_longitude" class="oe_inline" nolabel="1"/>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','<=',0)]}">E </span>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','>=',0)]}">W </span>
|
||||
<span class="oe_grey">) </span>
|
||||
@@ -88,10 +88,10 @@
|
||||
<div>
|
||||
<h3>
|
||||
<span class="oe_grey">( </span>
|
||||
<field name="partner_latitude" nolabel="1" readonly="1" class="oe_inline"/>
|
||||
<field name="partner_latitude" nolabel="1" class="oe_inline"/>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','<=',0)]}">N </span>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_latitude','>=',0)]}">S </span>
|
||||
<field name="partner_longitude" class="oe_inline" readonly="1" nolabel="1"/>
|
||||
<field name="partner_longitude" class="oe_inline" nolabel="1"/>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','<=',0)]}">E </span>
|
||||
<span class="oe_grey oe_inline" attrs="{'invisible':[('partner_longitude','>=',0)]}">W </span>
|
||||
<span class="oe_grey">) </span>
|
||||
|
||||
@@ -0,0 +1,963 @@
|
||||
# Amharic translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2014-03-18 13:39+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Amharic <am@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-19 05:52+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_openerpuser0
|
||||
msgid "Openerp user"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "Allow timesheets validation by managers"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,requirements:0
|
||||
msgid "Requirements"
|
||||
msgstr "አስፈላጊ"
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,name:hr.process_transition_contactofemployee0
|
||||
msgid "Link the employee to information"
|
||||
msgstr "የሰራተኞች መረጃ ማገናኘት"
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,sinid:0
|
||||
msgid "SIN No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_board_hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_dashboard
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_main
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_reporting
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_root
|
||||
#: model:ir.ui.menu,name:hr.menu_human_resources_configuration
|
||||
msgid "Human Resources"
|
||||
msgstr "የሰው ሀይል አስተዳደር"
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image_medium:0
|
||||
msgid ""
|
||||
"Medium-sized photo of the employee. It is automatically resized as a "
|
||||
"128x128px image, with aspect ratio preserved. Use this field in form views "
|
||||
"or some kanban views."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Time Tracking"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
msgid "Group By..."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.view_department_form_installer
|
||||
msgid "Create Your Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_employee:0
|
||||
msgid "Number of employees currently occupying this job position."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "Organize employees periodic evaluation"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,department_id:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,department_id:0
|
||||
#: model:ir.model,name:hr.model_hr_department
|
||||
msgid "Department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_email:0
|
||||
msgid "Work Email"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image:0
|
||||
msgid ""
|
||||
"This field holds the image used as photo for the employee, limited to "
|
||||
"1024x1024px."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_holidays:0
|
||||
msgid "This installs the module hr_holidays."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Jobs"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "In Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_unread:0
|
||||
msgid "Unread Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,company_id:0
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,company_id:0
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_recruitment:0
|
||||
msgid "Expected in Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:res.users,employee_ids:0
|
||||
msgid "Related employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee.category:0
|
||||
msgid "Error! You cannot create recursive Categories."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "This installs the module hr_recruitment."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Birth"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_categ_form
|
||||
#: model:ir.ui.menu,name:hr.menu_view_employee_category_form
|
||||
msgid "Employee Tags"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Launch Recruitement"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,name:hr.process_transition_employeeuser0
|
||||
msgid "Link a user to an employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,parent_id:0
|
||||
msgid "Parent Department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_config
|
||||
msgid "Leaves"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Married"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_ids:0
|
||||
msgid "Messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Talent Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_timesheet_sheet:0
|
||||
msgid "This installs the module hr_timesheet_sheet."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Mobile:"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_unread:0
|
||||
msgid "If checked new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,color:0
|
||||
msgid "Color Index"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_employeeuser0
|
||||
msgid ""
|
||||
"The Related user field on the Employee form allows to link the OpenERP user "
|
||||
"(and her rights) to the employee."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_medium:0
|
||||
msgid "Medium-sized photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,identification_id:0
|
||||
msgid "Identification No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,gender:0
|
||||
msgid "Female"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_attendance_reason_new_config
|
||||
msgid "Attendance"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_phone:0
|
||||
msgid "Work Phone"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,child_ids:0
|
||||
msgid "Child Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,description:0
|
||||
#: model:ir.model,name:hr.model_hr_job
|
||||
msgid "Job Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,work_location:0
|
||||
msgid "Office Location"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_follower_ids:0
|
||||
msgid "Followers"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: model:ir.model,name:hr.model_hr_employee
|
||||
#: model:process.node,name:hr.process_node_employee0
|
||||
msgid "Employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employeecontact0
|
||||
msgid "Other information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,image_small:0
|
||||
msgid ""
|
||||
"Small-sized photo of the employee. It is automatically resized as a 64x64px "
|
||||
"image, with aspect ratio preserved. Use this field anywhere a small image is "
|
||||
"required."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,birthday:0
|
||||
msgid "Date of Birth"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,no_of_recruitment:0
|
||||
msgid "Number of new employees you expect to recruit."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.client,name:hr.action_client_hr_menu
|
||||
msgid "Open HR Menu"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_summary:0
|
||||
msgid ""
|
||||
"Holds the Chatter summary (number of messages, ...). This summary is "
|
||||
"directly in html format in order to be inserted in kanban views."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_account_analytic_analysis:0
|
||||
msgid ""
|
||||
"This installs the module account_analytic_analysis, which will install sales "
|
||||
"management too."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:board.board:0
|
||||
msgid "Human Resources Dashboard"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,job_id:0
|
||||
#: view:hr.job:0
|
||||
msgid "Job"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,no_of_employee:0
|
||||
msgid "Current Number of Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,member_ids:0
|
||||
msgid "Members"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_configuration
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_employee0
|
||||
msgid "Employee form and structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_expense:0
|
||||
msgid "Manage employees expenses"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Tel:"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Divorced"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,parent_id:0
|
||||
msgid "Parent Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
#: model:ir.actions.act_window,name:hr.open_module_tree_department
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_department_tree
|
||||
msgid "Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,name:hr.process_node_employeecontact0
|
||||
msgid "Employee Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.action_hr_job
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to define a new job position.\n"
|
||||
" </p><p>\n"
|
||||
" Job Positions are used to define jobs and their "
|
||||
"requirements.\n"
|
||||
" You can keep track of the number of employees you have per "
|
||||
"job\n"
|
||||
" position and follow the evolution according to what you "
|
||||
"planned\n"
|
||||
" for the future.\n"
|
||||
" </p><p>\n"
|
||||
" You can attach a survey to a job position. It will be used "
|
||||
"in\n"
|
||||
" the recruitment process to evaluate the applicants for this "
|
||||
"job\n"
|
||||
" position.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,gender:0
|
||||
msgid "Male"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid ""
|
||||
"$('.oe_employee_picture').load(function() { if($(this).width() > "
|
||||
"$(this).height()) { $(this).addClass('oe_employee_picture_wide') } });"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_evaluation:0
|
||||
msgid "This installs the module hr_evaluation."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.employee:0
|
||||
msgid "Error! You cannot create recursive hierarchy of Employee(s)."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_attendance:0
|
||||
msgid "This installs the module hr_attendance."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image_small:0
|
||||
msgid "Smal-sized photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
#: model:ir.model,name:hr.model_hr_employee_category
|
||||
msgid "Employee Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,category_ids:0
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_contract:0
|
||||
msgid "This installs the module hr_contract."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Related User"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee.category,name:0
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "Stop Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_attendance:0
|
||||
msgid "Install attendances feature"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,bank_account_id:0
|
||||
msgid "Employee bank salary account"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,note:0
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_tree
|
||||
msgid "Employees Structure"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Contact Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_holidays:0
|
||||
msgid "Manage holidays, leaves and allocation requests"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,child_ids:0
|
||||
msgid "Child Departments"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: view:hr.job:0
|
||||
#: field:hr.job,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,otherid:0
|
||||
msgid "Other Id"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.process,name:hr.process_process_employeecontractprocess0
|
||||
msgid "Employee Contract"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Contracts"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,message_ids:0
|
||||
msgid "Messages and communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,ssnid:0
|
||||
msgid "SSN No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_is_follower:0
|
||||
msgid "Is a Follower"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_recruitment:0
|
||||
msgid "Manage the recruitment process"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Human Resources Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Install your country's payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,bank_account_id:0
|
||||
msgid "Bank Account Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,message_summary:0
|
||||
msgid "Summary"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.transition,note:hr.process_transition_contactofemployee0
|
||||
msgid ""
|
||||
"In the Employee form, there are different kind of information like Contact "
|
||||
"information."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_view_employee_list_my
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to add a new employee.\n"
|
||||
" </p><p>\n"
|
||||
" With just a quick glance on the OpenERP employee screen, "
|
||||
"you\n"
|
||||
" can easily find all the information you need for each "
|
||||
"person;\n"
|
||||
" contact data, job position, availability, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "HR Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Citizenship & Other Info"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: constraint:hr.department:0
|
||||
msgid "Error! You cannot create recursive departments."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,address_id:0
|
||||
msgid "Working Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Public Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,marital:0
|
||||
msgid "Marital Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_ir_actions_act_window
|
||||
msgid "ir.actions.act_window"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,last_login:0
|
||||
msgid "Latest Connection"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,image:0
|
||||
msgid "Photo"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_module_tree_department
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to create a department.\n"
|
||||
" </p><p>\n"
|
||||
" OpenERP's department structure is used to manage all "
|
||||
"documents\n"
|
||||
" related to employees by departments: expenses, timesheets,\n"
|
||||
" leaves and holidays, recruitments, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_timesheet:0
|
||||
msgid "This installs the module hr_timesheet."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,expected_employees:0
|
||||
msgid ""
|
||||
"Expected number of employees for this job position after new recruitment."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.view_department_form_installer
|
||||
msgid ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Click to define a new department.\n"
|
||||
" </p><p>\n"
|
||||
" Your departments structure is used to manage all documents\n"
|
||||
" related to employees by departments: expenses and "
|
||||
"timesheets,\n"
|
||||
" leaves and holidays, recruitments, etc.\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
msgid "Personal Information"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,city:0
|
||||
msgid "City"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,passport_id:0
|
||||
msgid "Passport No"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,mobile_phone:0
|
||||
msgid "Work Mobile"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.job,state:0
|
||||
msgid "Recruitement in Progress"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_account_analytic_analysis:0
|
||||
msgid ""
|
||||
"Allow invoicing based on timesheets (the sale application will be installed)"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee.category:0
|
||||
msgid "Employees Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,address_home_id:0
|
||||
msgid "Home Address"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_timesheet:0
|
||||
msgid "Manage timesheets"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.open_payroll_modules
|
||||
msgid "Payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Single"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,name:0
|
||||
msgid "Job Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.job:0
|
||||
msgid "In Position"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_payroll:0
|
||||
msgid "This installs the module hr_payroll."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_contract:0
|
||||
msgid "Record contracts per employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.department:0
|
||||
msgid "department"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,country_id:0
|
||||
msgid "Nationality"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Additional Features"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,notes:0
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.action2
|
||||
msgid "Subordinate Hierarchy"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,resource_id:0
|
||||
msgid "Resource"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,complete_name:0
|
||||
#: field:hr.employee,name_related:0
|
||||
#: field:hr.employee.category,complete_name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,gender:0
|
||||
msgid "Gender"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee.category,employee_ids:0
|
||||
#: field:hr.job,employee_ids:0
|
||||
#: model:ir.actions.act_window,name:hr.hr_employee_normal_action_tree
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_list
|
||||
#: model:ir.actions.act_window,name:hr.open_view_employee_list_my
|
||||
#: model:ir.ui.menu,name:hr.menu_open_view_employee_list_my
|
||||
msgid "Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,sinid:0
|
||||
msgid "Social Insurance Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,name:0
|
||||
msgid "Department Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_reporting_timesheet
|
||||
msgid "Reports"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.config.settings,module_hr_payroll:0
|
||||
msgid "Manage payroll"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
#: model:ir.actions.act_window,name:hr.action_human_resources_configuration
|
||||
msgid "Configure Human Resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.job,state:0
|
||||
msgid "No Recruitment"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.employee,ssnid:0
|
||||
msgid "Social Security Number"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:process.node,note:hr.process_node_openerpuser0
|
||||
msgid "Creation of a OpenERP user"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,login:0
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.job,expected_employees:0
|
||||
msgid "Total Forecasted Employees"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.job,state:0
|
||||
msgid ""
|
||||
"By default 'In position', set it to 'In Recruitment' if recruitment process "
|
||||
"is going on for this job position."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_res_users
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,name:hr.action_hr_job
|
||||
#: model:ir.ui.menu,name:hr.menu_hr_job
|
||||
msgid "Job Positions"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.actions.act_window,help:hr.open_board_hr
|
||||
msgid ""
|
||||
"<div class=\"oe_empty_custom_dashboard\">\n"
|
||||
" <p>\n"
|
||||
" <b>Human Resources dashboard is empty.</b>\n"
|
||||
" </p><p>\n"
|
||||
" To add your first report into this dashboard, go to any\n"
|
||||
" menu, switch to list or graph view, and click <i>'Add "
|
||||
"to\n"
|
||||
" Dashboard'</i> in the extended search options.\n"
|
||||
" </p><p>\n"
|
||||
" You can filter and group data before inserting into the\n"
|
||||
" dashboard using the search options.\n"
|
||||
" </p>\n"
|
||||
" </div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,coach_id:0
|
||||
msgid "Coach"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: sql_constraint:hr.job:0
|
||||
msgid "The name of the job position must be unique per company!"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: help:hr.config.settings,module_hr_expense:0
|
||||
msgid "This installs the module hr_expense."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: model:ir.model,name:hr.model_hr_config_settings
|
||||
msgid "hr.config.settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.department,manager_id:0
|
||||
#: view:hr.employee:0
|
||||
#: field:hr.employee,parent_id:0
|
||||
msgid "Manager"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: selection:hr.employee,marital:0
|
||||
msgid "Widower"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: field:hr.employee,child_ids:0
|
||||
msgid "Subordinates"
|
||||
msgstr ""
|
||||
|
||||
#. module: hr
|
||||
#: view:hr.config.settings:0
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-13 06:16+0000\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-14 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: l10n_be_invoice_bba
|
||||
|
||||
@@ -161,6 +161,7 @@ class mail_thread(osv.AbstractModel):
|
||||
if res[id]['message_unread_count']:
|
||||
title = res[id]['message_unread_count'] > 1 and _("You have %d unread messages") % res[id]['message_unread_count'] or _("You have one unread message")
|
||||
res[id]['message_summary'] = "<span class='oe_kanban_mail_new' title='%s'><span class='oe_e'>9</span> %d %s</span>" % (title, res[id].pop('message_unread_count'), _("New"))
|
||||
res[id].pop('message_unread_count', None)
|
||||
return res
|
||||
|
||||
def read_followers_data(self, cr, uid, follower_ids, context=None):
|
||||
|
||||
@@ -14,6 +14,10 @@ _logger = logging.getLogger(__name__)
|
||||
class pad_common(osv.osv_memory):
|
||||
_name = 'pad.common'
|
||||
|
||||
def pad_is_configured(self, cr, uid, context=None):
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
return bool(user.company_id.pad_server)
|
||||
|
||||
def pad_generate_url(self, cr, uid, context=None):
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id;
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
.oe_pad_loading{
|
||||
text-align: center;
|
||||
opacity: 0.75;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.etherpad_readonly ul, .etherpad_readonly ol {
|
||||
|
||||
@@ -1,66 +1,82 @@
|
||||
openerp.pad = function(instance) {
|
||||
var _t = instance.web._t;
|
||||
|
||||
instance.web.form.FieldPad = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeWidgetMixin, {
|
||||
template: 'FieldPad',
|
||||
content: "",
|
||||
init: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
this.set("configured", true);
|
||||
this.on("change:configured", this, this.switch_configured);
|
||||
this._configured_deferred = this.view.dataset.call('pad_is_configured').done(function(data) {
|
||||
self.set("configured", !!data);
|
||||
}).fail(function(data, event) {
|
||||
event.preventDefault();
|
||||
self.set("configured", true);
|
||||
});
|
||||
},
|
||||
initialize_content: function() {
|
||||
var self = this;
|
||||
this.switch_configured();
|
||||
this.$('.oe_pad_switch').click(function() {
|
||||
self.$el.toggleClass('oe_pad_fullscreen');
|
||||
self.$el.find('.oe_pad_switch').toggleClass('fa-expand fa-compress');
|
||||
self.view.$el.find('.oe_chatter').toggle();
|
||||
});
|
||||
this._configured_deferred.always(function() {
|
||||
var configured = self.get('configured');
|
||||
self.$(".oe_unconfigured").toggle(!configured);
|
||||
self.$(".oe_configured").toggle(configured);
|
||||
});
|
||||
this.render_value();
|
||||
},
|
||||
switch_configured: function() {
|
||||
this.$(".oe_unconfigured").toggle(! this.get("configured"));
|
||||
this.$(".oe_configured").toggle(this.get("configured"));
|
||||
},
|
||||
render_value: function() {
|
||||
var self = this;
|
||||
if (this.get("configured") && ! this.get("value")) {
|
||||
self.view.dataset.call('pad_generate_url', {
|
||||
context: {
|
||||
model: self.view.model,
|
||||
field_name: self.name,
|
||||
object_id: self.view.datarecord.id
|
||||
},
|
||||
}).done(function(data) {
|
||||
if (! data.url) {
|
||||
self.set("configured", false);
|
||||
var self = this;
|
||||
this._configured_deferred.always(function() {
|
||||
if (! self.get('configured')) {
|
||||
return;
|
||||
};
|
||||
var value = self.get('value');
|
||||
if (self.get('effective_readonly')) {
|
||||
if (_.str.startsWith(value, 'http')) {
|
||||
this.pad_loading_request = self.view.dataset.call('pad_get_content', {url: value}).done(function(data) {
|
||||
self.$('.oe_pad_content').removeClass('oe_pad_loading').html('<div class="oe_pad_readonly"><div>');
|
||||
self.$('.oe_pad_readonly').html(data);
|
||||
}).fail(function() {
|
||||
self.$('.oe_pad_content').text(_t('Unable to load pad'));
|
||||
});
|
||||
} else {
|
||||
self.set("value", data.url);
|
||||
self.$('.oe_pad_content').addClass('oe_pad_loading').show().text(_t("This pad will be initialized on first edit"));
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$('.oe_pad_content').html("");
|
||||
var value = this.get('value');
|
||||
if (this.pad_loading_request) {
|
||||
this.pad_loading_request.abort();
|
||||
}
|
||||
if (_.str.startsWith(value, 'http')) {
|
||||
if (! this.get('effective_readonly')) {
|
||||
var content = '<iframe width="100%" height="100%" frameborder="0" src="' + value + '?showChat=false&userName=' + this.session.username + '"></iframe>';
|
||||
this.$('.oe_pad_content').html(content);
|
||||
this._dirty_flag = true;
|
||||
} else {
|
||||
this.content = '<div class="oe_pad_loading">... Loading pad ...</div>';
|
||||
this.pad_loading_request = $.get(value + '/export/html').done(function(data) {
|
||||
groups = /\<\s*body\s*\>(.*?)\<\s*\/body\s*\>/.exec(data);
|
||||
data = (groups || []).length >= 2 ? groups[1] : '';
|
||||
self.$('.oe_pad_content').html('<div class="oe_pad_readonly"><div>');
|
||||
self.$('.oe_pad_readonly').html(data);
|
||||
}).fail(function() {
|
||||
self.$('.oe_pad_content').text('Unable to load pad');
|
||||
}
|
||||
else {
|
||||
var def = $.when();
|
||||
if (! value || !_.str.startsWith(value, 'http')) {
|
||||
def = self.view.dataset.call('pad_generate_url', {
|
||||
context: {
|
||||
model: self.view.model,
|
||||
field_name: self.name,
|
||||
object_id: self.view.datarecord.id
|
||||
},
|
||||
}).done(function(data) {
|
||||
if (! data.url) {
|
||||
self.set("configured", false);
|
||||
} else {
|
||||
self.set("value", data.url);
|
||||
}
|
||||
});
|
||||
}
|
||||
def.then(function() {
|
||||
value = self.get('value');
|
||||
if (_.str.startsWith(value, 'http')) {
|
||||
var content = '<iframe width="100%" height="100%" frameborder="0" src="' + value + '?showChat=false&userName=' + self.session.username + '"></iframe>';
|
||||
self.$('.oe_pad_content').html(content);
|
||||
self._dirty_flag = true;
|
||||
}
|
||||
else {
|
||||
self.$('.oe_pad_content').text(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -513,7 +513,7 @@ class pos_order(osv.osv):
|
||||
_description = "Point of Sale"
|
||||
_order = "id desc"
|
||||
|
||||
def create_from_ui(self, cr, uid, orders, context=None):
|
||||
def create_from_ui(self, cr, uid, orders, context=None):
|
||||
|
||||
# Keep only new orders
|
||||
submitted_references = [o['data']['name'] for o in orders]
|
||||
|
||||
@@ -35,14 +35,14 @@ class mail_message(osv.Model):
|
||||
"""
|
||||
if uid == SUPERUSER_ID:
|
||||
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
context=context, count=False, access_rights_uid=access_rights_uid)
|
||||
context=context, count=count, access_rights_uid=access_rights_uid)
|
||||
group_ids = self.pool.get('res.users').browse(cr, uid, uid, context=context).groups_id
|
||||
group_user_id = self.pool.get("ir.model.data").get_object_reference(cr, uid, 'base', 'group_user')[1]
|
||||
if group_user_id not in [group.id for group in group_ids]:
|
||||
args = [('subtype_id', '!=', False)] + list(args)
|
||||
|
||||
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
context=context, count=False, access_rights_uid=access_rights_uid)
|
||||
context=context, count=count, access_rights_uid=access_rights_uid)
|
||||
|
||||
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||
""" Add Access rules of mail.message for non-employee user:
|
||||
|
||||
@@ -115,11 +115,29 @@ class product_pricelist(osv.osv):
|
||||
if name and operator == '=' and not args:
|
||||
# search on the name of the pricelist and its currency, opposite of name_get(),
|
||||
# Used by the magic context filter in the product search view.
|
||||
query_args = {'name': name, 'limit': limit}
|
||||
query_args = {'name': name, 'limit': limit, 'lang': (context or {}).get('lang') or 'en_US'}
|
||||
query = """SELECT p.id
|
||||
FROM product_pricelist p JOIN
|
||||
res_currency c ON (p.currency_id = c.id)
|
||||
WHERE p.name || ' (' || c.name || ')' = %(name)s
|
||||
FROM ((
|
||||
SELECT pr.id, pr.name
|
||||
FROM product_pricelist pr JOIN
|
||||
res_currency cur ON
|
||||
(pr.currency_id = cur.id)
|
||||
WHERE pr.name || ' (' || cur.name || ')' = %(name)s
|
||||
)
|
||||
UNION (
|
||||
SELECT tr.res_id as id, tr.value as name
|
||||
FROM ir_translation tr JOIN
|
||||
product_pricelist pr ON (
|
||||
pr.id = tr.res_id AND
|
||||
tr.type = 'model' AND
|
||||
tr.name = 'product.pricelist,name' AND
|
||||
tr.lang = %(lang)s
|
||||
) JOIN
|
||||
res_currency cur ON
|
||||
(pr.currency_id = cur.id)
|
||||
WHERE tr.value || ' (' || cur.name || ')' = %(name)s
|
||||
)
|
||||
) p
|
||||
ORDER BY p.name"""
|
||||
if limit:
|
||||
query += " LIMIT %(limit)s"
|
||||
|
||||
@@ -527,12 +527,13 @@ class product_product(osv.osv):
|
||||
cr, uid, pricelist, operator='=', context=context, limit=1)
|
||||
pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
|
||||
|
||||
products = self.browse(cr, uid, ids, context=context)
|
||||
qtys = map(lambda x: (x, quantity, partner), products)
|
||||
pl = plobj.browse(cr, uid, pricelist, context=context)
|
||||
price = plobj._price_get_multi(cr,uid, pl, qtys, context=context)
|
||||
for id in ids:
|
||||
res[id] = price.get(id, 0.0)
|
||||
if isinstance(pricelist, (int, long)):
|
||||
products = self.browse(cr, uid, ids, context=context)
|
||||
qtys = map(lambda x: (x, quantity, partner), products)
|
||||
pl = plobj.browse(cr, uid, pricelist, context=context)
|
||||
price = plobj._price_get_multi(cr,uid, pl, qtys, context=context)
|
||||
for id in ids:
|
||||
res[id] = price.get(id, 0.0)
|
||||
for id in ids:
|
||||
res.setdefault(id, 0.0)
|
||||
return res
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
# Amharic translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
|
||||
"PO-Revision-Date: 2014-03-18 08:01+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Amharic <am@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-19 05:52+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
#: field:product.product,turnover:0
|
||||
msgid "Turnover"
|
||||
msgstr "ተመላሽ"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,expected_margin_rate:0
|
||||
msgid "Expected Margin (%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.margin,from_date:0
|
||||
msgid "From"
|
||||
msgstr "ከ"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,total_cost:0
|
||||
msgid ""
|
||||
"Sum of Multiplication of Invoice price and quantity of Supplier Invoices "
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.margin,to_date:0
|
||||
msgid "To"
|
||||
msgstr "ለ"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,total_margin:0
|
||||
msgid "Turnover - Standard price"
|
||||
msgstr "የተመላሽ መደበኛ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,total_margin_rate:0
|
||||
msgid "Total Margin Rate(%)"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: selection:product.margin,invoice_state:0
|
||||
#: selection:product.product,invoice_state:0
|
||||
msgid "Draft, Open and Paid"
|
||||
msgstr "ያልተከፈለና የተከፈለ ደረሰኞች"
|
||||
|
||||
#. module: product_margin
|
||||
#: code:addons/product_margin/wizard/product_margin.py:73
|
||||
#: model:ir.actions.act_window,name:product_margin.product_margin_act_window
|
||||
#: model:ir.ui.menu,name:product_margin.menu_action_product_margin
|
||||
#: view:product.product:0
|
||||
#, python-format
|
||||
msgid "Product Margins"
|
||||
msgstr "የእቃው አይነት በአንድ መጠን ሲጨምር"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,purchase_avg_price:0
|
||||
#: field:product.product,sale_avg_price:0
|
||||
msgid "Avg. Unit Price"
|
||||
msgstr "የእቃዎች መካከለኛ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,sale_num_invoiced:0
|
||||
msgid "# Invoiced in Sale"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Catalog Price"
|
||||
msgstr "ቅናሽ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: selection:product.margin,invoice_state:0
|
||||
#: selection:product.product,invoice_state:0
|
||||
msgid "Paid"
|
||||
msgstr "ተከፈል"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
#: field:product.product,sales_gap:0
|
||||
msgid "Sales Gap"
|
||||
msgstr "የሽያጭ ክፍተት"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,sales_gap:0
|
||||
msgid "Expected Sale - Turn Over"
|
||||
msgstr "ሊሸጥ የሚችል እቃ"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,sale_expected:0
|
||||
msgid "Expected Sale"
|
||||
msgstr "ሊሸጥ የሚችል እቃ"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Standard Price"
|
||||
msgstr "የእቃው መደበኛ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,purchase_num_invoiced:0
|
||||
msgid "Sum of Quantity in Supplier Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,date_to:0
|
||||
msgid "Margin Date To"
|
||||
msgstr "የእቃው መጠን የጨመረበት ቀን"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Analysis Criteria"
|
||||
msgstr "የመመዘኛ መስፈርት"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
#: field:product.product,total_cost:0
|
||||
msgid "Total Cost"
|
||||
msgstr "አጠቃላይ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,normal_cost:0
|
||||
msgid "Sum of Multiplication of Cost price and quantity of Supplier Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,expected_margin:0
|
||||
msgid "Expected Margin"
|
||||
msgstr "የሚጠበቅ ጭማሪ"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "#Purchased"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,expected_margin_rate:0
|
||||
msgid "Expected margin * 100 / Expected Sale"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,sale_avg_price:0
|
||||
msgid "Avg. Price in Customer Invoices."
|
||||
msgstr "የመካከለኛ ዋጋ ለገዢዎች"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,purchase_avg_price:0
|
||||
msgid "Avg. Price in Supplier Invoices "
|
||||
msgstr "የመካከለኛ ዋጋ አቅራቢዎች "
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.margin,invoice_state:0
|
||||
#: field:product.product,invoice_state:0
|
||||
msgid "Invoice State"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,purchase_gap:0
|
||||
msgid "Normal Cost - Total Cost"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,sale_expected:0
|
||||
msgid ""
|
||||
"Sum of Multiplication of Sale Catalog price and quantity of Customer Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,total_margin:0
|
||||
msgid "Total Margin"
|
||||
msgstr "የሁሉም ዋጋ በአንድ መጠን ሲጨምር"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,date_from:0
|
||||
msgid "Margin Date From"
|
||||
msgstr "እቃው ከጨመረበት ቀን ጀምሮ"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,turnover:0
|
||||
msgid ""
|
||||
"Sum of Multiplication of Invoice price and quantity of Customer Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,normal_cost:0
|
||||
msgid "Normal Cost"
|
||||
msgstr "መደበኛ ዋጋ"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Purchases"
|
||||
msgstr "ግዢዎች"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,purchase_num_invoiced:0
|
||||
msgid "# Invoiced in Purchase"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,expected_margin:0
|
||||
msgid "Expected Sale - Normal Cost"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.margin:0
|
||||
msgid "Properties categories"
|
||||
msgstr "በአይነታቸው መከፍፈል"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,total_margin_rate:0
|
||||
msgid "Total margin * 100 / Turnover"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.margin:0
|
||||
msgid "Open Margins"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: selection:product.margin,invoice_state:0
|
||||
#: selection:product.product,invoice_state:0
|
||||
msgid "Open and Paid"
|
||||
msgstr "የተከፈተና የትከፈል"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Sales"
|
||||
msgstr "ሽያጭ"
|
||||
|
||||
#. module: product_margin
|
||||
#: model:ir.model,name:product_margin.model_product_product
|
||||
msgid "Product"
|
||||
msgstr "ውጤት"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.margin:0
|
||||
msgid "General Information"
|
||||
msgstr "አጠቃላይ መርጃ"
|
||||
|
||||
#. module: product_margin
|
||||
#: field:product.product,purchase_gap:0
|
||||
msgid "Purchase Gap"
|
||||
msgstr "የግዢ ክፍተት"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.margin:0
|
||||
msgid "Cancel"
|
||||
msgstr "መሰረዝ"
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.product:0
|
||||
msgid "Margins"
|
||||
msgstr "በአንድ መጠን ሲጨምር"
|
||||
|
||||
#. module: product_margin
|
||||
#: help:product.product,sale_num_invoiced:0
|
||||
msgid "Sum of Quantity in Customer Invoices"
|
||||
msgstr ""
|
||||
|
||||
#. module: product_margin
|
||||
#: view:product.margin:0
|
||||
msgid "or"
|
||||
msgstr "ወይም"
|
||||
|
||||
#. module: product_margin
|
||||
#: model:ir.model,name:product_margin.model_product_margin
|
||||
msgid "Product Margin"
|
||||
msgstr "የእቃው መጨመር"
|
||||
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-08-13 04:04+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2014-03-15 06:42+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 06:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: project
|
||||
#: view:project.project:0
|
||||
@@ -671,7 +671,7 @@ msgstr "新任务"
|
||||
#. module: project
|
||||
#: field:project.config.settings,module_project_issue_sheet:0
|
||||
msgid "Invoice working time on issues"
|
||||
msgstr ""
|
||||
msgstr "依据问题工作时间开票"
|
||||
|
||||
#. module: project
|
||||
#: view:project.project:0
|
||||
@@ -828,7 +828,7 @@ msgstr "花费的时间"
|
||||
#: view:project.project:0
|
||||
#: view:project.task:0
|
||||
msgid "í"
|
||||
msgstr ""
|
||||
msgstr "í"
|
||||
|
||||
#. module: project
|
||||
#: field:account.analytic.account,company_uom_id:0
|
||||
@@ -958,7 +958,7 @@ msgstr "本项目和相关项目的任务实际花费的小时数合计"
|
||||
msgid ""
|
||||
"Follow this project to automatically track the events associated to tasks "
|
||||
"and issues of this project."
|
||||
msgstr ""
|
||||
msgstr "关注此项目的同时,追踪此项目的任务和问题关联的事件。"
|
||||
|
||||
#. module: project
|
||||
#: view:project.task:0
|
||||
@@ -1018,7 +1018,7 @@ msgstr "信息和通信历史记录"
|
||||
msgid ""
|
||||
"To invoice or setup invoicing and renewal options, go to the related "
|
||||
"contract:"
|
||||
msgstr ""
|
||||
msgstr "开票或设定发票更新选项,到相关的合同:"
|
||||
|
||||
#. module: project
|
||||
#: field:project.task.delegate,state:0
|
||||
|
||||
@@ -7,14 +7,14 @@ msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-11-19 10:53+0000\n"
|
||||
"Last-Translator: Guipo Hao <hrlpool@sohu.com>\n"
|
||||
"PO-Revision-Date: 2014-03-15 07:15+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 07:04+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: sale
|
||||
#: help:sale.order,message_summary:0
|
||||
@@ -247,7 +247,7 @@ msgstr "计量单位 "
|
||||
#: code:addons/sale/wizard/sale_make_invoice_advance.py:101
|
||||
#, python-format
|
||||
msgid "Incorrect Data"
|
||||
msgstr ""
|
||||
msgstr "错误的数据"
|
||||
|
||||
#. module: sale
|
||||
#: code:addons/sale/wizard/sale_make_invoice_advance.py:102
|
||||
@@ -1570,7 +1570,7 @@ msgstr "查找未开票明细"
|
||||
#. module: sale
|
||||
#: model:ir.model,name:sale.model_account_config_settings
|
||||
msgid "account.config.settings"
|
||||
msgstr ""
|
||||
msgstr "会计.配置.设定"
|
||||
|
||||
#. module: sale
|
||||
#: sql_constraint:sale.order:0
|
||||
@@ -2080,7 +2080,7 @@ msgstr "产品销售单位"
|
||||
#. module: sale
|
||||
#: model:process.node,note:sale.process_node_quotation0
|
||||
msgid "Draft state of sales order"
|
||||
msgstr "销售订单草稿状态"
|
||||
msgstr "草稿状态的销售订单"
|
||||
|
||||
#. module: sale
|
||||
#: field:sale.order,origin:0
|
||||
@@ -2286,7 +2286,9 @@ msgstr ""
|
||||
msgid ""
|
||||
"Before choosing a product,\n"
|
||||
" select a customer in the sales form."
|
||||
msgstr "在挑选产品前,在 销售表单选择一个客户"
|
||||
msgstr ""
|
||||
"在挑选产品前,\n"
|
||||
" 在销售表单中选择一个客户。"
|
||||
|
||||
#. module: sale
|
||||
#: view:sale.order:0
|
||||
|
||||
+20
-16
@@ -8,14 +8,14 @@ msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
|
||||
"PO-Revision-Date: 2012-12-09 05:00+0000\n"
|
||||
"Last-Translator: sum1201 <Unknown>\n"
|
||||
"PO-Revision-Date: 2014-03-16 16:41+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 07:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:842
|
||||
@@ -76,6 +76,8 @@ msgid ""
|
||||
" %s\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"附件没弄好,你可以在OpenERP服务器上查看: %s\n"
|
||||
"\n"
|
||||
|
||||
#. module: share
|
||||
#: model:ir.module.category,name:share.module_category_share
|
||||
@@ -147,7 +149,7 @@ msgstr "共享URL"
|
||||
#: code:addons/share/wizard/share_wizard.py:881
|
||||
#, python-format
|
||||
msgid "These are your credentials to access this protected area:\n"
|
||||
msgstr ""
|
||||
msgstr "这是你访问这个保护区域的凭证:\n"
|
||||
|
||||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
@@ -173,7 +175,7 @@ msgstr ""
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please indicate the emails of the persons to share with, one per line."
|
||||
msgstr ""
|
||||
msgstr "请标明分享的用户电子邮箱,每行一个。"
|
||||
|
||||
#. module: share
|
||||
#: help:share.wizard,domain:0
|
||||
@@ -189,7 +191,7 @@ msgstr "下一个"
|
||||
#: code:addons/share/wizard/share_wizard.py:662
|
||||
#, python-format
|
||||
msgid "Action and Access Mode are required to create a shared access."
|
||||
msgstr ""
|
||||
msgstr "操作和访问模式都需要要创建一个共享入口。"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:850
|
||||
@@ -256,7 +258,7 @@ msgstr "非共享组"
|
||||
msgid ""
|
||||
"An email notification with instructions has been sent to the following "
|
||||
"people:"
|
||||
msgstr ""
|
||||
msgstr "带有操作说明的邮件通知已经发送到以下人了:"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:77
|
||||
@@ -273,6 +275,8 @@ msgid ""
|
||||
"Sales, HR, etc.)\n"
|
||||
"It is open source and can be found on http://www.openerp.com."
|
||||
msgstr ""
|
||||
"OpenERP是强大的、用户友好的商业应用套装(CRM,销售、人事、等)\n"
|
||||
"而且是开源的,可以在 http://www.openerp.com 找到并下载。"
|
||||
|
||||
#. module: share
|
||||
#: field:share.wizard,action_id:0
|
||||
@@ -282,7 +286,7 @@ msgstr "共享操作"
|
||||
#. module: share
|
||||
#: help:share.wizard,record_name:0
|
||||
msgid "Name of the shared record, if sharing a precise record"
|
||||
msgstr ""
|
||||
msgstr "如果共享一个精确记录,记录下分享名"
|
||||
|
||||
#. module: share
|
||||
#: field:res.users,share:0
|
||||
@@ -337,7 +341,7 @@ msgstr "创建新的"
|
||||
#. module: share
|
||||
#: help:share.wizard,name:0
|
||||
msgid "Title for the share (displayed to users as menu and shortcut name)"
|
||||
msgstr ""
|
||||
msgstr "共享标题(显示给用户的菜单和快捷方式的名称)"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:636
|
||||
@@ -348,7 +352,7 @@ msgstr "创建用户 %s (%s )间接共享过滤器,在用户组 %s"
|
||||
#. module: share
|
||||
#: help:share.wizard,share_root_url:0
|
||||
msgid "Main access page for users that are granted shared access"
|
||||
msgstr ""
|
||||
msgstr "用户主要访问的页面被授权共享访问"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:206
|
||||
@@ -356,7 +360,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"You must configure your email address in the user preferences before using "
|
||||
"the Share button."
|
||||
msgstr ""
|
||||
msgstr "在使用分享按钮前,你必须在用户首选项处配置你的电子邮件。"
|
||||
|
||||
#. module: share
|
||||
#: model:res.groups,name:share.group_share_user
|
||||
@@ -387,7 +391,7 @@ msgstr "数据库"
|
||||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
msgid "Share with these People (one email per line)"
|
||||
msgstr ""
|
||||
msgstr "与这些人分享(每行一个电子邮件)"
|
||||
|
||||
#. module: share
|
||||
#: field:share.wizard,domain:0
|
||||
@@ -409,7 +413,7 @@ msgstr "简述"
|
||||
#: help:share.wizard,embed_code:0
|
||||
msgid ""
|
||||
"Embed this code in your documents to provide a link to the shared document."
|
||||
msgstr ""
|
||||
msgstr "在你的文档中嵌入下列代码以提供到分享文档的连接。"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:513
|
||||
@@ -431,7 +435,7 @@ msgstr "共享你的单据"
|
||||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
msgid "Or insert the following code where you want to embed your documents"
|
||||
msgstr ""
|
||||
msgstr "或者在你想要嵌入你的文档时,插入下列代码"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:886
|
||||
@@ -439,7 +443,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"The documents have been automatically added to your current OpenERP "
|
||||
"documents.\n"
|
||||
msgstr ""
|
||||
msgstr "一份文档已经被自动增加到你现在的OpenERP文档中了。\n"
|
||||
|
||||
#. module: share
|
||||
#: model:ir.model,name:share.model_share_wizard_result_line
|
||||
|
||||
@@ -906,7 +906,7 @@ class share_result_line(osv.osv_memory):
|
||||
'login': fields.related('user_id', 'login', string='Login', type='char', size=64, required=True, readonly=True),
|
||||
'password': fields.char('Password', size=64, readonly=True),
|
||||
'share_url': fields.function(_share_url, string='Share URL', type='char', size=512),
|
||||
'share_wizard_id': fields.many2one('share.wizard', 'Share Wizard', required=True),
|
||||
'share_wizard_id': fields.many2one('share.wizard', 'Share Wizard', required=True, ondelete='cascade'),
|
||||
'newly_created': fields.boolean('Newly created', readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
|
||||
@@ -2232,14 +2232,14 @@ class stock_move(osv.osv):
|
||||
if move.picking_id:
|
||||
pickings.add(move.picking_id.id)
|
||||
if move.move_dest_id and move.move_dest_id.state == 'waiting':
|
||||
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'})
|
||||
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'}, context=context)
|
||||
if context.get('call_unlink',False) and move.move_dest_id.picking_id:
|
||||
workflow.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
|
||||
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
|
||||
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False}, context=context)
|
||||
if not context.get('call_unlink',False):
|
||||
for pick in self.pool.get('stock.picking').browse(cr, uid, list(pickings), context=context):
|
||||
if all(move.state == 'cancel' for move in pick.move_lines):
|
||||
self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'})
|
||||
self.pool.get('stock.picking').write(cr, uid, [pick.id], {'state': 'cancel'}, context=context)
|
||||
|
||||
for id in ids:
|
||||
workflow.trg_trigger(uid, 'stock.move', id, cr)
|
||||
|
||||
@@ -792,7 +792,7 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Products">
|
||||
<field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree', 'picking_type': 'internal'}" options='{"reload_on_button": true}'/>
|
||||
<field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree', 'picking_type': 'internal'}" options='{"reload_on_button": true}'/>
|
||||
<field name="note" placeholder="Add an internal note..." class="oe_inline"/>
|
||||
</page>
|
||||
<page string="Additional Info">
|
||||
@@ -926,7 +926,7 @@
|
||||
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Customer" domain="[('customer','=',True)]" />
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='move_lines']" position="replace">
|
||||
<field name="move_lines" context="{'address_out_id': partner_id, 'picking_type': 'out', 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||
<field name="move_lines" context="{'address_out_id': partner_id, 'picking_type': 'out', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||
</xpath>
|
||||
<xpath expr="/form/sheet" position="after">
|
||||
<div class="oe_chatter">
|
||||
@@ -1053,7 +1053,7 @@
|
||||
<field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Supplier" domain="[('supplier','=',True)]" context="{'default_supplier':1,'default_customer':0}"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='move_lines']" position="replace">
|
||||
<field name="move_lines" context="{'address_in_id': partner_id, 'picking_type': 'in', 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||
<field name="move_lines" context="{'address_in_id': partner_id, 'picking_type': 'in', 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree'}" options='{"reload_on_button": true}'/>
|
||||
</xpath>
|
||||
<xpath expr="/form/sheet" position="after">
|
||||
<div class="oe_chatter">
|
||||
|
||||
@@ -314,6 +314,23 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||
'/website/image/<model>/<id>/<field>'
|
||||
], auth="public", website=True)
|
||||
def website_image(self, model, id, field, max_width=maxint, max_height=maxint):
|
||||
""" Fetches the requested field and ensures it does not go above
|
||||
(max_width, max_height), resizing it if necessary.
|
||||
|
||||
Resizing is bypassed if the object provides a $field_big, which will
|
||||
be interpreted as a pre-resized version of the base field.
|
||||
|
||||
If the record is not found or does not have the requested field,
|
||||
returns a placeholder image via :meth:`~.placeholder`.
|
||||
|
||||
Sets and checks conditional response parameters:
|
||||
* :mailheader:`ETag` is always set (and checked)
|
||||
* :mailheader:`Last-Modified is set iif the record has a concurrency
|
||||
field (``__last_update``)
|
||||
|
||||
The requested field is assumed to be base64-encoded image data in
|
||||
all cases.
|
||||
"""
|
||||
Model = request.registry[model]
|
||||
|
||||
response = werkzeug.wrappers.Response()
|
||||
@@ -322,15 +339,17 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||
|
||||
ids = Model.search(request.cr, request.uid,
|
||||
[('id', '=', id)], context=request.context) \
|
||||
or Model.search(request.cr, openerp.SUPERUSER_ID,
|
||||
[('id', '=', id), ('website_published', '=', True)], context=request.context)
|
||||
or Model.search(request.cr, openerp.SUPERUSER_ID,
|
||||
[('id', '=', id), ('website_published', '=', True)], context=request.context)
|
||||
|
||||
if not ids:
|
||||
return self.placeholder(response)
|
||||
|
||||
presized = '%s_big' % field
|
||||
concurrency = '__last_update'
|
||||
[record] = Model.read(request.cr, openerp.SUPERUSER_ID, [id],
|
||||
[concurrency, field], context=request.context)
|
||||
[concurrency, field, presized],
|
||||
context=request.context)
|
||||
|
||||
if concurrency in record:
|
||||
server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
@@ -354,25 +373,28 @@ class Website(openerp.addons.web.controllers.main.Home):
|
||||
if response.status_code == 304:
|
||||
return response
|
||||
|
||||
data = record[field].decode('base64')
|
||||
fit = int(max_width), int(max_height)
|
||||
data = (record.get(presized) or record[field]).decode('base64')
|
||||
|
||||
buf = cStringIO.StringIO(data)
|
||||
|
||||
image = Image.open(buf)
|
||||
image.load()
|
||||
image = Image.open(cStringIO.StringIO(data))
|
||||
response.mimetype = Image.MIME[image.format]
|
||||
|
||||
# record provides a pre-resized version of the base field, use that
|
||||
# directly
|
||||
if record.get(presized):
|
||||
response.set_data(data)
|
||||
return response
|
||||
|
||||
fit = int(max_width), int(max_height)
|
||||
w, h = image.size
|
||||
max_w, max_h = fit
|
||||
|
||||
if w < max_w and h < max_h:
|
||||
response.data = data
|
||||
response.set_data(data)
|
||||
else:
|
||||
image.thumbnail(fit, Image.ANTIALIAS)
|
||||
image.save(response.stream, image.format)
|
||||
# invalidate content-length computed by make_conditional as writing
|
||||
# to response.stream does not do it (as of werkzeug 0.9.3)
|
||||
# invalidate content-length computed by make_conditional as
|
||||
# writing to response.stream does not do it (as of werkzeug 0.9.3)
|
||||
del response.headers['Content-Length']
|
||||
|
||||
return response
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<t t-set="additional_title">Partner Detail</t>
|
||||
<div id="wrap">
|
||||
<div class="oe_structure">
|
||||
<section data-snippet-id="title">
|
||||
<section>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
@@ -73,7 +73,7 @@ response = request.website.render("website.template_partner_post", values)
|
||||
<t t-set="additional_title">Partners</t>
|
||||
<div id="wrap">
|
||||
<div class="oe_structure">
|
||||
<section data-snippet-id="title">
|
||||
<section>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
@@ -89,7 +89,7 @@ def slug(value):
|
||||
else:
|
||||
# assume name_search result tuple
|
||||
id, name = value
|
||||
slugname = slugify(name)
|
||||
slugname = slugify(name or '')
|
||||
if not slugname:
|
||||
return str(id)
|
||||
return "%s-%d" % (slugname, id)
|
||||
@@ -580,10 +580,26 @@ class ir_attachment(osv.osv):
|
||||
return hashlib.new('sha1', attachment_dict['datas']).hexdigest()
|
||||
return None
|
||||
|
||||
def _datas_big(self, cr, uid, ids, name, arg, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
if context and context.get('bin_size'):
|
||||
return result
|
||||
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if not record.datas: continue
|
||||
try:
|
||||
result[record.id] = openerp.tools.image_resize_image_big(record.datas)
|
||||
except IOError: # apparently the error PIL.Image.open raises
|
||||
pass
|
||||
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'datas_checksum': fields.function(_datas_checksum, size=40,
|
||||
string="Datas checksum", type='char', store=True, select=True),
|
||||
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char')
|
||||
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'),
|
||||
'datas_big': fields.function (_datas_big, type='binary', store=True,
|
||||
string="Resized file content"),
|
||||
}
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #ad1d28;
|
||||
}
|
||||
.oe_product section {
|
||||
background: rgba(16, 138, 147, 0.75) !important;
|
||||
}
|
||||
.oe_product section .text-info {
|
||||
color: #DFD6F5;
|
||||
}
|
||||
ul.wizard li {
|
||||
background: #debb27 !important;
|
||||
}
|
||||
ul.wizard .chevron:before {
|
||||
border-left: 10px solid #debb27 !important;
|
||||
}
|
||||
ul.wizard .text-primary {
|
||||
color: #ad1d28 !important;
|
||||
}
|
||||
ul.wizard .text-success {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before {
|
||||
color: #79D5DB !important;
|
||||
}
|
||||
.input-group-addon .fa {
|
||||
color: #444;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#website-top-navbar button.btn-primary {
|
||||
color: #fff;
|
||||
border: 2px solid #0061c2;
|
||||
}
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
.oe_product section {
|
||||
background: rgba(40, 40, 40, 0.85) !important;
|
||||
}
|
||||
.oe_product section .text-info {
|
||||
color: #BA66E4;
|
||||
}
|
||||
ul.wizard li {
|
||||
background: #222 !important;
|
||||
}
|
||||
ul.wizard .chevron:before {
|
||||
border-left: 10px solid #222 !important;
|
||||
}
|
||||
.popover, .modal-content {
|
||||
border: 1px solid rgba(200,200,200,0.5);
|
||||
}
|
||||
.close {
|
||||
color: #fff;
|
||||
}
|
||||
.popover.bottom .arrow:after {
|
||||
border-bottom-color: #333;
|
||||
}
|
||||
.popover.top .arrow:after {
|
||||
border-top-color: #333;
|
||||
}
|
||||
.popover.left .arrow:after {
|
||||
border-left-color: #333;
|
||||
}
|
||||
.popover.right .arrow:after {
|
||||
border-right-color: #333;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #2c3e50;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#website-top-navbar button.btn-primary {
|
||||
border: 2px solid #e4332e;
|
||||
}
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.oe_product section .text-info {
|
||||
color: #2A9CBE;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
.oe_product section {
|
||||
background: rgba(40, 40, 45, 0.80) !important;
|
||||
}
|
||||
ul.wizard li {
|
||||
background-image: -webkit-linear-gradient(#8a9196,#7a8288 60%,#788084) !important;
|
||||
background-image: linear-gradient(#8a9196,#7a8288 60%,#788084 ) !important;
|
||||
color: #ccc;
|
||||
}
|
||||
ul.wizard .chevron:before {
|
||||
border-left: 10px solid #7C8386 !important;
|
||||
}
|
||||
ul.wizard li.text-primary {
|
||||
color: #fff;
|
||||
}
|
||||
.close {
|
||||
color: #fff;
|
||||
}
|
||||
.popover {
|
||||
-webkit-box-shadow: 0px 0px 20px rgba(0,0,0,0.5);
|
||||
box-shadow: 0px 0px 20px rgba(0,0,0,0.5);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
.carousel .carousel-caption.content,
|
||||
.carousel .carousel-caption.content h1,
|
||||
.carousel .carousel-caption.content h2,
|
||||
.carousel .carousel-caption.content h3,
|
||||
.carousel .carousel-caption.content h4,
|
||||
.carousel .carousel-caption.content h5 {
|
||||
color: #ccc;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#website-top-navbar a.btn-link {
|
||||
color: #fff;
|
||||
}
|
||||
.popover .close {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -328,14 +328,10 @@
|
||||
}
|
||||
.oe_overlay .oe_handle.size .oe_handle_button {
|
||||
z-index: 3;
|
||||
content: "Resize";
|
||||
width: 64px;
|
||||
text-align: center;
|
||||
margin-left: -32px;
|
||||
margin-top: -10px;
|
||||
cursor: row-resize;
|
||||
left: 0px;
|
||||
top: 9px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size .oe_handle_button:hover {
|
||||
background: rgba(30, 30, 30, 0.8);
|
||||
@@ -344,6 +340,24 @@
|
||||
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.oe_overlay .oe_handle.size .size {
|
||||
width: 64px;
|
||||
cursor: row-resize;
|
||||
top: 9px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size .auto_size {
|
||||
width: 20px;
|
||||
padding: 0 5px;
|
||||
top: 1px;
|
||||
margin-left: 36px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.oe_overlay .oe_handle.readonly {
|
||||
cursor: auto !important;
|
||||
}
|
||||
.oe_overlay .oe_handle.readonly:before, .oe_overlay .oe_handle.readonly.size {
|
||||
display: none !important;
|
||||
}
|
||||
.oe_overlay .icon.btn {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -351,7 +365,7 @@
|
||||
position: absolute;
|
||||
left: 50% !important;
|
||||
text-align: center;
|
||||
top: -11px;
|
||||
top: -20px;
|
||||
z-index: 1002;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options > .btn-group {
|
||||
@@ -618,8 +632,3 @@
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
[data-snippet-id] {
|
||||
min-height: 10px;
|
||||
min-width: 10px;
|
||||
}
|
||||
|
||||
@@ -240,18 +240,28 @@
|
||||
bottom: -6px
|
||||
.oe_handle_button
|
||||
z-index: 3
|
||||
content: "Resize"
|
||||
width: 64px
|
||||
text-align: center
|
||||
margin-left: -32px
|
||||
margin-top: -10px
|
||||
cursor: row-resize
|
||||
left: 0px
|
||||
top: 9px
|
||||
&:hover
|
||||
background: rgba(30, 30, 30, .8)
|
||||
color: #fff
|
||||
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
|
||||
.size
|
||||
width: 64px
|
||||
cursor: row-resize
|
||||
top: 9px
|
||||
.auto_size
|
||||
width: 20px
|
||||
padding: 0 5px
|
||||
top: 1px
|
||||
margin-left: 36px
|
||||
cursor: pointer
|
||||
&.readonly
|
||||
cursor: auto !important
|
||||
&:before, &.size
|
||||
display: none !important
|
||||
|
||||
.icon.btn
|
||||
display: inline-block
|
||||
@@ -260,7 +270,7 @@
|
||||
position: absolute
|
||||
left: 50% !important
|
||||
text-align: center
|
||||
top: -11px
|
||||
top: -20px
|
||||
z-index: 1002
|
||||
> .btn-group
|
||||
left: -50%
|
||||
@@ -485,10 +495,6 @@
|
||||
height: 16px
|
||||
display: inline-block
|
||||
|
||||
[data-snippet-id]
|
||||
min-height: 10px
|
||||
min-width: 10px
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,6 +102,10 @@ header a.navbar-brand img {
|
||||
max-height: 50px;
|
||||
}
|
||||
|
||||
#wrapwrap p:empty:after {
|
||||
content: "\2060";
|
||||
}
|
||||
|
||||
/* ----- Snippets Styles ----- */
|
||||
.readable {
|
||||
font-size: 120%;
|
||||
@@ -116,9 +120,10 @@ header a.navbar-brand img {
|
||||
}
|
||||
|
||||
/* ----- BOOTSTRAP FIX ----- */
|
||||
.container .container {
|
||||
.container .container, .readable .container {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
|
||||
@@ -216,7 +221,6 @@ footer {
|
||||
/* -- Hack for removing double scrollbar from mobile preview -- */
|
||||
div#mobile-preview.modal {
|
||||
overflow: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
ul.nav-stacked > li > a {
|
||||
@@ -236,7 +240,7 @@ ul.nav-stacked > li > a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-publish='off'] {
|
||||
[data-publish='off'] > *:not(.css_options) {
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -280,12 +284,16 @@ ul.nav-stacked > li > a {
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
[data-snippet-id], .colmd, .hr, .blockquote {
|
||||
section, .carousel, .parallax, .row, .hr, .blockquote {
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.carousel, .parallax, .blockquote {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
[data-snippet-id]:not([data-snippet-id="carousel"]) {
|
||||
section, .parallax, .row, .hr, .blockquote {
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
@@ -380,10 +388,10 @@ ul.nav-stacked > li > a {
|
||||
}
|
||||
|
||||
/* Parallax Theme */
|
||||
div.carousel[data-snippet-id="slider"] .carousel-indicators li {
|
||||
div.carousel .carousel-indicators li {
|
||||
border: 1px solid grey;
|
||||
}
|
||||
div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
|
||||
div.carousel .carousel-indicators .active {
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,12 @@ header
|
||||
img
|
||||
max-height: 50px
|
||||
|
||||
// add {WORD JOINER} (equivalent to deprecated ZERO WIDTH NO-BREAK SPACE) at
|
||||
// the beginning of paragraphs so they don't "disappear" after saving when
|
||||
// used solely for spacing.
|
||||
#wrapwrap p:empty:after
|
||||
content: '\2060'
|
||||
|
||||
/* ----- Snippets Styles ----- */
|
||||
|
||||
.readable
|
||||
@@ -78,17 +84,16 @@ header
|
||||
|
||||
/* ----- EDITOR ----- */
|
||||
|
||||
|
||||
.css_non_editable_mode_hidden
|
||||
display: none
|
||||
|
||||
|
||||
/* ----- BOOTSTRAP FIX ----- */
|
||||
|
||||
.container
|
||||
.container, .readable
|
||||
.container
|
||||
padding-left: 0
|
||||
padding-right: 0
|
||||
width: auto
|
||||
|
||||
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
|
||||
|
||||
@@ -179,7 +184,6 @@ footer
|
||||
/* -- Hack for removing double scrollbar from mobile preview -- */
|
||||
div#mobile-preview.modal
|
||||
overflow: hidden
|
||||
overflow-y: hidden
|
||||
|
||||
ul.nav-stacked > li > a
|
||||
padding: 2px 15px
|
||||
@@ -195,7 +199,7 @@ ul.nav-stacked > li > a
|
||||
.btn-success, .css_unpublish
|
||||
display: none
|
||||
|
||||
[data-publish='off']
|
||||
[data-publish='off']>*:not(.css_options)
|
||||
+opacity(0.5)
|
||||
|
||||
/* ---- END of PUBLISH ---- */
|
||||
@@ -230,11 +234,13 @@ ul.nav-stacked > li > a
|
||||
.oe_img_bg
|
||||
background-size: 100%
|
||||
|
||||
[data-snippet-id],.colmd,.hr,.blockquote
|
||||
section, .carousel, .parallax, .row, .hr, .blockquote
|
||||
min-height: 30px
|
||||
.carousel, .parallax, .blockquote
|
||||
overflow: hidden
|
||||
|
||||
@media (max-width: 400px)
|
||||
[data-snippet-id]:not([data-snippet-id="carousel"])
|
||||
section, .parallax, .row, .hr, .blockquote
|
||||
height: auto !important
|
||||
|
||||
.carousel-inner
|
||||
@@ -312,7 +318,7 @@ ul.nav-stacked > li > a
|
||||
|
||||
/* Parallax Theme */
|
||||
|
||||
div.carousel[data-snippet-id="slider"]
|
||||
div.carousel
|
||||
.carousel-indicators
|
||||
li
|
||||
border: 1px solid grey
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
},
|
||||
canUndo: false,
|
||||
editorFocus: true,
|
||||
context: 'a',
|
||||
});
|
||||
//noinspection JSValidateTypes
|
||||
editor.addCommand('image', {
|
||||
@@ -115,6 +116,7 @@
|
||||
},
|
||||
canUndo: false,
|
||||
editorFocus: true,
|
||||
context: 'img',
|
||||
});
|
||||
|
||||
editor.ui.addButton('Link', {
|
||||
@@ -205,8 +207,9 @@
|
||||
icon: '/website/static/src/img/bglink.png',
|
||||
modes: { wysiwyg: true },
|
||||
editorFocus: true,
|
||||
context: 'a',
|
||||
panel: {
|
||||
css: '/website/static/lib/bootstrap/css/bootstrap.css',
|
||||
css: '/web/static/lib/bootstrap/css/bootstrap.css',
|
||||
attributes: { 'role': 'listbox', 'aria-label': label },
|
||||
},
|
||||
|
||||
@@ -346,14 +349,40 @@
|
||||
requires: 'widget',
|
||||
|
||||
init: function (editor) {
|
||||
var specials = {
|
||||
// Can't find the correct ACL rule to only allow img tags
|
||||
image: { content: '*' },
|
||||
html: { text: '*' },
|
||||
monetary: {
|
||||
text: {
|
||||
selector: 'span.oe_currency_value',
|
||||
allowedContent: { }
|
||||
}
|
||||
}
|
||||
};
|
||||
_(specials).each(function (editable, type) {
|
||||
editor.widgets.add(type, {
|
||||
draggable: false,
|
||||
editables: editable,
|
||||
upcast: function (el) {
|
||||
return el.attributes['data-oe-type'] === type;
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
editor.widgets.add('oeref', {
|
||||
editables: { text: '*' },
|
||||
draggable: false,
|
||||
|
||||
editables: {
|
||||
text: {
|
||||
selector: '*',
|
||||
allowedContent: { }
|
||||
},
|
||||
},
|
||||
upcast: function (el) {
|
||||
var matches = el.attributes['data-oe-type'] && el.attributes['data-oe-type'] !== 'monetary';
|
||||
if (!matches) { return false; }
|
||||
|
||||
var type = el.attributes['data-oe-type'];
|
||||
if (!type || (type in specials)) {
|
||||
return false;
|
||||
}
|
||||
if (el.attributes['data-oe-original']) {
|
||||
while (el.children.length) {
|
||||
el.children[0].remove();
|
||||
@@ -363,16 +392,9 @@
|
||||
));
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
editor.widgets.add('monetary', {
|
||||
editables: { text: 'span.oe_currency_value' },
|
||||
draggable: false,
|
||||
|
||||
upcast: function (el) {
|
||||
return el.attributes['data-oe-type'] === 'monetary';
|
||||
}
|
||||
});
|
||||
|
||||
editor.widgets.add('icons', {
|
||||
draggable: false,
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
"use strict";
|
||||
|
||||
var website = {};
|
||||
// The following line can be removed in 2017
|
||||
openerp.website = website;
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Helpers
|
||||
---------------------------------------------------- */
|
||||
website.get_context = function (dict) {
|
||||
var html = document.documentElement;
|
||||
return _.extend({
|
||||
@@ -34,26 +36,11 @@
|
||||
}
|
||||
return parsedSearch;
|
||||
};
|
||||
|
||||
website.parseHash = function () {
|
||||
return website.parseQS(window.location.hash.substring(1));
|
||||
};
|
||||
|
||||
/* ----- TEMPLATE LOADING ---- */
|
||||
var templates_def = $.Deferred().resolve();
|
||||
website.add_template_file = function(template) {
|
||||
templates_def = templates_def.then(function() {
|
||||
var def = $.Deferred();
|
||||
openerp.qweb.add_template(template, function(err) {
|
||||
if (err) {
|
||||
def.reject(err);
|
||||
} else {
|
||||
def.resolve();
|
||||
}
|
||||
});
|
||||
return def;
|
||||
});
|
||||
};
|
||||
website.add_template_file('/website/static/src/xml/website.xml');
|
||||
website.reload = function () {
|
||||
location.hash = "scrollTop=" + window.document.body.scrollTop;
|
||||
if (location.search.indexOf("enable_editor") > -1) {
|
||||
@@ -63,103 +50,9 @@
|
||||
}
|
||||
};
|
||||
|
||||
var all_ready = null;
|
||||
var dom_ready = website.dom_ready = $.Deferred();
|
||||
$(document).ready(function () {
|
||||
website.is_editable = website.is_editable || $('html').data('editable');
|
||||
website.is_editable_button= website.is_editable_button || $('html').data('editable');
|
||||
dom_ready.resolve();
|
||||
// fix for ie
|
||||
if($.fn.placeholder) $('input, textarea').placeholder();
|
||||
});
|
||||
|
||||
website.init_kanban = function ($kanban) {
|
||||
$('.js_kanban_col', $kanban).each(function () {
|
||||
var $col = $(this);
|
||||
var $pagination = $('.pagination', $col);
|
||||
if(!$pagination.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var page_count = $col.data('page_count');
|
||||
var scope = $pagination.last().find("li").size()-2;
|
||||
var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, '');
|
||||
|
||||
var data = {
|
||||
'domain': $col.data('domain'),
|
||||
'model': $col.data('model'),
|
||||
'template': $col.data('template'),
|
||||
'step': $col.data('step'),
|
||||
'orderby': $col.data('orderby')
|
||||
};
|
||||
|
||||
$pagination.on('click', 'a', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $a = $(ev.target);
|
||||
if($a.parent().hasClass('active')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var page = +$a.attr("href").split(",").pop().split('-')[1];
|
||||
data['page'] = page;
|
||||
|
||||
$.post('/website/kanban/', data, function (col) {
|
||||
$col.find("> .thumbnail").remove();
|
||||
$pagination.last().before(col);
|
||||
});
|
||||
|
||||
var page_start = page - parseInt(Math.floor((scope-1)/2), 10);
|
||||
if (page_start < 1 ) page_start = 1;
|
||||
var page_end = page_start + (scope-1);
|
||||
if (page_end > page_count ) page_end = page_count;
|
||||
|
||||
if (page_end - page_start < scope) {
|
||||
page_start = page_end - scope > 0 ? page_end - scope : 1;
|
||||
}
|
||||
|
||||
$pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1));
|
||||
$pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end));
|
||||
for(var i=0; i < scope; i++) {
|
||||
$pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i);
|
||||
}
|
||||
$pagination.find('li.active').removeClass('active');
|
||||
$pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a deferred resolved when the templates are loaded
|
||||
* and the Widgets can be instanciated.
|
||||
*/
|
||||
website.ready = function() {
|
||||
if (!all_ready) {
|
||||
all_ready = dom_ready.then(function () {
|
||||
return templates_def;
|
||||
}).then(function () {
|
||||
if (website.is_editable) {
|
||||
website.id = $('html').data('website-id');
|
||||
website.session = new openerp.Session();
|
||||
var modules = ['website'];
|
||||
return openerp._t.database.load_translations(website.session, modules, website.get_context().lang);
|
||||
}
|
||||
}).promise();
|
||||
}
|
||||
return all_ready;
|
||||
};
|
||||
|
||||
website.error = function(data, url) {
|
||||
var $error = $(openerp.qweb.render('website.error_dialog', {
|
||||
'title': data.data ? data.data.arguments[0] : "",
|
||||
'message': data.data ? data.data.arguments[1] : data.statusText,
|
||||
'backend_url': url
|
||||
}));
|
||||
$error.appendTo("body");
|
||||
$error.modal('show');
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Widgets
|
||||
---------------------------------------------------- */
|
||||
website.prompt = function (options) {
|
||||
/**
|
||||
* A bootstrapped version of prompt() albeit asynchronous
|
||||
@@ -231,11 +124,13 @@
|
||||
dialog.on('click', '.btn-primary', function () {
|
||||
def.resolve(field.val(), field, dialog);
|
||||
dialog.remove();
|
||||
$('.modal-backdrop').remove();
|
||||
});
|
||||
});
|
||||
dialog.on('hidden.bs.modal', function () {
|
||||
def.reject();
|
||||
dialog.remove();
|
||||
$('.modal-backdrop').remove();
|
||||
});
|
||||
if (field.is('input[type="text"], select')) {
|
||||
field.keypress(function (e) {
|
||||
@@ -248,6 +143,16 @@
|
||||
return def;
|
||||
};
|
||||
|
||||
website.error = function(data, url) {
|
||||
var $error = $(openerp.qweb.render('website.error_dialog', {
|
||||
'title': data.data ? data.data.arguments[0] : "",
|
||||
'message': data.data ? data.data.arguments[1] : data.statusText,
|
||||
'backend_url': url
|
||||
}));
|
||||
$error.appendTo("body");
|
||||
$error.modal('show');
|
||||
};
|
||||
|
||||
website.form = function (url, method, params) {
|
||||
var form = document.createElement('form');
|
||||
form.setAttribute('action', url);
|
||||
@@ -263,11 +168,117 @@
|
||||
form.submit();
|
||||
};
|
||||
|
||||
dom_ready.then(function () {
|
||||
website.init_kanban = function ($kanban) {
|
||||
$('.js_kanban_col', $kanban).each(function () {
|
||||
var $col = $(this);
|
||||
var $pagination = $('.pagination', $col);
|
||||
if(!$pagination.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----- BOOTSTRAP STUFF ---- */
|
||||
// $('.js_tooltip').bstooltip();
|
||||
var page_count = $col.data('page_count');
|
||||
var scope = $pagination.last().find("li").size()-2;
|
||||
var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, '');
|
||||
|
||||
var data = {
|
||||
'domain': $col.data('domain'),
|
||||
'model': $col.data('model'),
|
||||
'template': $col.data('template'),
|
||||
'step': $col.data('step'),
|
||||
'orderby': $col.data('orderby')
|
||||
};
|
||||
|
||||
$pagination.on('click', 'a', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $a = $(ev.target);
|
||||
if($a.parent().hasClass('active')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var page = +$a.attr("href").split(",").pop().split('-')[1];
|
||||
data['page'] = page;
|
||||
|
||||
$.post('/website/kanban/', data, function (col) {
|
||||
$col.find("> .thumbnail").remove();
|
||||
$pagination.last().before(col);
|
||||
});
|
||||
|
||||
var page_start = page - parseInt(Math.floor((scope-1)/2), 10);
|
||||
if (page_start < 1 ) page_start = 1;
|
||||
var page_end = page_start + (scope-1);
|
||||
if (page_end > page_count ) page_end = page_count;
|
||||
|
||||
if (page_end - page_start < scope) {
|
||||
page_start = page_end - scope > 0 ? page_end - scope : 1;
|
||||
}
|
||||
|
||||
$pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1));
|
||||
$pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end));
|
||||
for(var i=0; i < scope; i++) {
|
||||
$pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i);
|
||||
}
|
||||
$pagination.find('li.active').removeClass('active');
|
||||
$pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Async Ready and Template loading
|
||||
---------------------------------------------------- */
|
||||
var templates_def = $.Deferred().resolve();
|
||||
website.add_template_file = function(template) {
|
||||
templates_def = templates_def.then(function() {
|
||||
var def = $.Deferred();
|
||||
openerp.qweb.add_template(template, function(err) {
|
||||
if (err) {
|
||||
def.reject(err);
|
||||
} else {
|
||||
def.resolve();
|
||||
}
|
||||
});
|
||||
return def;
|
||||
});
|
||||
};
|
||||
website.add_template_file('/website/static/src/xml/website.xml');
|
||||
|
||||
website.dom_ready = $.Deferred();
|
||||
$(document).ready(function () {
|
||||
website.is_editable = website.is_editable || $('html').data('editable');
|
||||
website.is_editable_button= website.is_editable_button || $('html').data('editable');
|
||||
website.dom_ready.resolve();
|
||||
// fix for ie
|
||||
if($.fn.placeholder) $('input, textarea').placeholder();
|
||||
});
|
||||
|
||||
var all_ready = null;
|
||||
/**
|
||||
* Returns a deferred resolved when the templates are loaded
|
||||
* and the Widgets can be instanciated.
|
||||
*/
|
||||
website.ready = function() {
|
||||
if (!all_ready) {
|
||||
all_ready = website.dom_ready.then(function () {
|
||||
return templates_def;
|
||||
}).then(function () {
|
||||
if (website.is_editable) {
|
||||
website.id = $('html').data('website-id');
|
||||
website.session = new openerp.Session();
|
||||
var modules = ['website'];
|
||||
return openerp._t.database.load_translations(website.session, modules, website.get_context().lang);
|
||||
}
|
||||
}).promise();
|
||||
}
|
||||
return all_ready;
|
||||
};
|
||||
|
||||
website.inject_tour = function() {
|
||||
// if a tour is active inject tour js
|
||||
}
|
||||
|
||||
website.dom_ready.then(function () {
|
||||
/* ----- PUBLISHING STUFF ---- */
|
||||
$(document).on('click', '.js_publish_management .js_publish_btn', function () {
|
||||
var $data = $(this).parents(".js_publish_management:first");
|
||||
|
||||
@@ -5,20 +5,26 @@
|
||||
if (!website.snippet) website.snippet = {};
|
||||
website.snippet.readyAnimation = [];
|
||||
|
||||
website.snippet.start_animation = function () {
|
||||
website.snippet.start_animation = function (editable_mode, $target) {
|
||||
for (var k in website.snippet.animationRegistry) {
|
||||
var Animation = website.snippet.animationRegistry[k];
|
||||
var selector = "[data-snippet-id='"+k+"']";
|
||||
var selector = "";
|
||||
if (Animation.prototype.selector) {
|
||||
selector += ", " + Animation.prototype.selector;
|
||||
if (selector != "") selector += ", "
|
||||
selector += Animation.prototype.selector;
|
||||
}
|
||||
if ($target) {
|
||||
if ($target.is(selector)) selector = $target;
|
||||
else continue;
|
||||
}
|
||||
|
||||
$(selector).each(function() {
|
||||
var $snipped_id = $(this);
|
||||
if ( !$snipped_id.parents("#oe_snippets").length &&
|
||||
!$snipped_id.parent("body").length &&
|
||||
!$snipped_id.data("snippet-view")) {
|
||||
website.snippet.readyAnimation.push($snipped_id);
|
||||
$snipped_id.data("snippet-view", new Animation($snipped_id));
|
||||
$snipped_id.data("snippet-view", new Animation($snipped_id, editable_mode));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -32,7 +38,9 @@
|
||||
}
|
||||
});
|
||||
};
|
||||
$(document).ready(website.snippet.start_animation);
|
||||
$(document).ready(function () {
|
||||
website.snippet.start_animation();
|
||||
});
|
||||
|
||||
|
||||
website.snippet.animationRegistry = {};
|
||||
@@ -41,9 +49,9 @@
|
||||
$: function () {
|
||||
return this.$el.find.apply(this.$el, arguments);
|
||||
},
|
||||
init: function (dom) {
|
||||
init: function (dom, editable_mode) {
|
||||
this.$el = this.$target = $(dom);
|
||||
this.start();
|
||||
this.start(editable_mode);
|
||||
},
|
||||
/*
|
||||
* start
|
||||
@@ -71,7 +79,7 @@
|
||||
});
|
||||
|
||||
website.snippet.animationRegistry.parallax = website.snippet.Animation.extend({
|
||||
parallax: ".parallax",
|
||||
selector: ".parallax",
|
||||
start: function () {
|
||||
var self = this;
|
||||
setTimeout(function () {self.set_values();});
|
||||
@@ -108,7 +116,7 @@
|
||||
img.onload = function () {
|
||||
var offset = 0;
|
||||
var padding = parseInt($(document.body).css("padding-top"));
|
||||
if (speed < 1) {
|
||||
if (speed > 1) {
|
||||
var inner_offset = - self.$target.outerHeight() + this.height / this.width * document.body.clientWidth;
|
||||
var outer_offset = self.$target.offset().top - (document.body.clientHeight - self.$target.outerHeight()) - padding;
|
||||
offset = - outer_offset * speed + inner_offset;
|
||||
@@ -123,4 +131,21 @@
|
||||
}
|
||||
});
|
||||
|
||||
website.snippet.animationRegistry.share = website.snippet.Animation.extend({
|
||||
selector: ".oe_share",
|
||||
start: function () {
|
||||
var url = encodeURIComponent(window.location.href);
|
||||
var title = encodeURIComponent($("title").text());
|
||||
this.$target.find("a").each(function () {
|
||||
var $a = $(this);
|
||||
$a.attr("href", $(this).attr("href").replace("{url}", url).replace("{title}", title));
|
||||
if ($a.attr("target") && $a.attr("target").match(/_blank/i)) {
|
||||
$a.click(function () {
|
||||
window.open(this.href,'','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,11 +35,11 @@
|
||||
element: 'button[data-action=snippet]',
|
||||
placement: 'bottom',
|
||||
title: _t("Insert building blocks"),
|
||||
content: _t("To add content in a page, you can insert building blocks."),
|
||||
content: _t("Click here to insert blocks of centent in the page."),
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'carousel',
|
||||
snippet: '#snippet_structure .oe_snippet:first',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a Banner"),
|
||||
content: _t("Drag the Banner block and drop it in your page."),
|
||||
@@ -47,14 +47,14 @@
|
||||
},
|
||||
{
|
||||
waitFor: '.oe_overlay_options .oe_options:visible',
|
||||
element: '#wrap [data-snippet-id=carousel]:first .carousel-caption > div',
|
||||
element: '#wrap .carousel:first .carousel-caption > div',
|
||||
placement: 'top',
|
||||
title: _t("Customize banner's text"),
|
||||
content: _t("Click in the text and start editing it."),
|
||||
popover: { next: _t("Continue") },
|
||||
},
|
||||
{
|
||||
element: '.oe_overlay_options .oe_options',
|
||||
element: '.oe_overlay_options .oe_options:visible',
|
||||
placement: 'left',
|
||||
title: _t("Customize the banner"),
|
||||
content: _t("Customize any block through this menu. Try to change the background of the banner."),
|
||||
@@ -69,14 +69,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
element: 'a[href="#snippet_feature"]',
|
||||
placement: 'bottom',
|
||||
title: _t("Feature blocks list"),
|
||||
content: _t("Click on 'Features' to see the feature blocks list."),
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'features',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(6)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop This Block"),
|
||||
content: _t("Drag the <em>'Features'</em> block and drop it below the banner."),
|
||||
@@ -92,8 +85,8 @@
|
||||
},
|
||||
{
|
||||
waitFor: 'button[data-action=edit]:visible',
|
||||
title: _("Good Job!"),
|
||||
content: _("Well done, you created your homepage."),
|
||||
title: _t("Good Job!"),
|
||||
content: _t("Well done, you created your homepage."),
|
||||
popover: { next: _t("Continue") },
|
||||
},
|
||||
{
|
||||
@@ -108,13 +101,13 @@
|
||||
element: '.modal:has(#mobile-viewport) button[data-dismiss=modal]',
|
||||
placement: 'right',
|
||||
title: _t("Check Mobile Preview"),
|
||||
content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."),
|
||||
content: _t("Scroll to check rendering and then close the mobile preview."),
|
||||
popover: { next: _t("Continue") },
|
||||
},
|
||||
{
|
||||
waitNot: '.modal',
|
||||
element: '#content-menu-button',
|
||||
placement: 'bottom',
|
||||
placement: 'left',
|
||||
title: _t("Add new pages and menus"),
|
||||
content: _t("The 'Content' menu allows you to add pages or add the top menu."),
|
||||
popover: { next: _t("Close Tutorial") },
|
||||
|
||||
@@ -3,9 +3,22 @@
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
// don't need template to use bootstrap Tour in automatic mode
|
||||
if (typeof QWeb2 !== "undefined")
|
||||
website.add_template_file('/website/static/src/xml/website.tour.xml');
|
||||
|
||||
// don't need to use bootstrap Tour to launch an automatic tour
|
||||
function bootstrap_tour_stub () {
|
||||
if (typeof Tour === "undefined") {
|
||||
window.Tour = function Tour() {};
|
||||
Tour.prototype.addSteps = function () {};
|
||||
Tour.prototype.end = function () {};
|
||||
Tour.prototype.goto = function () {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (website.EditorBar)
|
||||
website.EditorBar.include({
|
||||
tours: [],
|
||||
@@ -175,6 +188,9 @@ website.Tour = openerp.Class.extend({
|
||||
},
|
||||
|
||||
registerTour: function () {
|
||||
if (this.automatic) {
|
||||
bootstrap_tour_stub();
|
||||
}
|
||||
this.tour = new Tour({
|
||||
name: this.id,
|
||||
storage: this.tourStorage,
|
||||
@@ -205,7 +221,7 @@ website.Tour = openerp.Class.extend({
|
||||
|
||||
if (!step.element) step.orphan = true;
|
||||
if (step.snippet) {
|
||||
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
|
||||
step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -377,7 +393,7 @@ website.Tour = openerp.Class.extend({
|
||||
|
||||
if (step.snippet) {
|
||||
|
||||
var selector = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
|
||||
var selector = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail';
|
||||
self.autoDragAndDropSnippet(selector);
|
||||
|
||||
} else if (step.element.match(/#oe_snippets .* \.oe_snippet_thumbnail/)) {
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
website.Tour.LoginEdit = website.Tour.extend({
|
||||
id: 'login_edit',
|
||||
name: "Try to log as admin and check editor",
|
||||
path: '/',
|
||||
init: function () {
|
||||
var self = this;
|
||||
self.steps = [
|
||||
{
|
||||
title: "click login",
|
||||
element: '#top_menu a[href*="/web/login"]',
|
||||
},
|
||||
{
|
||||
title: "insert login",
|
||||
element: '.oe_login_form input[name="login"]',
|
||||
sampleText: "admin",
|
||||
},
|
||||
{
|
||||
title: "insert password",
|
||||
waitFor: '.oe_login_form input[name="login"][value!=""]',
|
||||
element: '.oe_login_form input[name="password"]',
|
||||
sampleText: "admin",
|
||||
},
|
||||
{
|
||||
title: "select 2 Standard tickets",
|
||||
waitFor: '.oe_login_form input[name="password"][value!=""]',
|
||||
element: '.oe_login_form button',
|
||||
},
|
||||
{
|
||||
title: "go back to website from backend",
|
||||
element: 'a[data-action-model="ir.actions.act_url"]:contains("Website")',
|
||||
},
|
||||
{
|
||||
title: 'try to edit',
|
||||
waitNot: '#wrap .carousel',
|
||||
element: 'button[data-action=edit]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check edit mode',
|
||||
waitFor: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check branding',
|
||||
waitFor: '#wrap[data-oe-model="ir.ui.view"]',
|
||||
},
|
||||
{
|
||||
title: 'check rte',
|
||||
waitFor: '#oe_rte_toolbar',
|
||||
},
|
||||
{
|
||||
title: 'check insert block button',
|
||||
element: '[data-action="snippet"]:visible',
|
||||
},
|
||||
{
|
||||
title: 'add snippets',
|
||||
snippet: 'carousel',
|
||||
},
|
||||
{
|
||||
title: 'try to save',
|
||||
waitFor: '.oe_overlay_options .oe_options:visible',
|
||||
element: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check saved',
|
||||
waitFor: '#wrap div.carousel',
|
||||
element: 'button[data-action=edit]:visible',
|
||||
},
|
||||
{
|
||||
title: 'try to re-edit',
|
||||
waitFor: 'button[data-action=save]:visible',
|
||||
element: '#wrap .carousel',
|
||||
},
|
||||
{
|
||||
title: 'remove snippet',
|
||||
element: '.oe_snippet_remove',
|
||||
},
|
||||
{
|
||||
title: 'try to re-save',
|
||||
waitNot: '#wrap .carousel',
|
||||
element: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: "click admin",
|
||||
waitFor: 'button[data-action=edit]:visible',
|
||||
element: 'a:contains("Administrator")',
|
||||
},
|
||||
{
|
||||
title: "click logout",
|
||||
element: '#top_menu a[href*="/logout"]',
|
||||
},
|
||||
{
|
||||
title: "check logout",
|
||||
waitFor: '#top_menu a[href*="/web/login"]',
|
||||
},
|
||||
];
|
||||
return this._super();
|
||||
},
|
||||
});
|
||||
// for test without editor bar
|
||||
website.Tour.add(website.Tour.LoginEdit);
|
||||
|
||||
}());
|
||||
@@ -1,34 +0,0 @@
|
||||
(function () {
|
||||
|
||||
function LoadScript(src) {
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = function() {
|
||||
if(xmlHttp.readyState == 4) {
|
||||
if (xmlHttp.status == 200 || xmlHttp.status == 304) {
|
||||
new Function(xmlHttp.responseText)();
|
||||
} else {
|
||||
throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src);
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlHttp.open("GET", src, false);
|
||||
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
if (typeof jQuery === "undefined")
|
||||
LoadScript("/web/static/lib/jquery/jquery.js");
|
||||
if (typeof _ === "undefined")
|
||||
LoadScript("/web/static/lib/underscore/underscore.js");
|
||||
if (typeof openerp === "undefined") {
|
||||
LoadScript("/web/static/lib/qweb/qweb2.js");
|
||||
LoadScript("/web/static/src/js/openerpframework.js");
|
||||
}
|
||||
if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file)
|
||||
LoadScript("/website/static/src/js/website.js");
|
||||
if (typeof Tour === "undefined")
|
||||
LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js");
|
||||
if (typeof openerp === "undefined" || !openerp.website.Tour)
|
||||
LoadScript("/website/static/src/js/website.tour.js");
|
||||
|
||||
})();
|
||||
@@ -65,6 +65,7 @@
|
||||
},
|
||||
processTranslatableNodes: function () {
|
||||
var self = this;
|
||||
var source_attr = 'data-oe-source-id';
|
||||
var $editables = $('[data-oe-model="ir.ui.view"]')
|
||||
.not('link, script')
|
||||
.not('.oe_snippets,.oe_snippet, .oe_snippet *')
|
||||
@@ -72,7 +73,8 @@
|
||||
|
||||
$editables.each(function () {
|
||||
var $node = $(this);
|
||||
var view_id = $node.attr('data-oe-source-id') || $node.attr('data-oe-id');
|
||||
var source_id = $node.parents('[' + source_attr + ']:first').attr(source_attr)|0;
|
||||
var view_id = $node.attr('data-oe-source-id') || source_id || $node.attr('data-oe-id');
|
||||
self.transNode(this, view_id|0);
|
||||
});
|
||||
$('.oe_translatable_text').on('paste', function () {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<button type="button" data-action="save"
|
||||
class="btn btn-primary">Save</button>
|
||||
or
|
||||
<a href="#" data-action="cancel">Discard</a>
|
||||
<a href="#" data-action="cancel" class="btn btn-link">Discard</a>
|
||||
</form>
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
</ul>
|
||||
@@ -97,7 +97,7 @@
|
||||
target="fileframe"
|
||||
class="col-sm-8">
|
||||
<div class="text-center">
|
||||
<input type="file" name="upload" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
|
||||
<input type="file" name="upload" accept="image/*" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
|
||||
<button type="button" class="btn btn-primary btn-lg filepicker">
|
||||
Upload an image from your computer
|
||||
</button>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<t t-name="website.snippet_overlay">
|
||||
<div class="oe_overlay">
|
||||
<div class="oe_overlay_options">
|
||||
<div class="oe_overlay_options" contentEditable="false">
|
||||
<div class="btn-group">
|
||||
<a href="#" class="btn btn-default btn-sm oe_snippet_parent" title="Select Container Block"><i class="fa fa-upload"></i></a>
|
||||
<div class="dropdown oe_options hidden btn-group">
|
||||
@@ -34,6 +34,16 @@
|
||||
<a href="#" class="btn btn-default btn-sm oe_snippet_remove" title="Remove Block">&nbsp;<i class="fa fa-trash-o"></i>&nbsp; </a>
|
||||
</div>
|
||||
</div>
|
||||
<div class='oe_handles'>
|
||||
<div class='oe_handle n readonly'><div></div></div>
|
||||
<div class='oe_handle e readonly'><div></div></div>
|
||||
<div class='oe_handle w readonly'><div></div></div>
|
||||
<div class='oe_handle size readonly'>
|
||||
<div class="oe_handle_button size">Resize</div>
|
||||
<div class="oe_handle_button auto_size">x</div>
|
||||
</div>
|
||||
<div class='oe_handle s readonly'><div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -45,13 +55,6 @@
|
||||
|
||||
<div t-name="website.snippets.resize" data-snippet-id='resize'>
|
||||
<!-- custom data for the widget -->
|
||||
<div class='oe_handles'>
|
||||
<div class='oe_handle n'><div></div></div>
|
||||
<div class='oe_handle e'><div></div></div>
|
||||
<div class='oe_handle w'><div></div></div>
|
||||
<div class='oe_handle size'><div class="oe_handle_button size">Resize</div></div>
|
||||
<div class='oe_handle s'><div></div></div>
|
||||
</div>
|
||||
<div class='oe_snippet_thumbnail'>Margin resize</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class TestConvertBack(common.TransactionCase):
|
||||
rendered = self.registry('website.qweb').render_tag_field(
|
||||
e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, {
|
||||
'record': record,
|
||||
}))
|
||||
}, context={'inherit_branding': True}))
|
||||
element = html.fromstring(
|
||||
rendered, parser=html.HTMLParser(encoding='utf-8'))
|
||||
|
||||
@@ -216,7 +216,7 @@ class TestConvertBack(common.TransactionCase):
|
||||
rendered = self.registry('website.qweb').render_tag_field(
|
||||
e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, {
|
||||
'record': record,
|
||||
}))
|
||||
}, context={'inherit_branding': True}))
|
||||
|
||||
element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8'))
|
||||
# emulate edition
|
||||
|
||||
@@ -121,6 +121,6 @@ class URL(object):
|
||||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(CrawlSuite())
|
||||
base.addTest(CrawlSuite('admin', tools.config['admin_passwd']))
|
||||
base.addTest(CrawlSuite('admin', 'admin'))
|
||||
base.addTest(CrawlSuite('demo', 'demo'))
|
||||
return base
|
||||
|
||||
@@ -8,6 +8,6 @@ class TestUi(openerp.tests.HttpCase):
|
||||
self.phantom_js("/", "console.log('ok')", "openerp.website.editor", login='admin')
|
||||
|
||||
def test_04_admin_tour_banner(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour", login='admin')
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour.tours.banner", login='admin')
|
||||
|
||||
# vim:et:
|
||||
|
||||
+179
-150
@@ -13,14 +13,7 @@
|
||||
|
||||
<div id="snippet_structure" class="tab-pane fade in active">
|
||||
|
||||
<div data-snippet-id="carousel" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<li class="oe_snippet_options divider"></li>
|
||||
<li class="oe_snippet_options">
|
||||
<a href="#" class="button js_add">Add Slide</a>
|
||||
</li>
|
||||
<li class="oe_snippet_options">
|
||||
<a href="#" class="button js_remove">Remove Slide</a>
|
||||
</li>
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_banner.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Banner</span>
|
||||
@@ -51,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text-Image</span>
|
||||
@@ -79,7 +72,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="image-text" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_text.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Image-Text</span>
|
||||
@@ -107,7 +100,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="jumbotron" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Big Message</span>
|
||||
@@ -128,7 +121,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="text-block" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_block.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text Block</span>
|
||||
@@ -166,7 +159,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="title" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_title.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Title</span>
|
||||
@@ -183,7 +176,7 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="features" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Features</span>
|
||||
@@ -214,7 +207,7 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="big-picture" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_big_picture.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Big Picture</span>
|
||||
@@ -246,7 +239,7 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_three_columns.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Three Columns</span>
|
||||
@@ -291,7 +284,7 @@
|
||||
|
||||
<div id="snippet_content" class="tab-pane fade">
|
||||
|
||||
<div data-snippet-id="well" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_well.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Well</span>
|
||||
@@ -303,7 +296,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="quote" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quote.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Quote</span>
|
||||
@@ -318,7 +311,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="panel" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_panel.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Panel</span>
|
||||
@@ -335,7 +328,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="hr" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Separator</span>
|
||||
@@ -343,11 +336,29 @@
|
||||
<hr class="oe_snippet_body"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Share</span>
|
||||
</div>
|
||||
<div class="oe_snippet_body oe_share">
|
||||
<h3>
|
||||
Share
|
||||
<a target="_Blank" class="oe_share_facebook" href="https://www.facebook.com/sharer/sharer.php?u={url}"><i class="fa fa-facebook-square"></i></a>
|
||||
<a target="_Blank" class="oe_share_twitter" href="https://twitter.com/intent/tweet?text={title}&url={url}"><i class="fa fa-twitter"></i></a>
|
||||
<a target="_Blank" class="oe_share_linkedin" href="http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&"><i class="fa fa-linkedin"></i></a>
|
||||
<a target="_Blank" class="oe_share_google" href="https://plus.google.com/share?url={url}"><i class="fa fa-google-plus-square"></i></a>
|
||||
<a href="mailto:?body={url}&subject={title}"><i class="fa fa-envelope-o"></i></a>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="snippet_feature" class="tab-pane fade">
|
||||
|
||||
<div data-snippet-id="portfolio" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_portfolio.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Portfolio</span>
|
||||
@@ -380,7 +391,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="image-gallery" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_gallery.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Image Gallery</span>
|
||||
@@ -422,7 +433,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="pricing" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_comparison.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Comparisons</span>
|
||||
@@ -528,7 +539,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="cta" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Button</span>
|
||||
@@ -545,7 +556,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="faq" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_faq.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">FAQ</span>
|
||||
@@ -592,7 +603,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="references" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_references.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">References</span>
|
||||
@@ -609,7 +620,7 @@
|
||||
</h3>
|
||||
</div>
|
||||
<div class="col-md-4 col-md-offset-1 mt16 mb32">
|
||||
<blockquote data-snippet-id="quote">
|
||||
<blockquote>
|
||||
<p>
|
||||
Write a quote here from one of your customers. Quotes are a
|
||||
great way to build confidence in your products or services.
|
||||
@@ -618,7 +629,7 @@
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="col-md-4 col-md-offset-2 mt16 mb32">
|
||||
<blockquote data-snippet-id="quote">
|
||||
<blockquote>
|
||||
<p>
|
||||
OpenERP provides essential platform for our project management.
|
||||
Things are better organized and more visible with it.
|
||||
@@ -646,14 +657,7 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="slider" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<li class="oe_snippet_options divider"></li>
|
||||
<li class="oe_snippet_options">
|
||||
<a href="#" class="button js_add">Add Slide</a>
|
||||
</li>
|
||||
<li class="oe_snippet_options">
|
||||
<a href="#" class="button js_remove">Remove Slide</a>
|
||||
</li>
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Quotes Slider</span>
|
||||
@@ -706,7 +710,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="features-list" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Feature Grid</span>
|
||||
@@ -766,22 +770,11 @@
|
||||
|
||||
<div id="snippet_effect" class="tab-pane fade">
|
||||
|
||||
<div data-snippet-id="parallax" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_parallax.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Parallax</span>
|
||||
</div>
|
||||
<li class="oe_snippet_options dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Scroll Speed</a>
|
||||
<ul class="dropdown-menu" name="parallax-scroll">
|
||||
<li data-value="0"><a>Static</a></li>
|
||||
<li data-value="0.3"><a>Very Slow</a></li>
|
||||
<li data-value="0.6"><a>Slow</a></li>
|
||||
<li data-value="1"><a>Fixed</a></li>
|
||||
<li data-value="1.4"><a>Fast</a></li>
|
||||
<li data-value="1.7"><a>Very Fast</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<section class="oe_snippet_body parallax"
|
||||
style="background-image: url('/website/static/src/img/banner/mountains.jpg')"
|
||||
data-scroll-background-ratio="0.3">
|
||||
@@ -789,16 +782,16 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div data-snippet-id="parallax_quote" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Parallax Slider</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body parallax" data-snippet-id="parallax"
|
||||
<section class="oe_snippet_body parallax"
|
||||
style="background-image: url('/website/static/src/img/parallax/quote.png')"
|
||||
data-scroll-background-ratio="0.3">
|
||||
<div><div><div class="oe_structure">
|
||||
<div id="myQuoteCarousel" class="carousel quotecarousel slide mb0" data-snippet-id="slider">
|
||||
<div id="myQuoteCarousel" class="carousel quotecarousel slide mb0">
|
||||
<!-- Indicators -->
|
||||
<ol class="carousel-indicators mb0">
|
||||
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
|
||||
@@ -850,109 +843,145 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- use to declare snippet for snippet editor -->
|
||||
<div id="snippet_hidden" class="hidden">
|
||||
<div id="snippet_options" class="hidden">
|
||||
|
||||
<div data-snippet-id='colmd' data-selector-vertical-children='.row'>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_column.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Add Column</span>
|
||||
</div>
|
||||
<div class="oe_snippet_body col-md-4">
|
||||
<img class="img img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg"/>
|
||||
<h4 class="mt16">Feature</h4>
|
||||
<p>
|
||||
Delete the above image or replace it with a picture
|
||||
that illustrates your message. Click on the picture to
|
||||
change it's <em>rounded corner</em> style.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="snippet_styles" class="hidden">
|
||||
|
||||
<div data-snippet-style-id='text-style' data-selector="section">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Style</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="readable"><a>Narrow</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-style-id='carousel-style' data-selector="div[data-snippet-id='carousel']">
|
||||
<li class="dropdown-submenu" data-required="true">
|
||||
<a tabindex="-1" href="#">Layout</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="text_only"><a>Text Only</a></li>
|
||||
<li data-class="image_text"><a>Image - Text</a></li>
|
||||
<li data-class="text_image"><a>Text - Image</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-style-id='background' data-selector="section, section[data-snippet-id='parallax'], div[data-snippet-id='carousel'], div[data-snippet-id='slider']">
|
||||
<li class="dropdown-submenu" data-required="true">
|
||||
<a tabindex="-1" href="#">Background</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Uniform Color</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class='oe_dark'><a>Darken</a></li>
|
||||
<li data-class='oe_green'><a>Green</a></li>
|
||||
<li data-class='oe_red'><a>Red</a></li>
|
||||
<li data-class='oe_blue_light'><a>Turquoise</a></li>
|
||||
<li data-class='oe_blue'><a>Dark Blue</a></li>
|
||||
<li data-class='oe_orange'><a>Orange</a></li>
|
||||
<li data-class='oe_purple'><a>Purple</a></li>
|
||||
<li data-class='oe_black'><a>Black</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">People</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/parallax/parallax_bg.jpg"><a>Sunflower</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/business_guy.jpg"><a>Business Guy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Landscape</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/flower_field.jpg"><a>Flowers Field</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/mountains.jpg"><a>Mountains</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Various</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/orange_red.jpg"><a>Orange Red</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/velour.jpg"><a>Velour</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/wood.jpg"><a>Wood</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/yellow_green.jpg"><a>Yellow Green</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/parallax/quote.png"><a>Quote</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-class=""><a>None</a></li>
|
||||
<li><a style="background: none; padding: 5px; border-top: 1px solid #ddd;"></a></li>
|
||||
<li class="oe_custom_bg" data-class="oe_img_bg"><a><b>Choose an image...</b></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
<t t-call="website.snippet_options"/>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="snippet_options">
|
||||
|
||||
<div data-snippet-option-id='blog-style'
|
||||
data-selector="section:not(.carousel):not(.parallax)">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Style</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value="readable"><a>Narrow</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='background'
|
||||
data-selector="section, .carousel, .parallax">
|
||||
<li class="dropdown-submenu" data-required="true">
|
||||
<a tabindex="-1" href="#">Background</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Uniform Color</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value='oe_dark'><a>Darken</a></li>
|
||||
<li data-value='oe_green'><a>Green</a></li>
|
||||
<li data-value='oe_red'><a>Red</a></li>
|
||||
<li data-value='oe_blue_light'><a>Turquoise</a></li>
|
||||
<li data-value='oe_blue'><a>Dark Blue</a></li>
|
||||
<li data-value='oe_orange'><a>Orange</a></li>
|
||||
<li data-value='oe_purple'><a>Purple</a></li>
|
||||
<li data-value='oe_black'><a>Black</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">People</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/parallax/parallax_bg.jpg"><a>Sunflower</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/business_guy.jpg"><a>Business Guy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Landscape</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/flower_field.jpg"><a>Flowers Field</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/mountains.jpg"><a>Mountains</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Various</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/orange_red.jpg"><a>Orange Red</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/velour.jpg"><a>Velour</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/wood.jpg"><a>Wood</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/yellow_green.jpg"><a>Yellow Green</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/parallax/quote.png"><a>Quote</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-value=""><a>None</a></li>
|
||||
<li><a style="background: none; padding: 5px; border-top: 1px solid #ddd;"></a></li>
|
||||
<li class="oe_custom_bg" data-value="oe_img_bg"><a><b>Choose an image...</b></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='carousel-style'
|
||||
data-selector="div[data-snippet-id='carousel']">
|
||||
<li class="dropdown-submenu" data-required="true">
|
||||
<a tabindex="-1" href="#">Layout</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-value="text_only"><a>Text Only</a></li>
|
||||
<li data-value="image_text"><a>Image - Text</a></li>
|
||||
<li data-value="text_image"><a>Text - Image</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='carousel'
|
||||
data-selector=".carousel">
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a href="#" class="button js_add">Add Slide</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="button js_remove">Remove Slide</a>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='margin-y'
|
||||
data-selector="section, .row > [class*='col-md-'], .carousel, .parallax, hr">
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='resize'
|
||||
data-selector="section, .carousel, .parallax"
|
||||
data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='margin-x'
|
||||
data-selector=".row > [class*='col-md-']"
|
||||
data-selector-vertical-children='.row'>
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='content'
|
||||
data-selector="blockquote, .well, .panel, .oe_share"
|
||||
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel, .oe_share"
|
||||
data-selector-children=".content">
|
||||
</div>
|
||||
|
||||
<div data-snippet-option-id='parallax'
|
||||
data-selector=".parallax">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Scroll Speed</a>
|
||||
<ul class="dropdown-menu" name="parallax-scroll">
|
||||
<li data-value="0"><a>Static</a></li>
|
||||
<li data-value="0.3"><a>Very Slow</a></li>
|
||||
<li data-value="0.6"><a>Slow</a></li>
|
||||
<li data-value="1"><a>Fixed</a></li>
|
||||
<li data-value="1.4"><a>Fast</a></li>
|
||||
<li data-value="1.7"><a>Very Fast</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -206,6 +206,7 @@
|
||||
<template id="website.theme_amelia" name="Amelia" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/amelia.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/amelia.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -218,48 +219,56 @@
|
||||
<template id="website.theme_cosmo" name="Cosmo" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/cosmo.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/cosmo.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_cyborg" name="Cyborg" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/cyborg.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/cyborg.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_flatly" name="Flatly" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/flatly.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/flatly.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_journal" name="Journal" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/journal.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/journal.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_readable" name="Readable" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/readable.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/readable.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_simplex" name="Simplex" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/simplex.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/simplex.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_slate" name="Slate" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/slate.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/slate.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website.theme_spacelab" name="Spacelab" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/spacelab.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/spacelab.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -272,6 +281,7 @@
|
||||
<template id="website.theme_yeti" name="Yeti" inherit_option_id="website.theme">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/yeti.min.css' t-ignore="true"/>
|
||||
<link rel='stylesheet' href='/website/static/src/css/bootswatch/yeti.fix.css' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@
|
||||
</li>
|
||||
<t t-raw="0"/>
|
||||
<li t-if="publish_edit">
|
||||
<a t-att-href="'/web#return_label=Website&model=%s&id=%s' % (object._name, object.id)"
|
||||
<a t-attf-href="/web#return_label=Website&view_type=form&model=#{object._name}&id=#{object.id}&action=#{action}"
|
||||
title='Edit in backend'>Edit</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'image-text',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(2)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a Block"),
|
||||
content: _t("Drag this block and drop it in your page."),
|
||||
@@ -79,7 +79,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'text-block',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(4)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a block"),
|
||||
content: _t("Drag this block and drop it below the image block."),
|
||||
|
||||
@@ -155,7 +155,19 @@
|
||||
<template id="blog_post_complete" name="Blog Post">
|
||||
<t t-call="website_blog.index">
|
||||
|
||||
<div class="container" id="title">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="blog_post"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<t t-set="action" t-value="'website_blog.action_blog_post'"/>
|
||||
<li>
|
||||
<form class="duplicate hidden" action="/blogpost/duplicate">
|
||||
<input name="blog_post_id" t-att-value="blog_post.id"/>
|
||||
</form>
|
||||
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
|
||||
</li>
|
||||
</t>
|
||||
|
||||
<div id="title">
|
||||
<h1 class="text-center" t-field="blog_post.name"/>
|
||||
<p class="post-meta text-muted text-center" name="blog_post_data">
|
||||
<span class="fa fa-calendar oe_date"> <span t-field="blog_post.create_date"/> &nbsp;</span>
|
||||
@@ -167,18 +179,6 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="blog_post"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<li>
|
||||
<form class="duplicate hidden" action="/blogpost/duplicate">
|
||||
<input name="blog_post_id" t-att-value="blog_post.id"/>
|
||||
</form>
|
||||
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
|
||||
</li>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<div t-field="blog_post.content"/>
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ class website_event(http.Controller):
|
||||
}
|
||||
return request.website.render("website_event.event_description_full", values)
|
||||
|
||||
@http.route('/event/add_event/', type='http', auth="user", multilang=True, methods=['POST'], website=True)
|
||||
@http.route('/event/add_event', type='http', auth="user", multilang=True, methods=['POST'], website=True)
|
||||
def add_event(self, event_name="New Event", **kwargs):
|
||||
return self._add_event(event_name, request.context, **kwargs)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'image-text',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(2)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a block"),
|
||||
content: _t("Drag the 'Image-Text' block and drop it in your page."),
|
||||
@@ -80,7 +80,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'text-block',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(4)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a block"),
|
||||
content: _t("Drag the 'Text Block' in your event page."),
|
||||
|
||||
@@ -189,6 +189,11 @@
|
||||
</ol>
|
||||
</div>
|
||||
<div class="col-sm-5" groups="event.group_event_manager">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="event"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<t t-set="action" t-value="'event.action_event_view'"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,14 +32,9 @@
|
||||
'views/website_mail.xml',
|
||||
'views/website_email_designer.xml',
|
||||
'views/email_template_view.xml',
|
||||
'data/mail_groups.xml',
|
||||
'security/website_mail.xml',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/website_mail.css',
|
||||
],
|
||||
'js': [
|
||||
'static/src/js/website_mail.js',
|
||||
],
|
||||
'qweb': [
|
||||
'static/src/xml/website_mail.xml'
|
||||
],
|
||||
|
||||
@@ -26,33 +26,67 @@ from openerp.addons.web.http import request
|
||||
|
||||
class WebsiteMail(http.Controller):
|
||||
|
||||
def _find_or_create_partner(self, email, context=None):
|
||||
# TDE TODO: FIXME: use mail_thread method
|
||||
@http.route(['/website_mail/follow'], type='json', auth="public", website=True)
|
||||
def website_message_subscribe(self, id=0, object=None, message_is_follower="on", email=False, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
|
||||
partner_obj = request.registry['res.partner']
|
||||
user_obj = request.registry['res.users']
|
||||
partner_ids = []
|
||||
if email and email != u'false': # post contains stringified booleans
|
||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", email)], context=request.context)
|
||||
if not partner_ids:
|
||||
partner_ids = [partner_obj.name_create(request.cr, SUPERUSER_ID, email, request.context)[0]]
|
||||
else:
|
||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id]
|
||||
return partner_ids
|
||||
website = request.registry['website']
|
||||
|
||||
@http.route(['/website_mail/follow/'], type='json', auth="public", website=True)
|
||||
def website_message_subscribe(self, id=0, object=None, message_is_follower="on", email=False, **post):
|
||||
_id = int(id)
|
||||
_message_is_follower = message_is_follower == 'on'
|
||||
_object = request.registry[object]
|
||||
partner_ids = self._find_or_create_partner(email, request.context)
|
||||
|
||||
if _message_is_follower:
|
||||
_object.check_access_rule(request.cr, request.uid, [_id], 'read', request.context)
|
||||
_object.message_unsubscribe(request.cr, SUPERUSER_ID, [_id], partner_ids, context=request.context)
|
||||
# search partner_id
|
||||
public_id = website.get_public_user(cr, uid, context)
|
||||
if uid != public_id:
|
||||
partner_ids = [user_obj.browse(cr, uid, uid, context).partner_id.id]
|
||||
else:
|
||||
_object.check_access_rule(request.cr, request.uid, [_id], 'read', request.context)
|
||||
_object.message_subscribe(request.cr, SUPERUSER_ID, [_id], partner_ids, context=request.context)
|
||||
obj = _object.browse(request.cr, request.uid, _id)
|
||||
follower_ids = [p.id for p in obj.message_follower_ids]
|
||||
# mail_thread method
|
||||
partner_ids = _object._find_partner_from_emails(
|
||||
cr, SUPERUSER_ID, _id, [email], context=context, check_followers=True)
|
||||
if not partner_ids or not partner_ids[0]:
|
||||
partner_ids = [partner_obj.create(cr, SUPERUSER_ID, {'name': email, 'email': email}, context=context)]
|
||||
|
||||
# add or remove follower
|
||||
if _message_is_follower:
|
||||
_object.check_access_rule(cr, uid, [_id], 'read', context)
|
||||
_object.message_unsubscribe(cr, SUPERUSER_ID, [_id], partner_ids, context=context)
|
||||
return False
|
||||
else:
|
||||
_object.check_access_rule(cr, uid, [_id], 'read', context)
|
||||
# add partner to session
|
||||
request.session['partner_id'] = partner_ids[0]
|
||||
_object.message_subscribe(cr, SUPERUSER_ID, [_id], partner_ids, context=context)
|
||||
return True
|
||||
|
||||
@http.route(['/website_mail/is_follower'], type='json', auth="public", website=True)
|
||||
def call(self, model, id, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
|
||||
partner_obj = request.registry.get('res.partner')
|
||||
users_obj = request.registry.get('res.users')
|
||||
obj = request.registry.get(model)
|
||||
website = request.registry['website']
|
||||
|
||||
partner_id = None
|
||||
public_id = website.get_public_user(cr, uid, context)
|
||||
if uid != public_id:
|
||||
partner_id = users_obj.browse(cr, SUPERUSER_ID, uid, context).partner_id
|
||||
elif request.session.get('partner_id'):
|
||||
partner_id = partner_obj.browse(cr, SUPERUSER_ID, request.session.get('partner_id'), context)
|
||||
|
||||
email = ""
|
||||
is_follower = False
|
||||
if partner_id:
|
||||
email = partner_id and partner_id.email
|
||||
is_follower = partner_id.id in [
|
||||
fol.id for fol in obj.browse(cr, SUPERUSER_ID, id, context).message_follower_ids]
|
||||
|
||||
return {
|
||||
'is_user': uid != public_id,
|
||||
'email': email,
|
||||
'is_follower': is_follower
|
||||
}
|
||||
|
||||
return partner_ids[0] in follower_ids and 1 or 0
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="mail.group" id="group_all_employees">
|
||||
<field name="name">Newsletter</field>
|
||||
<field name="public">public</field>
|
||||
<field name="description">Public Newsletter.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -54,7 +54,7 @@ class MailMessage(osv.Model):
|
||||
args = ['&', ('website_published', '=', True)] + list(args)
|
||||
|
||||
return super(MailMessage, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
context=context, count=False, access_rights_uid=access_rights_uid)
|
||||
context=context, count=count, access_rights_uid=access_rights_uid)
|
||||
|
||||
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||
""" Add Access rules of mail.message for non-employee user:
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
var _t = openerp._t;
|
||||
|
||||
website.snippet.options.subscribe = website.snippet.Option.extend({
|
||||
on_prompt: function () {
|
||||
var self = this;
|
||||
return website.prompt({
|
||||
id: "editor_new_subscribe_button",
|
||||
window_title: _t("Add a Subscribe Button"),
|
||||
select: _t("Mailing List"),
|
||||
init: function (field) {
|
||||
return website.session.model('mail.group')
|
||||
.call('name_search', ['', [['public','=','public']]], { context: website.get_context() });
|
||||
},
|
||||
}).then(function (mail_group_id) {
|
||||
self.$target.attr("data-id", mail_group_id);
|
||||
});
|
||||
},
|
||||
drop_and_build_snippet: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
this.on_prompt().fail(function () {
|
||||
self.editor.on_remove();
|
||||
});
|
||||
},
|
||||
start : function () {
|
||||
var self = this;
|
||||
this.$el.find(".js_mailing_list").on("click", _.bind(this.on_prompt, this));
|
||||
this._super();
|
||||
},
|
||||
clean_for_save: function () {
|
||||
this.$target.addClass("hidden");
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -1,30 +1,59 @@
|
||||
$(document).ready(function () {
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
$(document).on('click', '.js_follow_btn, .js_unfollow_btn', function (ev) {
|
||||
ev.preventDefault();
|
||||
var website = openerp.website;
|
||||
|
||||
var self = this;
|
||||
var $data = $(this).parents("div.js_follow");
|
||||
var $email = $data.find(".js_follow_email");
|
||||
website.snippet.animationRegistry.follow = website.snippet.Animation.extend({
|
||||
selector: ".js_follow",
|
||||
start: function (editable_mode) {
|
||||
var self = this;
|
||||
|
||||
if ($email.length && !$email.val().match(/.+@.+/)) {
|
||||
return false;
|
||||
}
|
||||
// set value and display button
|
||||
self.$target.find("input").removeClass("hidden");
|
||||
openerp.jsonRpc('/website_mail/is_follower', 'call', {
|
||||
model: this.$target.data('object'),
|
||||
id: +this.$target.data('id'),
|
||||
}).always(function (data) {
|
||||
self.$target.find('input.js_follow_email')
|
||||
.val(data.email ? data.email : "")
|
||||
.attr("disabled", data.is_follower && data.email.length ? "disabled" : false);
|
||||
self.$target.attr("data-follow", data.is_follower ? 'on' : 'off');
|
||||
self.$target.removeClass("hidden");
|
||||
});
|
||||
|
||||
var message_is_follower = $data.attr("data-follow") || "off";
|
||||
$data.attr("data-follow", message_is_follower == 'off' ? 'on' : 'off');
|
||||
|
||||
openerp.jsonRpc('/website_mail/follow', 'call', {
|
||||
'id': $data.data('id'),
|
||||
'object': $data.data('object'),
|
||||
'message_is_follower': message_is_follower,
|
||||
'email': $email.length ? $email.val() : false,
|
||||
}).then(function (result) {
|
||||
if (result) {
|
||||
$data.find(" > *").toggleClass("hidden");
|
||||
// not if editable mode to allow designer to edit alert field
|
||||
if (!editable_mode) {
|
||||
$('.js_follow > .alert').addClass("hidden");
|
||||
$('.js_follow > .input-group-btn.hidden').removeClass("hidden");
|
||||
this.$target.find('.js_follow_btn, .js_unfollow_btn').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
self.on_click();
|
||||
});
|
||||
}
|
||||
$data.attr("data-follow", result ? 'on' : 'off');
|
||||
});
|
||||
});
|
||||
},
|
||||
on_click: function () {
|
||||
var self = this;
|
||||
var $email = this.$target.find(".js_follow_email:visible");
|
||||
|
||||
});
|
||||
if ($email.length && !$email.val().match(/.+@.+/)) {
|
||||
this.$target.addClass('has-error');
|
||||
return false;
|
||||
}
|
||||
this.$target.removeClass('has-error');
|
||||
|
||||
openerp.jsonRpc('/website_mail/follow', 'call', {
|
||||
'id': +this.$target.data('id'),
|
||||
'object': this.$target.data('object'),
|
||||
'message_is_follower': this.$target.attr("data-follow") || "off",
|
||||
'email': $email.length ? $email.val() : false,
|
||||
}).then(function (follow) {
|
||||
if (follow) {
|
||||
self.$target.find(".js_follow_email, .input-group-btn").addClass("hidden");
|
||||
self.$target.find(".alert").removeClass("hidden");
|
||||
}
|
||||
self.$target.find('input.js_follow_email').attr("disabled", follow ? "disabled" : false);
|
||||
self.$target.attr("data-follow", follow ? 'on' : 'off');
|
||||
});
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div id="snippet_email_structure" class="tab-pane fade in active">
|
||||
|
||||
|
||||
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_block.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text Block</span>
|
||||
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text-Image</span>
|
||||
@@ -104,7 +104,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="image-text" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_text.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Image-Text</span>
|
||||
@@ -145,7 +145,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website_mail/static/src/img/blocks/block_two_columns.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Two Columns</span>
|
||||
@@ -185,7 +185,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website_mail/static/src/img/blocks/block_three_columns.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Three Columns</span>
|
||||
@@ -236,7 +236,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="hr" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Separator</span>
|
||||
@@ -262,7 +262,7 @@
|
||||
<div id="snippet_email_feature" class="tab-pane fade">
|
||||
|
||||
|
||||
<div data-snippet-id="big-picture" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_big_picture.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Big Picture</span>
|
||||
@@ -298,7 +298,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="pricing" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_comparison.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Comparisons</span>
|
||||
@@ -389,7 +389,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Big Message</span>
|
||||
@@ -413,7 +413,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div data-snippet-id="cta" data-selector-children=".oe_structure, [data-oe-type=html]">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Button</span>
|
||||
@@ -478,18 +478,59 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="snippet_styles" class="hidden">
|
||||
<div id="snippet_options" class="hidden">
|
||||
<t t-call="website.snippet_options"/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<template id="subscribe" inherit_id="website.snippets" name="Snippet Subscribe">
|
||||
|
||||
<xpath expr="//div[@id='snippet_content']" position="inside">
|
||||
<div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Subscribe Button</span>
|
||||
</div>
|
||||
|
||||
<div class="oe_snippet_body input-group js_follow"
|
||||
data-id="0"
|
||||
data-object="mail.group"
|
||||
data-follow="off">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">Unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">Subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">thanks for your subscription!</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
|
||||
<xpath expr="//div[@id='snippet_options']" position="inside">
|
||||
<div data-snippet-option-id='subscribe'
|
||||
data-selector=".js_follow"
|
||||
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel"
|
||||
>
|
||||
<li>
|
||||
<a href="#" class="button js_mailing_list">Change mailing list</a>
|
||||
</li>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<input
|
||||
type="email" name="email"
|
||||
class="js_follow_email form-control"
|
||||
t-att-value="email or ''"
|
||||
placeholder="your email..."
|
||||
groups="base.group_public"/>
|
||||
<span class="input-group-btn">
|
||||
@@ -22,6 +21,7 @@
|
||||
|
||||
<template id="head" inherit_id="website.layout" name="Mail customization">
|
||||
<xpath expr="//head" position="inside">
|
||||
<script type="text/javascript" src="/website_mail/static/src/js/website_mail.editor.js" groups="base.group_website_publisher"></script>
|
||||
<script type="text/javascript" src="/website_mail/static/src/js/website_mail.js"></script>
|
||||
<link rel='stylesheet' href='/website_mail/static/src/css/website_mail.css'/>
|
||||
</xpath>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import controllers
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
'name': 'Mailing List Archive',
|
||||
'category': 'Website',
|
||||
'summary': '',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
OpenERP Mail Group : Mailing List Archives
|
||||
==========================================
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['website_mail'],
|
||||
'data': [
|
||||
'views/website_mail_group.xml'
|
||||
],
|
||||
'qweb': [],
|
||||
'installable': True,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import main
|
||||
|
||||
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -0,0 +1,91 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
|
||||
|
||||
class MailGroup(http.Controller):
|
||||
_thread_per_page = 10
|
||||
|
||||
@http.route([
|
||||
"/groups",
|
||||
], type='http', auth="public", website=True)
|
||||
def view(self, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
group_obj = request.registry.get('mail.group')
|
||||
group_ids = group_obj.search(cr, uid, [], context=context)
|
||||
values = {'groups': group_obj.browse(cr, uid, group_ids, context)}
|
||||
return request.website.render('website_mail_group.mail_groups', values)
|
||||
|
||||
@http.route(["/groups/subscription/"], type='json', auth="user")
|
||||
def subscription(self, group_id=0, action=False ,**post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
group_obj = request.registry.get('mail.group')
|
||||
if action:
|
||||
group_obj.message_subscribe_users(cr, uid, [group_id], context=context)
|
||||
else:
|
||||
group_obj.message_unsubscribe_users(cr, uid, [group_id], context=context)
|
||||
return []
|
||||
|
||||
@http.route([
|
||||
"/groups/<model('mail.group'):group>/<any(thread,list):mode>",
|
||||
"/groups/<model('mail.group'):group>/<any(thread,list):mode>/page/<int:page>"
|
||||
], type='http', auth="public", website=True)
|
||||
def thread(self, group, mode='thread', page=1, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
|
||||
thread_obj = request.registry.get('mail.message')
|
||||
domain = [('model','=','mail.group'), ('res_id','=',group.id)]
|
||||
if mode=='thread':
|
||||
domain.append(('parent_id','=',False))
|
||||
thread_count = thread_obj.search_count(cr, uid, domain, context=context)
|
||||
pager = request.website.pager(
|
||||
url='/groups/%s/%s/' % (group.id, mode),
|
||||
total=thread_count,
|
||||
page=page,
|
||||
step=self._thread_per_page,
|
||||
)
|
||||
thread_ids = thread_obj.search(cr, uid, domain, limit=self._thread_per_page, offset=pager['offset'])
|
||||
|
||||
messages = thread_obj.browse(cr, uid, thread_ids, context)
|
||||
for m in messages:
|
||||
print m.subject
|
||||
values = {
|
||||
'messages': messages,
|
||||
'group': group,
|
||||
'pager': pager,
|
||||
'mode': mode
|
||||
}
|
||||
return request.website.render('website_mail_group.group_messages', values)
|
||||
|
||||
@http.route([
|
||||
"/groups/<model('mail.group'):group>/message/<model('mail.message'):message>",
|
||||
], type='http', auth="public", website=True)
|
||||
def get_thread(self, group, message, mode='thread', page=1, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
values = {
|
||||
'message': message,
|
||||
'group': group,
|
||||
'mode': mode,
|
||||
'page': page,
|
||||
}
|
||||
return request.website.render('website_mail_group.group_message', values)
|
||||
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<template id="footer_mailing_list" inherit_id="website.layout" name="Footer Mailing List Link">
|
||||
<xpath expr="//footer//div[@name='info']/ul" position="inside">
|
||||
<li><a t-attf-href="/groups">Mailing List</a></li>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="mail_groups" name="Mailing Lists">
|
||||
<t t-call="website.layout">
|
||||
<div class="container">
|
||||
<h1>
|
||||
Our Mailing Lists
|
||||
</h1>
|
||||
<div class="row">
|
||||
<div class="col-sm-4" style="height: 140px" t-foreach="groups" t-as="group">
|
||||
<img t-att-src="'/website/image?model=mail.group&field=image_small&id='+str(group['id'])" class="pull-left"/>
|
||||
<div>
|
||||
<strong><a t-attf-href="/groups/#{ slug(group) }/thread" t-esc="group.name"/></strong>
|
||||
<div t-esc="group.description" class="text-muted"/>
|
||||
|
||||
<div class="input-group js_follow"
|
||||
t-att-data-id="group.id"
|
||||
data-object="mail.group"
|
||||
data-follow="off">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">You have been subscribed!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="group_messages" name="Message Threads">
|
||||
<t t-call="website.layout">
|
||||
<section class="container">
|
||||
<div class="row mt8">
|
||||
<div class="col-md-5 mt16">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/groups">Mailing Lists</a></li>
|
||||
<li class="active" t-esc="group.name"/>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="col-md-5 pull-right">
|
||||
<t t-call="website.pager"/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="mt8 mb32">
|
||||
<span t-field="group.name"/>
|
||||
<small>List Archive</small>
|
||||
</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<ul class="nav nav-pills nav-stacked" id="group_mode">
|
||||
<li t-attf-class="#{mode=='thread' and 'active' or ''}">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/thread">By thread</a>
|
||||
</li>
|
||||
<li t-attf-class="#{mode=='list' and 'active' or ''}">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/list">By date</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="group_message">
|
||||
<t t-call="website.layout">
|
||||
<div class="container">
|
||||
<div class="row mt8">
|
||||
<div class="col-md-5">
|
||||
<ol class="breadcrumb mb8">
|
||||
<li><a href="/groups">Mailing Lists</a></li>
|
||||
<li>
|
||||
<a t-attf-href="/groups/#{ slug(group) }/#{mode}/page/#{str(page)}">
|
||||
<span t-field="group.name"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="active" t-esc="message.subject or 'Message'"/>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 t-field="message.subject"/>
|
||||
<img class="img-rounded pull-left" t-att-src="'/website/image?model=mail.message&field=author_avatar&id='+str(message.id)" style="width : 30px"/>
|
||||
<h4 class="mt0 mb32">
|
||||
<span t-field="message.author_id.name"/>
|
||||
on <span t-field="message.date"/>
|
||||
</h4>
|
||||
<div t-raw="message.body"/>
|
||||
|
||||
<div class="row" t-if="message.attachment_ids">
|
||||
<h3 class="col-sm-12">Attachment(s):</h3>
|
||||
<div class="col-md-2 col-sm-3 text-center" t-foreach='message.attachment_ids' t-as='attachment'>
|
||||
<a t-att-href="'/mail/download_attachment?model=mail.message&id='+str(message.id)+'&method=download_attachment&attachment_id='+str(attachment.id)" target="_blank">
|
||||
<t t-if="attachment.file_type == 'webimage'">
|
||||
<img t-att-src="'/web/binary/image?model=ir.attachment&field=datas&id=' + str(attachment.id) + '&resize=100,80'"
|
||||
class='oe_attachment_embedded'></img>
|
||||
</t>
|
||||
<t t-if="attachment.file_type != 'webimage'">
|
||||
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.file_type + '.png'"
|
||||
class='oe_attachment_webimage'></img>
|
||||
</t>
|
||||
<div class='oe_attachment_name'><t t-raw='attachment.name' /></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="message.child_ids">
|
||||
<h2 class="page-header">Follow ups</h2>
|
||||
<t t-set="messages" t-value="message.child_ids"/>
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
<div t-if="message.parent_id">
|
||||
<h2 class="page-header">Reference</h2>
|
||||
<t t-set="messages" t-value="[message.parent_id]"/>
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
|
||||
<div class="jumbotron mt64">
|
||||
<h1>Join the discussion</h1>
|
||||
<p>
|
||||
Join this mailing list to follow or participate to this discussion.<br/>
|
||||
<span t-field="group.name"/>: <i t-field="group.description"/>
|
||||
</p>
|
||||
|
||||
<div style="max-width: 400px">
|
||||
<div class="input-group js_follow"
|
||||
t-att-data-id="group.id"
|
||||
data-object="mail.group"
|
||||
data-follow="off">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">You have been subscribed!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="messages_short">
|
||||
<ul class="media-list">
|
||||
<li t-foreach="messages" t-as="thread" class="media">
|
||||
<a t-attf-href="/groups/#{group.id}/message/#{ slug(thread) }?mode=#{mode}" class="pull-left">
|
||||
<img class="img-rounded pull-right mt0" style="height: 40px"
|
||||
t-att-src="'/website/image?model=mail.message&field=author_avatar&id='+str(thread.id)"/>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h4 class="media-heading">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/message/#{ slug(thread) }" t-esc="thread.subject"/>
|
||||
<br/>
|
||||
<small>by <t t-esc="thread.author_id.name and thread.author_id.name or thread.email_from"/> on <t t-esc="thread.date"/></small>
|
||||
</h4>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -321,7 +321,7 @@ class Ecommerce(http.Controller):
|
||||
context=dict(context, mail_create_nosubcribe=True))
|
||||
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
|
||||
|
||||
@http.route(['/shop/add_product/'], type='http', auth="user", methods=['POST'], website=True, multilang=True)
|
||||
@http.route(['/shop/add_product'], type='http', auth="user", methods=['POST'], website=True, multilang=True)
|
||||
def add_product(self, name=None, category=0, **post):
|
||||
if not name:
|
||||
name = _("New Product")
|
||||
@@ -603,7 +603,7 @@ class Ecommerce(http.Controller):
|
||||
if tx:
|
||||
acquirer_ids = [tx.acquirer_id.id]
|
||||
else:
|
||||
acquirer_ids = payment_obj.search(cr, SUPERUSER_ID, [('website_published', '=', True)], context=context)
|
||||
acquirer_ids = payment_obj.search(cr, SUPERUSER_ID, [('website_published', '=', True), '|', ('company_id', '=', order.company_id.id), ('company_id', '=', False)], context=context)
|
||||
values['acquirers'] = payment_obj.browse(cr, uid, acquirer_ids, context=context)
|
||||
render_ctx = dict(context, submit_class='btn btn-primary', submit_txt='Pay Now')
|
||||
for acquirer in values['acquirers']:
|
||||
|
||||
@@ -54,10 +54,9 @@
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
padding: 0 15px 24px 0;
|
||||
max-height: 110px;
|
||||
min-height: 56px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background: rgba(100, 100, 100, 0.1);
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
z-index: 5;
|
||||
}
|
||||
.oe_product .product_price {
|
||||
@@ -72,9 +71,8 @@
|
||||
}
|
||||
.oe_product .oe_subdescription {
|
||||
font-size: 0.8em;
|
||||
max-height: 42px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.oe_mycart .input-group-addon {
|
||||
|
||||
@@ -48,10 +48,9 @@
|
||||
bottom: 0
|
||||
overflow: hidden
|
||||
padding: 0 15px 24px 0
|
||||
max-height: 110px
|
||||
min-height: 56px
|
||||
border-top: 1px solid rgba(255,255,255,0.2)
|
||||
background: rgba(100, 100, 100, 0.1)
|
||||
background: rgba(255, 255, 255, 0.75)
|
||||
z-index: 5
|
||||
.product_price
|
||||
padding: 5px 0
|
||||
@@ -63,9 +62,8 @@
|
||||
height: 100%
|
||||
.oe_subdescription
|
||||
font-size: 0.8em
|
||||
max-height: 42px
|
||||
overflow: hidden
|
||||
margin-bottom: 30px
|
||||
margin-bottom: 10px
|
||||
|
||||
.oe_mycart
|
||||
.input-group-addon
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
snippet: 'big-picture',
|
||||
snippet: '#snippet_structure .oe_snippet:eq(7)',
|
||||
placement: 'bottom',
|
||||
title: _t("Drag & Drop a block"),
|
||||
content: _t("Drag the 'Big Picture' block and drop it in your page."),
|
||||
|
||||
@@ -4,21 +4,20 @@ import unittest2
|
||||
|
||||
import openerp.tests
|
||||
|
||||
inject = [
|
||||
("openerp.website.Tour", os.path.join(os.path.dirname(__file__), '../../website/static/src/js/website.tour.js')),
|
||||
("openerp.website.Tour.ShopTest", os.path.join(os.path.dirname(__file__), "../static/src/js/website.tour.sale.js")),
|
||||
]
|
||||
|
||||
class TestUi(openerp.tests.HttpCase):
|
||||
def test_01_admin_shop_tour(self):
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin")
|
||||
|
||||
def test_02_admin_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin")
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="admin")
|
||||
|
||||
def test_03_demo_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject)
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo")
|
||||
|
||||
@unittest2.expectedFailure
|
||||
def test_04_public_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", inject=inject)
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest")
|
||||
|
||||
@@ -193,15 +193,15 @@
|
||||
|
||||
</td>
|
||||
</t>
|
||||
<td t-if="not td_product"/>
|
||||
<td t-if="not td_product" class="oe-height-2"/>
|
||||
</t>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<t t-if="not bins">
|
||||
<div class="text-center text-muted">
|
||||
<h3 class="css_editable_display">No product defined.</h3>
|
||||
<t groups="base.group_website_publisher">
|
||||
<h3>No product found.</h3>
|
||||
<t groups="base.group_website_publisher" t-ignore="true">
|
||||
<p groups="base.group_sale_manager">Use the <i>'Content'</i> top menu to create a new product.</p>
|
||||
</t>
|
||||
</div>
|
||||
@@ -293,6 +293,7 @@
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="product"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<t t-set="action" t-value="'product.product_template_action'"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user