Browse Source

Merge 5101dbeed9 into 17f4b3cf7f

pull/352/merge
Cyril VINH-TUNG 4 years ago
committed by GitHub
parent
commit
f545e20e1f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 96
      pos_default_empty_image/README.rst
  2. 1
      pos_default_empty_image/__init__.py
  3. 21
      pos_default_empty_image/__manifest__.py
  4. 25
      pos_default_empty_image/i18n/pos_default_empty_image.pot
  5. 1
      pos_default_empty_image/models/__init__.py
  6. 20
      pos_default_empty_image/models/product_product.py
  7. BIN
      pos_default_empty_image/static/description/icon.png
  8. BIN
      pos_default_empty_image/static/description/pos_display_default.png
  9. BIN
      pos_default_empty_image/static/description/pos_display_improved.png
  10. 21
      pos_default_empty_image/static/src/css/pos_default_empty_image.css
  11. 8
      pos_default_empty_image/static/src/js/db.js
  12. 42
      pos_default_empty_image/static/src/js/widgets.js
  13. 22
      pos_default_empty_image/static/src/xml/pos_default_empty_image.xml
  14. 12
      pos_default_empty_image/views/templates.xml

96
pos_default_empty_image/README.rst

@ -0,0 +1,96 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
================================================
Optimize loading time for products without image
================================================
This module extends the functionality of point of sale to make PoS load faster
and to improve products display.
Point Of Sale Load faster
=========================
In the point of sale, loading products without image spend unnecessary time
and resources.
When you have 8000 products in your Point of Sale and most of them
don't have images, removing thousands of useless requests is welcome:
the PoS loads faster that way.
Improve products display
========================
By default, Odoo PoS display a useless generic image for products that doesn't
have images.
.. figure:: /pos_default_empty_image/static/description/pos_display_default.png
:width: 800 px
With this module, the display of the product is changed, (Size of the name
is increased for better visibility);
.. figure:: /pos_default_empty_image/static/description/pos_display_improved.png
:width: 800 px
Technical information
=====================
Each time the PoS instantiate a product, it will add this code for each product
.. code:: html
<img src="'/web/binary/image?model=product.product&field=image_medium&id='+product.id;" />
The browser will trigger as many requests than there are different urls.
If you have many products, the browser will soon reach his limit of
network connections to Odoo server and will wait for free slots instead of
loading other valuable contents. Then the PoS is then very slow to work with.
This module adds a field has_image in product.product model.
If product has no image, the product image url is not sent to the PoS
Updates
=======
* Feb 2016 : First version
* March 2018 : migration to v10 and improvements for Display
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/pos/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Contributors
------------
* Hparfr <https://github.com/hparfr> `Akretion <https://akretion.com>`_
* Sylvain LE GAL <https://twitter.com/legalsylvain>
* Invitu <https://github.com/invitu>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

1
pos_default_empty_image/__init__.py

@ -0,0 +1 @@
from . import models

21
pos_default_empty_image/__manifest__.py

@ -0,0 +1,21 @@
# © 2015 Akretion, GRAP, OCA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'POS Default empty image',
'version': '11.0.1.0.0',
'category': 'Point Of Sale',
'summary': 'Optimize loading time for products without image',
'author': "Akretion, GRAP, Odoo Community Association (OCA)",
'website': "https://www.github.com/OCA/pos",
'license': 'AGPL-3',
'depends': [
'point_of_sale',
],
'data': [
'views/templates.xml',
],
'qweb': [
'static/src/xml/pos_default_empty_image.xml',
],
'installable': True,
}

25
pos_default_empty_image/i18n/pos_default_empty_image.pot

@ -0,0 +1,25 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_default_empty_image
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: pos_default_empty_image
#: model:ir.model.fields,field_description:pos_default_empty_image.field_product_product_has_image
msgid "Has Image"
msgstr ""
#. module: pos_default_empty_image
#: model:ir.model,name:pos_default_empty_image.model_product_product
msgid "Product"
msgstr ""

1
pos_default_empty_image/models/__init__.py

@ -0,0 +1 @@
from . import product_product

20
pos_default_empty_image/models/product_product.py

@ -0,0 +1,20 @@
# Copyright (C) 2017 - Today:
# GRAP (http://www.grap.coop)
# Akretion (http://www.akretion.com)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
class ProductProduct(models.Model):
_inherit = 'product.product'
@api.multi
@api.depends('image')
def _compute_has_image(self):
for product in self:
product.has_image = product.image
has_image = fields.Boolean(
compute='_compute_has_image', string='Has Image', store=True)

BIN
pos_default_empty_image/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

BIN
pos_default_empty_image/static/description/pos_display_default.png

After

Width: 845  |  Height: 138  |  Size: 51 KiB

BIN
pos_default_empty_image/static/description/pos_display_improved.png

After

Width: 844  |  Height: 138  |  Size: 54 KiB

21
pos_default_empty_image/static/src/css/pos_default_empty_image.css

@ -0,0 +1,21 @@
/*
Copyright (C) 2014 - Today: GRAP (http://www.grap.coop)
@author Julien WESTE
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
*/
.product-img-without-image{
height:25px !important;
}
.product-name-without-image{
bottom:auto !important;
top:25px !important;
padding-top:3px !important;
height:80px !important;
font-size: 24px !important;
line-height: 20px;
text-align: center;
word-wrap: break-word;
}

8
pos_default_empty_image/static/src/js/db.js

@ -0,0 +1,8 @@
odoo.define('pos_default_empty_image.db', function (require) {
"use strict";
var models = require('point_of_sale.models');
// load new field 'has_image' for 'product.product' model
models.load_fields("product.product", ['has_image']);
});

42
pos_default_empty_image/static/src/js/widgets.js

@ -0,0 +1,42 @@
odoo.define('pos_default_empty_image.widgets', function (require) {
"use strict";
var screens = require('point_of_sale.screens');
var core = require('web.core');
var QWeb = core.qweb;
//don't try to get an image if we know the product ain't one
var ProductListImageWidget = screens.ProductListWidget.include({
get_product_image_url: function(product){
if (product.has_image)
return this._super(product);
},
// Change product display if product has no image;
render_product: function(product){
if (product.has_image){
return this._super(product);
}
else {
var current_pricelist = this._get_active_pricelist();
var cache_key = this.calculate_cache_key(product, current_pricelist);
var cached = this.product_cache.get_node(cache_key);
if(!cached){
var product_html = QWeb.render('ProductNoImage',{
widget: this,
product: product,
pricelist: current_pricelist,
});
var product_node = document.createElement('div');
product_node.innerHTML = product_html;
product_node = product_node.childNodes[1];
this.product_cache.cache_node(cache_key,product_node);
return product_node;
}
return cached;
}
},
});
});

22
pos_default_empty_image/static/src/xml/pos_default_empty_image.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="ProductNoImage">
<span class='product' t-att-data-product-id="product.id">
<div class="product-img-without-image">
<t t-if="!product.to_weight">
<span class="price-tag">
<t t-esc="widget.format_currency(product.get_price(pricelist, 1),'Product Price')"/>
</span>
</t>
<t t-if="product.to_weight">
<span class="price-tag">
<t t-esc="widget.format_currency(product.get_price(pricelist, 1),'Product Price')+'/'+widget.pos.units_by_id[product.uom_id[0]].name"/>
</span>
</t>
</div>
<div class="product-name-without-image">
<t t-esc="product.display_name"/>
</div>
</span>
</t>
</templates>

12
pos_default_empty_image/views/templates.xml

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="assets_backend" name="pos_default_empty_image assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/pos_default_empty_image/static/src/js/db.js"></script>
<script type="text/javascript" src="/pos_default_empty_image/static/src/js/widgets.js"></script>
</xpath>
<xpath expr="//link[@id='pos-stylesheet']" position="after">
<link rel="stylesheet" href="/pos_default_empty_image/static/src/css/pos_default_empty_image.css"/>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save