Merge remote-tracking branch 'origin/develop' into develop

develop
Ahmed Aly 2018-04-17 09:58:38 +02:00
commit d73634182f
1568 changed files with 208964 additions and 2 deletions

View File

@ -8,7 +8,7 @@ db_port = 5432
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons,ext/3rd-party-addons
addons_path = ext/odoo/addons,ext/custom-addons,ext/3rd-party-addons,ext/clarico-addons
; For enterprise use the addons path bellow
; addons_path = ext/enterprise-addons,ext/odoo/addons,ext/3rd-party-addons,ext/custom-addons,dmi/run1
timezone = Europe/Vienna

View File

@ -0,0 +1,28 @@
Odoo Proprietary License v1.0
This software and associated files (the "Software") may only be used (executed,
modified, executed after modifications) if you have purchased a valid license
from the authors, typically via Odoo Apps, or if you have received a written
agreement from the authors of the Software (see the COPYRIGHT file).
You may develop Odoo modules that use the Software as a library (typically
by depending on it, importing it and using its resources), but without copying
any source code or material from the Software. You may distribute those
modules under the license of your choice, provided that this license is
compatible with the terms of the Odoo Proprietary License (For example:
LGPL, MIT, or proprietary licenses similar to this one).
It is forbidden to publish, distribute, sublicense, or sell copies of the Software
or modified copies of the Software.
The above copyright notice and this permission notice must be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from . import prod
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
{
'name': 'Import product images from URL',
'version': '11.0.0.1',
'sequence': 4,
'summary': 'Easy to Import/set product images from URL',
"price": 10,
"currency": "EUR",
"category": "Extra Tools",
'description': """
BrowseInfo developed a new odoo/OpenERP module apps.
This module use for import product images,import images on product, multiple images on product, Import bulk images on product.Import product photos, Import from product images from link, Import images form link. Import from other website. Add product image. Update product Image.Import picture of product, import images from CSV, Import product images from CSV file, Import product data from CSV file. Set product image from URL , Import product images from URL, Import product images from CSV file. IMport product image from URL,Multi product images, Mutiple images on product, website multi images
تستخدم هذه الوحدة لاستيراد صور المنتجات ، واستيراد الصور على المنتج ، والصور المتعددة على المنتج ، واستيراد الصور المجمعة على المنتج. استيراد صور المنتج ، والاستيراد من صور المنتج من الرابط ، واردات نموذج ارتباط الصور. استيراد من موقع آخر. أضف صورة المنتج. تحديث صورة المنتج Image.Import من المنتج ، واستيراد الصور من CSV ، استيراد صور المنتج من ملف CSV ، استيراد بيانات المنتج من ملف CSV. تعيين صورة المنتج من عنوان URL ، استيراد صور المنتجات من عنوان URL ، استيراد صور المنتجات من ملف CSV. صورة المنتج IMport من URL ، صور متعددة المنتج ، صور Mutiple على المنتج ، صور متعددة الموقع
Este módulo se usa para importar imágenes de productos, importar imágenes en el producto, múltiples imágenes en el producto, importar imágenes a granel en el producto. Importación de fotos del producto, Importar imágenes del producto desde el enlace, Importar imágenes en el enlace. Importar desde otro sitio web. Agregar imagen del producto. Actualice la imagen del producto. Importe la imagen del producto, importe las imágenes desde CSV, importe las imágenes del producto desde el archivo CSV, importe los datos del producto desde el archivo CSV. Establecer imagen de producto desde URL, importar imágenes de producto desde URL, importar imágenes de producto desde archivo CSV. IMportar imagen del producto desde URL, imágenes de productos múltiples, imágenes mutiples en producto, imágenes múltiples del sitio web
Ce module sert à importer des images de produits, importer des images sur le produit, plusieurs images sur le produit, Importer des images en vrac sur le produit. Importer des photos de produits, Importer des images de produits du lien, Importer des images. Importer depuis un autre site Web. Ajouter l'image du produit. Mettre à jour le produit Image.Import image du produit, importer des images à partir de CSV, Importer des images de produit à partir du fichier CSV, Importer des données de produit à partir du fichier CSV. Définir l'image du produit à partir de l'URL, importer des images de produit à partir de l'URL, importer des images de produit à partir du fichier CSV. Importer l'image du produit de l'URL, Multi images de produits, Mutiple images sur le produit, site Web multi images
Este módulo usa para importar imagens de produtos, importar imagens no produto, várias imagens no produto, Importar imagens em massa no produto. Importar fotos de produtos, Importar de imagens de produtos do link, Importar link de formulário de imagens. Importar de outro site. Adicione a imagem do produto. Atualize a imagem do produto. Importe a imagem do produto, importe imagens do CSV, Importe imagens do produto do arquivo CSV, Importe dados do produto do arquivo CSV. Defina a imagem do produto a partir de URL, Importe imagens de produtos de URL, Importe imagens de produtos do arquivo CSV. Importe a imagem do produto a partir de URL, imagens de vários produtos, imagens Mutiple no produto, imagens multi site
""",
'author': 'BrowseInfo',
'website': 'http://www.browseinfo.in',
'live_test_url':'https://youtu.be/0_GwCnhXAWE',
'depends': ['base','sale','product'],
'data': [
"security/ir.model.access.csv",
"product_view.xml"
],
'qweb': [
],
'demo': [],
'test': [],
'installable': True,
'auto_install': False,
"images":['static/description/Banner.png'],
}

View File

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api, _
import urllib
import re
#from BeautifulSoup import BeautifulSoup
from bs4 import BeautifulSoup
import base64
class bi_product_image(models.Model):
_name = "bi.product.image"
product_id = fields.Many2one('product.template', 'Product')
name = fields.Char('Name')
color = fields.Integer('Color Index')
image = fields.Binary('Image')
@api.multi
def set_image(self):
tmpl_id_bi = self.product_id
tmpl_id_bi.image_medium = self.image
return True
class product_template(models.Model):
_inherit = "product.template"
url = fields.Char('URL')
product_images_bi = fields.One2many('bi.product.image', 'product_id', 'Multiple Image For Product')
@api.multi
def write(self, vals):
super(product_template, self).write(vals)
if vals.get('url'):
img = self.process_url(vals.get('url'), self.id)
return True
@api.multi
def pre_process_url(self, raw_url):
if ' ' not in raw_url[-1]:
raw_url = raw_url.replace(' ', '%20')
return raw_url
elif ' ' in raw_url[-1]:
raw_url = raw_url[:-1]
raw_url = raw_url.replace(' ', '%20')
return raw_url
@api.multi
def process_url(self, url, prod_temp_id_bi):
html_data = urllib.request.urlopen(url)
soup = BeautifulSoup(html_data)
images = []
for img in soup.findAll('img'):
images.append(img.get('src'))
if not images:
imgdata = base64.encodestring(urllib.request.urlopen(url).read())
file_name = url.split('/')[-1]
prod = self.env['bi.product.image'].create({
'product_id':prod_temp_id_bi,
'name':file_name,
'image':imgdata
})
for imgurl in images:
try:
imgurl = self.pre_process_url(imgurl)
imgdata = base64.encodestring(urllib2.request.urlopen(imgurl).read())
file_name = imgurl.split('/')[-1]
prod = self.env['bi.product.image'].create({
'product_id':prod_temp_id_bi,
'name':file_name,
'image':imgdata
})
except:
pass
@api.model
def create(self, vals):
res = super(product_template, self).create(vals)
if res.url:
img = self.process_url(vals.get('url'), res.id)
return res

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="bi_inherit_product_template" model="ir.ui.view">
<field name="name">bi.inherit.product.template</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view" />
<field name="type">form</field>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="url" placeholder="Enter Product Image URL"/>
</field>
<xpath expr='//sheet//notebook' position='inside'>
<page string="Product Images">
<field name="product_images_bi" mode="kanban,tree">
<kanban>
<field name="color"/>
<field name="name"/>
<field name="image"/>
<templates>
<t t-name="kanban-box">
<t t-set="color" t-value="kanban_color(record.color.raw_value)"/>
<div t-att-class="color" style="position: relative">
<a t-if="! read_only_mode" type="delete" style="position: absolute; right: 0; padding: 4px; diplay: inline-block">X</a>
<div class="oe_module_vignette">
<a type="open">
<t t-if="record.image.raw_value === true">
<img t-att-src="kanban_image('product.image', 'image', record.id.value)" class="oe_avatar oe_kanban_avatar_smallbox"/>
</t>
<t t-if="record.image and record.image.raw_value !== false">
<img t-att-src="'data:image/png;base64,'+record.image.raw_value" class="oe_avatar oe_kanban_avatar_smallbox"/>
</t>
<t t-if="record.image.raw_value === false and (!record.image or record.image.raw_value === false)">
<t t-if="record.is_company.raw_value === true">
<img t-att-src='_s + "/base/static/src/img/company_image.png"' class="oe_kanban_image oe_kanban_avatar_smallbox"/>
</t>
<t t-if="record.is_company.raw_value === false">
<img t-att-src='_s + "/base/static/src/img/avatar.png"' class="oe_kanban_image oe_kanban_avatar_smallbox"/>
</t>
</t>
</a>
<div class="oe_module_desc">
<div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_color_border">
<table class="oe_kanban_table">
<tr>
<td class="oe_kanban_title1" align="left" valign="middle">
<h4><a type="open"><field name="name"/></a></h4>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</t>
</templates>
</kanban>
<tree>
<field name="name"/>
</tree>
<form>
<header>
<button name="set_image" string="Set As Product Image" type="object"/>
</header>
<group>
<group>
<field name="name"/>
</group>
<group>
<field name="image"/>
</group>
</group>
</form>
</field>
</page>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_product_image_bi_custom,access.bi.product.image,model_bi_product_image,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_product_image_bi_custom access.bi.product.image model_bi_product_image 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,174 @@
<section class="oe_container oe_dark" style="overflow: hidden;
background: #efefef;
box-shadow: none;">
<div class="mt32 mb32">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;"><b>Import multiple product images from URL</b></h2>
<h3 class="oe_slogn" style=" text-align: center;">This module is use for Import bulk product image from URL also set main product image.</h3>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<section class="oe_container oe_dark lead">
<div class="oe_row">
<div class="oe_span12" style="width: 828px;">
<div class="panel panel-primary" style="border-color: #528df3 !important;">
<div class="panel-heading" style="background-color: #528df3 !important;">
<h3 class="panel-title" style="font-size: 25px;"><i class="fa fa-mail-forward"></i>key features:</h3>
</div>
<div class="panel-body">
<ul class="list-unstyled">
<li><i class="fa fa-check text-primary" style="color: #528df3 !important;"></i> Add multiple images for product which can be useful for webshop.</li>
<li><i class="fa fa-check text-primary" style="color: #528df3 !important;"></i> Easy to import bulk images on a product.</li>
<li><i class="fa fa-check text-primary" style="color: #528df3 !important;"></i> Set main product image from imported images.</li>
<li><i class="fa fa-check text-primary" style="color: #528df3 !important;"></i> Easily download this images from odoo.</li>
</ul>
</div>
</div>
</div>
</div>
</section>
</section>
<br/>
<section class="container mt32">
<div class="row">
<h4 class="oe_slogan" style=" text-align: center;"><span align="center" class="label label-success" style="background-color:#528df3;"> <span class="fa fa-star fa-spin"></span>Import multiple product images from URL</span></h4>
</div>
</section>
<br>
<section>
<div class="container mt32">
<div class="col-md-12 mb32">
<div class="col-md-4">
<div class="text-center">
<div class="text-center">
<i class="fa fa-product-hunt fa-4x" style="color:#528df3;"></i>
<h4>Imported Product Images.</h4>
<div class="dt-iconboxes-text">
<p style="text-align: justify;">
It allows to see all imported product images in product images tab.
</p></div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<div class="text-center">
<i class="fa fa-download fa-4x" style="color:#528df3;"></i>
<h4>Download Product Image.</h4>
<div class="dt-iconboxes-text">
<p style="text-align: justify;">
It allows to download images from odoo.
</p></div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<div class="dt-iconboxes layout-6">
<i class="fa fa-question-circle fa-4x" style="color:#528df3;"></i>
<h4> Support For 90 Days</h4>
<div class="dt-iconboxes-text">
<p style="text-align: justify;">
As this module is the very useful for all type of Industries. You can contact us for any Query regarding this Module.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="container mt32">
<div class="row">
<h4 class="oe_slogan" style=" text-align: center;"><span align="center" class="label label-success " style="background-color:#528df3;"> <span class="fa fa-star fa-spin"></span> How to use</span></h4>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h1 class="text-info" style="text-align: center;padding-bottom: 40px;"><strong>Product image URL.</strong></h1>
<h3 class="text-info" style="font-size: 25px;">You can enter product image URL.</h3>
<br/>
<img class="img-border img-responsive thumbnail" style="border: 3px solid black;" src="image_url.png">
</div>
</div>
</section>
<section class="oe_container lead">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="text-info" style="font-size: 25px;">All linked images on the URL will be imported in one click and you can see all imported product images in product images tab.</h3>
<br/>
<img class="img-border img-responsive thumbnail" style="border: 3px solid black;" src="product_image.png">
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h1 class="text-info" style="text-align: center;padding-bottom: 40px;"><strong>Set product image.</strong></h1>
<h3 class="text-info" style="font-size: 25px;">You can select particular image to set as product image also you can download images from odoo.</h3>
<br/>
<img class="img-border img-responsive thumbnail" style="border: 3px solid black;" src="set_product_image.png">
</div>
</div>
</section>
<section class="oe_container lead">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<img class="img-border img-responsive thumbnail" style="border: 3px solid black;" src="product_image_set.png">
</div>
</div>
</section>
<section class="container mt32">
<div class="row">
<h4 class="oe_slogan" style=" text-align: center;"><span align="center" class="label label-success" style="background-color:red;">Installation Guide</span></h4>
<h3 class="text-info" style="text-align: center;">
<strong style="color:red;">Before using this module you have to install "beautifulsoup" package in your system.</strong>
</h3>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Free Support</h2>
<h3 class="oe_slogan" style="font-size: 20px; color: #000000 !important;">You will get 90 Days free support incase any bugs or issue (Except data recovery).</h3>
<p class="oe_slogan">
At BrowseInfo we offer end to end solution for Odoo services. Which includes analysis &amp; consultation on the workflows and integration part. Please note that You're not allowed to distribute this module after purchase! Incase of any question regarding this module feel free to email us on <a href="mailto:sales@browseinfo.in">sales@browseinfo.in</a> or raise a ticket on support.
</p>
</div>
</div>
</section>
<section class="oe_container lead">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">
<a href="http://www.browseinfo.in" target="new">
<img src="bi_logo.png">
</a>
<br>
<a href="sales@browseinfo.in" style="color: #000000 !important;">
Get Help &amp; Support</a>
</h2>
</div>
<br>
<div class="oe_slogan oe_spaced text-center">
<a class="btn btn-success mt8" title="Website" style="background-color: #9B0F4E; color: #FFFFFF !important;" href="http://www.browseinfo.in"> Website </a> <a class="btn btn-success mt8" title="Blog" style="background-color: #9B0F4E; color: #FFFFFF !important;" href="http://www.blog.browseinfo.in"> Blog </a> <a class="btn btn-success mt8" title="Contact Us" style="background-color: #9B0F4E; color: #FFFFFF !important;" href="mailto:sales@browseinfo.in"> Support </a> <a class="btn btn-success mt8" title="Request New Features now !" style="background-color: #9B0F4E; color: #FFFFFF !important;" href="mailto:sales@browseinfo.in"> Request New Features </a>
</div>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models

View File

@ -0,0 +1,38 @@
# -*- encoding: utf-8 -*-
###########################################################################
# Copyright (C) 2016 - Turkesh Patel. <http://www.almightycs.com>
#
# @author Turkesh Patel <info@almightycs.com>
###########################################################################
{
'name': 'Product Image and line sequence on Invoice Report',
'version': '1.0',
'author': 'Almighty Consulting Services',
'support': 'info@almightycs.com',
'category': 'Accounting',
'summary': 'Product Image and line sequence on Invoice Reports',
'description': """Product Image and line sequence on Invoice Report
Print Image in Invoice report
Invoice Report
Image in Report
product image
line sequence in report
line number in report
sequence number in report
row number in report
""",
'author': 'Almighty Consulting Services',
'depends': ['account'],
'website': 'http://www.almightycs.com',
'data': [
"views/invoice_product_view.xml",
"views/report_invoice.xml",
],
'images': [
'static/description/invoice_report_print_image_almightycs.png',
],
'application': False,
'price': 14,
'currency': 'EUR',
}

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import invoice

View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from odoo import fields, models
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
print_image = fields.Boolean('Print Image', help="""If Checked, you can see the product image in report""")
image_sizes = fields.Selection(
[('image', 'Big sized Image'), ('image_medium', 'Medium Sized Image'),
('image_small', 'Small Sized Image')],
'Image Sizes', default="image_small", help="Image size to be displayed in report")

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,109 @@
<head>
<style>
.backgrounds{background-color:#fff; color:#0B80E6}
</style>
</head>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12 oe_mt32 mb32">
<h3 class="oe_slogan">Product Image and sequence on Invoice Reports.</h3><h4><br/>In many cases we need to print product image in Invoice for more clerification or to make report more attrative and clear.<br/></h4>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_demo oe_picture oe_screenshot">
<a href="http://www.almightycs.com/blog/blogs-1/post/product-image-and-line-sequence-on-reports-odoo-48" target="_blank">
<img src="invoice_report_print_image_almightycs.png">
</a>
<div class="oe_demo_footer oe_centeralign">Option to print image on report.</div>
</div>
<div class="oe_demo oe_picture oe_screenshot mt92 mb92">
<a href="http://www.almightycs.com/blog/blogs-1/post/product-image-and-line-sequence-on-reports-odoo-48" target="_blank">
<img src="invoice_report_print_image_small_almightycs.png">
</a>
<div class="oe_demo_footer oe_centeralign">Invoice report with small image.</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_demo oe_picture oe_screenshot mb92">
<a href="http://www.almightycs.com/blog/blogs-1/post/product-image-and-line-sequence-on-reports-odoo-48" target="_blank">
<img src="invoice_report_print_image_medium_almightycs.png">
</a>
<div class="oe_demo_footer oe_centeralign">Invoice report with medium image.</div>
</div>
<div class="oe_demo oe_picture oe_screenshot mt92 mb92">
<a href="http://www.almightycs.com/blog/blogs-1/post/product-image-and-line-sequence-on-reports-odoo-48" target="_blank">
<img src="invoice_report_print_image_big_almightycs.png">
</a>
<div class="oe_demo_footer oe_centeralign">Invoice report with large image.</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h3 class="oe_slogan">Other Configuration</h3>
<p class="oe_slogan">To use this module no technical knowledge is required even no configuration is needed. Just install module and functionality is ready to use. For more customization and help contactus.</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<a href="http://www.almightycs.com" target="_blank">
<img src="acs.png" width="200" height="auto">
</a>
<div class="oe_demo_footer oe_centeralign">Meet Us</div>
</div>
</div>
<div class="oe_span6">
<br/><br/>
<h2 class="oe_slogan">Do you need help?</h2>
<h3 class="oe_slogan">
Let's offer you the best services!
</h3>
<p class="oe_mt32 text-center">
Contact us by our official channels.
</p>
<p class="oe_mt32 text-center">
Skype: turkesh4friends
</p>
<div class="oe_spaced">
<ul class="text-center list-inline">
<li>
<a href="https://in.linkedin.com/pub/patel-turkesh/1b/51b/32b" Target="_blank"><i class="fa fa-linkedin-square fa-xs backgrounds"></i></a>
</li>
<li>
<a href="https://www.facebook.com/public/Turkesh-Patel" Target="_blank"><i class="fa fa-facebook-square fa-xs backgrounds"></i></a>
</li>
<li>
<a href="https://github.com/tpa-odoo" Target="_blank"><i class="fa fa-github-square fa-xs backgrounds"></i></a>
</li>
<li>
<a href="https://plus.google.com/+TurkeshPatel" Target="_blank"><i class="fa fa-google-plus-square fa-xs backgrounds"></i></a>
</li>
<li>
<a href="https://twitter.com/turkeshpatel?lang=en" Target="_blank" ><i class="fa fa-twitter-square fa-xs backgrounds"></i></a>
</li>
<li>
<a title="Contact us" data-toggle="tooltip" data-placement="left" Target="_blank" href="http://www.almightycs.com/page/website.contactus"><i class="fa fa-envelope-square fa-xs backgrounds"></i></a>
</li>
</ul>
</div>
</div>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="invoice_form_inhs" model="ir.ui.view">
<field name="name">account.invoice.form.image</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<field name="date_due" position="after">
<field name="print_image"/>
<field name="image_sizes"/>
</field>
</field>
</record>
</odoo>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice_document_inherit" inherit_id="account.report_invoice_document">
<xpath expr="//table[hasclass('table table-condensed')/thead/tr/th[1]" position="before">
<th>
#
</th>
<t>
<t t-if="o.print_image and o.image_sizes in ('image', 'image_medium', 'image_small') ">
<th>
Product Image
</th>
</t>
</t>
</xpath>
<xpath expr="//table/tbody/tr/td[1]" position="before">
<td>
<span t-esc="l_index + 1"/>.
</td>
<t t-if="l.product_id">
<t t-if="o.image_sizes == 'image' and o.print_image ">
<td>
<span t-field="l.product_id.image"
t-field-options="{&quot;widget&quot;: &quot;image&quot;, &quot;class&quot;: &quot;img-rounded&quot;}"/>
</td>
</t>
<t t-if="o.image_sizes == 'image_medium' and o.print_image">
<td>
<span t-field="l.product_id.image_medium"
t-field-options="{&quot;widget&quot;: &quot;image&quot;, &quot;class&quot;: &quot;img-rounded&quot;}"/>
</td>
</t>
<t t-if="o.image_sizes == 'image_small' and o.print_image ">
<td>
<span t-field="l.product_id.image_small"
t-field-options="{&quot;widget&quot;: &quot;image&quot;, &quot;class&quot;: &quot;img-rounded&quot;}"/>
</td>
</t>
</t>
</xpath>
</template>
</odoo>

View File

@ -0,0 +1,55 @@
===============================================
Company-dependent values in System Parameters
===============================================
Adds multi-company support to many features
Based on built-in company_dependent parameters. Real values are stored at ``ir.property``.
Check Usage instructions for understanding how it works.
Running auto-tests
==================
On following conditions:
* ``at_install`` tests are run in other modules
* during tests ``ir.config_parameter`` is used
* ``ir_config_parameter_multi_company`` is installed, but not loaded yet
The following error may appear::
ERROR: column ir_config_parameter.value does not exist
To avoid it, add the module to ``--load`` parameter, e.g.::
./odoo-bin --load=web,ir_config_parameter_multi_company --test-enable -i some_module ...
Credits
=======
Contributors
------------
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__
Sponsors
--------
* `IT-Projects LLC <https://it-projects.info>`__
Maintainers
-----------
* `IT-Projects LLC <https://it-projects.info>`__
Further information
===================
Demo: http://runbot.it-projects.info/demo/misc-addons/10.0
HTML Description: https://apps.odoo.com/apps/modules/10.0/ir_config_parameter_multi_company/
Usage instructions: `<doc/index.rst>`_
Changelog: `<doc/changelog.rst>`_
Tested on Odoo 11.0 8787f5acee9b5d2cad15b97804522dc04717a1c1

View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
from . import models
def uninstall_hook(cr, registry):
from odoo import api, SUPERUSER_ID
env = api.Environment(cr, SUPERUSER_ID, {})
# remove properties
field_id = env.ref('base.field_ir_config_parameter_value').id
env['ir.property'].search([('fields_id', '=', field_id)]).unlink()
# update base module
env['ir.module.module'].search([('name', '=', 'base')]).button_upgrade()

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
{
"name": """Company-dependent values in System Parameters""",
"summary": """Adds multi-company support for dozens features""",
"category": "Extra Tools",
# "live_test_url": "",
"images": [],
"version": "11.0.2.0.0",
"application": False,
"author": "IT-Projects LLC, Ivan Yelizariev",
"support": "apps@it-projects.info",
"website": "https://it-projects.info/team/yelizariev",
"license": "LGPL-3",
"price": 40.00,
"currency": "EUR",
"depends": [
"base_setup",
],
"external_dependencies": {"python": [], "bin": []},
"data": [
],
"qweb": [
],
"demo": [
],
"post_load": None,
"pre_init_hook": None,
"post_init_hook": None,
"uninstall_hook": 'uninstall_hook',
"auto_install": False,
"installable": True,
}

View File

@ -0,0 +1,20 @@
`2.0.0`
-------
- **IMP:** removing module is not dangerous anymore
- **FIX:** after updating module base some parameters losted their values
`1.1.0`
-------
- **ADD:** automatically resolve problem with csrf-token
`1.0.1`
-------
- **FIX:** workaround for the error on authentication that appeared after latest odoo updates
`1.0.0`
-------
- Init version

View File

@ -0,0 +1,102 @@
===============================================
Company-dependent values in System Parameters
===============================================
Installation
============
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way
* Make database backup (or at least ``ir.config_parameter`` table)
Configuration
=============
* Open menu ``[[ Settings ]] >> General Settings``
* Activate **[x] Multi Company - Manage multiple companies**
* Click ``[Apply]``
* Open menu ``[[ Settings ]] >> Users >> Users``
* Select your user
* Add some companies to **Allowed Companies** field
Usage
=====
* `Activate Developer Mode <https://odoo-development.readthedocs.io/en/latest/odoo/usage/debug-mode.html>`__
* Open menu ``[[ Settings ]] >> Technical >> Parameters >> System Parameters``
* Choose some record or create new one
* Set some value
* Switch your user to another company
* Click top right-hand button with your user name
* Click ``Preferences``
* Set new value for **Company** field
* Click ``[Save]``
* Set new value for the System Parameter record
* Switch back to previous company
* RESULT: Value of the System Parameter depends on current company
Default values
--------------
All system parameters created before module installation (as well as just created parameters) become default value for corresponding parameters. Example:
* Before installation:
* **param1** = *value1*
* **param2** = *value2*
* After installation:
* **param1** = *value1* -- default value for param1
* **param2** = *value2* -- default value for param2
* Now if we switch to companyA and make following updates:
* **param1** = *value11*
* And if we switch to companyB and make following updates:
* **param2** = *value22*
* **param3** = *value3*
* Then for companyA we have
* **param1** = *value11* (value for companyA)
* **param2** = *value2* (default value)
* **param3** = *value3* (default value)
* Then for companyB we have
* **param1** = *value1* (via default value)
* **param2** = *value22* (value for companyB)
* **param3** = *value3* (via default value)
Company Properties
------------------
For understanding which values are default and which are company dependent do as following:
* `Activate Developer Mode <https://odoo-development.readthedocs.io/en/latest/odoo/usage/debug-mode.html>`__
* Open menu ``[[ Settings ]] >> Technical >> Parameters >> Company Properties``
* Click ``[Group By] -> Field``
* Now you can find all records under ``Value (ir.config_parameter)``
Uninstallation
==============
On uninstallation parameter values are restored to *Default values* (see above).
Nevertheless, it's recommended to follow steps below, if you are not sure, that
those values are ones you need.
* It's recommended to make database backup before uninstallating the module
* Open menu ``[[ Settings ]] >> Technical >> Parameters >> System Parameters``
* Make Export of all records (``[Action] -> Export``) -- exporting only column ``value`` is enough.
* Click ``[Import]`` button
* Upload ``*.csv`` file
* Click ``[Validate]`` -- it may take some time. It must not return errors!
* Don't close current page!
* Uninstall the module at another page
* Return back to page with importing
* Click ``[Import]``

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from odoo import api, SUPERUSER_ID
def migrate(cr, version):
# fill column
#
# we can do it only "post-", because in "pre-" there is no
# _update_config_parameter_value method yet
env = api.Environment(cr, SUPERUSER_ID, {})
field_id = env.ref('base.field_ir_config_parameter_value').id
default_values = env['ir.property'].search([
('fields_id', '=', field_id),
('company_id', '=', False)
])
default_values._update_config_parameter_value()

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
def migrate(cr, version):
# in prevous version, column doesn't exist. We must create it, because it
# will be renamed to value_tmp during updating the module
# Create Column
cr.execute("ALTER TABLE ir_config_parameter ADD COLUMN value VARCHAR")

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from odoo import api, SUPERUSER_ID
def migrate(cr, version):
# fill column
#
# we can do it only "post-", because in "pre-" there is no
# _update_config_parameter_value method yet
env = api.Environment(cr, SUPERUSER_ID, {})
field_id = env.ref('base.field_ir_config_parameter_value').id
default_values = env['ir.property'].search([
('fields_id', '=', field_id),
('company_id', '=', False)
])
default_values._update_config_parameter_value()

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
def migrate(cr, version):
# in prevous version, column doesn't exist. We must create it, because it
# will be renamed to value_tmp during updating the module
# Create Column
cr.execute("ALTER TABLE ir_config_parameter ADD COLUMN value VARCHAR")

View File

@ -0,0 +1,3 @@
from . import ir_config_parameter
from . import res_users
from . import ir_property

View File

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
import logging
from odoo import models, fields, api, _, tools
from odoo.addons.base.ir.ir_config_parameter import IrConfigParameter as IrConfigParameterOriginal, _default_parameters
_logger = logging.getLogger(__name__)
PROP_NAME = _('Default value for "%s"')
DATABASE_SECRET_KEY = 'database.secret'
class IrConfigParameter(models.Model):
_inherit = 'ir.config_parameter'
value = fields.Text(company_dependent=True)
@api.multi
def _get_property(self, for_default=False):
self.ensure_one()
domain = self.env['ir.property']._get_domain('value', self._name)
domain += [('res_id', '=', '%s,%s' % (self._name, self.id))]
if for_default:
# find: ('company_id', 'in', [company_id, False])
# update to: ('company_id', 'in', [False])
domain = [
('company_id', 'in', [False])
if x[0] == 'company_id'
else
x
for x in domain
]
prop = self.env['ir.property'].search(domain)
return prop
@api.model
def create(self, vals):
res = super(IrConfigParameter, self).create(vals)
# make value company independent
prop = res._get_property()
prop.company_id = None
prop.name = PROP_NAME % res.key
res._update_db_value(vals.get('value'))
return res
@api.multi
def write(self, vals):
res = super(IrConfigParameter, self).write(vals)
if 'key' in vals:
# Change property name after renaming the parameter to avoid confusions
self.ensure_one() # it's not possible to update key on multiple records
name = PROP_NAME % vals.get('key')
prop = self._get_property(for_default=True)
prop.name = name
return res
def _update_db_value(self, value):
"""Store value in db column. We can use it only directly,
because ORM treat value as computed multi-company field"""
self.ensure_one()
self.env.cr.execute("UPDATE ir_config_parameter SET value=%s WHERE id = %s", (value, self.id, ))
@api.model
def reset_database_secret(self):
value = _default_parameters[DATABASE_SECRET_KEY]()
self.set_param(DATABASE_SECRET_KEY, value)
return value
@api.model
def get_param(self, key, default=False):
company_id = self.env.context.get('company_id')
if not company_id:
website_id = self.env.context.get('website_id')
if website_id:
website = self.env['website'].browse(website_id)
company_id = website.company_id and website.company_id.id
if not company_id:
# Warning. Since odoo 11.0 it means that by default Administrator's company value is used
company_id = self.env.user.company_id.id
self_company = self.with_context(force_company=company_id)
res = super(IrConfigParameter, self_company).get_param(key, default)
if key == DATABASE_SECRET_KEY and not res:
# If we have empty database.secret, we reset it automatically
# otherwise admin cannot even login
# TODO: we don't really need to reset database.secret, because in current version of the module column value is presented and up-to-date. Keep it until we are sure, that without this redefinition everything works after migration from previous versions fo the module.
return self_company.reset_database_secret()
return res
@api.model
@tools.ormcache_context('self._uid', 'key', keys=("force_company",))
def _get_param(self, key):
_logger.debug('_get_param(%s) context: %s', key, self.env.context)
# call undecorated super method. See odoo/tools/cache.py::ormcache and http://decorator.readthedocs.io/en/stable/tests.documentation.html#getting-the-source-code
return IrConfigParameterOriginal._get_param.__wrapped__(self, key)
@api.multi
def _create_default_value(self, value):
"""Set company-independent default value"""
self.ensure_one()
domain = [
('company_id', '=', False),
('res_id', '=', '%s,%s' % (self._name, self.id))
]
existing = self.env['ir.property'].search(domain)
if existing:
# already exists
return existing
_logger.debug('Create default value for %s', self.key)
return self.env['ir.property'].create({
'fields_id': self.env.ref('base.field_ir_config_parameter_value').id,
'res_id': '%s,%s' % (self._name, self.id),
'name': PROP_NAME % self.key,
'value': value,
'type': 'text',
})
def _auto_init(self):
cr = self.env.cr
# rename "value" to "value_tmp"
# to don't lose values, because during installation the column "value" is deleted
cr.execute("ALTER TABLE ir_config_parameter RENAME COLUMN value TO value_tmp")
def post_init_callback():
self._post_init()
self.pool.post_init(post_init_callback)
return super(IrConfigParameter, self)._auto_init()
def _post_init(self):
cr = self.env.cr
# rename "value_tmp" back to "value_tmp"
cr.execute("ALTER TABLE ir_config_parameter RENAME COLUMN value_tmp TO value")
for r in self.env['ir.config_parameter'].sudo().search([]):
cr.execute("SELECT key,value FROM ir_config_parameter WHERE id = %s", (r.id, ))
res = cr.dictfetchone()
value = res.get('value')
# value may be empty after migration from previous module version
if value:
# create default value if it doesn't exist
r._create_default_value(value)

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
from odoo import models, api
class IrProperty(models.Model):
_inherit = 'ir.property'
@api.multi
def write(self, vals):
res = super(IrProperty, self).write(vals)
self._update_config_parameter_value()
return res
@api.multi
def _update_config_parameter_value(self):
"""Check for default value in ir.config_parameter
and copy value to "value" column"""
field = self.env.ref('base.field_ir_config_parameter_value')
for r in self:
if r.fields_id != field:
# It's not for ir.config_parameter
continue
if r.company_id:
# it's not default value
continue
if not r.res_id:
# Paramater is not specified
continue
# Default value is updated. Set new value in column "value"
model, res_id = r.res_id.split(',')
value = r.get_by_record()
param = self.env['ir.config_parameter'].browse(int(res_id))
param._update_db_value(value)

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
import hmac
from hashlib import sha256
from odoo import models, tools
class Users(models.Model):
_inherit = 'res.users'
@tools.ormcache('sid')
def _compute_session_token(self, sid):
""" Compute a session token given a session id and a user id.
DIFFERENCE from original: read database.secret via orm.
See https://github.com/odoo/odoo/pull/22612#issuecomment-375040429
TODO: we don't really need this redefinition, because in current version of the module column value is presented and up-to-date. Keep it until we are sure, that without this redefinition everything works after migration from previous versions fo the module.
"""
database_secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
# retrieve the fields used to generate the session token
session_fields = ', '.join(sorted(self._get_session_token_fields()))
self.env.cr.execute("""SELECT %s, %%s
FROM res_users
WHERE id=%%s""" % (session_fields),
(database_secret, self.id,))
if self.env.cr.rowcount != 1:
self._invalidate_session_cache()
return False
data_fields = self.env.cr.fetchone()
# generate hmac key
key = (u'%s' % (data_fields,)).encode('utf-8')
# hmac the session id
data = sid.encode('utf-8')
h = hmac.new(key, data, sha256)
# keep in the cache the token
return h.hexdigest()

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,100 @@
<section class="oe_container">
<div class="row">
<div class="col-md-12">
<h2 class="oe_slogan" style="color:#875A7B;">Company-dependent values in System Parameters</h2>
<h3 class="oe_slogan">Adds multi-company support for dozens features</h3>
</div>
</div>
</section>
<section class="oe_container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-warning oe_mt32" style="padding:0.3em 0.6em; font-size: 150%;">
Many applications don't have multi-company support. Common reason is that ones are based on System Parameter, which is not company-dependent by default.
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="row">
<div class="col-md-12">
<div class="alert alert-info oe_mt32" style="padding:0.3em 0.6em; font-size: 150%;">
<i class="fa fa-hand-o-right"></i><b> Examples: </b>
<ul class="list-unstyled">
<li>
<i class="fa fa-check-square-o text-primary"></i>
Paypal and other payments acquirers
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
Google drive integration
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
Google calendar integration
</li>
<li>
</ul>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="row">
<div class="col-md-8">
<h2>Need our service?</h2>
<p class="oe_mt32">Contact us by <a href="mailto:apps@it-projects.info">email</a> or fill out <a href="https://www.it-projects.info/page/website.contactus " target="_blank">request form</a></p>
<ul>
<li><a href="mailto:apps@it-projects.info">apps@it-projects.info <i class="fa fa-envelope-o"></i></a></li>
<li><a href="https://www.it-projects.info/page/website.contactus " target="_blank">https://www.it-projects.info/page/website.contactus <i class="fa fa-list-alt"></i></a></li>
</ul>
</div>
<div class="col-md-4">
<div class="stamp" style="width:200px;">
<div style="margin-top: 15px;
position: relative;
font-family:'Vollkorn', serif;
font-size: 16px;
line-height: 25px;
text-transform: uppercase;
font-weight: bold;
color: #75526b;
border: 3px dashed #75526b;
float: left;
padding: 4px 12px;
-webkit-transform: rotate(-1deg);
-o-transform: rotate(-1deg);
-moz-transform: rotate(-1deg);
-ms-transform: rotate(-1deg);">
Tested on Odoo<br/>10.0 community
</div>
<!--<div style="margin-top: 15px;
position: relative;
font-family:'Vollkorn', serif;
font-size: 16px;
line-height: 25px;
text-transform: uppercase;
font-weight: bold;
color: #75526b;
border: 3px dashed #75526b;
float: left;
padding: 4px 12px;
-webkit-transform: rotate(-8deg);
-o-transform: rotate(-8deg);
-moz-transform: rotate(-8deg);
-ms-transform: rotate(-8deg);">
Tested on Odoo<br/>10.0 enterprise
</div>-->
</div>
</div>
</div>
</section>

View File

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

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
from odoo.tests import common
class TestBase(common.TransactionCase):
at_install = False
post_install = True
def setUp(self):
super(TestBase, self).setUp()
self.config_param = self.env['ir.config_parameter']
self.main_company = self.env.user.company_id
self.second_company = self.env['res.company'].create({'name': 'Second company'})
def test_cache(self):
KEY = 'test_key'
VALUE1 = 'value1'
VALUE2 = 'value2'
# set value for first company
self.config_param.set_param(KEY, VALUE1)
# call get_param to cache the value
self.assertEqual(self.config_param.get_param(KEY), VALUE1, 'Value is not saved!')
# set value for second company
self.env.user.company_id = self.second_company
self.config_param.set_param(KEY, VALUE2)
param = self.config_param.search([('key', '=', KEY)])
# check without cache first
self.assertEqual(param.value, VALUE2, 'Value for second company is not saved!')
# check cache
self.assertEqual(self.config_param.get_param(KEY), VALUE2, 'Cache gives value for wrong company!')
self.env.user.company_id = self.main_company
self.assertEqual(self.config_param.get_param(KEY), VALUE1)

View File

@ -0,0 +1,28 @@
Odoo Proprietary License v1.0
This software and associated files (the "Software") may only be used (executed,
modified, executed after modifications) if you have purchased a valid license
from the authors, typically via Odoo Apps, or if you have received a written
agreement from the authors of the Software (see the COPYRIGHT file).
You may develop Odoo modules that use the Software as a library (typically
by depending on it, importing it and using its resources), but without copying
any source code or material from the Software. You may distribute those
modules under the license of your choice, provided that this license is
compatible with the terms of the Odoo Proprietary License (For example:
LGPL, MIT, or proprietary licenses similar to this one).
It is forbidden to publish, distribute, sublicense, or sell copies of the Software
or modified copies of the Software.
The above copyright notice and this permission notice must be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from . import models
from . import controllers
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
{
'name': 'Website Product Attachments(Documents)',
'summary': """This Module is allow customer to Download Product's Documents/Attachments on website.""" ,
'category': 'eCommerce',
'version': '11.0.0.1',
"price": 10,
"currency": 'EUR',
'author': 'BrowseInfo',
'description': """
This Module is allow customer to Download Product's Documents/Attachments on website.
Website Product Documents
Product Documents on Website Shop ,Product Attachments on Website Shop,Product Documents/Attachments on Website Shop
Product Documents on Shop ,Product Attachments on Shop,Product Documents/Attachments on Shop.
Show Product Documents on Website Shop ,Show Product Attachments on Website Shop,Show Product Documents/Attachments on Website Shop
Show Product Documents on Shop ,Show Product Attachments on Shop,Show Product Documents/Attachments on Shop.
Visible Product Documents on Website Shop ,visible Product Attachments on Website Shop,visible Product Documents/Attachments on Website Shop
visible Product Documents on Shop ,visible Product Attachments on Shop,visible Product Documents/Attachments on Shop.
Show Product Document on Website Shop ,Show Product Attachment on Website Shop,Show Product Document/Attachment on Website Shop
Show Product Document on Shop ,Show Product Attachment on Shop,Show Product Document/Attachment on Shop.
Visible Product Document on Website Shop ,visible Product Attachment on Website Shop,visible Product Document/Attachment on Website Shop
visible Product Document on Shop ,visible Product Attachment on Shop,visible Product Document/Attachment on Shop.
Product Document on Website Shop ,Product Attachment on Website Shop,Product Document/Attachment on Website Shop
Product Document on Shop ,Product Attachment on Shop,Product Document/Attachment on Shop
Display Product Documents on Website Shop ,Display Product Attachments on Website Shop,Product Documents/Attachments on Website Shop
Display Product Documents on Shop ,Display Product Attachments on Shop,Display Product Documents/Attachments on Shop
Display Product Document on Website Shop ,Display Product Attachment on Website Shop,Product Document/Attachment on Website Shop
Display Product Document on Shop ,Display Product Attachment on Shop,Display Product Document/Attachment on Shop
""",
'license':'OPL-1',
'depends': ['website','website_sale'],
'data': [
'security/ir.model.access.csv',
'views/product_attachment.xml',
'views/template.xml',
],
'application': True,
'installable': True,
"images":["static/description/Banner.png"],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
{
'name': 'Website Product Attachments(Documents)',
'summary': """This Module is allow customer to Download Product's Documents/Attachments on website.""" ,
'category': 'eCommerce',
'version': '11.0.0.1',
"price": 15,
"currency": 'EUR',
'author': 'BrowseInfo',
'description': """
This Module is allow customer to Download Product's Documents/Attachments on website.
Website Product Documents
Product Documents on Website Shop ,Product Attachments on Website Shop,Product Documents/Attachments on Website Shop
Product Documents on Shop ,Product Attachments on Shop,Product Documents/Attachments on Shop.
Show Product Documents on Website Shop ,Show Product Attachments on Website Shop,Show Product Documents/Attachments on Website Shop
Show Product Documents on Shop ,Show Product Attachments on Shop,Show Product Documents/Attachments on Shop.
Visible Product Documents on Website Shop ,visible Product Attachments on Website Shop,visible Product Documents/Attachments on Website Shop
visible Product Documents on Shop ,visible Product Attachments on Shop,visible Product Documents/Attachments on Shop.
Show Product Document on Website Shop ,Show Product Attachment on Website Shop,Show Product Document/Attachment on Website Shop
Show Product Document on Shop ,Show Product Attachment on Shop,Show Product Document/Attachment on Shop.
Visible Product Document on Website Shop ,visible Product Attachment on Website Shop,visible Product Document/Attachment on Website Shop
visible Product Document on Shop ,visible Product Attachment on Shop,visible Product Document/Attachment on Shop.
Product Document on Website Shop ,Product Attachment on Website Shop,Product Document/Attachment on Website Shop
Product Document on Shop ,Product Attachment on Shop,Product Document/Attachment on Shop
Display Product Documents on Website Shop ,Display Product Attachments on Website Shop,Product Documents/Attachments on Website Shop
Display Product Documents on Shop ,Display Product Attachments on Shop,Display Product Documents/Attachments on Shop
Display Product Document on Website Shop ,Display Product Attachment on Website Shop,Product Document/Attachment on Website Shop
Display Product Document on Shop ,Display Product Attachment on Shop,Display Product Document/Attachment on Shop
""",
'license':'OPL-1',
'depends': ['website','website_sale'],
'data': [
'security/ir.model.access.csv',
'views/product_attachment.xml',
'views/template.xml',
],
'application': True,
'installable': True,
"images":["static/description/Banner.png"],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from . import main
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
import base64
import io
from io import StringIO
from odoo import http, SUPERUSER_ID
from odoo.http import request
from odoo.addons.website.controllers.main import QueryURL
from odoo.addons.website_sale.controllers.main import WebsiteSale
import logging
_logger = logging.getLogger(__name__)
class WebsiteSaleAttachment(WebsiteSale):
@http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True)
def product(self, product, category='', search='', **kwargs):
res = super(WebsiteSaleAttachment,self).product(product,category,search,**kwargs)
attachment_obj = request.env['product.attachment']
attachments = attachment_obj.search([('product_tmpl_id', '=', product.id)])
res.qcontext.update({
'attachments': attachments
})
return res
@http.route(['/download/attachment'], type='http', auth="public", website=True)
def download_attachment(self, attachment_id):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
attachment = request.env['product.attachment'].sudo().search_read([('id', '=', int(attachment_id))], ["attachment","name"])
if attachment:
attachment = attachment[0]
else:
return redirect('/shop')
data = io.BytesIO(base64.standard_b64decode(attachment["attachment"]))
return http.send_file(data, filename=attachment['name'], as_attachment=True)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from . import product
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Part of BrowseInfo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api, _
class ProductAttachment(models.Model):
_name = 'product.attachment'
name = fields.Char(string='Name')
description = fields.Text(string='Description')
attachment = fields.Binary(string='Attachment')
product_tmpl_id = fields.Many2one('product.template','Product')
class ProductTemplate(models.Model):
_inherit = 'product.template'
attachments = fields.One2many('product.attachment','product_tmpl_id','Images')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
odoo_website_product_attachment_visitor_user,odoo_website_product_attachment_visitor_user_name,odoo_website_product_attachment.model_product_attachment,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 odoo_website_product_attachment_visitor_user odoo_website_product_attachment_visitor_user_name odoo_website_product_attachment.model_product_attachment 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,123 @@
<section class="oe_container oe_dark"
style="overflow: hidden; background: #efefef; box-shadow: none;">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan" style="color: #00B0FF; font-family: Quicksand;">Website
Product Attachment</h2>
<h3 class="oe_slogan" style="color: #31708f;">This Module allows
us to add product attachment that can be downloaded by user like
Product Details, User Manual, Warranty Conditions.</h3>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h4 class="oe_slogan" style="color: #424242;">Website Product
Attachment Features</h4>
<div style="font-size: medium;">
<p>This module allows you to attach documents of the product
along with its description.</p>
<ul>
<li>Attach any kind of files.</li>
<li>Add numbers of documents.</li>
<li>Easy to access.</li>
<li>Easily remove multiple files at a time.</li>
</ul>
<p>To add an attachment to any product. Go to Sale -> Product.
Select Product Attachment tab.</p>
</div>
</div>
</div>
</section>
<section class="oe_container"
style="overflow: hidden; background: #efefef; box-shadow: none;">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan" style="color: #31708f; font-family: Quicksand;text-align: center;">How
it works</h2>
<div style="text-align: center; font-size: medium;">
<p style="color: #31708f">In Product attachment of any product,
Add an item.</p>
</div>
</div>
</div>
<img class="img-border img-responsive thumbnail"
src="website_attachment_2.png" style="border: 3px solid black">
<br>
<div style="text-align: center; font-size: medium;">
<p class="fa fa-check " aria-hidden="true" style="color: #31708f">
After adding details and attaching document to the product save it.
You will be able to see that it is available for download.</p>
</div>
<img class="img-border img-responsive thumbnail"
src="website_attachment_1.png" style="border: 3px solid black">
<br> <br>
</section>
<section class="oe_container">
<div class="oe_row or_spaced">
<div class="oe_span12">
<h2 class="oe_slogan" style="color: #31708f">Website Product
Attachment</h2>
<div style="text-align: center; font-size: medium;">
<p style="color: #31708f">Now we can see attachment of documents
we had attached in products. By clicking on that we can download
the attachment.</p>
</div>
<img class="img-border img-responsive thumbnail"
src="website_attachment_3.png" style="border: 3px solid black">
<br> <br>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Free Support</h2>
<h3 class="oe_slogan"
style="font-size: large; color: #000000 !important;">You will
get 90 Days free support in-case any bugs or issue (Except data
recovery).</h3>
<p class="oe_slogan" style="font-size: medium;">
At BrowseInfo we offer end to end solution for Odoo services. Which
includes analysis &amp; consultation on the work-flows and
integration part. Please note that You're not allowed to distribute
this module after purchase! In-case of any question regarding this
module feel free to email us on <a href="mailto:sales@browseinfo.in">sales@browseinfo.in</a>
or raise a ticket on support.
</p>
</div>
</div>
</section>
<section class="oe_container lead"
style="overflow: hidden; background: #ECEFF1; box-shadow: none;">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">
<a href="http://www.browseinfo.in" target="new"> <img
src="bi_logo.png">
</a> <br> <a href="sales@browseinfo.in"
style="color: #000000 !important;"> Get Help &amp; Support</a>
</h2>
</div>
<br>
<div class="oe_slogan oe_spaced text-center">
<a class="btn btn-success mt8" title="Website"
style="background-color: #9B0F4E; color: #FFFFFF !important;"
href="http://www.browseinfo.in"> Website </a> <a
class="btn btn-success mt8" title="Blog"
style="background-color: #9B0F4E; color: #FFFFFF !important;"
href="http://www.blog.browseinfo.in"> Blog </a> <a
class="btn btn-success mt8" title="Contact Us"
style="background-color: #9B0F4E; color: #FFFFFF !important;"
href="mailto:sales@browseinfo.in"> Support </a> <a
class="btn btn-success mt8" title="Request New Features now !"
style="background-color: #9B0F4E; color: #FFFFFF !important;"
href="mailto:sales@browseinfo.in"> Request New Features </a>
</div>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- inherited product template form view -->
<record id="product_attachment_template_only_form_view" model="ir.ui.view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='sales']" position="after">
<page string="Product Attachments">
<field name="attachments" mode="tree" context="{'default_name': name}">
<form string="Product Attachments">
<sheet>
<group>
<field name="name"/>
<field name="description"/>
<field name="attachment"/>
</group>
</sheet>
</form>
<tree editable="bottom">
<field name="name"/>
<field name="description"/>
<field name="attachment"/>
</tree>
</field>
</page>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Product Attachment in single_product_page page -->
<template id="product_attachment_in_single_product_page" inherit_id="website_sale.product" active="True" customize_show="True" name="Show Product Attachment">
<xpath expr="//form" position="after">
<t t-if="attachments">
<div class="product_attachment">
<h4>Product Documents/Attachments</h4>
<t t-foreach="attachments" t-as="attachment">
<form t-att-action="'/download/attachment?attachment_id=%i' % attachment.id" method="post">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<button type="submit" class="btn btn-default" style="margin: 0 0 10px;"> <i class="fa fa-download"></i> <span t-esc="attachment.name"/> </button>
</form>
</t>
</div>
</t>
</xpath>
</template>
</data>
</openerp>

View File

@ -0,0 +1,398 @@
SOFTWARE LICENCE AGREEMENT
==========================
This AGREEMENT is made effective on the date of the purchase of the software
between Webkul Software Pvt. Ltd.,Company incorporated under the Companies
Act, 1956 (hereinafter referred to as “Licensor"), and the purchaser of the
software/ product (hereinafter referred to as "Licensee").
Preamble
--------
Licensor is a web and mobile product based organization engaged in the
business of developing and marketing software for enterprise level e-commerce
businesses. It is an ISO and NSR (NASSCOM) certified organization having a
team of more than 150 creative engineers which come from different
backgrounds. It has developed more than 700 web extensions and apps in the
past few years for open source platforms which are used and trusted globally.
Licensee now wishes to obtain license, and Licensor wishes to grant a license,
to allow use of the software so purchased in developing the e-commerce
business website/ mobile app of the Licensee, subject to the terms and
conditions set forth herein.
THEREFORE, with the intent to be legally bound, the parties hereby agree as
follows:
Agreement
---------
1.DEFINITIONS.
As used in this Agreement, the following capitalized terms
shall have the definitions set forth below:
"Derivative Works" are works developed by Licensee, its officers, agents,
contractors or employees, which are based upon, in whole or in part, the
Source Code and/or the Documentation and may also be based upon and/or
incorporate one or more other preexisting works of the Licensor. Derivative
Works may be any improvement, revision, modification, translation (including
compilation or recapitulation by computer), abridgment, condensation,
expansion, or any other form in which such a preexisting work may be recast,
transformed, or adapted. For purposes hereof, a Derivative Work shall also
include any compilation that incorporates such a preexisting work.
"Documentation" is written, printed or otherwise recorded or stored (digital
or paper) material relating to the Software and/or Source Code, including
technical specifications and instructions for its use including Software/
Source Code annotations and other descriptions of the principles of its
operation and instructions for its use.
"Improvements" shall mean, with respect to the Software, all modifications and
changes made, developed, acquired or conceived after the date hereof and
during the entire term of this Agreement.
"Source Code" is the computer programming source code form of the Software in
the form maintained by the Licensor, and includes all non-third-party
executables, libraries, components, and Documentation created or used in the
creation, development, maintenance, and support of the Software as well as all
updates, error corrections and revisions thereto provided by Licensor, in
whole or in part.
2.SOFTWARE LICENSE.
(a)Grant of License. For the consideration set forth below, Licensor hereby
grants to Licensee, and Licensee hereby accepts the worldwide, non-exclusive,
perpetual, royalty-free rights and licenses set forth below:
(i)The right and license to use and incorporate the software, in whole or in
part, to develop its website/ mobile app (including the integration of all or
part of the Licensors software into Licensee's own software) on one domain (
Except Joomla modules , listed on store are entitled to be used on unlimited
domain as per the standard guidelines ) only, solely for the own personal or
business use of the Licensee. However, the License does not authorize the
Licensee to compile, copy or distribute the said Software or its Derivative
Works.
(ii)The right and license does not authorize the Licensee to share any backup
or archival copies of the Software and / or the Source Code and Documentation
on any public internet space including github , stackoverflow etc . The
Licensee must ensure that the backup are not accessible to any other person
and the Licensee must prevent copying / use of source code by any unauthorized
persons.
(iii)The right and license does not authorize the Licensee to migrate the
domain license to another domain.
(iv)Our Joomla extensions are published under the GNU/GPL.
(b)Scope; Rights and Responsibilities.
(i)Licensor shall enable the Licensee to download one complete copy of the
Software.
(ii)The Software is intended for the sole use of the Licensee in development
of its own website/ mobile app.
(iii)Licensee does not have the right to hand over, sell, distribute,
sub-license, rent, lease or lend any portion of the Software or Documentation,
whether modified or unmodified, to anyone. Licensee should not place the
Software on a server so that it becomes accessible via a public network such
as the Internet for distribution purposes. In case the Licensee is using any
source code management system like github, it can use the code there only when
it has paid subscription from such management system.
(iv) In case the Licensee purchases the module and allow the third party
development agency to customize as per its need, it is at liberty to do so
subject to the condition that the Licensee as well as the Agency are not
authorized to sell the modified version of the extension. Except for the
required customization purposes, Licensee is not authorized to release the
Source Code, Derivative Work source code and/or Documentation to any third
party, which shall be considered as violation of the Agreement, inter-alia
entailing forthwith termination and legal action.
(c)Ownership.
(i)Software and Source Code. All right, title, copyright, and interest in the
Software, Source Code, Software Modifications and Error corrections will be
and remain the property of Licensor.
(ii)Derivative Works. As creation of Derivative Works by the Licensee is
prohibited, thus, all right, title, copyright, and interest in any and/or all
Derivative Works and Improvements created by, or on behalf of, Licensee will
also be deemed to the property of Licensor. Licensor shall be entitled to
protect copyright / intellectual property in all such Derivative Works and
Improvements also in any country as it may deem fit including without
limitation seeking copyright and/or patent protection.
3.CONSIDERATION.
(a)Licensee shall pay to Licensor the amount as mentioned on the website from
where the order is placed, as one-time, upfront fees in consideration for the
licenses and rights granted hereunder (hereinafter referred to as the "License
Fee"). The License Fee to be paid by Licensee shall be paid upfront at the
time of placing the order, and no credit will be allowed under any
circumstances.
(b)Once paid, the License Fees shall be non-refundable. The Licensee has fully
satisfied itself about the Software and has seen the demonstration, and only
thereafter has placed the order. Thus, the License Fees or any part thereof is
non-refundable. No claim for refund of the Licence Fees shall be entertained
under any circumstances.
4.REPRESENTATIONS AND WARRANTIES.
(a)Mutual. Each of the parties represents and warrants to the other as
follows.
(i)such party is a legal entity duly organized, validly existing and in good
standing;
(ii)such party has the power and authority to conduct its business as
presently conducted and to enter into, execute, deliver and perform this
Agreement.
(iii)This Agreement has been duly and validly accepted by such party and
constitutes the legal, valid and binding obligations of such party
respectively, enforceable against such party in accordance with their
respective terms;
(iv)the acceptance, execution, delivery and performance of this Agreement does
not and will not violate such party's charter or by-laws; nor require any
consent, authorization, approval, exemption or other action by any third party
or governmental entity.
(b)Licensor warrants that, at the time of purchase of the Software:
the Software will function materially as set forth in the website or published
functionality provided by Licensor to customers and potential customers
describing the Software; and
Software add-ons, if purchased by the Licensee from the Licensor, will not
materially diminish the features or functions of or the specifications of the
Software as they existed as of the execution of this Agreement.
(c)Title. Licensor represents and warrants that it is the exclusive owner of
all copyright/ intellectual property in the Software (including the Source
Code) and has good and marketable title to the Software (including the Source
Code) free and clear of all liens, claims and encumbrances of any nature
whatsoever (collectively, "Liens"). Licensor's grant of license and rights to
Licensee hereunder does not, and will not infringe any third party's property,
intellectual property or personal rights.
5.TERM.
(a)Subject to Licensee's payment obligations, this Agreement shall commence as
on the date of making payment of the Software by the Licensee to the Licensor,
and shall continue until terminated by either party.
(b)The Licensor retains the right to terminate the license at any time, if the
Licensee is not abiding by any of the terms of the Agreement. The Licensee may
terminate the Agreement at any time at its own discretion by uninstalling the
Software and /or by destroying the said Software (or any copies thereof).
However, the Licensee shall not be entitled to seek any refund of the amount
paid by it to the Licensor, under any circumstances.
(c)Survival. In the event this Agreement is terminated for any reason, the
provisions set forth in Sections 2(a), 2(b), and 2(c) shall survive.
6.INDEMNIFICATION.
The Licensee release the Licensor from, and agree to indemnify, defend and
hold harmless the Licensor (and its officers, directors, employees, agents and
Affiliates) against, any claim, loss, damage, settlement, cost, taxes, expense
or other liability (including, without limitation, attorneys' fees) (each, a
"Claim") arising from or related to: (a) any actual or alleged breach of any
obligations in this Agreement; (b) any refund, adjustment, or return of
Software,(c) any claim for actual or alleged infringement of any Intellectual
Property Rights made by any third party or damages related thereto; or (d)
Taxes.
7.LIMITATION OF LIABILITY.
The Licensor will not be liable for any direct, indirect, incidental, special,
consequential or exemplary damages, including but not limited to, damages for
loss of profits, goodwill, use, data or other intangible losses arising out of
or in connection with the Software, whether in contract, warranty, tort etc. (
including negligence, software liability, any type of civil responsibility or
other theory or otherwise) to the Licensee or any other person for cost of
software, cover, recovery or recoupment of any investment made by the Licensee
or its affiliates in connection with this Agreement, or for any other loss of
profit, revenue, business, or data or punitive or consequential damages
arising out of or relating to this Agreement. Further, the aggregate liability
of the Licensor, arising out of or in connection with this Agreement or the
transactions contemplated hereby will not exceed at any time, or under any
circumstances, the total amounts received by the Licensor from the Licensee in
connection with the particular software giving rise to the claim.
8.FORCE MAJEURE.
The Licensor will not be liable for any delay or failure to perform any of its
obligations under this Agreement by reasons, events or other matters beyond
its reasonable control.
9.RELATIONSHIP OF PARTIES.
The Licensor and Licensee are independent legal entities, and nothing in this
Agreement will be construed to create a partnership, joint venture,
association of persons, agency, franchise, sales representative, or employment
relationship between the parties. The Licensee will have no authority to make
or accept any offers or representations on behalf of the Licensor. The
relationship between the parties is that of Licensor and Licensee only, and
the rights, duties, liabilities of each party shall be governed by this
Agreement.
10.MODIFICATION.
The Licensor may amend any of the terms and conditions contained in this
Agreement at any time and solely at its discretion. Any changes will be
effective upon the posting of such changes on the Portal/ website, and the
Licensee is responsible for reviewing these changes and informing itself of
all applicable changes or notices. The continued use of a software by the
Licensee after posting of any changes by the Licensor, will constitute the
acceptance of such changes or modifications by the Licensee.
11.MISCELLANEOUS.
(a)General Provisions. This Agreement: (i) may be amended only by a writing
signed by each of the parties; (ii) may be executed in several counterparts,
each of which shall be deemed an original but all of which shall constitute
one and the same instrument; (iii) contains the entire agreement of the
parties with respect to the transactions contemplated hereby and supersedes
all prior written and oral agreements, and all contemporaneous oral
agreements, relating to such transactions; (iv) shall be governed by, and
construed and enforced in accordance with, the laws of India; and (v) shall be
binding upon, and inure to the benefit of, the parties and their respective
successors and permitted assigns. Each of the parties hereby irrevocably
submits to the jurisdiction of the Courts at Delhi, India, for the purposes of
any action or proceeding arising out of or relating to this Agreement or the
subject matter hereof and brought by any other party.
(b)Assignment. Except for the purpose of customization as mentioned in clause
2(b)(iv) above, Licensee cannot assign, pledge or otherwise transfer, whether
by operation of law or otherwise, this Agreement, or any of its obligations
hereunder, without the prior written consent of Licensor, which consent shall
not be unreasonably withheld.
(c)Notices. Unless otherwise specifically provided herein, all notices,
consents, requests, demands and other communications required or permitted
hereunder:
(i)shall be in writing;
(ii)shall be sent by messenger, certified or registered mail/email, or
reliable express delivery service, to the appropriate address(es) set forth
below; and
(iii)shall be deemed to have been given on the date of receipt by the
addressee, as evidenced by a receipt executed by the addressee (or a
responsible person in his or her office), the records of the Party delivering
such communication or a notice to the effect that such addressee refused to
claim or accept such communication, if sent by messenger, mail or express
delivery service.
All such communications shall be sent to the following addresses or numbers,
or to such other addresses or numbers as any party may inform the others by
giving five days' prior notice:
If to Webkul Software Pvt. Ltd.:
Webkul Software Pvt. Ltd.
A-67, Sector 63, NOIDA 201301,
Uttar Pradesh, India
If to Licensee:
At the address mentioned by the Licensee
(at the time of placing order of generating Invoice)
(d)Severability. It is the intent of the parties that the provisions of this
Agreement be enforced to the fullest extent permissible under the laws and
public policies of India in which enforcement hereof is sought. In
furtherance of the foregoing, each provision hereof shall be severable from
each other provision, and any provision hereof which is/ becomes unenforceable
shall be subject to the following: (i) if such provision is contrary to or
conflicts with any requirement of any statute, rule or regulation in effect,
then such requirement shall be incorporated into, or substituted for, such
unenforceable provision to the minimum extent necessary to make such provision
enforceable; (ii) the court, agency or arbitrator considering the matter is
hereby authorized to (or, if such court, agency or arbitrator is unwilling or
fails to do so, then the parties shall) amend such provision to the minimum
extent necessary to make such provision enforceable, and the parties hereby
consent to the entry of an order so amending such provision; and (iii) if
any such provision cannot be or is not reformed and made enforceable pursuant
to clause (i) or (ii) above, then such provision shall be ineffective to the
minimum extent necessary to make the remainder of this Agreement enforceable.
Any application of the foregoing provisions to any provision hereof shall not
effect the validity or enforceability of any other provision hereof.
(e)By purchasing the Software, the Licensee acknowledge that it has read this
Agreement, and that it agrees to the content of the Agreement, its terms and
agree to use the Software in compliance with this Agreement.
(f)The Licensor holds the sole copyright of the Software. The Software or any
portion thereof is a copyrightable matter and is liable to be protected by the
applicable laws. Copyright infringement in any manner can lead to prosecution
according to the current law. The Licensor reserves the right to revoke the
license of any user who is not holding any license or is holding an invalid
license.
(g)This Agreement gives the right to use only one copy of the Software on one
domain solely for the own personal or business use of the Licensee, subject to
all the terms and conditions of this Agreement. A separate License has to be
purchased for each new Software installation. Any distribution of the Software
without the written consent of the Licensor (including non-commercial
distribution) is regarded as violation of this Agreement, and will entail
immediate termination of the Agreement and may invite liability, both civil
and criminal, as per applicable laws.
(h)The Licensor reserves the rights to publish a selected list of users/
Licensees of its Software, and no permission of any Licensee is needed in this
regard. The Licensee agrees that the Licensor may, in its sole discretion,
disclose or make available any information provided or submitted by the
Licensee or related to it under this Agreement to any judicial,
quasi-judicial, governmental, regulatory or any other authority as may be
required by the Licensor to co-operate and / or comply with any of their
orders, instructions or directions or to fulfill any requirements under
applicable Laws.
(i)If the Licensee continues to use the Software even after the sending of the
notice by the Licensor for termination, the Licensee agree to accept an
injunction to restrain itself from its further use, and to pay all costs (
including but not limited to reasonable attorney fees) to enforce injunction
or to revoke the License, and any damages suffered by the Licensor because of
the misuse of the Software by the Licensee.
12.ARBITRATION.
If any dispute arises between the Licensor and the Licensee at any time, in
connection with the validity, interpretation, implementation or alleged breach
of any provision of this Agreement, the same shall be referred to a sole
Arbitrator who shall be an independent and neutral third party appointed
exclusively by the Licensor. The Licensee shall not object to the appointment
of the Arbitrator so appointed by the Licensor. The place of arbitration shall
be Delhi, India. The Arbitration & Conciliation Act, 1996 as amended by The
Arbitration & Conciliation (Amendment) Act, 2015, shall govern the
arbitration proceedings. The arbitration proceedings shall be held in the
English language.
This document is an electronic record in terms of Information Technology Act,
2000 and the amended provisions pertaining to electronic records in various
statutes as amended by the Information Technology Act, 2000. This electronic
record is generated by a computer system and does not require any physical or
digital signatures.

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from . import models
from . import wizard
def pre_init_check(cr):
from odoo.service import common
from odoo.exceptions import Warning
version_info = common.exp_version()
server_serie = version_info.get('server_serie')
if server_serie != '11.0':
raise Warning(
'Module support Odoo series 11.0 found {}.'.format(server_serie))

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
##########################################################################
# Author : Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# Copyright(c): 2015-Present Webkul Software Pvt. Ltd.
# All Rights Reserved.
#
#
#
# This program is copyright property of the author mentioned above.
# You can`t redistribute it and/or modify it.
#
#
# You should have received a copy of the License along with this program.
# If not, see <https://store.webkul.com/license.html/>
##########################################################################
{
'name': 'Product Custom Options',
'summary': """
This module adds support of custom option for Sale management.
""",
'description': """
This module adds support of custom option for Sale management.
""",
'author': 'Webkul Software Pvt. Ltd.',
'website': 'http://www.webkul.com',
'license': 'Other proprietary',
'category': 'Sales',
'sequence': '1',
'version': '1.0.0',
'live_test_url': 'http://odoodemo.webkul.com/?module=product_custom_options&version=11.0',
'depends': ['sale_management'],
'data': [
'security/ir.model.access.csv',
'views/custom_options_views.xml',
'views/product_template_views.xml',
'views/sale_views.xml',
'wizard/option_selection_wizard_views.xml'
],
'demo': [
'data/custom_options_demo.xml',
],
'images': ['static/description/Banner.png'],
'application': True,
'pre_init_hook': 'pre_init_check',
'price': 45,
'currency': 'EUR',
}

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- "License URL : <https://store.webkul.com/license.html/>" -->
<odoo>
<data noupdate="1">
<record id="custom_options_product_tmpl_1" model="product.template" context="{'create_product_product': True}">
<field name="name">Bottle</field>
<field name="categ_id" ref="product.product_category_5"/>
<field name="standard_price">8.0</field>
<field name="list_price">10.0</field>
<field name="type">consu</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="default_code">BOTTLE</field>
<field name='weight'>0.300</field>
<field name="image" type="base64" file="product_custom_options/static/img/custom_options_product_1-image.jpg"/>
</record>
<record id="custom_options_product_1" model="product.product">
<field name="default_code">BOTTLE</field>
<field name="product_tmpl_id" ref="custom_options_product_tmpl_1"/>
</record>
<record id="custom_options_1" model="product.custom.options">
<field name="name">Color</field>
<field name="input_type">radio</field>
<field name="prod_tmpl_id" ref="custom_options_product_tmpl_1"/>
</record>
<record id="custom_options_1_value_1" model="product.custom.options.value">
<field name="name">Blue</field>
<field name="price">1</field>
<field name="custom_option_id" ref="custom_options_1"/>
</record>
<record id="custom_options_1_value_2" model="product.custom.options.value">
<field name="name">Red</field>
<field name="price">2</field>
<field name="custom_option_id" ref="custom_options_1"/>
</record>
<record id="custom_options_1_value_3" model="product.custom.options.value">
<field name="name">Green</field>
<field name="price">3</field>
<field name="custom_option_id" ref="custom_options_1"/>
</record>
<record id="custom_options_1_value_4" model="product.custom.options.value">
<field name="name">No Choice</field>
<field name="price">0</field>
<field name="custom_option_id" ref="custom_options_1"/>
</record>
<record id="custom_options_sale_order_1" model="sale.order">
<field name="partner_id" ref="base.res_partner_2"/>
<field name="partner_invoice_id" ref="base.res_partner_2"/>
<field name="partner_shipping_id" ref="base.res_partner_2"/>
<field name="user_id" ref="base.user_demo"/>
<field name="pricelist_id" ref="product.list0"/>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="date_order" eval="(DateTime.today() + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M')"/>
</record>
<record id="custom_options_sale_order_line_1" model="sale.order.line">
<field name="order_id" ref="custom_options_sale_order_1"/>
<field name="name">Bottle</field>
<field name="product_id" ref="custom_options_product_1"/>
<field name="product_uom_qty">3</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="price_unit">100.00</field>
<field name="is_custom_product" eval="True"/>
</record>
<record id="sale_custom_options_1" model="sale.custom.options">
<field name="custom_option_id" ref="custom_options_1"/>
<field name="order_line_id" ref="custom_options_sale_order_line_1"/>
<field name="price">3</field>
<field name="input_data">Green</field>
</record>
<function model="sale.order.line" name="save_option" eval="[[ref('custom_options_sale_order_line_1')]]"/>
</data>
</odoo>

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2015-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from . import custom_options
from . import product_template
from . import sale

View File

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2015-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class ProductCustomOptions(models.Model):
_name = "product.custom.options"
def _get_input_type(self):
return [
('field', 'Text Field'),
('area', 'Text Area'),
('date', 'Date'),
('date_time', 'Date & Time'),
('time', 'Time'),
('radio', 'Radio Button'),
('multiple', 'Multiple Select'),
('checkbox', 'Checkbox'),
('drop_down', 'Dropdown'),
('file', 'File'),
]
name = fields.Char(string="Title", help="Title for the custom option.")
input_type = fields.Selection(_get_input_type,
string="Input Type", help="Input type for the custom option.")
prod_tmpl_id = fields.Many2one(
'product.template', string='Product Template')
price = fields.Float(string="Price", help="Price for the custom option.")
custom_options_value_ids = fields.One2many(
'product.custom.options.value', 'custom_option_id', string="Custom Options Values")
# File related info
allowed_file_extention = fields.Char(string="Allowed File Extention", help="Allowed File Extention.")
image_size_length = fields.Integer(string="Image Length", help="Maximum length allowed for Image.")
image_size_width = fields.Integer(string="Image Width", help="Maximum width allowed for Image.")
class ProductCustomOptionsValue(models.Model):
_name = "product.custom.options.value"
name = fields.Char(string="Title", help="Title for the custom option value.")
price = fields.Float(string="Price", help="Price for the custom option value.")
custom_option_id = fields.Many2one('product.custom.options', string="Custom Option")
class SaleCustomOptions(models.Model):
_name = "sale.custom.options"
custom_option_id = fields.Many2one(
'product.custom.options', string="Custom Option", required=True)
order_line_id = fields.Many2one(
'sale.order.line', string="Order Line", required=True, ondelete='cascade', index=True)
price = fields.Float(string="Price", help="Price for the custom option value.")
input_data = fields.Text(string="Input")
file_data = fields.Binary(string="File Uploaded")
@api.multi
def remove(self):
if self.order_line_id.state in ['cancel','done']:
raise UserError("You can't remove an option when order is Locked or Cancelled.")
orderLineId = self.order_line_id.id
self.unlink()
return {
'name': ("Information"),
'view_mode': 'form',
'view_type': 'form',
'res_model': 'sale.order.line',
'view_id': self.env.ref('product_custom_options.sale_order_line_custom_options_form').id,
'res_id': orderLineId,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
}

View File

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from odoo import api, fields, models
class ProductTemplate(models.Model):
_inherit = "product.template"
custom_option_ids = fields.One2many(
'product.custom.options', 'prod_tmpl_id',
string='Custom Options')

View File

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
is_custom_product = fields.Boolean("Have custom options")
sale_options_ids = fields.One2many(
'sale.custom.options', 'order_line_id',string="Custom Options")
sale_options_price = fields.Float(string="Price", help="Price for the custom option.", compute='_compute_options_price')
@api.onchange('product_id')
def _onchange_product_id(self):
if self.product_id.custom_option_ids:
self.is_custom_product = True
else:
self.is_custom_product = False
@api.multi
def _compute_options_price(self):
for line in self:
line.sale_options_price = sum(line.sale_options_ids.mapped('price'))
@api.multi
def configure_product(self):
productObj = self.product_id
if productObj.custom_option_ids:
return {
'name': ("Information"),
'view_mode': 'form',
'view_type': 'form',
'res_model': 'sale.order.line',
'view_id': self.env.ref('product_custom_options.sale_order_line_custom_options_form').id,
'res_id': self.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
}
@api.multi
def add_option(self):
productObj = self.product_id
if productObj.custom_option_ids:
wizardObj = self.env['sale.option.selection.wizard'].create({'order_line_id': self.id})
return {
'name': ("Information"),
'view_mode': 'form',
'view_type': 'form',
'src_model': 'sale.order.line',
'res_model': 'sale.option.selection.wizard',
'view_id': self.env.ref('product_custom_options.sale_option_selection_wizard_form').id,
'res_id': wizardObj.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
}
@api.multi
def save_option(self):
price_unit = 0.00
product = self.product_id.with_context(
lang=self.order_id.partner_id.lang,
partner=self.order_id.partner_id.id,
quantity=self.product_uom_qty,
date=self.order_id.date_order,
pricelist=self.order_id.pricelist_id.id,
uom=self.product_uom.id
)
name = product.name_get()[0][1]
if product.description_sale:
name += '\n' + product.description_sale
if self.order_id.pricelist_id and self.order_id.partner_id:
price_unit = self.env['account.tax']._fix_tax_included_price_company(self._get_display_price(product), product.taxes_id, self.tax_id, self.company_id)
if self.sale_options_ids:
from_currency = self.order_id.company_id.currency_id
tmp = from_currency.compute(self.sale_options_price, self.order_id.pricelist_id.currency_id)
price_unit += tmp
description = self.sale_options_ids.mapped(
lambda option: option.custom_option_id.name+': '+option.input_data)
if description:
name +='\n'+'\n'.join(description)
self.name = name
self.price_unit = price_unit

View File

@ -0,0 +1,14 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_product_custom_options,access_product_custom_options,model_product_custom_options,,1,0,0,0
access_product_custom_options_value,access_product_custom_options_value,model_product_custom_options_value,,1,0,0,0
access_sale_custom_options,access_sale_custom_options,model_sale_custom_options,,1,1,1,1
access_product_custom_options_salesman,access_product_custom_options,model_product_custom_options,sales_team.group_sale_salesman,1,1,1,0
access_product_custom_options_value_salesman,access_product_custom_options_value,model_product_custom_options_value,sales_team.group_sale_salesman,1,1,1,0
access_sale_custom_options_salesman,access_sale_custom_options,model_sale_custom_options,sales_team.group_sale_salesman,1,1,1,1
access_product_custom_options_manager,access_product_custom_options,model_product_custom_options,sales_team.group_sale_manager,1,1,1,1
access_product_custom_options_value_manager,access_product_custom_options_value,model_product_custom_options_value,sales_team.group_sale_manager,1,1,1,1
access_sale_custom_options_manager,access_sale_custom_options,model_sale_custom_options,sales_team.group_sale_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_product_custom_options access_product_custom_options model_product_custom_options 1 0 0 0
3 access_product_custom_options_value access_product_custom_options_value model_product_custom_options_value 1 0 0 0
4 access_sale_custom_options access_sale_custom_options model_sale_custom_options 1 1 1 1
5 access_product_custom_options_salesman access_product_custom_options model_product_custom_options sales_team.group_sale_salesman 1 1 1 0
6 access_product_custom_options_value_salesman access_product_custom_options_value model_product_custom_options_value sales_team.group_sale_salesman 1 1 1 0
7 access_sale_custom_options_salesman access_sale_custom_options model_sale_custom_options sales_team.group_sale_salesman 1 1 1 1
8 access_product_custom_options_manager access_product_custom_options model_product_custom_options sales_team.group_sale_manager 1 1 1 1
9 access_product_custom_options_value_manager access_product_custom_options_value model_product_custom_options_value sales_team.group_sale_manager 1 1 1 1
10 access_sale_custom_options_manager access_sale_custom_options model_sale_custom_options sales_team.group_sale_manager 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,161 @@
<!-- Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- License URL: https://store.webkul.com/license.html/ -->
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Product Custom Options</h2>
<h3 class="oe_slogan">Custom options are an easy way to offer a selection of product variations that do not rely on attributes.The advantage is that you're not needed to manage inventory based on it's variation. Custom options are a good solution if your inventory needs are simple.</h3>
<div class="oe_span12">
<div class="panel panel-primary">
<div class="panel-body">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b> Features </b>
</div>
<ul class="list-unstyled">
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Product variations that do not rely on attributes.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Single inventory of the product, unlike Variants.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Admin can easily define custom options from product view.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Many types of options are supported like Text, Date, Radio, Dropdown, Checkboxes & file etc.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Multiple input selection types are also supported.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>You can also provide a custom option to upload a file.</li>
<li style="font-size: 20px;"><i class="fa fa-check text-primary"></i>Configure button will be visible on order line for the products having custom options.</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Product Custom options tab</b>
</div>
<p>User can easily add multiple custom options in product template.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_001.png" target="_blank">
<img src="screenshot/screenshot_001.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Custom options configuration</b>
</div>
<p>User can select and add custom options as per the choice. Price for the options can also be set.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_002.png" target="_blank">
<img src="screenshot/screenshot_002.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Custom options in Sale Order</b>
</div>
<p>Button will be visible to the order line containing a product having custom options configured.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_003.png" target="_blank">
<img src="screenshot/screenshot_003.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Custom options selection at order line.</b>
</div>
<p>After clicking configure button a popup window will opened containing button 'Add Option' & the custom options info.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_004.png" target="_blank">
<img src="screenshot/screenshot_004.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Custom options info with price.</b>
</div>
<p>Once the options are selected & added to the product then it'll show selected options info along with the total price of the custom options.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_005.png" target="_blank">
<img src="screenshot/screenshot_005.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<div class="alert alert-info">
<i class="fa fa-arrow-circle-o-right"></i>
<b>Selected options info in order line description.</b>
</div>
<p>Once the options are selected & added to the product then it'll show selected options info along with the total price of the custom options.</p>
<div class="oe_demo oe_picture oe_screenshot" style="max-height: 100%;">
<a href="screenshot/screenshot_006.png" target="_blank">
<img src="screenshot/screenshot_006.png" alt="Online Demo">
</a>
</div>
</div>
</div>
</section>
<section class="oe_container lead">
<div class="oe_row">
<div class="oe_span12">
<h2 class="oe_slogan">Complimentary Support</h2>
<p>
You will get 90 days free support for any doubt, queries, and bug fixing (excluding data recovery) or any type of issue related to this module.
</p>
</div>
</div>
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan text-center">Help and Support</h2>
</div>
<br>
<div class="oe_slogan oe_spaced">
<span><a data-toggle="tooltip" data-placement="bottom" title="Get Instant Help !" target="_blank" href="https://webkul.uvdesk.com/en/customer/create-ticket/"> <i class="fa fa-life-ring"></i> Help </a></span>
<span><a data-toggle="tooltip" data-placement="bottom" title="Get Instant Support!" target="_blank" href="https://webkul.uvdesk.com/en/customer/create-ticket/"><i class="fa fa-ticket"></i> Support</a></span>
<span><a data-toggle="tooltip" data-placement="bottom" title="Request Features now !" target="_blank" href="https://webkul.uvdesk.com/en/customer/create-ticket/"><i class="fa fa-check-circle"></i> Request new Features </a></span>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_span12">
<!-- Matomo Image Tracker-->
<img src="http://odooimg.webkul.com/analytics/piwik/piwik.php?idsite=3&rec=1&action_name=PRODUCT-CUSTOM-OPTIONS&url=https://apps.openerp.com/apps/modules/11.0/product_custom_options&uid=product_custom_options" style="border:0" alt="" />
<!-- End Matomo -->
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2015-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- License URL: https://store.webkul.com/license.html/ -->
<odoo>
<record id="product_custom_options_view_form" model="ir.ui.view">
<field name="name">product.custom.options.form</field>
<field name="model">product.custom.options</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name" />
</group>
<group>
<field name="input_type" />
<field name="price" attrs="{'invisible':[('input_type','in',('radio','checkbox','drop_down','multiple'))]}"/>
</group>
</group>
<group name="File Information" string="File Information" attrs="{'invisible':[('input_type','!=','file')]}">
<field name="allowed_file_extention" />
<field name="image_size_length" />
<field name="image_size_width" />
</group>
<group name="Option Values" string="Option Values"
attrs="{'invisible':[('input_type','not in',('radio','checkbox','drop_down','multiple'))]}">
<field name="custom_options_value_ids" nolabel="1">
<tree editable="bottom">
<field name='name'/>
<field name='price'/>
</tree>
</field>
</group>
</sheet>
</form>
</field>
</record>
<record id="product_custom_options_view_tree" model="ir.ui.view">
<field name="name">product.custom.options.tree</field>
<field name="model">product.custom.options</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="input_type"/>
</tree>
</field>
</record>
<record id="sale_custom_options_view_form" model="ir.ui.view">
<field name="name">sale.custom.options.form</field>
<field name="model">sale.custom.options</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="custom_option_id" />
</group>
<group>
<field name="input_data" />
<field name="file_data" />
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="sale_custom_options_view_tree" model="ir.ui.view">
<field name="name">sale.custom.options.tree</field>
<field name="model">sale.custom.options</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<tree>
<field name="custom_option_id"/>
<field name="input_data"/>
<field name="price"/>
<button name="remove" type="object" class="fa fa-trash-o btn-link"/>
</tree>
</field>
</record>
</odoo>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2015-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- "License URL : <https://store.webkul.com/license.html/>" -->
<odoo>
<record id="product_template_form_view_inherit" model="ir.ui.view">
<field name="name">product.template.common.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<notebook position="inside">
<page string="Custom Options" name="custom_options">
<field name='custom_option_ids' />
</page>
</notebook>
</field>
</record>
</odoo>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- "License URL : <https://store.webkul.com/license.html/>" -->
<odoo>
<record id="view_order_form_inherit_custom_options" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='order_line']/tree/field[@name='product_id']" position="after">
<field name="is_custom_product" invisible="1"/>
<button name="configure_product" string="Configure"
type="object" class="btn-primary" attrs="{'invisible':['|',('is_custom_product','=',False),('state', 'not in', ['draft', 'sent','sale'])]}"/>
<button name="configure_product" string="View"
type="object" class="btn-primary" attrs="{'invisible':['|',('is_custom_product','=',False),('state', 'not in', ['done','cancel'])]}"/>
</xpath>
<xpath expr="//field[@name='order_line']/form//field[@name='product_id']" position="after">
<field name="is_custom_product" invisible="1"/>
<br/>
</xpath>
<xpath expr="//field[@name='order_line']/form/group" position="before">
<header>
<button name="configure_product" string="Configure"
type="object" class="btn-primary" attrs="{'invisible':[('is_custom_product','=',False)]}"/>
</header>
</xpath>
</field>
</record>
<record id="sale_order_line_custom_options_form" model="ir.ui.view">
<field name="name">sale.order.line.custom.options.form</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<form>
<field name="state" invisible="1" />
<field name="qty_invoiced" invisible="1" />
<header>
<button name="add_option" string="Add Option" type="object" class="btn-primary" attrs="{'invisible':['|',('state','in',['cancel','done']),('qty_invoiced', '&gt;', 0)]}"/>
</header>
<group>
<field name="sale_options_price" readonly="1"/>
</group>
<field name="sale_options_ids" readonly="1"/>
<footer>
<button name="save_option" string="Save" type="object" class="btn-primary" attrs="{'invisible':[('state','in',['cancel','done'])]}" />
<button name="cancel" special="cancel" string="Close" type="object" />
</footer>
</form>
</field>
</record>
</odoo>

View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
from . import option_selection_wizard

View File

@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>)
# See LICENSE file for full copyright and licensing details.
# License URL : <https://store.webkul.com/license.html/>
##############################################################################
import base64
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.tools.mimetypes import guess_mimetype
class SaleOptionSelectionWizard(models.TransientModel):
_name = "sale.option.selection.wizard"
def _get_input_type(self):
return [
('field', 'Text Field'),
('area', 'Text Area'),
('date', 'Date'),
('date_time', 'Date & Time'),
('time', 'Time'),
('radio', 'Radio Button'),
('multiple', 'Multiple Select'),
('checkbox', 'Checkbox'),
('drop_down', 'Dropdown'),
('file', 'File'),
]
custom_option_id = fields.Many2one(
'product.custom.options', string="Custom Option")
order_line_id = fields.Many2one(
'sale.order.line', string="Order Line")
prod_tmpl_id = fields.Many2one(
'product.template',related="order_line_id.product_id.product_tmpl_id", string='Product Template')
input_type = fields.Selection(_get_input_type, related="custom_option_id.input_type",
string="Input Type", help="Input type for the custom option.")
text_input = fields.Char(string="Input")
area_input = fields.Text(string="Input")
date_input = fields.Date(string="Input")
datetime_input = fields.Datetime(string="Input")
radio_input = fields.Many2one("product.custom.options.value", string="Input")
dropdown_input = fields.Many2one("product.custom.options.value", string="Input")
multi_input = fields.Many2many("product.custom.options.value", string="Input")
checkbox_input = fields.Many2many("product.custom.options.value", string="Input")
file_input = fields.Binary(string="Input")
price = fields.Float(string="Price", help="Price for the custom option.")
@api.multi
def add_option(self):
optionObj = self.custom_option_id
optionType = self.input_type
price = 0.00
inputData = ''
if optionType == 'field':
inputData = str(self.text_input)
price = optionObj.price
elif optionType == 'area':
inputData = str(self.area_input)
price = optionObj.price
elif optionType == 'date':
inputData = str(self.date_input)
price = optionObj.price
elif optionType == 'date_time':
inputData = str(self.datetime_input)
price = optionObj.price
elif optionType == 'radio':
inputData = self.radio_input.name
price = self.radio_input.price
elif optionType == 'drop_down':
inputData = self.dropdown_input.name
price = self.dropdown_input.price
elif optionType == 'multiple':
inputData = ', '.join(self.multi_input.mapped('name'))
price = sum(self.multi_input.mapped('price'))
elif optionType == 'checkbox':
inputData = ', '.join(self.checkbox_input.mapped('name'))
price = sum(self.checkbox_input.mapped('price'))
elif optionType == 'file':
inputData = "File Input"
price = optionObj.price
mimetype = guess_mimetype(base64.b64decode(self.file_input))
allowed_file_extention = optionObj.allowed_file_extention
if mimetype not in allowed_file_extention.split(','):
raise UserError("File is not valid...!!! \nOnly files with extension {} are allowed.".format(allowed_file_extention))
description_ids = self.order_line_id.sale_options_ids.filtered(
lambda r: r.custom_option_id == optionObj)
if description_ids:
description_id = description_ids[0]
description_id.update({
'input_data': inputData,
'file_data': self.file_input,
'price': price,
})
else:
newId = self.order_line_id.sale_options_ids.new({
'custom_option_id': optionObj.id,
'order_line_id': self.order_line_id.id,
'input_data': inputData,
'price': price,
'file_data': self.file_input,
})
self.order_line_id.sale_options_ids += newId
return {
'name': ("Information"),
'view_mode': 'form',
'view_type': 'form',
'res_model': 'sale.order.line',
'view_id': self.env.ref('product_custom_options.sale_order_line_custom_options_form').id,
'res_id': self.order_line_id.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
}
@api.multi
def cancel_action(self):
return {
'name': ("Information"),
'view_mode': 'form',
'view_type': 'form',
'res_model': 'sale.order.line',
'view_id': self.env.ref('product_custom_options.sale_order_line_custom_options_form').id,
'res_id': self.order_line_id.id,
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2017-Present Webkul Software Pvt. Ltd. (<https://webkul.com/>) -->
<!-- See LICENSE file for full copyright and licensing details. -->
<!-- "License URL : <https://store.webkul.com/license.html/>" -->
<odoo>
<record id="sale_option_selection_wizard_form" model="ir.ui.view">
<field name="name">sale.option.selection.wizard.form</field>
<field name="model">sale.option.selection.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="prod_tmpl_id" readonly="1" invisible="1"/>
<field name="input_type" readonly="1" invisible="1"/>
<field name="custom_option_id" domain="[('prod_tmpl_id', '=', prod_tmpl_id)]"/>
<field name="text_input" attrs="{'invisible':[('input_type','!=','field')],'on_change': 'add_option'}"/>
<field name="area_input" attrs="{'invisible':[('input_type','!=','area')]}"/>
<field name="date_input" attrs="{'invisible':[('input_type','!=','date')]}"/>
<field name="datetime_input" attrs="{'invisible':[('input_type','!=','date_time')]}"/>
<field name="file_input" attrs="{'invisible':[('input_type','!=','file')]}"/>
<field name="radio_input" widget="radio"
attrs="{'invisible':[('input_type','!=','radio')]}"
domain="[('custom_option_id', '=', custom_option_id)]"/>
<field name="dropdown_input"
attrs="{'invisible':[('input_type','!=','drop_down')]}"
domain="[('custom_option_id', '=', custom_option_id)]"/>
<field name="multi_input" widget="many2many_tags"
attrs="{'invisible':[('input_type','!=','multiple')]}"
domain="[('custom_option_id', '=', custom_option_id)]"/>
<field name="checkbox_input"
attrs="{'invisible':[('input_type','!=','checkbox')]}"
domain="[('custom_option_id', '=', custom_option_id)]"/>
</group>
<group>
</group>
</group>
<footer>
<button name="add_option" string="Add Option" type="object" class="btn-primary" />
<button name="cancel_action" string="Cancel" type="object" />
</footer>
</form>
</field>
</record>
</odoo>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models
from . import controllers

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
{
'name': "Website Product Hover",
'summary': """
On website effects for product zoom will be shown as per settings on backend of module.
It can be selected at product level so that particluar product have that effect.
""",
'description': """
On website effects for product zoom will be shown as per settings on backend of module.
It can be selected at product level so that particluar product have that effect.
""",
'license':'OPL-1',
'author': "DRC Systems India Pvt. Ltd.",
'website': "http://www.drcsystems.com",
'category': 'website',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['website', 'product'],
# always loaded
'data': [
"views/templates.xml",
"views/product.xml",
"views/wbsite_config.xml"
],
'images' :['static/description/inner.gif'],
'price' : 50,
'currency':'EUR',
}

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import main

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
class ImageHover(http.Controller):
@http.route('/image/hover', type='json', auth='public', website=True)
def return_image_hover_effect(self, pid):
try:
product = request.env['product.template'].sudo().browse(int(pid))
if product and product.hover:
return product.hover
hover = request.env['res.config.settings'].sudo().get_values()
return hover['hover']
except:
return 'use default effect'

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import website_config
from . import product

View File

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from odoo import fields, models
class ProductTemplate(models.Model):
_inherit = "product.template"
hover = fields.Selection([('basic', 'Basic Zoom'),
('tints', 'Tints'),
('inner', 'Ineer Zoom'),
('lens', 'Lens Zoom'),
('fade_in_out', 'Fade In/Fade Out'),
('easing', 'Easing'),
('mousewheel', 'Mousewheel Zoom'),
('horizontal', 'Change Zoom window horizontal'),
('vertical', 'Change Zoom window vertical'),
], string="Hover Effect")

View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
class WebsiteConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
hover = fields.Selection([('basic', 'Basic Zoom'),
('tints', 'Tints'),
('inner', 'Ineer Zoom'),
('lens', 'Lens Zoom'),
('fade_in_out', 'Fade In/Fade Out'),
('easing', 'Easing'),
('mousewheel', 'Mousewheel Zoom'),
('horizontal', 'Change Zoom window horizontal'),
('vertical', 'Change Zoom window vertical'),
], default='basic', string="Hover Effect")
@api.model
def get_values(self):
res = super(WebsiteConfigSettings, self).get_values()
get_param = self.env['ir.config_parameter'].sudo().get_param
res.update(
hover=get_param('hover', default=''),
)
return res
def set_values(self):
super(WebsiteConfigSettings, self).set_values()
set_param = self.env['ir.config_parameter'].sudo().set_param
set_param('hover', (self.hover or '').strip())

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Some files were not shown because too many files have changed in this diff Show More