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.

226 lines
11 KiB

  1. # -*- coding: utf-8 -*-
  2. #from urllib.parse import urlparse, urljoin
  3. #import werkzeug
  4. from odoo import http
  5. from odoo.http import request
  6. from odoo import fields, http, tools, _
  7. import base64
  8. import requests
  9. import json
  10. import logging
  11. _logger = logging.getLogger(__name__)
  12. import payplug
  13. payplug.set_api_version("2019-08-06")
  14. import pprint
  15. from odoo.addons.website_sale.controllers.main import WebsiteSale
  16. from odoo.tools.json import scriptsafe as json_scriptsafe
  17. from odoo.exceptions import AccessError, UserError, ValidationError
  18. class WebsiteSaleOney(WebsiteSale):
  19. # CREATE SIMULATION ONEY IN PRODUCT FORM
  20. def _prepare_product_values(self, product, category, search, **kwargs):
  21. res=super(WebsiteSaleOney,self)._prepare_product_values(product, category, search, **kwargs)
  22. # IF PAYMENT ACQUIRER IS ONEY UPDATE VALUES
  23. payment_provider=request.env['payment.provider'].sudo().search([('code','=','payplug')], limit=1)
  24. # ONEY IS ACTIVE
  25. if payment_provider.state != 'disabled' and payment_provider.payment_type_oney == True:
  26. # IF THE PROVIDER IS ALLOWED FROM THE WEBSITE COMPANY
  27. company_ids=request.env.context.get('allowed_company_ids')
  28. if payment_provider.company_id.id in company_ids:
  29. authorized_by_company = True
  30. else:
  31. authorized_by_company = False
  32. # TO VERIFY THAT THE AMOUNT IS IN THE ONEY AUTHORIZED RANGE
  33. amount = res.get('product').list_price
  34. if amount < 100 or amount > 3000 :
  35. authorized_by_oney = False
  36. else:
  37. authorized_by_oney = True
  38. result_simulation=request.env['payment.provider'].sudo()._oney_payment_simulation(amount, 'FR')
  39. # UPDATE DICT WITH SIMULATION ONEY
  40. res.update(result_simulation)
  41. res.update({
  42. 'InformationMessage': payment_provider.oney_information_message,
  43. 'FooterMessage': payment_provider.oney_footer_message,
  44. 'amount_total_oney': amount,
  45. 'authorized_by_oney': authorized_by_oney,
  46. 'authorized_by_company': authorized_by_company,
  47. 'acquirer': payment_provider,
  48. 'currency_symbol': request.website.currency_id.symbol,
  49. })
  50. else:
  51. res.update({
  52. 'InformationMessage': False,
  53. 'FooterMessage': False,
  54. 'amount_total_oney': 0,
  55. 'authorized_by_oney': None,
  56. 'authorized_by_company': None,
  57. 'acquirer': payment_provider,
  58. 'currency_symbol': request.website.currency_id.symbol,
  59. })
  60. return res
  61. #UPDATE CART
  62. @http.route(['/shop/cart'], type='http', auth="public", website=True, sitemap=False)
  63. def cart(self, access_token=None, revive='', **post):
  64. res=super(WebsiteSaleOney,self).cart(access_token, revive, **post)
  65. # IF PAYMENT ACQUIRER IS ONEY UPDATE VALUES
  66. payment_provider=request.env['payment.provider'].sudo().search([('code','=','payplug')], limit=1)
  67. # ONEY IS ACTIVE
  68. if payment_provider.state != 'disabled' and payment_provider.payment_type_oney == True:
  69. amount=res.__dict__['qcontext']['website_sale_order'].amount_total
  70. # IF THE PROVIDER IS ALLOWED FROM THE WEBSITE COMPANY
  71. company_ids=request.env.context.get('allowed_company_ids')
  72. if payment_provider.company_id.id in company_ids:
  73. authorized_by_company = True
  74. else:
  75. authorized_by_company = False
  76. if amount < 100 or amount > 3000 :
  77. authorized_by_oney = False
  78. else:
  79. authorized_by_oney = True
  80. currency=res.__dict__['qcontext']['website_sale_order'].currency_id.symbol
  81. res.__dict__['qcontext'].update({
  82. 'InformationMessage': payment_provider.oney_information_message,
  83. 'FooterMessage': payment_provider.oney_footer_message,
  84. 'currency_symbol': request.website.currency_id.symbol,
  85. 'amount_total_oney': amount,
  86. 'authorized_by_oney': authorized_by_oney,
  87. 'authorized_by_company': authorized_by_company,
  88. })
  89. res.__dict__['qcontext'].update({'acquirer': payment_provider}) # IF ONEY IS DISABLED
  90. return res
  91. # UPDATE ONEY SIMULATION
  92. @http.route(['/shop/product/oney_simulation'], type='json', auth="public", website=True, csrf=False)
  93. def oney_simulation(self, **kw):
  94. values={}
  95. payment_provider=request.env['payment.provider'].sudo().search([('code','=','payplug')], limit=1)
  96. # ONEY IS ACTIVE
  97. if payment_provider.state != 'disabled' and payment_provider.payment_type_oney == True:
  98. result_simulation=request.env['payment.provider'].sudo()._oney_payment_simulation(float(kw.get('product_total_price')), 'FR')
  99. values = {
  100. 'amount_total_oney': "%.2f" %(float(kw.get('product_total_price'))),
  101. 'payment_3x': result_simulation['payment_3x'],
  102. 'payment_4x': result_simulation['payment_4x'],
  103. }
  104. return values
  105. # CREATE SIMULATION ONEY IN CART PAYMENT
  106. def _get_shop_payment_values(self, order, **kwargs):
  107. res = super(WebsiteSaleOney, self)._get_shop_payment_values(order, **kwargs)
  108. # Return de specific values for Payment Oney
  109. payment_provider = request.env['payment.provider'].sudo().search([('code','=','payplug')], limit=1)
  110. if payment_provider.state != 'disabled':
  111. country=order.partner_id.country_id
  112. if payment_provider.payment_type_oney == True:
  113. result_simulation=request.env['payment.provider'].sudo()._oney_payment_simulation(order.amount_total, 'FR')
  114. res.update(result_simulation)
  115. # ONEY PAYMENT CONTROL BETWEEN €100 AND €3000
  116. if order.amount_total >= 100.00 and order.amount_total <= 3000.00:
  117. authorized_by_oney=True
  118. else:
  119. authorized_by_oney=False
  120. # AUTHORIZED COUNTRY FOR ONEY
  121. authorized_country_oney=True
  122. if country not in payment_provider.available_oney_country_ids:
  123. authorized_country_oney=False
  124. total_qty_card=0.0
  125. limit_quantity=False
  126. for line in res['website_sale_order'].order_line:
  127. total_qty_card+=line.product_uom_qty
  128. if total_qty_card > 10.0:
  129. limit_quantity=True
  130. authorized_by_oney=False
  131. res.update({
  132. 'amount_oney': order.amount_total,
  133. 'authorized_by_oney': authorized_by_oney,
  134. 'limit_quantity': limit_quantity,
  135. 'InformationMessage': payment_provider.oney_information_message,
  136. 'type_oney': 'oney_x3_with_fees',
  137. 'currency_symbol': order.currency_id.symbol,
  138. 'authorized_country_oney': authorized_country_oney,
  139. })
  140. # AUTHORIZED COUNTRY FOR PAYPLUG
  141. if payment_provider.payment_type_payplug == True:
  142. authorized_country_payplug=True
  143. if country not in payment_provider.available_payplug_country_ids:
  144. authorized_country_payplug=False
  145. res.update({'authorized_country_payplug': authorized_country_payplug})
  146. # AUTHORIZED COUNTRY FOR AMEX
  147. if payment_provider.payment_type_amex == True:
  148. authorized_country_amex=True
  149. if country not in payment_provider.available_amex_country_ids:
  150. authorized_country_amex=False
  151. res.update({'authorized_country_amex': authorized_country_amex})
  152. # AUTHORIZED COUNTRY FOR BANCONTACT
  153. if payment_provider.payment_type_bancontact == True:
  154. authorized_country_bancontact=True
  155. if country not in payment_provider.available_bancontact_country_ids:
  156. authorized_country_bancontact=False
  157. res.update({'authorized_country_bancontact': authorized_country_bancontact})
  158. return res
  159. # UPDATE SESSION WITH PROVIDER PAYPLUG 'payplug','oney','amex','bancontact' AND 'oney_x3_with_fees','oney_x4_with_fees
  160. @http.route(['/provider_payplug'], type='json', auth="public", website=True)
  161. def provider_payplug(self, **kw):
  162. payment_provider = kw.get('provider_payplug')
  163. type_oney = kw.get('type_oney')
  164. if payment_provider is None:
  165. request.session['provider_payplug']='payplug'
  166. else:
  167. request.session['provider_payplug']=payment_provider
  168. if type_oney is None:
  169. request.session['type_oney']='oney_x3_with_fees'
  170. else:
  171. request.session['type_oney']=type_oney
  172. class PayPlugController(http.Controller):
  173. _return_url = '/payment/payplug/return'
  174. _webhook_url = '/payment/payplug/webhook'
  175. @http.route(
  176. _return_url, type='http', auth='public', methods=['GET'], csrf=False, save_session=False
  177. )
  178. def payplug_return_from_checkout(self, **post):
  179. payment=request.env['payment.transaction'].sudo().browse(int(post.get('transaction')))
  180. # SECRET KEY TEST OR LIVE
  181. secret_payplug_key=request.env['payment.provider'].sudo()._key_acquirer_state(payment.provider_id)
  182. # API PAYPLUG
  183. payplug.set_secret_key(secret_payplug_key)
  184. payment_payplug=payplug.Payment.retrieve(str(payment.provider_reference))
  185. tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('payplug', payment_payplug)
  186. tx_sudo._handle_notification_data('payplug', payment_payplug)
  187. return request.redirect('/payment/status')
  188. @http.route(
  189. _webhook_url, type='http', auth='public', methods=['GET'], csrf=False
  190. )
  191. def payplug_webhook(self, **post):
  192. payment=request.env['payment.transaction'].sudo().browse(int(post.get('transaction')))
  193. # DOWNLOAD SECRET KEY PAYPLUG TEST OR LIVE
  194. secret_payplug_key=request.env['payment.provider'].sudo()._key_acquirer_state(payment.provider_id)
  195. # API PAYPLUG
  196. payplug.set_secret_key(secret_payplug_key)
  197. payment_payplug=payplug.Payment.retrieve(str(payment.provider_reference))
  198. # TRANSACTION CANCEL OR ERROR
  199. CodeError=payment_payplug.failure.__dict__.get('_attributes')
  200. if CodeError['code']=='canceled':
  201. ErrorMessage='PayPlug Error\n'
  202. ErrorMessage+='Transaction canceled by customer'
  203. payment.sudo().write({
  204. 'state_message': ErrorMessage,
  205. 'state': 'cancel',
  206. })
  207. else:
  208. ErrorMessage='PayPlug Error\n'
  209. ErrorMessage+='Code Error : '+CodeError['code']+'\n'
  210. ErrorMessage+='Message : '+CodeError['message']
  211. payment.sudo().write({
  212. 'state_message': ErrorMessage,
  213. 'state': 'error',
  214. })
  215. return request.redirect('/shop')