commit
a85ac78f8d
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
from osv import osv
|
from osv import osv
|
||||||
from tools.translate import _
|
from tools.translate import _
|
||||||
|
import tools
|
||||||
|
|
||||||
class account_move_journal(osv.osv_memory):
|
class account_move_journal(osv.osv_memory):
|
||||||
_name = "account.move.journal"
|
_name = "account.move.journal"
|
||||||
|
@ -100,7 +101,7 @@ class account_move_journal(osv.osv_memory):
|
||||||
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||||
<button icon="terp-gtk-go-back-rtl" string="Open" name="action_open_window" default_focus="1" type="object"/>
|
<button icon="terp-gtk-go-back-rtl" string="Open" name="action_open_window" default_focus="1" type="object"/>
|
||||||
</group>
|
</group>
|
||||||
</form>""" % (str(journal), str(period))
|
</form>""" % (tools.ustr(journal), tools.ustr(period))
|
||||||
|
|
||||||
res.update({
|
res.update({
|
||||||
'arch':view
|
'arch':view
|
||||||
|
|
|
@ -181,9 +181,6 @@
|
||||||
<field name="amount_unreconciled" sum="Open Balance" readonly="1"/>
|
<field name="amount_unreconciled" sum="Open Balance" readonly="1"/>
|
||||||
<field name="amount" sum="Payment"/>
|
<field name="amount" sum="Payment"/>
|
||||||
</tree>
|
</tree>
|
||||||
<form string="Payment Information">
|
|
||||||
<label string="Form view not available for Payment Lines"/>
|
|
||||||
</form>
|
|
||||||
</field>
|
</field>
|
||||||
<field name="line_cr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('pre_line','=',False)]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}">
|
<field name="line_cr_ids" colspan="4" nolabel="1" attrs="{'invisible': [('pre_line','=',False)]}" default_get="{'journal_id':journal_id, 'partner_id':partner_id}">
|
||||||
<tree string="Credits" editable="bottom">
|
<tree string="Credits" editable="bottom">
|
||||||
|
|
|
@ -477,7 +477,7 @@ property or property parameter."),
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
||||||
|
@ -555,7 +555,7 @@ property or property parameter."),
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
for vals in self.browse(cr, uid, ids, context=context):
|
for vals in self.browse(cr, uid, ids, context=context):
|
||||||
|
@ -575,7 +575,7 @@ property or property parameter."),
|
||||||
@param ids: List of calendar attendee’s IDs
|
@param ids: List of calendar attendee’s IDs
|
||||||
@param *args: Get Tupple value
|
@param *args: Get Tupple value
|
||||||
@param context: A standard dictionary for contextual values """
|
@param context: A standard dictionary for contextual values """
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ property or property parameter."),
|
||||||
@param vals: Get Values
|
@param vals: Get Values
|
||||||
@param context: A standard dictionary for contextual values """
|
@param context: A standard dictionary for contextual values """
|
||||||
|
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if not vals.get("email") and vals.get("cn"):
|
if not vals.get("email") and vals.get("cn"):
|
||||||
cnval = vals.get("cn").split(':')
|
cnval = vals.get("cn").split(':')
|
||||||
|
@ -641,7 +641,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
alarm_obj = self.pool.get('calendar.alarm')
|
alarm_obj = self.pool.get('calendar.alarm')
|
||||||
res_alarm_obj = self.pool.get('res.alarm')
|
res_alarm_obj = self.pool.get('res.alarm')
|
||||||
|
@ -713,7 +713,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param model: Model name for which alarm is to be cleared.
|
@param model: Model name for which alarm is to be cleared.
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
alarm_obj = self.pool.get('calendar.alarm')
|
alarm_obj = self.pool.get('calendar.alarm')
|
||||||
ir_obj = self.pool.get('ir.model')
|
ir_obj = self.pool.get('ir.model')
|
||||||
|
@ -781,7 +781,7 @@ class calendar_alarm(osv.osv):
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: new record id for calendar_alarm.
|
@return: new record id for calendar_alarm.
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
event_date = vals.get('event_date', False)
|
event_date = vals.get('event_date', False)
|
||||||
if event_date:
|
if event_date:
|
||||||
|
@ -808,7 +808,7 @@ class calendar_alarm(osv.osv):
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
return True # XXX FIXME REMOVE THIS AFTER FIXING get_recurrent_dates!!
|
return True # XXX FIXME REMOVE THIS AFTER FIXING get_recurrent_dates!!
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
current_datetime = datetime.now()
|
current_datetime = datetime.now()
|
||||||
request_obj = self.pool.get('res.request')
|
request_obj = self.pool.get('res.request')
|
||||||
|
@ -943,8 +943,9 @@ class calendar_event(osv.osv):
|
||||||
@param end_date: Ending Datee
|
@param end_date: Ending Datee
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
value = {}
|
value = {}
|
||||||
if not start_date:
|
if not start_date:
|
||||||
return value
|
return value
|
||||||
|
@ -967,6 +968,14 @@ class calendar_event(osv.osv):
|
||||||
elif not end_date:
|
elif not end_date:
|
||||||
end = start + timedelta(hours=duration)
|
end = start + timedelta(hours=duration)
|
||||||
value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S")
|
value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
elif end_date and duration:
|
||||||
|
# we have both, keep them synchronized:
|
||||||
|
# set duration based on end_date (arbitrary decision: this avoid
|
||||||
|
# getting dates like 06:31:48 instead of 06:32:00)
|
||||||
|
end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
|
||||||
|
diff = end - start
|
||||||
|
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
|
||||||
|
value['duration'] = round(duration, 2)
|
||||||
|
|
||||||
return {'value': value}
|
return {'value': value}
|
||||||
|
|
||||||
|
@ -975,7 +984,7 @@ class calendar_event(osv.osv):
|
||||||
This function deletes event which are linked with the event with recurrent_uid
|
This function deletes event which are linked with the event with recurrent_uid
|
||||||
(Removes the events which refers to the same UID value)
|
(Removes the events which refers to the same UID value)
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
for event_id in ids:
|
for event_id in ids:
|
||||||
cr.execute("select id from %s where recurrent_uid=%%s" % (self._table), (event_id,))
|
cr.execute("select id from %s where recurrent_uid=%%s" % (self._table), (event_id,))
|
||||||
|
@ -992,7 +1001,7 @@ class calendar_event(osv.osv):
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: dictionary of rrule value.
|
@return: dictionary of rrule value.
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
cr.execute("UPDATE %s set freq='None',interval=0,count=0,end_date=Null,\
|
cr.execute("UPDATE %s set freq='None',interval=0,count=0,end_date=Null,\
|
||||||
mo=False,tu=False,we=False,th=False,fr=False,sa=False,su=False,\
|
mo=False,tu=False,we=False,th=False,fr=False,sa=False,su=False,\
|
||||||
|
@ -1203,7 +1212,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: Dictionary value which open Crm Meeting form.
|
@return: Dictionary value which open Crm Meeting form.
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
data_obj = self.pool.get('ir.model.data')
|
data_obj = self.pool.get('ir.model.data')
|
||||||
|
@ -1448,7 +1457,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if isinstance(ids, (str, int, long)):
|
if isinstance(ids, (str, int, long)):
|
||||||
select = [ids]
|
select = [ids]
|
||||||
|
@ -1477,14 +1486,23 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
|
|
||||||
if vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
if vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
||||||
vals['vtimezone'] = vals['vtimezone'][40:]
|
vals['vtimezone'] = vals['vtimezone'][40:]
|
||||||
|
|
||||||
|
updated_vals = self.onchange_dates(cr, uid, new_ids,
|
||||||
|
vals.get('date', False),
|
||||||
|
vals.get('duration', False),
|
||||||
|
vals.get('date_deadline', False),
|
||||||
|
vals.get('allday', False),
|
||||||
|
context=context)
|
||||||
|
vals.update(updated_vals.get('value', {}))
|
||||||
|
|
||||||
if new_ids:
|
if new_ids:
|
||||||
res = super(calendar_event, self).write(cr, uid, new_ids, vals, context=context)
|
res = super(calendar_event, self).write(cr, uid, new_ids, vals, context=context)
|
||||||
if (vals.has_key('alarm_id') or vals.has_key('base_calendar_alarm_id'))\
|
|
||||||
or (vals.has_key('date') or vals.has_key('duration') or vals.has_key('date_deadline')):
|
if ('alarm_id' in vals or 'base_calendar_alarm_id' in vals)\
|
||||||
|
or ('date' in vals or 'duration' in vals or 'date_deadline' in vals):
|
||||||
# change alarm details
|
# change alarm details
|
||||||
alarm_obj = self.pool.get('res.alarm')
|
alarm_obj = self.pool.get('res.alarm')
|
||||||
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date', \
|
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date', context=context)
|
||||||
context=context)
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process=None):
|
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process=None):
|
||||||
|
@ -1520,7 +1538,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@return: List of Dictionary of form [{‘name_of_the_field’: value, ...}, ...]
|
@return: List of Dictionary of form [{‘name_of_the_field’: value, ...}, ...]
|
||||||
"""
|
"""
|
||||||
# FIXME This whole id mangling has to go!
|
# FIXME This whole id mangling has to go!
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
if isinstance(ids, (str, int, long)):
|
if isinstance(ids, (str, int, long)):
|
||||||
|
@ -1558,7 +1576,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: Duplicate record id.
|
@return: Duplicate record id.
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
res = super(calendar_event, self).copy(cr, uid, base_calendar_id2real_id(id), default, context)
|
res = super(calendar_event, self).copy(cr, uid, base_calendar_id2real_id(id), default, context)
|
||||||
alarm_obj = self.pool.get('res.alarm')
|
alarm_obj = self.pool.get('res.alarm')
|
||||||
|
@ -1607,10 +1625,12 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
@return: new created record id.
|
@return: new created record id.
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
||||||
vals['vtimezone'] = vals['vtimezone'][40:]
|
vals['vtimezone'] = vals['vtimezone'][40:]
|
||||||
|
|
||||||
res = super(calendar_event, self).create(cr, uid, vals, context)
|
res = super(calendar_event, self).create(cr, uid, vals, context)
|
||||||
alarm_obj = self.pool.get('res.alarm')
|
alarm_obj = self.pool.get('res.alarm')
|
||||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
||||||
|
@ -1770,7 +1790,7 @@ class ir_values(osv.osv):
|
||||||
@param uid: the current user’s ID for security checks,
|
@param uid: the current user’s ID for security checks,
|
||||||
@param model: Get The Model
|
@param model: Get The Model
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
new_model = []
|
new_model = []
|
||||||
for data in models:
|
for data in models:
|
||||||
|
@ -1798,7 +1818,7 @@ class ir_model(osv.osv):
|
||||||
@param context: A standard dictionary for contextual values
|
@param context: A standard dictionary for contextual values
|
||||||
"""
|
"""
|
||||||
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
||||||
if not context:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
data = super(ir_model, self).read(cr, uid, new_ids, fields=fields, \
|
data = super(ir_model, self).read(cr, uid, new_ids, fields=fields, \
|
||||||
context=context, load=load)
|
context=context, load=load)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
<field name="res_model">crm.case.categ</field>
|
<field name="res_model">crm.case.categ</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_id" ref="crm_case_categ_tree-view"/>
|
<field name="view_id" ref="crm_case_categ_tree-view"/>
|
||||||
|
<field name="context">{'object_id': 'crm.lead'}</field>
|
||||||
<field name="domain">[('object_id.model', '=', 'crm.lead')]</field>
|
<field name="domain">[('object_id.model', '=', 'crm.lead')]</field>
|
||||||
<field name="help">Create specific categories that fit your company's activities in order to better classify and analyse them after they have been maintained in your leads and opportunities. You can use categories to reflect your product structure or the different types of sales you do.</field>
|
<field name="help">Create specific categories that fit your company's activities in order to better classify and analyse them after they have been maintained in your leads and opportunities. You can use categories to reflect your product structure or the different types of sales you do.</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
|
@ -115,7 +115,7 @@ class hr_job(osv.osv):
|
||||||
def on_change_expected_employee(self, cr, uid, ids, expected_employee, no_of_employee, context=None):
|
def on_change_expected_employee(self, cr, uid, ids, expected_employee, no_of_employee, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
result={}
|
result = {}
|
||||||
if expected_employee:
|
if expected_employee:
|
||||||
result['no_of_recruitment'] = expected_employee - no_of_employee
|
result['no_of_recruitment'] = expected_employee - no_of_employee
|
||||||
return {'value': result}
|
return {'value': result}
|
||||||
|
@ -165,23 +165,19 @@ class hr_employee(osv.osv):
|
||||||
'passport_id':fields.char('Passport', size=64)
|
'passport_id':fields.char('Passport', size=64)
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_company(self, cr, uid, ids, company, context=None):
|
def onchange_company(self, cr, uid, ids, company, context=None):
|
||||||
company_id = self.pool.get('res.company').browse(cr,uid,company)
|
address_id = False
|
||||||
for address in company_id.partner_id.address:
|
if company:
|
||||||
return {'value': {'address_id': address.id}}
|
company_id = self.pool.get('res.company').browse(cr,uid,company)
|
||||||
return {'value':{'address_id':False}}
|
address = self.pool.get('res.partner').address_get(cr, uid, [company_id.partner_id.id], ['default'])
|
||||||
|
address_id = address and address['default'] or False
|
||||||
def onchange_department(self, cr, uid, ids, department_id, context=None):
|
return {'value': {'address_id' : address_id}}
|
||||||
if not department_id:
|
|
||||||
return {'value':{'parent_id': False}}
|
|
||||||
manager = self.pool.get('hr.department').browse(cr, uid, department_id).manager_id
|
|
||||||
return {'value': {'parent_id':manager and manager.id or False}}
|
|
||||||
|
|
||||||
def onchange_user(self, cr, uid, ids, user_id, context=None):
|
def onchange_user(self, cr, uid, ids, user_id, context=None):
|
||||||
if not user_id:
|
work_email = False
|
||||||
return {'value':{'work_email': False}}
|
if user_id:
|
||||||
mail = self.pool.get('res.users').browse(cr,uid,user_id)
|
work_email = self.pool.get('res.users').browse(cr, uid, user_id).user_email
|
||||||
return {'value': {'work_email':mail.user_email}}
|
return {'value': {'work_email' : work_email}}
|
||||||
|
|
||||||
def _get_photo(self, cr, uid, context=None):
|
def _get_photo(self, cr, uid, context=None):
|
||||||
return open(os.path.join(
|
return open(os.path.join(
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<field name="company_id" widget="selection" groups="base.group_multi_company,base.group_extended" on_change="onchange_company(company_id)"/>
|
<field name="company_id" widget="selection" groups="base.group_multi_company,base.group_extended" on_change="onchange_company(company_id)"/>
|
||||||
<field name="active" groups="base.group_extended"/>
|
<field name="active" groups="base.group_extended"/>
|
||||||
<newline/>
|
<newline/>
|
||||||
<field name="department_id" widget="selection" on_change="onchange_department(department_id)"/>
|
<field name="department_id" widget="selection" />
|
||||||
<field name="parent_id" />
|
<field name="parent_id" />
|
||||||
</group>
|
</group>
|
||||||
<group colspan="2" col="1">
|
<group colspan="2" col="1">
|
||||||
|
|
|
@ -99,10 +99,10 @@ class hr_expense_expense(osv.osv):
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
|
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
|
||||||
if not employee_id:
|
department_id = False
|
||||||
return {'value':{'department_id': False}}
|
if employee_id:
|
||||||
dept = self.pool.get('hr.employee').browse(cr, uid, employee_id).department_id
|
department_id = self.pool.get('hr.employee').browse(cr, uid, employee_id).department_id.id or False
|
||||||
return {'value': {'department_id':dept and dept.id or False}}
|
return {'value':{'department_id':department_id}}
|
||||||
|
|
||||||
def expense_confirm(self, cr, uid, ids, *args):
|
def expense_confirm(self, cr, uid, ids, *args):
|
||||||
self.write(cr, uid, ids, {
|
self.write(cr, uid, ids, {
|
||||||
|
@ -248,17 +248,17 @@ class hr_expense_line(osv.osv):
|
||||||
def onchange_product_id(self, cr, uid, ids, product_id, uom_id, employee_id, context=None):
|
def onchange_product_id(self, cr, uid, ids, product_id, uom_id, employee_id, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
v = {}
|
res = {}
|
||||||
if product_id:
|
if product_id:
|
||||||
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||||
v['name'] = product.name
|
res['name'] = product.name
|
||||||
# Compute based on pricetype of employee company
|
# Compute based on pricetype of employee company
|
||||||
context['currency_id'] = self.pool.get('hr.employee').browse(cr, uid, employee_id, context=context).user_id.company_id.currency_id.id
|
context['currency_id'] = self.pool.get('hr.employee').browse(cr, uid, employee_id, context=context).user_id.company_id.currency_id.id
|
||||||
amount_unit = product.price_get('standard_price', context)[product.id]
|
amount_unit = product.price_get('standard_price', context)[product.id]
|
||||||
v['unit_amount'] = amount_unit
|
res['unit_amount'] = amount_unit
|
||||||
if not uom_id:
|
if not uom_id:
|
||||||
v['uom_id'] = product.uom_id.id
|
res['uom_id'] = product.uom_id.id
|
||||||
return {'value': v}
|
return {'value': res}
|
||||||
|
|
||||||
hr_expense_line()
|
hr_expense_line()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
OpenERP, Open Source Management Solution
|
||||||
|
Copyright © 2010 OpenERP SA (<http://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 Lice
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,2 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import company_pad
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
'name': 'Enhanced support for (Ether)Pad attachments',
|
||||||
|
'version': '1.0',
|
||||||
|
'category': 'Generic Modules/Others',
|
||||||
|
'description': """
|
||||||
|
Adds enhanced support for (Ether)Pad attachments in the web client, lets the
|
||||||
|
company customize which Pad installation should be used to link to new pads
|
||||||
|
(by default, pad.openerp.com)
|
||||||
|
""",
|
||||||
|
'author': 'OpenERP SA',
|
||||||
|
'website': 'http://openerp.com',
|
||||||
|
'depends': ['base'],
|
||||||
|
'update_xml': [
|
||||||
|
'company_pad.xml'
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'active': False,
|
||||||
|
'web': True,
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from osv import fields, osv
|
||||||
|
|
||||||
|
class company_pad(osv.osv):
|
||||||
|
_inherit = 'res.company'
|
||||||
|
_columns = {
|
||||||
|
'pad_index': fields.char('Pad root URL', size=64, required=True,
|
||||||
|
help="The root URL of the company's pad "
|
||||||
|
"instance"),
|
||||||
|
}
|
||||||
|
_defaults = {
|
||||||
|
'pad_index': 'http://pad.openerp.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
company_pad()
|
|
@ -0,0 +1,16 @@
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
<record id="view_company_form_with_pad" model="ir.ui.view">
|
||||||
|
<field name="name">res.company.form.pad</field>
|
||||||
|
<field name="model">res.company</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="inherit_id" ref="base.view_company_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//page[@string='Configuration']" position="inside">
|
||||||
|
<separator string="Pad" colspan="4"/>
|
||||||
|
<field name="pad_index"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
|
@ -0,0 +1,2 @@
|
||||||
|
import controllers
|
||||||
|
import editors
|
|
@ -0,0 +1,34 @@
|
||||||
|
import urlparse
|
||||||
|
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
|
from openobject.tools import expose
|
||||||
|
|
||||||
|
import openerp.controllers
|
||||||
|
from openerp.utils import rpc, TinyDict
|
||||||
|
|
||||||
|
class Piratepad(openerp.controllers.SecuredController):
|
||||||
|
_cp_path = "/piratepad"
|
||||||
|
|
||||||
|
def get_root(self):
|
||||||
|
return rpc.RPCProxy('res.company').read(
|
||||||
|
[rpc.session.company_id], ['pad_index'])[0]['pad_index']
|
||||||
|
|
||||||
|
def make_url(self, pad_name):
|
||||||
|
return urlparse.urljoin(
|
||||||
|
self.get_root(), '-'.join(pad_name.split())
|
||||||
|
)
|
||||||
|
|
||||||
|
@expose('json', methods=('POST',))
|
||||||
|
def link(self, pad_name):
|
||||||
|
params, data = TinyDict.split(cherrypy.session['params'])
|
||||||
|
ctx = dict(rpc.session.context,
|
||||||
|
default_res_model=params.model, default_res_id=params.id,
|
||||||
|
active_id=False, active_ids=[])
|
||||||
|
|
||||||
|
pad_link = self.make_url(pad_name)
|
||||||
|
attachment_id = rpc.RPCProxy('ir.attachment').create({
|
||||||
|
'name': pad_name,
|
||||||
|
'url': pad_link,
|
||||||
|
}, ctx)
|
||||||
|
return {'id': attachment_id, 'name': pad_name, 'url': pad_link}
|
|
@ -0,0 +1,46 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import openobject.templating
|
||||||
|
|
||||||
|
class SidebarTemplateEditor(openobject.templating.TemplateEditor):
|
||||||
|
templates = ['/openerp/widgets/templates/sidebar.mako']
|
||||||
|
ADD_ATTACHMENT_BUTTON = u'id="add-attachment"'
|
||||||
|
BINARY_ATTACHMENTS_FORM = u'<form id="attachment-box"'
|
||||||
|
|
||||||
|
def insert_pad_link(self, output):
|
||||||
|
# Insert the link on the line right after the link to open the
|
||||||
|
# attachment form
|
||||||
|
form_opener_insertion = output.index(
|
||||||
|
'\n',
|
||||||
|
output.index(self.ADD_ATTACHMENT_BUTTON)) + 1
|
||||||
|
output = output[:form_opener_insertion] + \
|
||||||
|
'''<a href="#" id="add-pad" class="button-a"
|
||||||
|
style="right: 44px;"
|
||||||
|
>${_("Pad")}</a>\n''' + \
|
||||||
|
output[form_opener_insertion:]
|
||||||
|
return output
|
||||||
|
|
||||||
|
def edit(self, template, template_text):
|
||||||
|
output = super(SidebarTemplateEditor, self).edit(template, template_text)
|
||||||
|
|
||||||
|
output = self.insert_pad_link(output)
|
||||||
|
|
||||||
|
form_insertion_point = output.index(self.BINARY_ATTACHMENTS_FORM)
|
||||||
|
return output[:form_insertion_point] + '''
|
||||||
|
<form id="pad-form" action="/piratepad/link" method="post">
|
||||||
|
<label for="sidebar_pad_datas">${_("Name")}:</label>
|
||||||
|
<input id="sidebar_pad_datas"
|
||||||
|
name="pad_name" size="5" />
|
||||||
|
<button>${_("Ok")}</button>
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript">
|
||||||
|
jQuery(document).ready(function() {
|
||||||
|
var $padForm = jQuery('#pad-form')
|
||||||
|
.hide()
|
||||||
|
.submit(createAttachment);
|
||||||
|
jQuery('#add-pad').click(function(e){
|
||||||
|
$padForm.show();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
''' + output[form_insertion_point:]
|
|
@ -31,6 +31,11 @@ class misc_tools_installer(osv.osv_memory):
|
||||||
'idea':fields.boolean('Ideas Box',help='Promote ideas of the employees, votes and discussion on best ideas.'),
|
'idea':fields.boolean('Ideas Box',help='Promote ideas of the employees, votes and discussion on best ideas.'),
|
||||||
'share':fields.boolean('Share Data / Portals',help='This module allows you to easily give restricted access of any filtered list of objects to any customer or supplier.' \
|
'share':fields.boolean('Share Data / Portals',help='This module allows you to easily give restricted access of any filtered list of objects to any customer or supplier.' \
|
||||||
'Just click on the share icon to give access to your customers on their project\'s tasks, support requests, invoices, etc.'),
|
'Just click on the share icon to give access to your customers on their project\'s tasks, support requests, invoices, etc.'),
|
||||||
|
'pad': fields.boolean('Native pad integration',
|
||||||
|
help="This module creates a tighter integration between a Pad "
|
||||||
|
"instance of your choosing and your OpenERP Web Client by "
|
||||||
|
"letting you easily link pads to OpenERP objects via "
|
||||||
|
"OpenERP attachments."),
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
<field name="idea"/>
|
<field name="idea"/>
|
||||||
<field name="survey"/>
|
<field name="survey"/>
|
||||||
<field name="subscription" groups="base.group_extended"/>
|
<field name="subscription" groups="base.group_extended"/>
|
||||||
|
<field name="pad"/>
|
||||||
</group>
|
</group>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
|
|
Loading…
Reference in New Issue