From 8bc734def0d1c824faa46513000b6a774607a993 Mon Sep 17 00:00:00 2001 From: Divya Modi Date: Fri, 31 Aug 2018 19:26:08 +0530 Subject: [PATCH 01/41] [WIP]partial commit for migration of apps-store --- website_apps_store/README.rst | 57 +++++ website_apps_store/__init__.py | 2 + website_apps_store/__manifest__.py | 23 ++ website_apps_store/controllers/__init__.py | 1 + website_apps_store/controllers/main.py | 200 ++++++++++++++++ website_apps_store/models/__init__.py | 1 + website_apps_store/models/product.py | 28 +++ website_apps_store/static/src/css/style.css | 17 ++ .../static/src/js/website_apps_store_tour.js | 102 +++++++++ .../static/src/js/website_sale.js | 170 ++++++++++++++ website_apps_store/tests/__init__.py | 4 + .../tests/test_tour_website_apps_store.py | 60 +++++ .../tests/test_website_apps_store.py | 65 ++++++ website_apps_store/views/assets.xml | 13 ++ website_apps_store/views/templates.xml | 214 ++++++++++++++++++ 15 files changed, 957 insertions(+) create mode 100644 website_apps_store/README.rst create mode 100644 website_apps_store/__init__.py create mode 100644 website_apps_store/__manifest__.py create mode 100644 website_apps_store/controllers/__init__.py create mode 100644 website_apps_store/controllers/main.py create mode 100644 website_apps_store/models/__init__.py create mode 100644 website_apps_store/models/product.py create mode 100644 website_apps_store/static/src/css/style.css create mode 100644 website_apps_store/static/src/js/website_apps_store_tour.js create mode 100644 website_apps_store/static/src/js/website_sale.js create mode 100644 website_apps_store/tests/__init__.py create mode 100644 website_apps_store/tests/test_tour_website_apps_store.py create mode 100644 website_apps_store/tests/test_website_apps_store.py create mode 100644 website_apps_store/views/assets.xml create mode 100644 website_apps_store/views/templates.xml diff --git a/website_apps_store/README.rst b/website_apps_store/README.rst new file mode 100644 index 00000000..2065229e --- /dev/null +++ b/website_apps_store/README.rst @@ -0,0 +1,57 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +================== +Website Apps Store +================== + +Providing facility for displaying the module specific information in a standard Odoo +e-commerce website (front-end) and download the zip file of the selected product. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/249/10.0 + +Known issues / Roadmap +====================== + +* Creation of an error queue if the exception occurs while generating zip file of the product + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Ruchir Shukla +* Eric Caudal + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/website_apps_store/__init__.py b/website_apps_store/__init__.py new file mode 100644 index 00000000..91c5580f --- /dev/null +++ b/website_apps_store/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models diff --git a/website_apps_store/__manifest__.py b/website_apps_store/__manifest__.py new file mode 100644 index 00000000..b4ef1219 --- /dev/null +++ b/website_apps_store/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2018 BizzAppDev +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Website Apps Store", + "version": "11.0.1.0.0", + 'author': 'Odoo Community Association (OCA), BizzAppDev', + "website": "https://github.com/OCA/apps-store", + "license": "AGPL-3", + "category": "Sales", + "depends": [ + 'website_sale', + 'apps_download', + 'apps_product_creator', + ], + "summary": "Website Apps Store", + "data": [ + 'views/assets.xml', + 'views/templates.xml', + ], + 'installable': True, + 'auto_install': False, + 'application': False +} diff --git a/website_apps_store/controllers/__init__.py b/website_apps_store/controllers/__init__.py new file mode 100644 index 00000000..12a7e529 --- /dev/null +++ b/website_apps_store/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/website_apps_store/controllers/main.py b/website_apps_store/controllers/main.py new file mode 100644 index 00000000..5ea68e7e --- /dev/null +++ b/website_apps_store/controllers/main.py @@ -0,0 +1,200 @@ +# Copyright 2017-2018 BizzAppDev +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging +import base64 + +from odoo import http +from odoo.http import request +from odoo.addons.http_routing.models.ir_http import slug +from odoo.addons.website.controllers.main import QueryURL +from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute + +_logger = logging.getLogger(__name__) + +PPG = 20 # Products Per Page +PPR = 4 # Products Per Row + + +class WebsiteSaleCustom(WebsiteSale): + + def _get_search_domain(self, search, category, attrib_values): + domain = request.website.sale_product_domain() + if search: + for srch in search.split(" "): + domain += [ + '|', '|', '|', '|', '|', '|', '|', ('name', 'ilike', srch), + ('description', 'ilike', srch), + ('description_sale', 'ilike', srch), + ('product_variant_ids.default_code', 'ilike', srch), + ('product_variant_ids.attribute_value_ids.name', + 'ilike', srch), + ('product_variant_ids.app_description_rst_html', + 'ilike', srch), + ('product_variant_ids.app_author_ids.name', 'ilike', srch), + ('product_variant_ids.app_summary', 'ilike', srch)] + if category: + domain += [('public_categ_ids', 'child_of', int(category))] + + if attrib_values: + attrib = None + ids = [] + for value in attrib_values: + if not attrib: + attrib = value[0] + ids.append(value[1]) + elif value[0] == attrib: + ids.append(value[1]) + else: + domain += [('attribute_line_ids.value_ids', 'in', ids)] + attrib = value[0] + ids = [value[1]] + if attrib: + domain += [('attribute_line_ids.value_ids', 'in', ids)] + + return domain + + @http.route([ + '/shop', + '/shop/page/', + '/shop/category/', + '/shop/category/\ + /page/' + ], type='http', auth="public", website=True) + def shop(self, page=0, category=None, search='', ppg=False, **post): + res = super(WebsiteSaleCustom, self).shop( + page=page, category=category, search=search, ppg=ppg, **post) + + if ppg: + try: + ppg = int(ppg) + except ValueError: + ppg = PPG + post["ppg"] = ppg + else: + ppg = PPG + + attrib_list = request.httprequest.args.getlist('attrib') + attrib_values = [ + [int(x) for x in v.split("-")] for v in attrib_list if v] + attributes_ids = {v[0] for v in attrib_values} + attrib_set = {v[1] for v in attrib_values} + domain = self._get_search_domain(search, category, attrib_values) + + keep = QueryURL('/shop', category=category and int(category), + search=search, attrib=attrib_list, + order=post.get('order'), + version=post.get('version'), author=post.get('author')) + if post.get('version'): + domain += [('product_variant_ids.attribute_value_ids.id', + '=', post.get('version'))] + if post.get('author'): + domain += [('product_variant_ids.app_author_ids.id', + '=', post.get('author'))] + + url = "/shop" + if category: + category = request.env['product.public.category'].browse( + int(category)) + url = "/shop/category/%s" % slug(category) + + attribute_id = request.env.ref( + 'apps_product_creator.attribute_odoo_version') + category_all = request.env['product.public.category'].search([]) + versions = request.env['product.attribute.value'].search([ + ('attribute_id', '=', attribute_id.id)]) + authors = request.env['odoo.author'].search([]) + Product = request.env['product.template'] + + product_count = Product.search_count(domain) + pager = request.website.pager(url=url, total=product_count, + page=page, step=ppg, + scope=7, url_args=post) + products = Product.search(domain, limit=ppg, offset=pager['offset'], + order=self._get_search_order(post)) + + ProductAttribute = request.env['product.attribute'] + if products: + # get all products without limit + selected_products = Product.search(domain, limit=False) + attributes = ProductAttribute.search( + [('attribute_line_ids.product_tmpl_id', 'in', + selected_products.ids)]) + else: + attributes = ProductAttribute.browse(attributes_ids) + + res.qcontext.update({ + 'search': search, + 'category': category, + 'attrib_values': attrib_values, + 'attrib_set': attrib_set, + 'pager': pager, + 'products': products, + 'search_count': product_count, # common for all searchbox + 'bins': TableCompute().process(products, ppg), + 'category_all': category_all, + 'versions': versions, + 'authors': authors, + 'version': post.get('version'), + 'author': post.get('author'), + 'attributes': attributes, + 'keep': keep, + }) + return res + + @http.route(['/shop/change_attribute_version'], type='json', + auth="public", website=True) + def change_product_attribute_version(self, **kwargs): + product_id = kwargs.get('product_id', False) + product = request.env['product.product'].sudo().browse(product_id) + vals = { + 'name_product': product.name, + 'technical_name': + product.odoo_module_version_id.module_id.technical_name, + 'license': product.app_license_id.name, + 'license_url': product.app_license_id.website, + 'author': ', '.join( + author.name for author in product.app_author_ids), + 'website': product.app_website, + 'repository': product.app_github_url, + 'rst_html': product.app_description_rst_html, + 'app_summary': product.app_summary, + } + return vals + + @http.route('/shop/cart/download_source', type='json', + auth="public", website=True) + def download_source_product(self, **kwargs): + product_id = kwargs.get('product_id', False) + tmpl_id = kwargs.get('product_template_id', False) + product = request.env['product.product'].sudo().browse(product_id) + if not product: + product_tmpl = request.env['product.template'].sudo().browse( + tmpl_id) + product = product_tmpl.get_version_info() + return product.id + + @http.route( + '/shop/download_product_zip/', + type='http', auth="public", website=True) + def download_product_zip(self, product, **kwargs): + attachment = request.env['ir.attachment'].sudo().search([ + ('res_id', '=', product.id), + ('res_model', '=', product._name), + ], limit=1) + if not attachment: + product.sudo().generate_zip_file() + attachment = request.env['ir.attachment'].sudo().search([ + ('res_id', '=', product.id), + ('res_model', '=', product._name), + ], limit=1) + + if attachment: + filecontent = base64.b64decode(attachment.datas) + disposition = 'attachment; filename=%s' % attachment.datas_fname + return request.make_response( + filecontent, + [('Content-Type', 'application/zip, application/octet-stream'), + ('Content-Length', len(filecontent)), + ('Content-Disposition', disposition)]) + return False diff --git a/website_apps_store/models/__init__.py b/website_apps_store/models/__init__.py new file mode 100644 index 00000000..9649db77 --- /dev/null +++ b/website_apps_store/models/__init__.py @@ -0,0 +1 @@ +from . import product diff --git a/website_apps_store/models/product.py b/website_apps_store/models/product.py new file mode 100644 index 00000000..2187ca63 --- /dev/null +++ b/website_apps_store/models/product.py @@ -0,0 +1,28 @@ +# Copyright (C) 2017-Today: Odoo Community Association (OCA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + def get_author_details(self): + author_ids = [] + for variant in self.product_variant_ids: + for author in variant.app_author_ids: + if author not in author_ids: + author_ids.append(author) + return author_ids + + def get_version_info(self): + versions = [] + for attr in self.attribute_line_ids: + for value in attr.value_ids: + versions.append(float(value.name)) + version = max([x for x in versions]) + product = self.env['product.product'].sudo().search([ + ('attribute_value_ids.name', 'ilike', str(version)), + ('product_tmpl_id', '=', self.id), + ]) + return product diff --git a/website_apps_store/static/src/css/style.css b/website_apps_store/static/src/css/style.css new file mode 100644 index 00000000..a44a5fc0 --- /dev/null +++ b/website_apps_store/static/src/css/style.css @@ -0,0 +1,17 @@ +.padd_0{ + padding: 0; +} +.zip_button{ + margin-top: 8px; + margin-bottom: 8px; + border: 1px solid #2976b6; + padding: 10px; + border-radius: 7px; + text-align: center; + font-weight: 600; + color: black; + background-color: #337ab4; +} +.font_12{ + font-size: 12px; +} diff --git a/website_apps_store/static/src/js/website_apps_store_tour.js b/website_apps_store/static/src/js/website_apps_store_tour.js new file mode 100644 index 00000000..868b77ae --- /dev/null +++ b/website_apps_store/static/src/js/website_apps_store_tour.js @@ -0,0 +1,102 @@ +odoo.define('website_apps_store.tour_custom', function (require) { +'use strict'; + +var Tour = require("web_tour.tour"); +var base = require("web_editor.base"); + + Tour.register('download_zip', { + name: "Download Zip File", + url: '/shop', + test: true, + wait_for: base.ready() + },[ + { + content: "Shop", + trigger: ".oe_product_cart a:contains('Odoo Module 1')" + }, + { + content: "Select Version", + trigger: "input[type=radio]", + run: function(){ + $('input[type=radio]:last').attr("checked", "checked"); + } + }, + { + content: "Download", + trigger: "button:contains(Download)" + } + ] + ); + + Tour.register('select_version_search', { + name: "Select Version", + url: '/shop', + test: true, + wait_for: base.ready() + },[ + { + content: "Shop", + trigger: ".dropdown_version_by a.dropdown-toggle" + }, + { + content: "Select Version", + trigger: ".dropdown_version_by .dropdown-menu a:contains('10.0')", + }, + ] + ); + + Tour.register('select_author_search', { + name: "Select Author", + url: '/shop', + test: true, + wait_for: base.ready() + },[ + { + content: "Shop", + trigger: ".dropdown_author_by a.dropdown-toggle" + }, + { + content: "Select Author", + trigger: ".dropdown_author_by .dropdown-menu a:first", + }, + ] + ); + + Tour.register('select_category_search', { + name: "Select Category", + url: '/shop', + test: true, + wait_for: base.ready() + },[ + { + content: "Shop", + trigger: ".dropdown_category_by a.dropdown-toggle" + }, + { + content: "Select Category", + trigger: ".dropdown_category_by .dropdown-menu a:contains('Category1')", + }, + ] + ); + + Tour.register('module_search', { + name: "Select Product(Module)", + url: '/shop', + test: true, + wait_for: base.ready() + },[ + { + content: "Shop", + trigger: ".search-query", + run: function(){ + $('.search-query').attr('value', 'Test'); + } + }, + { + content: "Search Button", + trigger: ".oe_search_button", + }, + ] + ); + +}); diff --git a/website_apps_store/static/src/js/website_sale.js b/website_apps_store/static/src/js/website_sale.js new file mode 100644 index 00000000..c23f0459 --- /dev/null +++ b/website_apps_store/static/src/js/website_sale.js @@ -0,0 +1,170 @@ +/** +* Copyright 2018 BizzAppDev +* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +**/ + +odoo.define('website_apps_store.website_sale', function (require) { + 'use strict'; + + require('web.dom_ready'); + var base = require("web_editor.base"); + var ajax = require('web.ajax'); + var utils = require('web.utils'); + var core = require('web.core'); + var config = require('web.config'); + require("website.content.zoomodoo"); + var _t = core._t; + + $('.oe_website_sale').each(function () { + var oe_website_sale = this; + var $product_global; + + function price_to_str(price) { + var l10n = _t.database.parameters; + var precision = 2; + + if ($(".decimal_precision").length) { + precision = parseInt($(".decimal_precision").last().data('precision')); + } + var formatted = _.str.sprintf('%.' + precision + 'f', price).split('.'); + formatted[0] = utils.insert_thousand_seps(formatted[0]); + return formatted.join(l10n.decimal_point); + } + + function update_product_image(event_source, product_id) { + var $img; + if ($('#o-carousel-product').length) { + $img = $(event_source).closest('tr.js_product, .oe_website_sale').find('img.js_variant_img'); + $img.attr("src", "/web/image/product.product/" + product_id + "/image"); + $img.parent().attr('data-oe-model', 'product.product').attr('data-oe-id', product_id) + .data('oe-model', 'product.product').data('oe-id', product_id); + + var $thumbnail = $(event_source).closest('tr.js_product, .oe_website_sale').find('img.js_variant_img_small'); + if ($thumbnail.length !== 0) { // if only one, thumbnails are not displayed + $thumbnail.attr("src", "/web/image/product.product/" + product_id + "/image/90x90"); + $('.carousel').carousel(0); + } + } + else { + $img = $(event_source).closest('tr.js_product, .oe_website_sale').find('span[data-oe-model^="product."][data-oe-type="image"] img:first, img.product_detail_img'); + $img.attr("src", "/web/image/product.product/" + product_id + "/image"); + $img.parent().attr('data-oe-model', 'product.product').attr('data-oe-id', product_id) + .data('oe-model', 'product.product').data('oe-id', product_id); + } + // reset zooming constructs + $img.filter('[data-zoom-image]').attr('data-zoom-image', $img.attr('src')); + if ($img.data('zoomOdoo') !== undefined) { + $img.data('zoomOdoo').isReady = false; + } + } + + $(oe_website_sale).on('change', 'input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]', function (ev) { + var $ul = $(ev.target).closest('.js_add_cart_variants'); + var $parent = $ul.closest('.js_product'); + var $product_id = $parent.find('.product_id').first(); + var $price = $parent.find(".oe_price:first .oe_currency_value"); + var $default_price = $parent.find(".oe_default_price:first .oe_currency_value"); + var $tech_deatil = $(".tech_deatil"); + var $license_detail = $(".license_detail"); + var $license_url = $(".license_url"); + var $author_detail = $(".author_detail"); + var $website_detail = $(".website_detail"); + var $repo_detail = $(".repo_detail"); + var $rst_html = $(".desc_rst"); + var $app_summary = $(".app_summary"); + var $name_product = $(".name_product"); + var $optional_price = $parent.find(".oe_optional:first .oe_currency_value"); + var variant_ids = $ul.data("attribute_value_ids"); + if(_.isString(variant_ids)) { + variant_ids = JSON.parse(variant_ids.replace(/'/g, '"')); + } + var values = []; + var unchanged_values = $parent.find('div.oe_unchanged_value_ids').data('unchanged_value_ids') || []; + + $parent.find('input.js_variant_change:checked, select.js_variant_change').each(function () { + values.push(+$(this).val()); + }); + values = values.concat(unchanged_values); + + $parent.find("label").removeClass("text-muted css_not_available"); + + var product_id = false; + for (var k in variant_ids) { + if (_.isEmpty(_.difference(variant_ids[k][1], values))) { + $.when(base.ready()).then(function() { + $price.html(price_to_str(variant_ids[k][2])); + $default_price.html(price_to_str(variant_ids[k][3])); + }); + if (variant_ids[k][3]-variant_ids[k][2]>0.01) { + $default_price.closest('.oe_website_sale').addClass("discount"); + $optional_price.closest('.oe_optional').show().css('text-decoration', 'line-through'); + $default_price.parent().removeClass('hidden'); + } else { + $optional_price.closest('.oe_optional').hide(); + $default_price.parent().addClass('hidden'); + } + product_id = variant_ids[k][0]; + $product_global = product_id; + update_product_image(this, product_id); + ajax.jsonRpc("/shop/change_attribute_version", 'call', { + 'product_id': product_id, + }).then(function (data) { + if(data){ + $tech_deatil.text(data['technical_name']); + $license_detail.text(data['license']); + $('.license_url').attr('href', data['license_url']); + $author_detail.text(data['author']); + $website_detail.text(data['website']); + $repo_detail.text(data['repository']); + $rst_html.html(data['rst_html']); + $app_summary.text(data['app_summary']); + $name_product.text(data['name_product']); + } + }); + break; + } + } + + $parent.find("input.js_variant_change:radio, select.js_variant_change").each(function () { + var $input = $(this); + var id = +$input.val(); + var values = [id]; + + $parent.find("ul:not(:has(input.js_variant_change[value='" + id + "'])) input.js_variant_change:checked, select.js_variant_change").each(function () { + values.push(+$(this).val()); + }); + + for (var k in variant_ids) { + if (!_.difference(values, variant_ids[k][1]).length) { + return; + } + } + $input.closest("label").addClass("css_not_available"); + $input.find("option[value='" + id + "']").addClass("css_not_available"); + }); + + if (product_id) { + $parent.removeClass("css_not_available"); + $product_id.val(product_id); + $parent.find("#add_to_cart").removeClass("disabled"); + } else { + $parent.addClass("css_not_available"); + $product_id.val(0); + $parent.find("#add_to_cart").addClass("disabled"); + } + }); + + $('#download_zip').on('click', function(ev){ + var product_template_id = $(this).data('tmpl-id'); + + ajax.jsonRpc("/shop/cart/download_source", 'call', { + 'product_id': $product_global, + 'product_template_id': product_template_id, + }).then(function (data) { + if(data){ + window.location.href = "/shop/download_product_zip/" + data; + } + }); + }); + }); +}); diff --git a/website_apps_store/tests/__init__.py b/website_apps_store/tests/__init__.py new file mode 100644 index 00000000..b450fb98 --- /dev/null +++ b/website_apps_store/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2017-Today: Odoo Community Association (OCA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import test_website_apps_store +from . import test_tour_website_apps_store diff --git a/website_apps_store/tests/test_tour_website_apps_store.py b/website_apps_store/tests/test_tour_website_apps_store.py new file mode 100644 index 00000000..9e6920d4 --- /dev/null +++ b/website_apps_store/tests/test_tour_website_apps_store.py @@ -0,0 +1,60 @@ +# Copyright 2017-2018 BizzAppDev +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import tests +import mock + +mock_get_module_path = ( + 'odoo.addons.apps_download.models.product.ProductProduct._get_module_path' +) + + +@tests.common.at_install(False) +@tests.common.post_install(True) +class TestUi(tests.HttpCase): + + def setUp(self): + super(TestUi, self).setUp() + self.tour = "odoo.__DEBUG__.services['web_tour.tour']" + + def test_download_zip_tour(self): + test_path = 'odoo.addons.apps_download.tests.test_modules.test_module' + with mock.patch(mock_get_module_path) as mock_func: + mock_func.return_value = test_path + self.phantom_js( + "/shop", + self.tour + ".run('download_zip')", + self.tour + ".tours.download_zip.ready", + login="admin" + ) + + def test_select_version_search_tour(self): + self.phantom_js( + "/shop", + self.tour + ".run('select_version_search')", + self.tour + ".tours.select_version_search.ready", + login="admin" + ) + + def test_select_author_search_tour(self): + self.phantom_js( + "/shop", + self.tour + ".run('select_author_search')", + self.tour + ".tours.select_author_search.ready", + login="admin" + ) + + def test_select_category_search_tour(self): + self.phantom_js( + "/shop", + self.tour + ".run('select_category_search')", + self.tour + ".tours.select_category_search.ready", + login="admin" + ) + + def test_module_search_tour(self): + self.phantom_js( + "/shop", + self.tour + ".run('module_search')", + self.tour + ".tours.module_search.ready", + login="admin" + ) diff --git a/website_apps_store/tests/test_website_apps_store.py b/website_apps_store/tests/test_website_apps_store.py new file mode 100644 index 00000000..899a7dde --- /dev/null +++ b/website_apps_store/tests/test_website_apps_store.py @@ -0,0 +1,65 @@ +# Copyright (C) 2018-Today: Odoo Community Association (OCA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.tests.common import TransactionCase + + +class TestWebsiteAppsStore(TransactionCase): + + def setUp(self): + super(TestWebsiteAppsStore, self).setUp() + + self.organization2 = self.env['github.organization'].create({ + 'name': 'Organization 2', + 'github_login': 'login', + }) + + self.repository2 = self.env['github.repository'].create({ + 'name': 'Repository2', + 'organization_id': self.organization2.id, + }) + + self.branch2 = self.env['github.repository.branch'].create({ + 'name': 'master', + 'repository_id': self.repository2.id, + }) + + self.odoo_module2 = self.env['odoo.module'].create({ + 'technical_name': 'odoo_module2', + }) + + self.attribute = self.env.ref( + 'apps_product_creator.attribute_odoo_version') + self.version = self.env.ref('apps_product_creator.odoo_version_100') + + self.odoo_module2_version2 = self.env['odoo.module.version'].create({ + 'name': 'Odoo Module 2', + 'technical_name': 'odoo_module2', + 'module_id': self.odoo_module2.id, + 'repository_branch_id': self.branch2.id, + 'license': 'AGPL-3', + 'summary': 'Summary Test', + 'website': 'Website Test', + 'description_rst': 'Description Test', + 'version': '10.0', + 'author': 'OCA', + 'depends': 'base', + 'external_dependencies': '{}', + }) + + def test_product_author_version_info(self): + self.assertFalse(self.odoo_module2.product_template_id) + self.odoo_module2.action_create_product() + self.assertTrue(self.odoo_module2.product_template_id) + self.odoo_module2.product_template_id.write({ + 'attribute_line_ids': [(0, 0, { + 'attribute_id': self.attribute.id, + 'value_ids': [(6, 0, [self.version.id])], + })] + }) + action = self.odoo_module2.action_view_products() + self.assertEqual( + self.odoo_module2.product_template_id.product_variant_ids.ids[0], + action['res_id'] + ) + self.odoo_module2.product_template_id.get_author_details() + self.odoo_module2.product_template_id.get_version_info() diff --git a/website_apps_store/views/assets.xml b/website_apps_store/views/assets.xml new file mode 100644 index 00000000..38190754 --- /dev/null +++ b/website_apps_store/views/assets.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/website_apps_store/views/templates.xml b/website_apps_store/views/templates.xml new file mode 100644 index 00000000..ed311393 --- /dev/null +++ b/website_apps_store/views/templates.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + From 8ca7e08c9902abd3179222a0604cb05e86da9144 Mon Sep 17 00:00:00 2001 From: Ruchir Shukla Date: Thu, 20 Sep 2018 21:11:52 +0530 Subject: [PATCH 02/41] [FIX]Proper path for the phantomjs --- .../i18n/website_apps_store.pot | 83 +++++++++++++++++++ .../tests/test_tour_website_apps_store.py | 18 ++-- 2 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 website_apps_store/i18n/website_apps_store.pot diff --git a/website_apps_store/i18n/website_apps_store.pot b/website_apps_store/i18n/website_apps_store.pot new file mode 100644 index 00000000..5e44b684 --- /dev/null +++ b/website_apps_store/i18n/website_apps_store.pot @@ -0,0 +1,83 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_apps_store +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Author: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "License: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Maintainer: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Repository: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Technical Name: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Website: " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "https://odoo-community.org" +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.author_display +msgid "Author\n" +" " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.category_display +msgid "Category\n" +" " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.version_display +msgid "Version\n" +" " +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.product +msgid "Download" +msgstr "" + +#. module: website_apps_store +#: model:ir.model,name:website_apps_store.model_product_template +msgid "Product Template" +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.variants +msgid "Versions Available:" +msgstr "" + diff --git a/website_apps_store/tests/test_tour_website_apps_store.py b/website_apps_store/tests/test_tour_website_apps_store.py index 9e6920d4..29c2fbfd 100644 --- a/website_apps_store/tests/test_tour_website_apps_store.py +++ b/website_apps_store/tests/test_tour_website_apps_store.py @@ -2,9 +2,11 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import tests import mock +import os mock_get_module_path = ( - 'odoo.addons.apps_download.models.product.ProductProduct._get_module_path' + 'odoo.addons.apps_download.models.product_product.ProductProduct' + '._get_module_path' ) @@ -17,14 +19,16 @@ def setUp(self): self.tour = "odoo.__DEBUG__.services['web_tour.tour']" def test_download_zip_tour(self): - test_path = 'odoo.addons.apps_download.tests.test_modules.test_module' + test_path = os.path.dirname(os.path.realpath(__file__)) + test_path = test_path.split('/website_apps_store')[0] + test_module_path = os.path.join( + test_path + '/apps_download' + '/tests', 'test_modules', + 'second_module') with mock.patch(mock_get_module_path) as mock_func: - mock_func.return_value = test_path + mock_func.return_value = test_module_path self.phantom_js( - "/shop", - self.tour + ".run('download_zip')", - self.tour + ".tours.download_zip.ready", - login="admin" + "/shop", self.tour + ".run('download_zip')", + self.tour + ".tours.download_zip.ready", login="admin" ) def test_select_version_search_tour(self): From 20458c54e7e6efadc570831a19d37d046358a6a1 Mon Sep 17 00:00:00 2001 From: Stephan Rozendaal Date: Mon, 1 Oct 2018 17:09:35 +0200 Subject: [PATCH 03/41] [IMP] Show a default 'OCA' icon on product When the related module has no icon, show a default 'OCA' icon from the static path. --- website_apps_store/static/src/img/oca.png | Bin 0 -> 9455 bytes website_apps_store/views/templates.xml | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 website_apps_store/static/src/img/oca.png diff --git a/website_apps_store/static/src/img/oca.png b/website_apps_store/static/src/img/oca.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/website_apps_store/views/templates.xml b/website_apps_store/views/templates.xml index ed311393..243cf58c 100644 --- a/website_apps_store/views/templates.xml +++ b/website_apps_store/views/templates.xml @@ -87,7 +87,16 @@ - + + + + + + + + + + @@ -204,6 +213,16 @@

+ + + + + + + + + + - From c3943e307a4d9571c093c73f872b0df9d959ebee Mon Sep 17 00:00:00 2001 From: "Olar Alca [Vauxoo]" Date: Tue, 2 Oct 2018 13:33:05 +0200 Subject: [PATCH 07/41] [IMP] apps-store (#15) * [IMP] apps-store: - Shop: * Removed filter by author. * Added a more informative placeholder to the searchbox * Added categories of apps to public categories. * Added a filter `All` option for categories dropdown. * Removed sort by price. - Changed the way products are created, now products are related to their correspondant category. (used the ones from Odoo.com/apps) - On PDP added the version of the app if it has no variants. * [REF] if no category found will defailt to 'Other' category --- website_apps_store/views/templates.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/website_apps_store/views/templates.xml b/website_apps_store/views/templates.xml index 3fa68cfa..76af2355 100644 --- a/website_apps_store/views/templates.xml +++ b/website_apps_store/views/templates.xml @@ -13,6 +13,9 @@