You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
9.2KB

  1. # Copyright 2017-2018 BizzAppDev
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. import logging
  4. import base64
  5. from odoo import http
  6. from odoo.http import request
  7. from odoo.addons.http_routing.models.ir_http import slug
  8. from odoo.addons.website.controllers.main import QueryURL
  9. from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute
  10. from odoo.exceptions import ValidationError
  11. _logger = logging.getLogger(__name__)
  12. PPG = 20 # Products Per Page
  13. PPR = 4 # Products Per Row
  14. class WebsiteSaleCustom(WebsiteSale):
  15. def _get_search_domain(self, search, category, attrib_values):
  16. domain = request.website.sale_product_domain()
  17. if search:
  18. for srch in search.split(" "):
  19. domain += [
  20. "|",
  21. "|",
  22. "|",
  23. "|",
  24. "|",
  25. "|",
  26. "|",
  27. "|",
  28. ("name", "ilike", srch),
  29. ("technical_name", "ilike", srch),
  30. ("description", "ilike", srch),
  31. ("description_sale", "ilike", srch),
  32. ("product_variant_ids.default_code", "ilike", srch),
  33. (
  34. "product_variant_ids.attribute_value_ids.name",
  35. "ilike",
  36. srch,
  37. ),
  38. (
  39. "product_variant_ids.app_description_rst_html",
  40. "ilike",
  41. srch,
  42. ),
  43. ("product_variant_ids.app_author_ids.name", "ilike", srch),
  44. ("product_variant_ids.app_summary", "ilike", srch),
  45. ]
  46. if category:
  47. domain += [("public_categ_ids", "child_of", int(category))]
  48. if attrib_values:
  49. attrib = None
  50. ids = []
  51. for value in attrib_values:
  52. if not attrib:
  53. attrib = value[0]
  54. ids.append(value[1])
  55. elif value[0] == attrib:
  56. ids.append(value[1])
  57. else:
  58. domain += [("attribute_line_ids.value_ids", "in", ids)]
  59. attrib = value[0]
  60. ids = [value[1]]
  61. if attrib:
  62. domain += [("attribute_line_ids.value_ids", "in", ids)]
  63. return domain
  64. @http.route()
  65. def shop(self, page=0, category=None, search="", ppg=False, **post):
  66. res = super(WebsiteSaleCustom, self).shop(
  67. page=page, category=category, search=search, ppg=ppg, **post
  68. )
  69. if ppg:
  70. try:
  71. ppg = int(ppg)
  72. except ValueError:
  73. ppg = PPG
  74. post["ppg"] = ppg
  75. else:
  76. ppg = PPG
  77. attrib_list = request.httprequest.args.getlist("attrib")
  78. attrib_values = [
  79. [int(x) for x in v.split("-")] for v in attrib_list if v
  80. ]
  81. attributes_ids = {v[0] for v in attrib_values}
  82. attrib_set = {v[1] for v in attrib_values}
  83. domain = self._get_search_domain(search, category, attrib_values)
  84. keep = QueryURL(
  85. "/shop",
  86. category=category and int(category),
  87. search=search,
  88. attrib=attrib_list,
  89. order=post.get("order"),
  90. maturity=post.get("maturity"),
  91. version=post.get("version"),
  92. author=post.get("author"),
  93. )
  94. if post.get("version"):
  95. domain += [
  96. (
  97. "product_variant_ids.attribute_value_ids.id",
  98. "=",
  99. post.get("version"),
  100. )
  101. ]
  102. if post.get("author"):
  103. domain += [
  104. (
  105. "product_variant_ids.app_author_ids.id",
  106. "=",
  107. post.get("author"),
  108. )
  109. ]
  110. if post.get("maturity", False):
  111. domain += [
  112. (
  113. "product_variant_ids.app_development_status",
  114. "=",
  115. post.get("maturity"),
  116. )
  117. ]
  118. url = "/shop"
  119. if search:
  120. post["search"] = search
  121. if attrib_list:
  122. post["attrib"] = attrib_list
  123. if category:
  124. category = request.env["product.public.category"].browse(
  125. int(category)
  126. )
  127. url = "/shop/category/%s" % slug(category)
  128. attribute_id = request.env.ref(
  129. "apps_product_creator.attribute_odoo_version"
  130. )
  131. category_all = request.env["product.public.category"].search([])
  132. versions = request.env["product.attribute.value"].search(
  133. [("attribute_id", "=", attribute_id.id)]
  134. )
  135. authors = request.env["odoo.author"].search([])
  136. Product = request.env["product.template"]
  137. product_count = Product.search_count(domain)
  138. pager = request.website.pager(
  139. url=url,
  140. total=product_count,
  141. page=page,
  142. step=ppg,
  143. scope=7,
  144. url_args=post,
  145. )
  146. products = Product.search(
  147. domain,
  148. limit=ppg,
  149. offset=pager["offset"],
  150. order=self._get_search_order(post),
  151. )
  152. ProductAttribute = request.env["product.attribute"]
  153. if products:
  154. # get all products without limit
  155. selected_products = Product.search(domain, limit=False)
  156. attributes = ProductAttribute.search(
  157. [
  158. (
  159. "attribute_line_ids.product_tmpl_id",
  160. "in",
  161. selected_products.ids,
  162. )
  163. ]
  164. )
  165. else:
  166. attributes = ProductAttribute.browse(attributes_ids)
  167. res.qcontext.update(
  168. {
  169. "search": search,
  170. "category": category,
  171. "attrib_values": attrib_values,
  172. "attrib_set": attrib_set,
  173. "pager": pager,
  174. "products": products,
  175. "search_count": product_count, # common for all searchbox
  176. "bins": TableCompute().process(products, ppg),
  177. "category_all": category_all,
  178. "versions": versions,
  179. "authors": authors,
  180. "version": post.get("version"),
  181. "author": post.get("author"),
  182. "attributes": attributes,
  183. "keep": keep,
  184. "maturity": post.get("maturity"),
  185. }
  186. )
  187. return res
  188. def validate_recaptcha(self, captcha):
  189. """Function for validating Recaptcha"""
  190. captcha_obj = request.env["website.form.recaptcha"]
  191. ip_addr = request.httprequest.environ.get("HTTP_X_FORWARDED_FOR")
  192. if ip_addr:
  193. ip_addr = ip_addr.split(",")[0]
  194. else:
  195. ip_addr = request.httprequest.remote_addr
  196. try:
  197. captcha_obj.validate_response(captcha, ip_addr)
  198. except ValidationError:
  199. raise ValidationError([captcha_obj.RESPONSE_ATTR])
  200. @http.route(
  201. [
  202. '/shop/download_product_zip/<model("product.template"):product_tmpl>'
  203. '/<model("product.product"):product>/'
  204. "<string:google_captcha>",
  205. '/shop/download_product_zip/<model("product.template"):product_tmpl>/'
  206. "<string:google_captcha>",
  207. ],
  208. type="http",
  209. auth="public",
  210. website=True,
  211. )
  212. def download_product_zip(
  213. self, product_tmpl, product=False, google_captcha="", **kwargs
  214. ):
  215. self.validate_recaptcha(google_captcha)
  216. if not product:
  217. product = product_tmpl.get_version_info()
  218. attachment = (
  219. request.env["ir.attachment"]
  220. .sudo()
  221. .search(
  222. [
  223. ("res_id", "=", product.id),
  224. ("res_model", "=", product._name),
  225. ],
  226. limit=1,
  227. )
  228. )
  229. if not attachment:
  230. product.sudo().generate_zip_file()
  231. attachment = (
  232. request.env["ir.attachment"]
  233. .sudo()
  234. .search(
  235. [
  236. ("res_id", "=", product.id),
  237. ("res_model", "=", product._name),
  238. ],
  239. limit=1,
  240. )
  241. )
  242. if attachment:
  243. filecontent = base64.b64decode(attachment.datas)
  244. disposition = 'attachment; filename="%s"' % attachment.datas_fname
  245. # increasing count for the product download
  246. product.sudo().download_count = product.sudo().download_count + 1
  247. return request.make_response(
  248. filecontent,
  249. [
  250. (
  251. "Content-Type",
  252. "application/zip, application/octet-stream",
  253. ),
  254. ("Content-Length", len(filecontent)),
  255. ("Content-Disposition", disposition),
  256. ],
  257. )
  258. return False
上海开阖软件有限公司 沪ICP备12045867号-1