[MERGE] MyNotChatterTask: image resize.
This revision adds standard image field names and sizes (image: 1024x1024; image_medium: 180x180; image_small: 50x50, the last two being function fields). This addons-side branch holds the update for mail.group, product, point of sale and hr. Default image for new hr employee has also been updated. Hr module now has its icon for the module kanban view. bzr revid: tde@openerp.com-20120807131152-qw0lw9s8s6lq5m2b
This commit is contained in:
@@ -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>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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': [
|
||||
|
||||
+30
-35
@@ -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"),
|
||||
@@ -200,11 +180,26 @@ class hr_employee(osv.osv):
|
||||
'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
File diff suppressed because one or more lines are too long
@@ -21,7 +21,7 @@
|
||||
<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>
|
||||
@@ -136,7 +136,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>
|
||||
|
||||
|
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
@@ -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):
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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."),
|
||||
|
||||
@@ -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'">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -174,7 +174,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 +182,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>
|
||||
|
||||
Reference in New Issue
Block a user