[Merge] Merge with main addons.

bzr revid: mdi@tinyerp.com-20120808043059-4o3sg9o8fm3dsxcp
This commit is contained in:
Divyesh Makwana (Open ERP)
2012-08-08 10:00:59 +05:30
37 changed files with 1230 additions and 1238 deletions
+1 -1
View File
@@ -43,7 +43,7 @@
</div>
</div>
</group>
<separator string="Chart of Account and Fiscal Year" attrs="{'invisible': ['|', ('expects_chart_of_accounts','=',False), ('has_chart_of_accounts','=',True)]}"/>
<separator string="Chart of Accounts" attrs="{'invisible': ['|', ('expects_chart_of_accounts','=',False), ('has_chart_of_accounts','=',True)]}"/>
<group attrs="{'invisible': ['|', ('expects_chart_of_accounts','=',False), ('has_chart_of_accounts','=',True)]}">
<label for="id" string="Chart of Account"/>
<div>
+1 -1
View File
@@ -7,7 +7,7 @@
<field name="password">anonymous</field>
<!-- Avoid auto-including this demo user in any default group -->
<field name="groups_id" eval="[(5,)]"/>
<field name="avatar">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</field>
<field name="image">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</field>
</record>
<!--
+3 -7
View File
@@ -347,7 +347,7 @@
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kaban_status_red</t>
<span t-attf-class="oe_kanban_status #{red}"> </span>
-->
<img t-att-src="kanban_image('res.users', 'avatar', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</div>
<div class="oe_kanban_footer_left">
<t t-if="record.needaction_pending.raw_value"><span class="oe_kanban_mail_new">New</span></t>
@@ -378,6 +378,7 @@
<field name="arch" type="xml">
<search string="Search Leads">
<field name="name" string="Lead / Customer" filter_domain="['|','|',('partner_name','ilike',self),('email_from','ilike',self),('name','ilike',self)]"/>
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike',self)]" />
<!-- subjects is not set as store=True so, it is placed outside filter_domain-->
<field name="subjects"/>
<field name="create_date"/>
@@ -398,15 +399,9 @@
<filter string="Salesperson" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}"/>
<filter string="Referrer" icon="terp-personal" domain="[]" context="{'group_by':'referred'}"/>
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'categ_id'}"/>
<filter string="Campaign" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'type_id'}" />
<filter string="Channel" icon="terp-call-start" domain="[]" context="{'group_by':'channel_id'}" />
<separator orientation="vertical"/>
<filter string="Campaign" icon="terp-gtk-jump-to-rtl"
domain="[]" context="{'group_by':'type_id'}" />
<filter string="Channel" icon="terp-call-start"
domain="[]" context="{'group_by':'channel_id'}" />
<separator orientation="vertical"/>
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<filter string="Creation" help="Create date" icon="terp-go-month" domain="[]" context="{'group_by':'create_date'}" groups="base.group_no_one"/>
@@ -619,6 +614,7 @@
<search string="Search Opportunities">
<field name="name" string="Opportunity / Customer"
filter_domain="['|','|','|',('partner_id','ilike',self),('partner_name','ilike',self),('email_from','ilike',self),('name', 'ilike', self)]"/>
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike', self)]" />
<filter icon="terp-mail-message-new" string="Inbox" help="Unread messages" name="needaction_pending" domain="[('needaction_pending','=',True)]"/>
<separator/>
<filter icon="terp-check" string="New" help="New Opportunities" name="new" domain="[('state','=','draft')]"/>
-13
View File
@@ -23,15 +23,6 @@
</group>
<div name="config_other" version="7.0" position="inside">
<separator string="Import and Synchronize Data from an Other Application"/>
<group>
<label for="id" string="Import From"/>
<div>
<div>
<field name="module_import_sugarcrm"/>
<label for="module_import_sugarcrm"/>
</div>
</div>
</group>
<group>
<label for="id" string="Synchronize with"/>
<div>
@@ -39,10 +30,6 @@
<field name="module_import_google"/>
<label for="module_import_google"/>
</div>
<div>
<field name="module_crm_caldav"/>
<label for="module_crm_caldav"/>
</div>
</div>
</group>
</div>
+6 -1
View File
@@ -38,7 +38,12 @@ You can manage:
""",
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'images': ['images/hr_department.jpeg', 'images/hr_employee.jpeg','images/hr_job_position.jpeg'],
'images': [
'images/hr_department.jpeg',
'images/hr_employee.jpeg',
'images/hr_job_position.jpeg',
'static/src/img/default_image.png',
],
'depends': ['base_setup','mail', 'resource', 'board'],
'init_xml': [],
'update_xml': [
+31 -36
View File
@@ -20,11 +20,9 @@
##############################################################################
import addons
import io
import logging
from osv import fields, osv
from PIL import Image
import StringIO
import tools
_logger = logging.getLogger(__name__)
class hr_employee_category(osv.osv):
@@ -149,33 +147,15 @@ class hr_employee(osv.osv):
_description = "Employee"
_inherits = {'resource.resource': "resource_id"}
def onchange_photo(self, cr, uid, ids, value, context=None):
if not value:
return {'value': {'photo_big': value, 'photo': value} }
return {'value': {'photo_big': self._photo_resize(cr, uid, value, 540, 450, context=context), 'photo': self._photo_resize(cr, uid, value, context=context)} }
def _set_photo(self, cr, uid, id, name, value, args, context=None):
if not value:
vals = {'photo_big': value}
else:
vals = {'photo_big': self._photo_resize(cr, uid, value, 540, 450, context=context)}
return self.write(cr, uid, [id], vals, context=context)
def _photo_resize(self, cr, uid, photo, heigth=180, width=150, context=None):
image_stream = io.BytesIO(photo.decode('base64'))
img = Image.open(image_stream)
img.thumbnail((heigth, width), Image.ANTIALIAS)
img_stream = StringIO.StringIO()
img.save(img_stream, "JPEG")
return img_stream.getvalue().encode('base64')
def _get_photo(self, cr, uid, ids, name, args, context=None):
def _get_image(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
for hr_empl in self.browse(cr, uid, ids, context=context):
if hr_empl.photo_big:
result[hr_empl.id] = self._photo_resize(cr, uid, hr_empl.photo_big, context=context)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_columns = {
'country_id': fields.many2one('res.country', 'Nationality'),
'birthday': fields.date("Date of Birth"),
@@ -195,16 +175,31 @@ class hr_employee(osv.osv):
'work_location': fields.char('Office Location', size=32),
'notes': fields.text('Notes'),
'parent_id': fields.many2one('hr.employee', 'Manager'),
'category_ids': fields.many2many('hr.employee.category', 'employee_category_rel', 'emp_id', 'category_id', 'Categories'),
'category_ids': fields.many2many('hr.employee.category', 'employee_category_rel', 'emp_id', 'category_id', 'Tags'),
'child_ids': fields.one2many('hr.employee', 'parent_id', 'Subordinates'),
'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade', required=True),
'coach_id': fields.many2one('hr.employee', 'Coach'),
'job_id': fields.many2one('hr.job', 'Job'),
'photo_big': fields.binary('Big-sized employee photo', help="This field holds the photo of the employee. The photo field is used as an interface to access this field. The image is base64 encoded, and PIL-supported. Full-sized photo are however resized to 540x450 px."),
'photo': fields.function(_get_photo, fnct_inv=_set_photo, string='Employee photo', type="binary",
'image': fields.binary("Photo",
help="This field holds the image used as a photo for the "\
"employee. The image is base64 encoded, and PIL-supported. "\
"It is limited to a 1024x1024 px image."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized photo", type="binary", multi="_get_image",
store = {
'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['photo_big'], 10),
}, help="Image used as photo for the employee. It is automatically resized as a 180x150 px image. A larger photo is stored inside the photo_big field."),
'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized photo of the employee. It is automatically "\
"resized as a 180x180 px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Smal-sized photo", type="binary", multi="_get_image",
store = {
'hr.employee': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized photo of the employee. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'passport_id':fields.char('Passport No', size=64),
'color': fields.integer('Color Index'),
'city': fields.related('address_id', 'city', type='char', string='City'),
@@ -260,13 +255,13 @@ class hr_employee(osv.osv):
work_email = self.pool.get('res.users').browse(cr, uid, user_id, context=context).user_email
return {'value': {'work_email' : work_email}}
def _default_get_photo(self, cr, uid, context=None):
photo_path = addons.get_module_resource('hr','images','photo.png')
return self._photo_resize(cr, uid, open(photo_path, 'rb').read().encode('base64'), context=context)
def _get_default_image(self, cr, uid, context=None):
image_path = addons.get_module_resource('hr', 'static/src/img', 'default_image.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
_defaults = {
'active': 1,
'photo': _default_get_photo,
'image': _get_default_image,
'marital': 'single',
'color': 0,
}
+21 -21
View File
File diff suppressed because one or more lines are too long
+14 -16
View File
@@ -21,39 +21,37 @@
<field name="arch" type="xml">
<form string="Employee" version="7.0">
<sheet>
<field name="photo" widget='image' class="oe_right" on_change="onchange_photo(photo)"/>
<field name="image_small" widget='image' class="oe_right oe_image_small"/>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" class="oe_inline"/>
<label class="oe_inline" string="," attrs="{'invisible': [('job_id', '=', False)]}"/>
<field class="oe_inline" name="job_id" domain="[('state','!=','old')]" context="{'form_view_ref': 'hr.view_hr_job_employee_form'}"/>
<label class="oe_inline" string="at" attrs="{'invisible': [('company_id', '=', False)]}" groups="base.group_multi_company"/>
<field class="oe_inline" name="company_id" groups="base.group_multi_company" on_change="onchange_company(company_id)"/>
<field name="name"/>
</h1>
<label for="department_id" class="oe_edit_only"/>
<h2><field name="department_id" on_change="onchange_department_id(department_id)"/></h2>
<label for="job_id" class="oe_edit_only"/>
<h2>
<field name="job_id" options='{"no_open": true}' domain="[('state','!=','old')]" context="{'form_view_ref': 'hr.view_hr_job_employee_form'}"/>
</h2>
<label for="category_ids" class="oe_edit_only"/>
<h3><field name="category_ids" widget="many2many_tags"/></h3>
<field name="category_ids" widget="many2many_tags" placeholder="e.g. Part Time"/>
</div>
<div class="oe_right oe_button_box" name="button_box">
<!-- Put here related buttons -->
</div>
<group colspan="4" col="4">
<field name="work_email" widget="email"/>
<field name="work_phone"/>
<field name="address_id" on_change="onchange_address_id(address_id)"/>
<field name="mobile_phone"/>
</group>
<notebook>
<page string="Information">
<group>
<group>
<field name="department_id" on_change="onchange_department_id(department_id)"/>
<field name="company_id" groups="base.group_multi_company" on_change="onchange_company(company_id)"/>
<field name="user_id" on_change="onchange_user(user_id)"/>
<field name="parent_id"/>
<field name="coach_id"/>
</group>
<group>
<field name="work_email" widget="email"/>
<field name="work_phone"/>
<field name="address_id" on_change="onchange_address_id(address_id)"/>
<field name="mobile_phone"/>
<field name="identification_id" groups="base.group_hr_user"/>
<field name="passport_id" groups="base.group_hr_user"/>
<field name="otherid" groups="base.group_hr_user"/>
@@ -136,7 +134,7 @@
<t t-name="kanban-box">
<div class="oe_employee_vignette">
<div class="oe_employee_image">
<a type="edit"><img t-att-src="kanban_image('hr.employee', 'photo', record.id.value)" class="oe_employee_picture"/></a>
<a type="edit"><img t-att-src="kanban_image('hr.employee', 'image_medium', record.id.value)" class="oe_employee_picture"/></a>
</div>
<div class="oe_employee_details">
<h4>
+4 -4
View File
@@ -65,10 +65,6 @@
<group name="timesheet_grp">
<label for="id" string="Time Tracking"/>
<div>
<div>
<field name="module_hr_attendance" on_change="onchange_hr_attendance(module_hr_attendance)" class="oe_inline"/>
<label for="module_hr_attendance"/>
</div>
<div>
<field name="module_hr_timesheet" on_change="onchange_hr_timesheet(module_hr_timesheet)" class="oe_inline"/>
<label for="module_hr_timesheet"/>
@@ -77,6 +73,10 @@
<field name="module_hr_timesheet_sheet" class="oe_inline"/>
<label for="module_hr_timesheet_sheet"/>
</div>
<div>
<field name="module_hr_attendance" on_change="onchange_hr_attendance(module_hr_attendance)" class="oe_inline"/>
<label for="module_hr_attendance"/>
</div>
</div>
</group>
<group name="recruitment_grp">

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

@@ -320,7 +320,8 @@
<a type="object" name="set_priority" args="['1']">
<img t-attf-src="/web/static/src/img/icons/star-#{priority == 1 ? 'on' : 'off'}.png" width="16" height="16" title="Excellent"/>
</a>
<img t-att-src="kanban_image('res.users', 'avatar', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</div>
</div>
<div class="oe_clear"></div>
+28 -38
View File
@@ -20,14 +20,11 @@
##############################################################################
import datetime as DT
import io
import openerp
import openerp.tools as tools
from operator import itemgetter
from osv import osv
from osv import fields
from PIL import Image
import StringIO
import tools
from tools.translate import _
from lxml import etree
@@ -51,32 +48,15 @@ class mail_group(osv.osv):
_inherit = ['mail.thread']
_inherits = {'mail.alias': 'alias_id'}
def onchange_photo(self, cr, uid, ids, value, context=None):
if not value:
return {'value': {'avatar_big': value, 'avatar': value} }
return {'value': {'photo_big': value, 'photo': self._photo_resize(cr, uid, value) } }
def _set_photo(self, cr, uid, id, name, value, args, context=None):
if value:
return self.write(cr, uid, [id], {'photo_big': value}, context=context)
else:
return self.write(cr, uid, [id], {'photo_big': value}, context=context)
def _photo_resize(self, cr, uid, photo, width=128, height=128, context=None):
image_stream = io.BytesIO(photo.decode('base64'))
img = Image.open(image_stream)
img.thumbnail((width, height), Image.ANTIALIAS)
img_stream = StringIO.StringIO()
img.save(img_stream, "JPEG")
return img_stream.getvalue().encode('base64')
def _get_photo(self, cr, uid, ids, name, args, context=None):
def _get_image(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
for group in self.browse(cr, uid, ids, context=context):
if group.photo_big:
result[group.id] = self._photo_resize(cr, uid, group.photo_big, context=context)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
def get_member_ids(self, cr, uid, ids, field_names, args, context=None):
if context is None:
context = {}
@@ -104,9 +84,9 @@ class mail_group(osv.osv):
result[id] = self.message_search(cr, uid, [id], limit=None, domain=[('date', '>=', lower_date)], count=True, context=context)
return result
def _get_default_photo(self, cr, uid, context=None):
avatar_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
return self._photo_resize(cr, uid, open(avatar_path, 'rb').read().encode('base64'), context=context)
def _get_default_image(self, cr, uid, context=None):
image_path = openerp.modules.get_module_resource('mail', 'static/src/img', 'groupdefault.png')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
_columns = {
'name': fields.char('Name', size=64, required=True),
@@ -121,16 +101,26 @@ class mail_group(osv.osv):
help="Members of those groups will automatically added as followers. "\
"Note that they will be able to manage their subscription manually "\
"if necessary."),
'photo_big': fields.binary('Full-size photo',
help='Field holding the full-sized PIL-supported and base64 encoded "\
version of the group image. The photo field is used as an "\
interface for this field.'),
'photo': fields.function(_get_photo, fnct_inv=_set_photo,
string='Photo', type="binary",
'image': fields.binary("Photo",
help="This field holds the image used as photo for the "\
"user. The image is base64 encoded, and PIL-supported. "\
"It is limited to a 12024x1024 px image."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized photo", type="binary", multi="_get_image",
store = {
'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['photo_big'], 10),
'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help='Field holding the automatically resized (128x128) PIL-supported and base64 encoded version of the group image.'),
help="Medium-sized photo of the group. It is automatically "\
"resized as a 180x180px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Small-sized photo", type="binary", multi="_get_image",
store = {
'mail.group': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized photo of the group. It is automatically "\
"resized as a 50x50px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'member_ids': fields.function(get_member_ids, fnct_search=search_member_ids,
type='many2many', relation='res.users', string='Group members', multi='get_member_ids'),
'member_count': fields.function(get_member_ids, type='integer',
@@ -147,7 +137,7 @@ class mail_group(osv.osv):
_defaults = {
'public': True,
'responsible_id': (lambda s, cr, uid, ctx: uid),
'photo': _get_default_photo,
'image': _get_default_image,
}
def _subscribe_user_with_group_m2m_command(self, cr, uid, ids, group_ids_command, context=None):
+2 -3
View File
@@ -19,7 +19,7 @@
<t t-name="kanban-box">
<div t-attf-class="{record.is_subscriber.raw_value} oe_group_vignette">
<div class="oe_group_image">
<a type="edit"><img t-att-src="kanban_image('mail.group', 'photo', record.id.value)" class="oe_group_photo" tooltip="kanban-description"/></a>
<a type="edit"><img t-att-src="kanban_image('mail.group', 'image_medium', record.id.value)" class="oe_group_photo" tooltip="kanban-description"/></a>
</div>
<div class="oe_group_details">
<h4><a type="edit"><field name="name"/></a></h4>
@@ -33,7 +33,6 @@
</div>
</div>
<script>
$('.oe_group_photo').load(function() { if($(this).width() > $(this).height()) { $(this).addClass('oe_group_photo_wide') } });
$('.oe_group_join').mouseover(function () { $(this).html('Follow'); }).mouseleave(function () { $(this).html('Not following'); });
$('.oe_group_leave').mouseover(function () { $(this).html('Unfollow'); }).mouseleave(function () { $(this).html('Following'); });
</script>
@@ -54,7 +53,7 @@
<sheet class="openerp_mail_group_sheet">
<group colspan="4" col="8">
<group colspan="1" col="2">
<field name="photo" widget='image' nolabel="1" on_change="onchange_photo(photo)"/>
<field name="image_small" widget='image' class="oe_image_small" nolabel="1"/>
</group>
<group colspan="7" col="6">
<div class="oe_edit_only">
+1 -1
View File
@@ -893,7 +893,7 @@ class mail_thread(osv.Model):
subscr_ids = subscr_obj.search(cr, uid, ['&', ('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
return [sub['user_id'][0] for sub in subscr_obj.read(cr, uid, subscr_ids, ['user_id'], context=context)]
def message_read_subscribers(self, cr, uid, ids, fields=['id', 'name', 'avatar'], context=None):
def message_read_subscribers(self, cr, uid, ids, fields=['id', 'name', 'image_small'], context=None):
""" Returns the current document followers as a read result. Used
mainly for Chatter having only one method to call to have
details about users.
+1 -1
View File
@@ -9,7 +9,7 @@
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="after">
<div class="oe_chatter oe_mail_group_footer">
<div class="oe_chatter">
<field name="message_ids" widget="mail_thread"
options='{"thread_level": 1}'/>
</div>
+1 -1
View File
@@ -27,7 +27,7 @@
<field name="notification_email_pref"/>
</field>
<xpath expr="/form/sheet" position="after">
<div class="oe_chatter oe_mail_group_footer">
<div class="oe_chatter">
<field name="message_ids" colspan="4" widget="mail_thread" nolabel="1"/>
</div>
</xpath>
+1 -13
View File
@@ -20,12 +20,6 @@
max-width: 80%;
}
/* Resize group logo */
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_image > img {
max-width: 100px;
max-height: 100px;
}
/* Resize group description */
.openerp .oe_form_sheetbg.openerp_mail_group_sheet .oe_form_field_text > textarea {
height: 40px;
@@ -63,14 +57,8 @@
.oe_group_photo {
width: 100px;
height: auto;
clip: rect(0px, 100px, 100px, 0px);
}
.oe_group_photo_wide {
height: 100px;
width: auto;
clip: rect(0px, 115px, 100px, 15px);
clip: rect(0px, 100px, 100px, 0px);
}
.oe_group_details {
+4 -4
View File
@@ -341,7 +341,7 @@ openerp.mail = function(session) {
this._super.apply(this, arguments);
// customize display: add avatar, clean previous content
var user_avatar = mail.ChatterUtils.get_image(this.session.prefix,
this.session.session_id, 'res.users', 'avatar', this.session.uid);
this.session.session_id, 'res.users', 'image_small', this.session.uid);
this.$element.find('img.oe_mail_icon').attr('src', user_avatar);
this.$element.find('div.oe_mail_msg_content').empty();
// create a context for the default_get of the compose form
@@ -742,7 +742,7 @@ openerp.mail = function(session) {
if (record.type == 'email') {
record.mini_url = ('/mail/static/src/img/email_icon.png');
} else {
record.mini_url = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'avatar', record.user_id[0]);
record.mini_url = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', record.user_id[0]);
}
// body text manipulation
if (record.subtype == 'plain') {
@@ -768,7 +768,7 @@ openerp.mail = function(session) {
},
display_current_user: function () {
var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'avatar', this.params.uid);
var avatar = mail.ChatterUtils.get_image(this.session.prefix, this.session.session_id, 'res.users', 'image_small', this.params.uid);
return this.$element.find('img.oe_mail_icon').attr('src', avatar);
},
@@ -913,7 +913,7 @@ openerp.mail = function(session) {
this.$element.find('div.oe_mail_recthread_followers h4').html('Followers (' + records.length + ')');
_(records).each(function (record) {
if (record.id == self.session.uid) { self.is_subscriber = true; }
record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.users', 'avatar', record.id);
record.avatar_url = mail.ChatterUtils.get_image(self.session.prefix, self.session.session_id, 'res.users', 'image_small', record.id);
$(session.web.qweb.render('mail.record_thread.subscriber', {'record': record})).appendTo(user_list);
});
if (self.is_subscriber) {
+1 -1
View File
@@ -22,7 +22,7 @@
<field name="module_marketing_campaign" class="oe_inline"/>
<label for="module_marketing_campaign"/>
</div>
<div>
<div attrs="{'invisible':[('module_marketing_campaign','=',False)]}">
<field name="module_marketing_campaign_crm_demo" class="oe_inline"/>
<label for="module_marketing_campaign_crm_demo"/>
</div>
+29 -39
View File
@@ -18,8 +18,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import pdb
import io
import openerp
import addons
@@ -27,10 +27,10 @@ import time
from datetime import datetime
from dateutil.relativedelta import relativedelta
import logging
from PIL import Image
import netsvc
from osv import fields, osv
import tools
from tools.translate import _
from decimal import Decimal
import decimal_precision as dp
@@ -1174,20 +1174,14 @@ class pos_category(osv.osv):
res = self.name_get(cr, uid, ids, context=context)
return dict(res)
def _get_small_image(self, cr, uid, ids, prop, unknow_none, context=None):
result = {}
def _get_image(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
for obj in self.browse(cr, uid, ids, context=context):
if not obj.category_image:
result[obj.id] = False
continue
image_stream = io.BytesIO(obj.category_image.decode('base64'))
img = Image.open(image_stream)
img.thumbnail((120, 100), Image.ANTIALIAS)
img_stream = StringIO.StringIO()
img.save(img_stream, "JPEG")
result[obj.id] = img_stream.getvalue().encode('base64')
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
@@ -1195,20 +1189,34 @@ class pos_category(osv.osv):
'parent_id': fields.many2one('pos.category','Parent Category', select=True),
'child_id': fields.one2many('pos.category', 'parent_id', string='Children Categories'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
'category_image': fields.binary('Image'),
'category_image_small': fields.function(_get_small_image, string='Small Image', type="binary",
'image': fields.binary("Image",
help="This field holds the image used for the category. "\
"The image is base64 encoded, and PIL-supported. "\
"It is limited to a 1024x1024 px image."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized image", type="binary", multi="_get_image",
store = {
'pos.category': (lambda self, cr, uid, ids, c={}: ids, ['category_image'], 10),
}),
'pos.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized image of the category. It is automatically "\
"resized as a 180x180 px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Smal-sized image", type="binary", multi="_get_image",
store = {
'pos.category': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized image of the category. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
}
def _get_default_image(self, cr, uid, context=None):
image_path = openerp.modules.get_module_resource('point_of_sale', 'images', 'default_category_photo.png')
return open(image_path, 'rb').read().encode('base64')
return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))
_defaults = {
'category_image': _get_default_image,
'image': _get_default_image,
}
pos_category()
@@ -1217,30 +1225,12 @@ import io, StringIO
class product_product(osv.osv):
_inherit = 'product.product'
def _get_small_image(self, cr, uid, ids, prop, unknow_none, context=None):
result = {}
for obj in self.browse(cr, uid, ids, context=context):
if not obj.product_image:
result[obj.id] = False
continue
image_stream = io.BytesIO(obj.product_image.decode('base64'))
img = Image.open(image_stream)
img.thumbnail((120, 100), Image.ANTIALIAS)
img_stream = StringIO.StringIO()
img.save(img_stream, "JPEG")
result[obj.id] = img_stream.getvalue().encode('base64')
return result
_columns = {
'income_pdt': fields.boolean('Point of Sale Cash In', help="This is a product you can use to put cash into a statement for the point of sale backend."),
'expense_pdt': fields.boolean('Point of Sale Cash Out', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
'pos_categ_id': fields.many2one('pos.category','Point of Sale Category',
help="If you want to sell this product through the point of sale, select the category it belongs to."),
'product_image_small': fields.function(_get_small_image, string='Small Image', type="binary",
store = {
'product.product': (lambda self, cr, uid, ids, c={}: ids, ['product_image'], 10),
}),
'to_weight' : fields.boolean('To Weight', help="This category contains products that should be weighted, mainly used for the self-checkout interface"),
}
_defaults = {
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -660,7 +660,7 @@
<field name="arch" type="xml">
<form string="Product PoS Categories" version="7.0">
<sheet>
<field name="category_image" widget='image' class="oe_avatar oe_right"/>
<field name="image_medium" widget='image' class="oe_avatar oe_right"/>
<div class="oe_left">
<group>
<field name="name"/>
@@ -462,6 +462,10 @@
cursor: pointer;
}
.point-of-sale .category-button .category-img img {
height: 100px;
}
.point-of-sale .category-button .category-name {
position: absolute;
-webkit-box-sizing: border-box;
@@ -506,6 +510,10 @@
text-align: center;
}
.point-of-sale .product .product-img img {
height: 100px;
}
.point-of-sale .product .price-tag {
position: absolute;
top: 2px;
@@ -139,7 +139,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
self.set('currency',currencies[0]);
});
var cat_def = fetch('pos.category', ['id','name', 'parent_id', 'child_id', 'category_image_small'])
var cat_def = fetch('pos.category', ['id','name', 'parent_id', 'child_id', 'image_medium'])
.pipe(function(result){
return self.set({'categories': result});
});
@@ -219,7 +219,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
return fetch(
'product.product',
//context {pricelist: shop.pricelist_id[0]}
['name', 'list_price','price','pos_categ_id', 'taxes_id','product_image_small', 'ean13', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type'],
['name', 'list_price','price','pos_categ_id', 'taxes_id','image_medium', 'ean13', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type'],
[['pos_categ_id','!=', false]],
{pricelist: shops[0].pricelist_id[0]} // context for price
);
@@ -444,7 +444,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
},
get_product_image: function(){
var product = this.get_product();
return product ? product.get('product_image_small') : undefined;
return product ? product.get('image_medium') : undefined;
},
get_product_weight: function(){
return this.weight || 0;
+2 -3
View File
@@ -83,7 +83,7 @@
<t t-name="CategoryButton">
<li class='category-button'>
<div class="category-img">
<img t-att-src="'data:image/gif;base64,'+ category.category_image_small" />
<img t-att-src="'data:image/gif;base64,'+ category.image_medium" />
</div>
<div class="category-name">
<t t-esc="category.name"/>
@@ -342,8 +342,7 @@
<li class='product'>
<a href="#">
<div class="product-img">
<img t-att-src="'data:image/gif;base64,'+ widget.model.get('product_image_small')" />
<img t-att-src="'data:image/gif;base64,'+ widget.model.get('image_medium')" />
<t t-if="!widget.model.get('to_weight')">
<span class="price-tag">
<t t-esc="widget.format_currency(widget.model.get('list_price'))"/>
File diff suppressed because one or more lines are too long
@@ -49,7 +49,7 @@
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())">
<span t-attf-class="oe_kanban_status oe_kaban_status_red"> </span>
</t>
<img t-att-src="kanban_image('res.users', 'avatar', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</div>
</div>
</div>
+30 -1
View File
@@ -25,6 +25,7 @@ import decimal_precision as dp
import math
from _common import rounding
import re
import tools
from tools.translate import _
def is_pair(x):
@@ -490,6 +491,15 @@ class product_product(osv.osv):
return result
def _get_image(self, cr, uid, ids, name, args, context=None):
result = dict.fromkeys(ids, False)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = tools.image_get_resized_images(obj.image)
return result
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_defaults = {
'active': lambda *a: 1,
'price_extra': lambda *a: 0.0,
@@ -523,7 +533,26 @@ class product_product(osv.osv):
'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'),
'name_template': fields.related('product_tmpl_id', 'name', string="Name", type='char', size=128, store=True, select=True),
'color': fields.integer('Color Index'),
'product_image': fields.binary('Image'),
'image': fields.binary("Image",
help="This field holds the image used for the product. "\
"The image is base64 encoded, and PIL-supported. "\
"It is limited to a 1024x1024 px image."),
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
string="Medium-sized image", type="binary", multi="_get_image",
store = {
'product.product': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Medium-sized image of the product. It is automatically "\
"resized as a 180x180 px image, with aspect ratio preserved. "\
"Use this field in form views or some kanban views."),
'image_small': fields.function(_get_image, fnct_inv=_set_image,
string="Small-sized image", type="binary", multi="_get_image",
store = {
'product.product': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
},
help="Small-sized image of the product. It is automatically "\
"resized as a 50x50 px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'seller_info_id': fields.function(_calc_seller, type='many2one', relation="product.supplierinfo", multi="seller_info"),
'seller_delay': fields.function(_calc_seller, type='integer', string='Supplier Lead Time', multi="seller_info", help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
'seller_qty': fields.function(_calc_seller, type='float', string='Supplier Quantity', multi="seller_info", help="This is minimum quantity to purchase from Main Supplier."),
+3 -4
View File
@@ -64,8 +64,7 @@
<field name="arch" type="xml">
<form string="Product" version="7.0">
<sheet>
<field name="product_image" widget="image" class="oe_avatar oe_right"/>
<field name="image_medium" widget="image" class="oe_avatar oe_right"/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" string="Product Name"/>
@@ -194,7 +193,7 @@
<kanban>
<field name="color"/>
<field name="type"/>
<field name="product_image"/>
<field name="image_medium"/>
<field name="list_price"/>
<templates>
<t t-name="kanban-box">
@@ -205,7 +204,7 @@
<field name="name"/>
</div>
<div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_box_show_onclick_trigger">
<img t-att-src="kanban_image('product.product', 'product_image', record.id.value)" width="48" style="float: left; padding: 0 4px 4px 0"/>
<img t-att-src="kanban_image('product.product', 'image_medium', record.id.value)" width="48" style="float: left; padding: 0 4px 4px 0"/>
Code: <field name="code"/>
<div t-if="record.type.raw_value == 'service'">No Stock</div>
<t t-if="record.type.raw_value != 'service'">
+2 -2
View File
@@ -263,7 +263,7 @@
</div>
<div class="oe_kanban_project_avatars">
<t t-foreach="record.members.raw_value" t-as="member">
<img t-att-src="kanban_image('res.users', 'avatar', member)" t-att-data-member_id="member"/>
<img t-att-src="kanban_image('res.users', 'image_small', member)" t-att-data-member_id="member"/>
</t>
</div>
</div>
@@ -555,7 +555,7 @@
<a t-if="record.kanban_state.raw_value === 'blocked'" type="object" string="Blocked" name="set_kanban_state_normal" class="oe_kanban_status oe_kanban_status_red"> </a>
<a t-if="record.priority.raw_value == 1" type="object" string="Priority" name="set_normal_priority" class="oe_e oe_star_on">7</a>
<a t-if="record.priority.raw_value != 1" type="object" string="Priority" name="set_high_priority" class="oe_e oe_star_off">7</a>
<img t-att-src="kanban_image('res.users', 'avatar', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</div>
<div class="oe_kanban_footer_left">
<span groups="project.group_time_work_estimation_tasks" title="Remaining hours">
+1 -1
View File
@@ -310,7 +310,7 @@
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())">
<span t-attf-class="oe_kanban_status oe_kaban_status_red"> </span>
</t>
<img t-att-src="kanban_image('res.users', 'avatar', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value[0])" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
</div>
</div>
</div>
+1 -1
View File
@@ -43,7 +43,7 @@ class purchase_config_settings(osv.osv_memory):
'group_purchase_delivery_address': fields.boolean("allow a different address for incoming products and invoicings",
implied_group='purchase.group_delivery_invoice_address',
help="Allows you to specify different delivery and invoice addresses on a purchase order."),
'module_purchase_analytic_plans': fields.boolean('use multiple analytic accounts on orders',
'module_purchase_analytic_plans': fields.boolean('allow using multiple analytic accounts on the same order',
help ="""Allows the user to maintain several analysis plans. These let you split
lines on a purchase order between several accounts and analytic plans.
This installs the module purchase_analytic_plans."""),
+2 -2
View File
@@ -86,11 +86,11 @@ class sale_configuration(osv.osv_memory):
help="""This adds the 'Margin' on sales order.
This gives the profitability by calculating the difference between the Unit Price and Cost Price.
This installs the module sale_margin."""),
'module_sale_journal': fields.boolean("allow batch invoicing through journals",
'module_sale_journal': fields.boolean("allow batch invoicing of delivery orders through journals",
help="""Allows you to categorize your sales and deliveries (picking lists) between different journals,
and perform batch operations on journals.
This installs the module sale_journal."""),
'module_analytic_user_function': fields.boolean("assign user roles per contract",
'module_analytic_user_function': fields.boolean("one employee can have different roles per contract",
help="""Allows you to define what is the default function of a specific user on a given account.
This is mostly used when a user encodes his timesheet. The values are retrieved and the fields are auto-filled.
But the possibility to change these values is still available.
+19 -12
View File
@@ -60,15 +60,30 @@
<field name="group_sale_pricelist" class="oe_inline"/>
<label for="group_sale_pricelist"/>
</div>
<div>
<field name="module_sale_journal" class="oe_inline"/>
<label for="module_sale_journal"/>
</div>
<div name="module_warning">
<field name="module_warning" class="oe_inline"/>
<label for="module_warning"/>
</div>
</div>
<group name="Sale" position="before">
<group>
<label for="id" string="Warehouse Features"/>
<div>
<div attrs="{'invisible':[('group_invoice_deli_orders','=',False)]}">
<field name="default_picking_policy" class="oe_inline"/>
<label for="default_picking_policy"/>
</div>
<div>
<field name="group_mrp_properties" class="oe_inline"/>
<label for="group_mrp_properties"/>
</div>
<div>
<field name="module_sale_journal" class="oe_inline"/>
<label for="module_sale_journal"/>
</div>
</div>
</group>
</group>
<group name="Sale" position="before">
<group>
<label for="id" string="Product Features"/>
@@ -81,10 +96,6 @@
<field name="group_discount_per_so_line" class="oe_inline"/>
<label for="group_discount_per_so_line"/>
</div>
<div>
<field name="group_mrp_properties" class="oe_inline"/>
<label for="group_mrp_properties"/>
</div>
<div>
<label for="decimal_precision"/>
<field name="decimal_precision" class="oe_inline"/>
@@ -97,10 +108,6 @@
<field name="group_multiple_shops" class="oe_inline"/>
<label for="group_multiple_shops"/>
</div>
<div attrs="{'invisible':[('group_invoice_deli_orders','=',False)]}">
<field name="default_picking_policy" class="oe_inline"/>
<label for="default_picking_policy"/>
</div>
<div name="module_sale_margin">
<field name="module_sale_margin" class="oe_inline"/>
<label for="module_sale_margin"/>
+4 -4
View File
@@ -168,7 +168,7 @@
<button name="print_quotation" string="Send by Post" type="object" states="sent"/>
<button name="action_button_confirm" states="draft" string="Confirm" type="object"/>
<button name="action_button_confirm" states="sent" string="Confirm" class="oe_highlight" type="object"/>
<button name="action_view_invoice" string="Open Invoice" type="object" class="oe_highlight"
<button name="action_view_invoice" string="View Invoice" type="object" class="oe_highlight"
attrs="{'invisible': ['|','|',('state', '!=','progress'), ('invoiced', '=', True),('order_policy','=','picking')]}"/>
<button name="action_view_delivery" string="View Delivery Order" type="object" class="oe_highlight"
attrs="{'invisible': ['|','|','|',('picking_ids','=',False),('picking_ids','=',[]), ('state', 'not in', ('progress','manual')),('shipped','=',True)]}"/>
@@ -287,7 +287,7 @@
<field name="product_uos" string="UoS" groups="product.group_uos"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="price_unit"/>
<field name="price_subtotal" groups="base.group_sale_notes_subtotal"/>
<field name="price_subtotal"/>
</tree>
</field>
<group class="oe_subtotal_footer oe_right" colspan="2" name="sale_total">
@@ -493,7 +493,7 @@
<field name="product_uom_qty" string="Qty"/>
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
<field name="salesman_id"/>
<field name="price_subtotal" sum="Total" groups="base.group_sale_notes_subtotal"/>
<field name="price_subtotal" sum="Total"/>
<field name="state"/>
<field name="invoiced"/>
</tree>
@@ -530,7 +530,7 @@
<group>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="price_subtotal" groups="base.group_sale_notes_subtotal"/>
<field name="price_subtotal"/>
<field name="invoiced"/>
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
</group>
+5 -4
View File
@@ -63,9 +63,10 @@
<field name="standard_price" position="replace" version="7.0">
<label string="Cost Price" for="standard_price" align="1.0" groups="base.group_user"/>
<div groups="base.group_user">
<field name="standard_price" attrs="{'readonly':[('cost_method','=','average')]}" nolabel="1"/>
<field name="standard_price" attrs="{'readonly':[('cost_method','=','average')]}" nolabel="1"/> -
<button name="%(action_view_change_standard_price)d" string="Update"
type="action" icon="gtk-execute" attrs="{'invisible':[('cost_method','&lt;&gt;','average')]}"/>
type="action" attrs="{'invisible':[('cost_method','&lt;&gt;','average')]}"
class="oe_link"/>
</div>
</field>
</field>
@@ -174,7 +175,7 @@
<kanban>
<field name="color"/>
<field name="type"/>
<field name="product_image"/>
<field name="image_medium"/>
<field name="list_price"/>
<field name="reception_count"/>
<field name="delivery_count"/>
@@ -182,7 +183,7 @@
<t t-name="kanban-box">
<div class="oe_product_vignette">
<div class="oe_product_img">
<a type="edit"><img t-att-src="kanban_image('product.product', 'product_image', record.id.value)" class="oe_product_photo"/></a>
<a type="edit"><img t-att-src="kanban_image('product.product', 'image_medium', record.id.value)" class="oe_product_photo"/></a>
</div>
<div class="oe_product_desc">
<h4><a type="edit"><field name="name"></field></a></h4>