diff --git a/odex25_donation/p_donation_gift/.idea/.gitignore b/odex25_donation/p_donation_gift/.idea/.gitignore deleted file mode 100644 index 26d33521a..000000000 --- a/odex25_donation/p_donation_gift/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/odex25_donation/p_donation_gift/.idea/inspectionProfiles/profiles_settings.xml b/odex25_donation/p_donation_gift/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da2..000000000 --- a/odex25_donation/p_donation_gift/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_gift/.idea/misc.xml b/odex25_donation/p_donation_gift/.idea/misc.xml deleted file mode 100644 index db8786c06..000000000 --- a/odex25_donation/p_donation_gift/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_gift/.idea/modules.xml b/odex25_donation/p_donation_gift/.idea/modules.xml deleted file mode 100644 index 9b91892b1..000000000 --- a/odex25_donation/p_donation_gift/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_gift/.idea/p_donation_gift.iml b/odex25_donation/p_donation_gift/.idea/p_donation_gift.iml deleted file mode 100644 index d0876a78d..000000000 --- a/odex25_donation/p_donation_gift/.idea/p_donation_gift.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_gift/static/src/js/gift.js b/odex25_donation/p_donation_gift/static/src/js/gift.js index f652f5d95..ad145bb63 100644 --- a/odex25_donation/p_donation_gift/static/src/js/gift.js +++ b/odex25_donation/p_donation_gift/static/src/js/gift.js @@ -4,7 +4,7 @@ odoo.define('p_donation_gift.gift', function (require) { require('web.dom_ready'); require('p_donation_theme.product-gift-card'); var publicWidget = require('web.public.widget'); - const {qweb, _t} = require('web.core'); + const { _t } = require('web.core'); function ArabictoEnglishNumber(strNum) { var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); diff --git a/odex25_donation/p_donation_theme/.idea/.gitignore b/odex25_donation/p_donation_theme/.idea/.gitignore deleted file mode 100644 index 26d33521a..000000000 --- a/odex25_donation/p_donation_theme/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/odex25_donation/p_donation_theme/.idea/.name b/odex25_donation/p_donation_theme/.idea/.name deleted file mode 100644 index 58e806f80..000000000 --- a/odex25_donation/p_donation_theme/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -templates.xml \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/.idea/inspectionProfiles/profiles_settings.xml b/odex25_donation/p_donation_theme/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da2..000000000 --- a/odex25_donation/p_donation_theme/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/.idea/misc.xml b/odex25_donation/p_donation_theme/.idea/misc.xml deleted file mode 100644 index d1e22ecb8..000000000 --- a/odex25_donation/p_donation_theme/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/.idea/modules.xml b/odex25_donation/p_donation_theme/.idea/modules.xml deleted file mode 100644 index 1e546e9f7..000000000 --- a/odex25_donation/p_donation_theme/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/.idea/p_donation_theme.iml b/odex25_donation/p_donation_theme/.idea/p_donation_theme.iml deleted file mode 100644 index d0876a78d..000000000 --- a/odex25_donation/p_donation_theme/.idea/p_donation_theme.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/__manifest__.py b/odex25_donation/p_donation_theme/__manifest__.py index f5583dbde..bf52f559f 100644 --- a/odex25_donation/p_donation_theme/__manifest__.py +++ b/odex25_donation/p_donation_theme/__manifest__.py @@ -11,7 +11,7 @@ 'currency': 'USD', 'license': 'LGPL-3', 'category': 'Uncategorized', - 'version': '16.0.4', + 'version': '14.0.1', 'depends': ['base', 'website_sale', 'theme_prime', 'droggol_theme_common', 'payment_hyperpay', 'payment_applepay'], 'data': [ @@ -20,19 +20,5 @@ 'views/views.xml', 'data/sms_data.xml' ], - 'assets': { - 'web.assets_frontend': [ - 'p_donation_theme/static/src/scss/hyperpay_quick_donation.scss', - 'p_donation_theme/static/src/scss/theme.scss', - 'p_donation_theme/static/src/js/*.js', - 'p_donation_theme/static/src/xml/donation.xml', - ], - 'web._assets_primary_variables': [ - "p_donation_theme/static/src/scss/primary_variables.scss", - ], - 'website.assets_editor': [ - 'p_donation_theme/static/src/js/components/*.js' - ] - }, 'images': ['static/description/banner.png'], } diff --git a/odex25_donation/p_donation_theme/controllers/main.py b/odex25_donation/p_donation_theme/controllers/main.py index 42d4f43bf..4b37cd21d 100644 --- a/odex25_donation/p_donation_theme/controllers/main.py +++ b/odex25_donation/p_donation_theme/controllers/main.py @@ -1,229 +1,154 @@ -from odoo import http, _ -from odoo.addons.website_sale.controllers.main import PaymentPortal -from odoo.exceptions import ValidationError -from odoo.http import request -import requests, logging -import phonenumbers -from phonenumbers.phonenumberutil import NumberParseException - -_logger = logging.getLogger(__name__) - - - -class PaymentPortalExtraFields(PaymentPortal): - - def check_mobile_number_validation(self, phone): - if phone[0] == '+' and phone[1] != '0': - if phone[1:4] == '966': - if len(phone[4:]) >= 8: - return phone - else: - phone = phone[0] + '966' + phone[1:] - elif phone[0] == '+' and phone[1] == '0': - phone = phone[0] + '966' + phone[2:] - elif phone[0] == '0' and phone[1] == '5': - phone = '+966' + phone[1:] - elif phone[0:2] == '00': # 00966555555555 - if phone[2:5] == '966': - phone = '+' + '966' + phone[5:] - elif phone[0] == '0': # 0966555555555 - if phone[1:4] == '966': - phone = '+' + '966' + phone[4:] - else: - if phone[0:3] == '966': - phone = '+' + phone - else: - phone = '+' + '966' + phone - return phone - - @http.route() - def shop_payment_transaction(self, *args, **kwargs): - order = request.website.sale_get_order() - if order: - try: - string_phone_number = kwargs.get('extra_mobile', '') - string_name = kwargs.get('extra_name', '') - if string_phone_number: - string_phone_number = kwargs.get('extra_mobile', '') - # string_phone_number = '+' + str(string_phone_number) - string_phone_number = self.check_mobile_number_validation(string_phone_number) - phone_number = phonenumbers.parse(string_phone_number) - is_valid = phonenumbers.is_possible_number(phone_number) - if not is_valid: - raise ValidationError(_('Mobile Number is invalid!')) - order.sudo().write({ - 'order_mobile_number': string_phone_number, - }) - if string_name: - order.sudo().write({ - 'order_name': string_name - }) - except NumberParseException: - raise ValidationError(_('Mobile Number is invalid!')) - except Exception as e: - raise ValidationError(_(e)) - return super().shop_payment_transaction(*args, **kwargs) - - @http.route( - '/quickpay/hyperpay/payment', type='json', auth='public', website=True - ) - def quick_hyperpay_payment(self, **kw): - success = False - order = request.website.sale_get_order(force_create=True) - test_domain = "https://test.oppwa.com/v1/payments" - live_domain = "https://oppwa.com/v1/payments" - product_id = kw.pop('product_id') - if order: - if product_id: - product_id = request.env['product.product'].sudo().browse(int(product_id)) - if product_id: - order.order_line.sudo().unlink() - order.write({ - 'order_line': - [(0, 0, { - 'product_id': product_id.id, - 'product_uom_qty': 1, - 'price_unit': float(kw.get('amount')), - 'product_uom': product_id.uom_id.id - })] - }) - try: - payment_acquire_id = request.env['payment.provider'].search([('code', '=','hyperpay'), ('company_id', 'in', (False, order.company_id.id))], limit=1) - temp_vals = { - 'access_token': order._portal_ensure_token(), - 'order_id': order.id, - 'payment_option_id': payment_acquire_id.id, - 'flow': 'direct', - 'tokenization_requested': False, - 'landing_route': '/', - 'currency_id': order.currency_id.id, - } - vals = self.shop_payment_transaction(**(temp_vals)) - payment_sudo = request.env['payment.transaction'].sudo() - tx = payment_sudo.search([('reference', '=', vals.get('reference', False))], limit=1) - if tx: - acq = tx.provider_id - payment_vals = { - "entityId": acq.hyperpay_merchant_id, - "amount": '%.2f' % tx.amount, - "currency": tx.currency_id and tx.sudo().currency_id.name or '', - "paymentType": "DB", - "customParameters[SHOPPER_tx_id]": tx.id, - "merchantTransactionId": tx.id, - 'paymentBrand': kw.get('paymentBrand'), - 'card.number': int(kw.get('card.number')), - 'card.holder': kw.get('card.holder'), - 'card.expiryMonth': '%02d' % int(kw.get('card.expiryMonth')), - 'card.expiryYear': kw.get('card.expiryYear'), - 'card.cvv': '%03d' % int(kw.get('card.cvv')), - } - try: - headers = { - "Authorization": "Bearer " + acq.hyperpay_authorization, - } - if acq.state == 'enabled': - p_url = live_domain - else: - p_url = test_domain - hyper_response = requests.post(url=p_url, data=payment_vals, headers=headers) - hyper_response = hyper_response.json() - tx.hyperpay_checkout_id = hyper_response.get('id') - hyper_response.update({ - 'tx_id': hyper_response.get('customParameters', {}).get('SHOPPER_tx_id') or tx and tx.id or '' - }) - tx._handle_notification_data('hyperpay', hyper_response) - confirmed_orders = tx._check_amount_and_confirm_order() - confirmed_orders._send_order_confirmation_mail() - if tx and tx.state == 'done': - success = True - except Exception as e: - _logger.info("Error in Quick Donation Payment: %s" % (e)) - except Exception as e: - _logger.info("Error in Quick Donation Payment: %s" % (e)) - return { - 'success': success, - } - - @http.route( - '/quickpay/hyperpay/payment/create', type='json', auth='public', website=True - ) - def quick_hyperpay_payment_trans_create(self, **kw): - success = False - order = request.website.sale_get_order(force_create=True) - product_id = kw.pop('product_id') - acquire_id = kw.pop('acquire_id') - mobile = kw.pop('mobile') - if order: - if product_id: - product_id = request.env['product.product'].sudo().browse(int(product_id)) - if product_id: - order.order_line.sudo().unlink() - order.write({ - 'order_line': - [(0, 0, { - 'product_id': product_id.id, - 'product_uom_qty': 1, - 'price_unit': float(kw.get('amount')), - 'product_uom': product_id.uom_id.id - })], - 'order_mobile_number': mobile - }) - try: - if acquire_id: - payment_acquire_id = request.env['payment.provider'].sudo().search( - [('code', 'in', ['hyperpay', 'applepay']), ('company_id', 'in', (False, order.company_id.id)), ('id', '=', int(acquire_id))], limit=1) - else: - payment_acquire_id = request.env['payment.provider'].sudo().search( - [('code', '=', 'hyperpay'), ('company_id', 'in', (False, order.company_id.id))], limit=1) - temp_vals = { - 'access_token': order._portal_ensure_token(), - 'order_id': order.id, - 'payment_option_id': payment_acquire_id.id, - 'flow': 'direct', - 'tokenization_requested': False, - 'landing_route': '/', - 'currency_id': order.currency_id.id, - } - vals = self.shop_payment_transaction(**(temp_vals)) - payment_sudo = request.env['payment.transaction'].sudo() - tx = payment_sudo.search([('reference', '=', vals.get('reference', False))], limit=1) - for sale in tx.sale_order_ids: - sale.done_with_quick_donation = True - final_vals = { - 'success': True, - 'tx_id': tx.id - } - if payment_acquire_id and payment_acquire_id.code == 'applepay' and tx: - redirect_url = '/quick/applepay/payment?tx=%s' % (tx.id) - final_vals.update({ - 'redirect_url': redirect_url - }) - return final_vals - except Exception as e: - _logger.info("Error in Quick Donation Payment: %s" % (e)) - return { - 'success': success, - } - - @http.route('/quick/applepay/payment', type='http', auth='public', website=True, csrf=False) - def apple_pay_payment_method(self, **kwargs): - tx = kwargs.get('tx') - payment_sudo = request.env['payment.transaction'].sudo() - tx = payment_sudo.search([('id', '=', int(tx))], limit=1) - if tx: - kw = tx._get_processing_values() - kw = tx._get_specific_rendering_values(kw) - - acquirer = request.env['payment.provider'].sudo().search([('code', '=', 'applepay')], limit=1) - - kw['currency'] = 'SAR' - _logger.info("Post Values From Apple Payment = %s" % (kw)) - - if acquirer.state == 'test': - return request.render("payment_applepay.payment_applepay_card", - {'check_out_id': kw.get('check_out_id'), 'return_url': kw.get('applepay_return')}) - else: - return request.render("payment_applepay.payment_applepay_card_live", - {'check_out_id': kw.get('check_out_id'), 'return_url': kw.get('applepay_return')}) - else: - return request.redirect('/') +from odoo import http, _ +from odoo.addons.website_sale.controllers.main import WebsiteSale +from odoo.addons.payment.controllers.portal import PaymentProcessing +from odoo.exceptions import ValidationError +from odoo.http import request +import logging +import phonenumbers +from phonenumbers.phonenumberutil import NumberParseException + +_logger = logging.getLogger(__name__) + + +class WebsiteSaleExtended(WebsiteSale): + + @http.route() + def checkout(self, **post): + response = super(WebsiteSaleExtended, self).checkout(**post) + response.qcontext.update({'hide_quick_donation': True}) + return response + + @http.route() + def payment(self, **post): + response = super(WebsiteSaleExtended, self).payment(**post) + response.qcontext.update({'hide_quick_donation': True}) + return response + + @http.route() + def cart(self, access_token=None, revive='', **post): + response = super(WebsiteSaleExtended, self).cart(access_token, revive, **post) + response.qcontext.update({'hide_quick_donation': True}) + return response + + @http.route() + def product(self, product, category='', search='', **kwargs): + response = super(WebsiteSaleExtended, self).product(product, category, search, **kwargs) + response.qcontext.update({'hide_quick_donation': True, 'product_details': True}) + return response + + @http.route() + def shop(self, page=0, category=None, search='', min_price=0.0, max_price=0.0, ppg=False, **post): + response = super().shop(page=page, category=category, search=search, min_price=min_price, max_price=max_price, ppg=ppg, **post) + return response + + def check_mobile_number_validation(self, phone): + if phone[0] == '+' and phone[1] != '0': + if phone[1:4] == '966': + if len(phone[4:]) >= 8: + return phone + else: + phone = phone[0] + '966' + phone[1:] + elif phone[0] == '+' and phone[1] == '0': + phone = phone[0] + '966' + phone[2:] + elif phone[0] == '0' and phone[1] == '5': + phone = '+966' + phone[1:] + elif phone[0:2] == '00': # 00966555555555 + if phone[2:5] == '966': + phone = '+' + '966' + phone[5:] + elif phone[0] == '0': # 0966555555555 + if phone[1:4] == '966': + phone = '+' + '966' + phone[4:] + else: + if phone[0:3] == '966': + phone = '+' + phone + else: + phone = '+' + '966' + phone + return phone + + @http.route('/customer/data/save', type='json', auth='public', website=True) + def save_customer_data(self, **kwargs): + order = request.website.sale_get_order() + if order: + try: + string_phone_number = kwargs.get('extra_mobile', '') + string_name = kwargs.get('extra_name', '') + if string_phone_number: + string_phone_number = kwargs.get('extra_mobile', '') + string_phone_number = self.check_mobile_number_validation(string_phone_number) + phone_number = phonenumbers.parse(string_phone_number) + is_valid = phonenumbers.is_possible_number(phone_number) + if not is_valid: + raise ValidationError(_('Mobile Number is invalid!')) + order.sudo().write({ + 'order_mobile_number': string_phone_number.replace('+', ''), + }) + if string_name: + order.sudo().write({ + 'order_name': string_name + }) + except NumberParseException: + raise ValidationError(_('Mobile Number is invalid!')) + except Exception as e: + raise ValidationError(_(e)) + return True + + @http.route('/quickpay/hyperpay/payment/create', type='json', auth='public', website=True) + def quick_hyperpay_payment_trans_create(self, **kw): + success = False + order = request.website.sale_get_order(force_create=True) + product_id = kw.pop('product_id') + acquire_id = kw.pop('acquire_id') + mobile = kw.pop('mobile', '') + string_phone_number = self.check_mobile_number_validation(mobile) + phone_number = phonenumbers.parse(string_phone_number) + is_valid = phonenumbers.is_possible_number(phone_number) + if not is_valid: + raise ValidationError(_('Mobile Number is invalid!')) + if order: + if product_id: + product_id = request.env['product.product'].sudo().browse(int(product_id)) + if product_id: + order.order_line.sudo().unlink() + order.write({ + 'order_line': + [(0, 0, { + 'product_id': product_id.id, + 'product_uom_qty': 1, + 'price_unit': float(kw.get('amount')), + 'product_uom': product_id.uom_id.id + })], + 'order_mobile_number': string_phone_number.replace('+', '') + }) + try: + if acquire_id: + payment_acquire_id = request.env['payment.acquirer'].sudo().search( + [('code', 'in', ['hyperpay', 'applepay']), ('company_id', 'in', (False, order.company_id.id)), ('id', '=', int(acquire_id))], limit=1) + else: + payment_acquire_id = request.env['payment.acquirer'].sudo().search( + [('code', '=', 'hyperpay'), ('company_id', 'in', (False, order.company_id.id))], limit=1) + + # Create transaction + vals = {'acquirer_id': payment_acquire_id, + 'return_url': '/shop/payment/validate'} + + transaction = order._create_payment_transaction(vals) + + # store the new transaction into the transaction list and if there's an old one, we remove it + # until the day the ecommerce supports multiple orders at the same time + last_tx_id = request.session.get('__website_sale_last_tx_id') + last_tx = request.env['payment.transaction'].browse(last_tx_id).sudo().exists() + if last_tx: + PaymentProcessing.remove_payment_transaction(last_tx) + PaymentProcessing.add_payment_transaction(transaction) + request.session['__website_sale_last_tx_id'] = transaction.id + + for sale in transaction.sale_order_ids: + sale.done_with_quick_donation = True + final_vals = { + 'success': True, + 'tx_id': transaction.id + } + return final_vals + except Exception as e: + _logger.info("Error in Quick Donation Payment: %s" % (e)) + return {'success': success} diff --git a/odex25_donation/p_donation_theme/models/product.py b/odex25_donation/p_donation_theme/models/product.py index 409009af4..2ddde0df9 100644 --- a/odex25_donation/p_donation_theme/models/product.py +++ b/odex25_donation/p_donation_theme/models/product.py @@ -1,11 +1,9 @@ from odoo import models, fields, api, _ from dateutil.relativedelta import relativedelta from datetime import datetime -import calendar -import time -import logging -logger = logging.getLogger(__name__) +import logging +logger = logging.getLogger(__name__) class ProductTemplate_Inherit(models.Model): _inherit = 'product.template' @@ -196,10 +194,6 @@ class ProductTemplate_Inherit(models.Model): else: rec['donated_amount'] = 0 - - - - class ProductProduct_Inherit(models.Model): _inherit = 'product.product' diff --git a/odex25_donation/p_donation_theme/models/sale.py b/odex25_donation/p_donation_theme/models/sale.py index 2b6961ab0..f84577588 100644 --- a/odex25_donation/p_donation_theme/models/sale.py +++ b/odex25_donation/p_donation_theme/models/sale.py @@ -21,6 +21,19 @@ class SaleOrder_Inherit(models.Model): qty = kwargs.get('add_qty', False) or kwargs.get('set_qty', False) if qty and order_line: self.convert_donation_qty_to_price(order_line, qty) + if 'donators_ids' in kwargs: + order_line = self.env['sale.order.line'].browse(res.get('line_id')).sudo() + order_line.extra_donators_ids.sudo().unlink() + extra_donators_ids = [] + for i in json_scriptsafe.loads(kwargs.get('donators_ids')): + extra_donators_ids.append((0, 0, { + 'sale_id': order_line.order_id.id, + 'product_id': int(i.get('product_id')), + 'donated_amount': float(i.get('donated_amount')), + 'donator_name': i.get('donator_name'), + 'donator_mobile_number': i.get('donator_mobile_number') + })) + order_line.extra_donators_ids = extra_donators_ids return res def convert_donation_qty_to_price(self, order_line, qty): @@ -50,48 +63,6 @@ class SaleOrder_Inherit(models.Model): ) return call_super - def _prepare_order_line_values( - self, product_id, quantity, linked_line_id=False, - no_variant_attribute_values=None, product_custom_attribute_values=None, - **kwargs - ): - call_super = super(SaleOrder_Inherit, self)._prepare_order_line_values(product_id, quantity, linked_line_id, - no_variant_attribute_values, - product_custom_attribute_values, **kwargs) - - order_id = call_super.get('order_id') - if order_id and 'donators_ids' in kwargs: - extra_donators_ids = [] - for i in json_scriptsafe.loads(kwargs.get('donators_ids')): - extra_donators_ids.append((0, 0, { - 'sale_id': order_id, - 'product_id': int(i.get('product_id')), - 'donated_amount': float(i.get('donated_amount')), - 'donator_name': i.get('donator_name'), - 'donator_mobile_number': i.get('donator_mobile_number') - })) - call_super.update({'extra_donators_ids' : extra_donators_ids}) - return call_super - - def _prepare_order_line_update_values( - self, order_line, quantity, linked_line_id=False, **kwargs - ): - call_super = super(SaleOrder_Inherit, self)._prepare_order_line_update_values(order_line, quantity, linked_line_id, **kwargs) - - if order_line and 'donators_ids' in kwargs: - order_line.extra_donators_ids.sudo().unlink() - extra_donators_ids = [] - for i in json_scriptsafe.loads(kwargs.get('donators_ids')): - extra_donators_ids.append((0, 0, { - 'sale_id': order_line.order_id.id, - 'product_id': int(i.get('product_id')), - 'donated_amount': float(i.get('donated_amount')), - 'donator_name': i.get('donator_name'), - 'donator_mobile_number': i.get('donator_mobile_number') - })) - order_line.extra_donators_ids = extra_donators_ids - return call_super - class ExtraDonators(models.Model): _name = "sale.order.extra_donators" diff --git a/odex25_donation/p_donation_theme/static/description/index.html b/odex25_donation/p_donation_theme/static/description/index.html index fe8daffa6..b19184288 100644 --- a/odex25_donation/p_donation_theme/static/description/index.html +++ b/odex25_donation/p_donation_theme/static/description/index.html @@ -1,380 +1,380 @@ - - - - - - - - - - - - - -
-
-
-
-
- logo -
-
- Community - Enterprise - Odoo.sh -
-
-
-
-
- -
-
-
-

Ensan.sa new donation platform

- - heading -

this module changes odoo e-commerce interface to Ensan.sa interface

-
-
-
-
-
- -
- - -
-
-
-
-

Ensan.sa new donation platform -

- -
-
- -
-
-
-
- -
-
-
-
-
- -
-
- Odoo - Customization
-
- -
-
- -
-
- Odoo - Implementation
-
- -
-
- -
-
- Odoo - Support
-
- - -
-
- -
-
- Hire - Odoo - Developer
-
- -
-
- -
-
- Odoo - Integration
-
- -
-
- -
-
- Odoo - Migration
-
- - -
-
- -
-
- Odoo - Consultancy
-
- -
-
- -
-
- Odoo - Implementation
-
- -
-
- -
-
- Odoo - Licensing Consultancy
-
-
- -
-
-
-
-
-
-
- -
- Trading -
-

- Easily procure - and - sell your products

-
-
- -
-
- -
- POS -
-

- Easy - configuration - and convivial experience

-
-
- -
-
- -
- Education -
-

- A platform for - educational management

-
-
- -
-
- -
- Manufacturing -
-

- Plan, track and - schedule your operations

-
-
- -
-
- -
- E-commerce & Website -
-

- Mobile - friendly, - awe-inspiring product pages

-
-
- -
-
- -
- Service Management -
-

- Keep track of - services and invoice

-
-
- -
-
- -
- Restaurant -
-

- Run your bar or - restaurant methodically

-
-
- -
-
- -
- Hotel Management -
-

- An - all-inclusive - hotel management application

-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
- -
- -
-
-
- -
- -
-
- -
- + + + + + + + + + + + + + +
+
+
+
+
+ logo +
+
+ Community + Enterprise + Odoo.sh +
+
+
+
+
+ +
+
+
+

Ensan.sa new donation platform

+ + heading +

this module changes odoo e-commerce interface to Ensan.sa interface

+
+
+
+
+
+ +
+ + +
+
+
+
+

Ensan.sa new donation platform +

+ +
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+
+
+
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+ +
+ \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/img/facebook.svg b/odex25_donation/p_donation_theme/static/src/img/facebook.svg index cbb13c4b1..a6e48b6c7 100644 --- a/odex25_donation/p_donation_theme/static/src/img/facebook.svg +++ b/odex25_donation/p_donation_theme/static/src/img/facebook.svg @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/img/icon-eye.svg b/odex25_donation/p_donation_theme/static/src/img/icon-eye.svg index e51eaa62c..4c10f7a63 100644 --- a/odex25_donation/p_donation_theme/static/src/img/icon-eye.svg +++ b/odex25_donation/p_donation_theme/static/src/img/icon-eye.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/icon-hand.svg b/odex25_donation/p_donation_theme/static/src/img/icon-hand.svg index ba448078e..5bff669ca 100644 --- a/odex25_donation/p_donation_theme/static/src/img/icon-hand.svg +++ b/odex25_donation/p_donation_theme/static/src/img/icon-hand.svg @@ -1,30 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/icon-last-donation.svg b/odex25_donation/p_donation_theme/static/src/img/icon-last-donation.svg index b920cc1ad..c8a3b1695 100644 --- a/odex25_donation/p_donation_theme/static/src/img/icon-last-donation.svg +++ b/odex25_donation/p_donation_theme/static/src/img/icon-last-donation.svg @@ -1,18 +1,18 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/icon-users.svg b/odex25_donation/p_donation_theme/static/src/img/icon-users.svg index c088b89cc..55ec54eaf 100644 --- a/odex25_donation/p_donation_theme/static/src/img/icon-users.svg +++ b/odex25_donation/p_donation_theme/static/src/img/icon-users.svg @@ -1,61 +1,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/icons-gift-green.svg b/odex25_donation/p_donation_theme/static/src/img/icons-gift-green.svg index b2a079b69..aa61b880d 100644 --- a/odex25_donation/p_donation_theme/static/src/img/icons-gift-green.svg +++ b/odex25_donation/p_donation_theme/static/src/img/icons-gift-green.svg @@ -1,3 +1,3 @@ - - - + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/rounded-applepay.svg b/odex25_donation/p_donation_theme/static/src/img/rounded-applepay.svg index dd469503e..ae57a85b2 100644 --- a/odex25_donation/p_donation_theme/static/src/img/rounded-applepay.svg +++ b/odex25_donation/p_donation_theme/static/src/img/rounded-applepay.svg @@ -1,14 +1,14 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/rounded-mada.svg b/odex25_donation/p_donation_theme/static/src/img/rounded-mada.svg index 6e1b211eb..ce990b428 100644 --- a/odex25_donation/p_donation_theme/static/src/img/rounded-mada.svg +++ b/odex25_donation/p_donation_theme/static/src/img/rounded-mada.svg @@ -1,20 +1,20 @@ - - - - - - - + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/rounded-mastercard.svg b/odex25_donation/p_donation_theme/static/src/img/rounded-mastercard.svg index 3ff39ce8c..e0e0e5434 100644 --- a/odex25_donation/p_donation_theme/static/src/img/rounded-mastercard.svg +++ b/odex25_donation/p_donation_theme/static/src/img/rounded-mastercard.svg @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/rounded-visa.svg b/odex25_donation/p_donation_theme/static/src/img/rounded-visa.svg index 17fc4ec46..24a306c44 100644 --- a/odex25_donation/p_donation_theme/static/src/img/rounded-visa.svg +++ b/odex25_donation/p_donation_theme/static/src/img/rounded-visa.svg @@ -1,14 +1,14 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/img/twitter.svg b/odex25_donation/p_donation_theme/static/src/img/twitter.svg index 50f3b0e57..4639c5d91 100644 --- a/odex25_donation/p_donation_theme/static/src/img/twitter.svg +++ b/odex25_donation/p_donation_theme/static/src/img/twitter.svg @@ -1,7 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/img/visa_dimmed.svg b/odex25_donation/p_donation_theme/static/src/img/visa_dimmed.svg index 22e25635d..6b339aefc 100644 --- a/odex25_donation/p_donation_theme/static/src/img/visa_dimmed.svg +++ b/odex25_donation/p_donation_theme/static/src/img/visa_dimmed.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/odex25_donation/p_donation_theme/static/src/js/checkout.js b/odex25_donation/p_donation_theme/static/src/js/checkout.js index a3b76c3f3..b8a390796 100644 --- a/odex25_donation/p_donation_theme/static/src/js/checkout.js +++ b/odex25_donation/p_donation_theme/static/src/js/checkout.js @@ -1,103 +1,99 @@ -odoo.define('p_donation_theme.payment', require => { - 'use strict'; - - const checkoutForm = require('payment.checkout_form'); - const publicWidget = require('web.public.widget'); - const manageForm = require('payment.manage_form'); - function ArabictoEnglishNumber(strNum) { - var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); - var en = '0123456789'.split(''); - strNum = strNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, x => en[ar.indexOf(x)]); - strNum = strNum.replace(/[^\d]/g, ''); - return strNum; - } - const websiteSaleextraMixin = { - - init: function() { - this._onCheck_extra_validation = _.debounce(this._onCheck_extra_validation, 100, true); - this._super(...arguments); - }, - - start: function() { - this.$submitButton = this.$('button[name="o_payment_submit_button"]'); - this._adaptConfirmButton(); - return this._super(...arguments); - }, - - _adaptConfirmButton: function() { - if (this.$('#order_mobile_number').length > 0) { - const disabledReasons = this.$submitButton.data('disabled_reasons') || {}; - disabledReasons.omn = !this.$('#order_mobile_number').val(); - this.$submitButton.data('disabled_reasons', disabledReasons); - } - }, - - }; - - checkoutForm.include(Object.assign({}, websiteSaleextraMixin, { - events: Object.assign({}, checkoutForm.prototype.events, { - 'input #order_mobile_number':'_convert_arabic_to_english' - }), - _convert_arabic_to_english(ev) { - ev.currentTarget.value = ArabictoEnglishNumber(ev.currentTarget.value) - this._onCheck_extra_validation(); - }, - _isButtonReady: function() { - const disabledReasonFound = _.contains( - this.$submitButton.data('disabled_reasons'), true - ); - return !disabledReasonFound && this._super(); - }, - _onCheck_extra_validation: function() { - this._adaptConfirmButton(); - - if (!this._enableButton()) { - this._disableButton(false); - } - }, - - })); - - publicWidget.registry.WebsiteSaleExtraField = publicWidget.Widget.extend( - Object.assign({}, websiteSaleextraMixin, { - selector: 'div[name="o_website_sale_free_cart"]', - events: { - 'change #order_mobile_number': '_onCheck_extra_validation', - }, - - start: function() { - this.$submitButton = this.$('button[name="o_payment_submit_button"]'); - this._onCheck_extra_validation(); - return this._super(...arguments); - }, - - _onCheck_extra_validation: function() { - this._adaptConfirmButton(); - - const disabledReasonFound = _.contains( - this.$submitButton.data('disabled_reasons'), true - ); - this.$submitButton.prop('disabled', disabledReasonFound); - }, - }) - ); - - - - const ExtraFieldMixin = { - _prepareTransactionRouteParams: function(code, paymentOptionId, flow) { - const transactionRouteParams = this._super(...arguments); - var extra_name = this.$('#order_name'); - var extra_mobile = this.$('#order_mobile_number'); - return { - ...transactionRouteParams, - 'extra_name': extra_name.length > 0 ? extra_name.val() : null, - 'extra_mobile': extra_mobile.length > 0 ? extra_mobile.val() : null, - }; - }, - - }; - - checkoutForm.include(ExtraFieldMixin); - manageForm.include(ExtraFieldMixin); +odoo.define('p_donation_theme.payment', require => { + 'use strict'; + + const publicWidget = require('web.public.widget'); + const paymentForm = require('payment.payment_form'); + + function ArabictoEnglishNumber(strNum) { + var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); + var en = '0123456789'.split(''); + strNum = strNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, x => en[ar.indexOf(x)]); + strNum = strNum.replace(/[^\d]/g, ''); + return strNum; + } + + const websiteSaleextraMixin = { + + init: function() { + this._onCheck_extra_validation = _.debounce(this._onCheck_extra_validation, 100, true); + this._super(...arguments); + }, + + start: function() { + this.$submitButton = this.$('button[name="o_payment_submit_button"]'); + this._adaptConfirmButton(); + return this._super(...arguments); + }, + + _adaptConfirmButton: function() { + if (this.$('#order_mobile_number').length > 0) { + const disabledReasons = this.$submitButton.data('disabled_reasons') || {}; + disabledReasons.omn = !this.$('#order_mobile_number').val(); + this.$submitButton.data('disabled_reasons', disabledReasons); + } + }, + + }; + + paymentForm.include( + Object.assign({}, websiteSaleextraMixin, { + events: _.extend(paymentForm.prototype.events, { + 'input #order_mobile_number':'_convert_arabic_to_english' + }), + + _convert_arabic_to_english(ev) { + ev.currentTarget.value = ArabictoEnglishNumber(ev.currentTarget.value) + this._onCheck_extra_validation(); + }, + _isButtonReady: function() { + const disabledReasonFound = _.contains( + this.$submitButton.data('disabled_reasons'), true + ); + return !disabledReasonFound && this._super(); + }, + _onCheck_extra_validation: function() { + this._adaptConfirmButton(); + + if (!this._enableButton()) { + this._disableButton(false); + } + }, + payEvent: function (ev) { + this._rpc({ + route: '/customer/data/save', + params: { + extra_name: this.$('#order_name').val(), + extra_mobile: this.$('#order_mobile_number').val(), + } + }).catch(error => { + console.error(error); + }); + this._super(ev); + } + }) + ); + + publicWidget.registry.WebsiteSaleExtraField = publicWidget.Widget.extend( + Object.assign({}, websiteSaleextraMixin, { + selector: 'div[name="o_website_sale_free_cart"]', + events: { + 'change #order_mobile_number': '_onCheck_extra_validation', + }, + + start: function() { + this.$submitButton = this.$('button[name="o_payment_submit_button"]'); + this._onCheck_extra_validation(); + return this._super(...arguments); + }, + + _onCheck_extra_validation: function() { + this._adaptConfirmButton(); + + const disabledReasonFound = _.contains( + this.$submitButton.data('disabled_reasons'), true + ); + this.$submitButton.prop('disabled', disabledReasonFound); + }, + }) + ); }); \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/js/hyperpay_quick_donation.js b/odex25_donation/p_donation_theme/static/src/js/hyperpay_quick_donation.js index 89ade7a72..bd9b5eb86 100644 --- a/odex25_donation/p_donation_theme/static/src/js/hyperpay_quick_donation.js +++ b/odex25_donation/p_donation_theme/static/src/js/hyperpay_quick_donation.js @@ -1,255 +1,283 @@ -odoo.define('p_donation_theme.quick_donation_hyperpay', function(require) { - "use strict"; - - var core = require('web.core'); - var Dialog = require('web.Dialog'); - var publicWidget = require('web.public.widget'); - var ajax = require('web.ajax'); - const { - assets - } = require('@web/core/assets'); - - var qweb = core.qweb; - var _t = core._t; - - function ArabictoEnglishNumber(strNum) { - var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); - var en = '0123456789'.split(''); - strNum = strNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, x => en[ar.indexOf(x)]); - strNum = strNum.replace(/[^\d]/g, ''); - return strNum; - } - - // Reference - // https://dev.to/pulljosh/how-to-load-html-css-and-js-code-into-an-iframe-2blc - const getGeneratedPageURL = ({ - html, - css, - js - }) => { - const getBlobURL = (code, type) => { - const blob = new Blob([code], { - type - }) - return URL.createObjectURL(blob) - } - - const source = ` - - - ${css} - ${js} - - - - - ${html || ''} - - - ` - - return getBlobURL(source, 'text/html') - } - - var QuickDonation_HyperpayPaymentForm = publicWidget.Widget.extend({ - init: function() { - this.quick_donation = $('#quick-donation-widget'); - this.tx_id = this.quick_donation.find('#hyperpay_tx').val(); - this._initBlockUI(); - this.start(); - }, - start: function() { - var self = this; - self._createHyperpayCheckoutId(); - }, - _createHyperpayCheckoutId: function() { - var self = this; - ajax.jsonRpc('/payment/hyperpay/checkout/create', 'call', { - 'txId': self.tx_id - }) - .then(function(result) { - if (result) { - self._renderHyperpayModal(result.checkoutId, result.domain, result.base_url, result.data_brands, result.acq); - } else { - console.log('Error Occured'); - } - }); - }, - _renderHyperpayModal: function(checkoutId, domain, base_url, data_brands, acq) { - var self = this; - try { - var $quick_donation_tag = this.quick_donation.find("#quick-donation-3") - var style_css = '' - var script = '' - var js_script = '' - var shopperResultUrlTag = '
' - var theIframe = document.createElement("iframe"); - theIframe.id = "quick_donation_hyperpay_iframe"; - theIframe.style = "display:none"; - var html = script + shopperResultUrlTag; - - const url = getGeneratedPageURL({ - html: html, - css: style_css, - js: js_script - }) - theIframe.src = url; - $quick_donation_tag[0].appendChild(theIframe); - $quick_donation_tag.addClass("show"); - } catch (err) { - console.log('component error:', err); - } - - }, - _initBlockUI: function() { - if (this.quick_donation.length > 0) { - this.quick_donation.find("#qn-spinner").removeClass('o_hidden') - this.quick_donation.find("#qd-options").addClass("blur_disabled"); - } - }, - - }); - - $(document).ready(function() { - $("#quick-donation-widget #quick-donation-button").on("click", function(ev){ - $("#quick-donation-widget").toggleClass("has-focus"); - }); - - $("#quick-donation-widget #qd-options li").on("click", function(ev){ - $("#quick-donation-widget #qd-options li").removeClass('active') - $(this).addClass('active') - }); - - $("#quick-donation-widget .pre-amount").on("click", function(ev){ - $('#quick-donation-widget #qd_amount').val(ev.currentTarget.dataset.amount); - }); - - $("#quick-donation-widget #editAmountBtn").on("click", function(ev){ - $('#quick-donation-widget .payment-info-box .amount-display').toggleClass('toggle-hide') - $('#quick-donation-widget .payment-info-box input').toggleClass('toggle-hide') - }); - - $("#vit-product-grid input.allow-ar-number").on("input", function(ev) { - $(this).val(ArabictoEnglishNumber($(this).val())) - }); - - $("#quick-donation-widget input.allow-ar-number").on("input", function(ev) { - $(this).val(ArabictoEnglishNumber($(this).val())) - }); - - $("#quick-donation-widget .payment-methods img").on("click", function(ev){ - $("#quick-donation-widget .payment-methods img").removeClass('active'); - $(this).addClass('active'); - }); - - $("#quick-donation-widget #qd-checkout-buuton").on("click", function(ev){ - var amount = $('#quick-donation-widget #qd_amount'); - var acquire_id = $("#quick-donation-widget .payment-methods img.active") - var product_id = $("#quick-donation-widget #qd-options li.active") - var mobile = $("#quick-donation-widget #qd_mobile_number") - var is_valid = false; - if (!amount.val() || amount.val() <= 0) { - amount.addClass("is-invalid"); - amount.removeClass("is-valid"); - $('#quick-donation-widget .field-validation-error').text("Invalid Amount!"); - } else if(!mobile.val() || mobile.val() <= 0) { - mobile.addClass("is-invalid"); - mobile.removeClass("is-valid"); - } else if(product_id.length == 0) { - $('#quick-donation-widget #donate_error_msg').removeClass('o_hidden').text("Missing Product.") - } else if(acquire_id.length == 0) { - $('#quick-donation-widget #donate_error_msg').removeClass('o_hidden').text("Click on Payment Icon to Proceed.") - } else { - amount.addClass("is-valid"); - amount.removeClass("is-invalid"); - $('#quick-donation-widget .field-validation-error').text(""); - $('#quick-donation-widget #donate_error_msg').addClass('o_hidden').text("") - is_valid = true; - } - if (is_valid) { - var quick_pay_detail = {}; - quick_pay_detail['amount'] = amount.val() - $('#quick-donation-widget #quick-donation-1').toggleClass('show'); - if (product_id.length > 0) { - product_id = product_id[0].dataset.product_id - } - else { - $('#quick-donation-widget #qn-failure').removeClass('o_hidden'); - } - quick_pay_detail['product_id'] = product_id; - quick_pay_detail['acquire_id'] = acquire_id[0].dataset.acquireId; - quick_pay_detail['mobile'] = mobile.val(); - ajax.jsonRpc('/quickpay/hyperpay/payment/create', 'call', quick_pay_detail) - .then(function (result) { - if (result['success'] && result['redirect_url']) { - - window.location.href = result['redirect_url'] - } - else if (result['success']) { - $('#quick-donation-widget #hyperpay_tx').val(result['tx_id']); - new QuickDonation_HyperpayPaymentForm(); - } - else { - $('#quick-donation-widget #qn-failure').removeClass('o_hidden'); - } - }); - } - }); - - }); - +odoo.define('p_donation_theme.quick_donation_hyperpay', function(require) { + "use strict"; + + var publicWidget = require('web.public.widget'); + var ajax = require('web.ajax'); + + function ArabictoEnglishNumber(strNum) { + var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); + var en = '0123456789'.split(''); + strNum = strNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, x => en[ar.indexOf(x)]); + strNum = strNum.replace(/[^\d]/g, ''); + return strNum; + } + + // Reference + // https://dev.to/pulljosh/how-to-load-html-css-and-js-code-into-an-iframe-2blc + const getGeneratedPageURL = ({ + html, + css, + js + }) => { + const getBlobURL = (code, type) => { + const blob = new Blob([code], { + type + }) + return URL.createObjectURL(blob) + } + + const source = ` + + + ${css} + ${js} + + + + + ${html || ''} + + + ` + + return getBlobURL(source, 'text/html') + } + + var QuickDonation_HyperpayPaymentForm = publicWidget.Widget.extend({ + init: function() { + this.quick_donation = $('#quick-donation-widget'); + this.tx_id = this.quick_donation.find('#hyperpay_tx').val(); + this._initBlockUI(); + this.start(); + }, + start: function() { + var self = this; + self._createHyperpayCheckoutId(); + }, + _createHyperpayCheckoutId: function() { + var self = this; + ajax.jsonRpc('/payment/hyperpay/checkout/create', 'call', { + 'txId': self.tx_id + }) + .then(function(result) { + if (result) { + self._renderHyperpayModal(result.checkoutId, result.domain, result.base_url, result.data_brands, result.acq); + } else { + console.log('Error Occured'); + } + }); + }, + _renderHyperpayModal: function(checkoutId, domain, base_url, data_brands, acq) { + var self = this; + try { + var $quick_donation_tag = this.quick_donation.find("#quick-donation-3") + var style_css = '' + var script = '' + var js_script = '' + var shopperResultUrlTag = '
' + var theIframe = document.createElement("iframe"); + theIframe.id = "quick_donation_hyperpay_iframe"; + theIframe.style = "display:none"; + var html = script + shopperResultUrlTag; + + const url = getGeneratedPageURL({ + html: html, + css: style_css, + js: js_script + }) + theIframe.src = url; + $quick_donation_tag[0].appendChild(theIframe); + $quick_donation_tag.addClass("show"); + } catch (err) { + console.log('component error:', err); + } + + }, + _initBlockUI: function() { + if (this.quick_donation.length > 0) { + this.quick_donation.find("#qn-spinner").removeClass('o_hidden') + this.quick_donation.find("#qd-options").addClass("blur_disabled"); + } + }, + + }); + + $(document).ready(function() { + $("#quick-donation-widget #quick-donation-button").on("click", function(ev){ + $("#quick-donation-widget").toggleClass("has-focus"); + }); + + $("#quick-donation-widget #qd-options li").on("click", function(ev){ + $("#quick-donation-widget #qd-options li").removeClass('active') + $(this).addClass('active') + $('#qd-options').trigger('change'); + }); + + $("#quick-donation-widget .pre-amount").on("click", function(ev){ + const $qdAmounnt = $('#quick-donation-widget #qd_amount'); + $qdAmounnt.val(ev.currentTarget.dataset.amount); + $qdAmounnt.trigger('change'); + }); + + $("#quick-donation-widget #editAmountBtn").on("click", function(ev){ + $('#quick-donation-widget .payment-info-box .amount-display').toggleClass('toggle-hide') + $('#quick-donation-widget .payment-info-box input').toggleClass('toggle-hide') + }); + + $("#vit-product-grid input.allow-ar-number").on("input", function(ev) { + $(this).val(ArabictoEnglishNumber($(this).val())) + }); + + $("#quick-donation-widget input.allow-ar-number").on("input", function(ev) { + $(this).val(ArabictoEnglishNumber($(this).val())) + }); + + $("#quick-donation-widget .payment-methods img").on("click", function(ev){ + $("#quick-donation-widget .payment-methods img").removeClass('active'); + $(this).addClass('active'); + }); + + $("#quick-donation-widget #qd-checkout-buuton").on("click", function(ev){ + var amount = $('#quick-donation-widget #qd_amount'); + var acquire_id = $("#quick-donation-widget .payment-methods img.active") + var product_id = $("#quick-donation-widget #qd-options li.active") + var mobile = $("#quick-donation-widget #qd_mobile_number") + const mobileRegex = /^(?:(\+966|00966|0)?5[0-9]{8}|5[0-9]{8})$/; + + var is_valid = false; + if (!amount.val() || amount.val() <= 0) { + amount.addClass("is-invalid"); + amount.removeClass("is-valid"); + $('#quick-donation-widget .field-validation-error').text("Invalid Amount!"); + } else if(!mobileRegex.test(mobile.val())) { + mobile.removeClass('is-valid').addClass('is-invalid'); + } else if(product_id.length == 0) { + $('#quick-donation-widget #donate_error_msg').removeClass('o_hidden').text("Missing Product.") + } else if(acquire_id.length == 0) { + $('#quick-donation-widget #donate_error_msg').removeClass('o_hidden').text("Click on Payment Icon to Proceed.") + } else { + amount.addClass("is-valid"); + amount.removeClass("is-invalid"); + $('#quick-donation-widget .field-validation-error').text(""); + $('#quick-donation-widget #donate_error_msg').addClass('o_hidden').text("") + is_valid = true; + } + if (is_valid) { + var quick_pay_detail = {}; + quick_pay_detail['amount'] = amount.val() + $('#quick-donation-widget #quick-donation-1').toggleClass('show'); + if (product_id.length > 0) { + product_id = product_id[0].dataset.product_id + } + else { + $('#quick-donation-widget #qn-failure').removeClass('o_hidden'); + } + quick_pay_detail['product_id'] = product_id; + quick_pay_detail['acquire_id'] = acquire_id[0].dataset.acquireId; + quick_pay_detail['mobile'] = mobile.val(); + ajax.jsonRpc('/quickpay/hyperpay/payment/create', 'call', quick_pay_detail) + .then(function (result) { + if (result['success'] && result['redirect_url']) { + + window.location.href = result['redirect_url'] + } + else if (result['success']) { + $('#quick-donation-widget #hyperpay_tx').val(result['tx_id']); + new QuickDonation_HyperpayPaymentForm(); + } + else { + $('#quick-donation-widget #qn-failure').removeClass('o_hidden'); + } + }); + } + }); + + }); + + publicWidget.registry.QuickDonationApplePay = publicWidget.Widget.extend({ + selector: '#quick-donation-widget', + events: { + "change #qd_amount": "updateApplePayCheckoutAmount", + "input #qd_mobile_number": "checkMobileNumberFormat" + }, + async start() { + await this._super(...arguments); + const amounts = this.$('.pre-amount'); + if (amounts.length > 0) { + this.$('#qd_amount').val(amounts.get(0).dataset.amount); + } + }, + updateApplePayCheckoutAmount: function() { + const event = new CustomEvent('applePayAmountUpdate', { + detail: { amount: this.$('#qd_amount').val() } + }); + document.dispatchEvent(event); + }, + checkMobileNumberFormat: function() { + const mobileInput = this.$('#qd_mobile_number'); + const mobileRegex = /^(?:(\+966|00966|0)?5[0-9]{8}|5[0-9]{8})$/; + + if (mobileRegex.test(mobileInput.val())) { + mobileInput.removeClass('is-invalid').addClass('is-valid'); + } else { + mobileInput.removeClass('is-valid').addClass('is-invalid'); + } + } + + }); + }); \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/js/product-gift-card.js b/odex25_donation/p_donation_theme/static/src/js/product-gift-card.js index 1c725f6b9..2803b4932 100644 --- a/odex25_donation/p_donation_theme/static/src/js/product-gift-card.js +++ b/odex25_donation/p_donation_theme/static/src/js/product-gift-card.js @@ -1,9 +1,8 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { "use strict"; require('web.dom_ready'); - var ajax = require('web.ajax'); var publicWidget = require('web.public.widget'); - const {qweb, _t} = require('web.core'); + const {qweb} = require('web.core'); function ArabictoEnglishNumber(strNum) { var ar = '٠١٢٣٤٥٦٧٨٩'.split(''); @@ -24,15 +23,46 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { 'change .donation-product-detail-layout #sendAsGiftCheckbox': '_donation_toggle_gift_container', 'click .donation-product-detail-layout .single-amount': '_update_default_amt', 'click .donation_share_btn': '_open_share_popup', + 'change .donation-product-detail-layout input.donation-input-amt': '_update_apple_pay_amount', 'input form input[name="add_qty"]': '_convert_arabic_to_english', 'input .donation-product-detail-layout input.only-number, .donation-product-detail-layout input.input-gifteeNumber, .donation-product-detail-layout input.number-input, .donation-product-detail-layout input.update_amount': '_convert_arabic_to_english' }), + xmlDependencies: ["/p_donation_theme/static/src/xml/donation.xml"], _convert_arabic_to_english(ev) { ev.currentTarget.value = ArabictoEnglishNumber(ev.currentTarget.value) - }, + async start() { + await this._super(...arguments); + const amounts = this.$('.donation-product-detail-layout .single-amount'); + const fixedQty = this.$('#fixedqtyinput-1'); + const $amountEl = this.$('input.donation-input-amt'); + if (amounts.length > 0) { + $amountEl.val(amounts.get(0).dataset.amount); + } else{ + $amountEl.val(fixedQty.data('price')); + } + }, + _update_apple_pay_amount() { + let total = 0; + const isGift = this.$('#sendAsGiftCheckbox').is(':checked'); + if (isGift) { + this.$('input.gift-donation-amount').each(function() { + const value = $(this).val(); + if (value) { + total += parseFloat(value, 10) || 0; + } + }); + } else { + total = this.$('input.personal-donation-amount').val() || 0; + } + const event = new CustomEvent('applePayAmountUpdate', { + detail: { amount: total } + }); + document.dispatchEvent(event); + + }, _submitForm() { const params = this.rootProduct; const $product = $('#product_detail'); @@ -60,9 +90,11 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { }, _onchange_quantity_price(ev) { - var price = ev.currentTarget.dataset.price - var qty = ArabictoEnglishNumber(ev.target.value) - $(ev.target).parent().parent().parent().find("input[inputmode=numeric]").val(price*qty) + var price = ev.currentTarget.dataset.price; + var qty = ArabictoEnglishNumber(ev.target.value); + const $amountEl = $(ev.target).parent().parent().parent().find("input[inputmode=numeric]"); + $amountEl.val(price*qty); + $amountEl.trigger('change'); }, _open_share_popup(ev) { @@ -109,10 +141,12 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { _donation_gift_input_amt(ev) { $(ev.target).parent().parent().parent().find("input.AnotherAmountAdd").val(ev.target.value) + this.$('input.donation-input-amt').trigger('change'); }, _donation_remove_gift_container(ev) { $(ev.target).closest(".gifteeBoxDetails").remove(); + this.$('input.donation-input-amt').trigger('change'); }, _donation_add_gift_container() { @@ -127,7 +161,9 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { } else { $(this).prop('id', temp_id_list[0].concat('-' + (parseInt(temp_id_list[1]) + 1)) ); - $(this).prop('value', ''); + if (!$(this).hasClass('donation-input-amt')){ + $(this).prop('value', ''); + } } var temp_name = $(this).prop("name") var temp_name_list = temp_name.split('-') @@ -147,6 +183,7 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { var temp_id_list = temp_id.split('-') new_box.prop('id', temp_id_list[0].concat('-' + (parseInt(temp_id_list[1]) + 1)) ); new_box.appendTo(".donation-product-detail-layout #gifteeContainer"); + this.$('input.donation-input-amt').trigger('change'); }, _donation_toggle_gift_container(ev) { @@ -157,9 +194,11 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { $(".donation-product-detail-layout .ProhectDetailsSubBox").find("input[inputmode=numeric]").val('') } else { - $(".donation-product-detail-layout #gift-details" ).hide(); - $(".donation-product-detail-layout .ProhectDetailsSubBox").removeClass("is-disabled"); + this.$('#gift-details input.donation-input-amt').val(''); + $(".donation-product-detail-layout #gift-details" ).hide(); + $(".donation-product-detail-layout .ProhectDetailsSubBox").removeClass("is-disabled"); } + this.$('input.donation-input-amt').trigger('change'); }, async _donation_total_amount() { @@ -183,7 +222,9 @@ odoo.define('p_donation_theme.product-gift-card', function (require) { }, _update_default_amt(ev) { - $("input.input-another-amount").val(ev.currentTarget.dataset.amount) + const $amountEl = $("input.input-another-amount"); + $amountEl.val(ev.currentTarget.dataset.amount); + $amountEl.trigger("change"); }, _is_all_input_valid() { diff --git a/odex25_donation/p_donation_theme/static/src/js/website_sale_tracking.js b/odex25_donation/p_donation_theme/static/src/js/website_sale_tracking.js new file mode 100644 index 000000000..7d877675a --- /dev/null +++ b/odex25_donation/p_donation_theme/static/src/js/website_sale_tracking.js @@ -0,0 +1,43 @@ +odoo.define('p_donation_theme.website_sale_tracking', function (require) { + 'use strict'; + + const tracking = require('website_sale.tracking'); + + tracking.include({ + events: _.extend(tracking.prototype.events, { + 'click a[href="/shop/checkout?express=1"]': '_onCheckoutStart', + }), + _onCheckoutStart: function (ev) { + ev.preventDefault(); + this._super.apply(this, arguments); + this._beginCheckoutGA4(); + setTimeout(function(){ + window.location.href = ev.currentTarget.href; + }, 1000); + }, + _onAddProductIntoCart: function (ev) { + this._super.apply(this, arguments); + const $product = $(ev.target.closest('form')); + const productTrackingInfo = JSON.parse($product.find('input[name="product-tracking-info"]').val()); + productTrackingInfo.quantity = 1; + $product.trigger('add_to_cart_event', [productTrackingInfo]); + }, + _beginCheckoutGA4: function () { + let $productRows = $("table#cart_products tbody tr"); + let items = $productRows.map(function() { + let result = {}; + let $el = $(this); + result.id = parseInt($el.data('product-id')); + result.quantity = parseInt($el.find('td.td-qty input').val()) || 1; + result.name = ($el.find('.td-product_name a').text() || '').trim(); + result.currency = ($('form[name="o_payment_express_checkout_form"]').attr('data-currency-name') || 'SAR').toUpperCase(); + result.price_unit= parseFloat($el.find('td.td-price span.oe_currency_value').text() || $el.find('td.td-price input').val()); + return result; + }).get(); + this._trackGA('event', 'begin_checkout', { + items: items, + }); + }, + }); + return tracking; +}); \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/scss/hyperpay_quick_donation.scss b/odex25_donation/p_donation_theme/static/src/scss/hyperpay_quick_donation.scss index 6d7c0e470..2d867982b 100644 --- a/odex25_donation/p_donation_theme/static/src/scss/hyperpay_quick_donation.scss +++ b/odex25_donation/p_donation_theme/static/src/scss/hyperpay_quick_donation.scss @@ -28,6 +28,7 @@ .wpwl-form { background-color:#196956; margin:0px; + max-width: 100%; } .wpwl-button-pay { @@ -43,4 +44,12 @@ .wpwl-label { color:white; -} \ No newline at end of file +} + +.apple-pay-button-container { + width: 100%; + height: 100%; + border: none; + overflow: hidden; + margin-bottom: 10px; +} diff --git a/odex25_donation/p_donation_theme/static/src/scss/primary_variables.scss b/odex25_donation/p_donation_theme/static/src/scss/primary_variables.scss index 7220bcfca..83b4c2517 100644 --- a/odex25_donation/p_donation_theme/static/src/scss/primary_variables.scss +++ b/odex25_donation/p_donation_theme/static/src/scss/primary_variables.scss @@ -1,17 +1,17 @@ -$o-theme-font-configs: map-merge($o-theme-font-configs, ( - 'Greta-Arabic-Bold': ( - 'family': ('Greta-Arabic-Bold'), - ), - 'Greta-AR-LT-Bold': ( - 'family': ('Greta-AR-LT-Bold'), - ), - 'Greta-AR-LT-Semibold': ( - 'family': ('Greta-AR-LT-Semibold'), - ), - 'Greta-AR-LT-Regular': ( - 'family': ('Greta-AR-LT-Regular'), - ), - 'Greta-AR-LT-Light': ( - 'family': ('Greta-AR-LT-Light'), - ), +$o-theme-font-configs: map-merge($o-theme-font-configs, ( + 'Greta-Arabic-Bold': ( + 'family': ('Greta-Arabic-Bold'), + ), + 'Greta-AR-LT-Bold': ( + 'family': ('Greta-AR-LT-Bold'), + ), + 'Greta-AR-LT-Semibold': ( + 'family': ('Greta-AR-LT-Semibold'), + ), + 'Greta-AR-LT-Regular': ( + 'family': ('Greta-AR-LT-Regular'), + ), + 'Greta-AR-LT-Light': ( + 'family': ('Greta-AR-LT-Light'), + ), )); \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/static/src/scss/theme.scss b/odex25_donation/p_donation_theme/static/src/scss/theme.scss index ea8a334c7..abbbedb57 100644 --- a/odex25_donation/p_donation_theme/static/src/scss/theme.scss +++ b/odex25_donation/p_donation_theme/static/src/scss/theme.scss @@ -13389,4 +13389,63 @@ .apple-pay-button-white-with-line { -apple-pay-button-style: white-outline } +} + + +#payment_method { + position: relative; + .card{ + margin-bottom: 45px; + } + .apple-pay-button-container { + position: absolute; + bottom: 40px; + height: auto; + margin: 0; + } +} + +@media (max-width: 399.99px) { + #payment_method { + .apple-pay-button-container { + bottom: 40px; + } + } +} + +// X-Small devices (portrait phones, less than 576px) +@media (min-width: 400px) and (max-width: 575.98px) { + #payment_method { + + .apple-pay-button-container { + bottom: 40px; + } + } +} + +// Small devices (landscape phones, less than 768px) +@media (min-width: 576px) and (max-width: 767.98px) { + #payment_method { + .apple-pay-button-container { + bottom: 40px; + } + } +} + +// Medium devices (tablets, less than 992px) +@media (min-width: 768px) and (max-width: 991.98px) { + #payment_method { + .apple-pay-button-container { + bottom: 40px; + } + } +} + +// Large devices (desktops, less than 1200px) +@media (min-width: 992px) and (max-width: 1199.98px) { + #payment_method { + .apple-pay-button-container { + bottom: 40px; + } + } } \ No newline at end of file diff --git a/odex25_donation/p_donation_theme/views/templates.xml b/odex25_donation/p_donation_theme/views/templates.xml index fd595c10b..9487e393d 100644 --- a/odex25_donation/p_donation_theme/views/templates.xml +++ b/odex25_donation/p_donation_theme/views/templates.xml @@ -1,1404 +1,1442 @@ - - - - - Product Item Grid: Donation Style - qweb - theme_prime.product_item_grid_3 - - -
- - -
- - -
-
-
-
-
-
-
- -
-
Target
-
- - -
-
-
-
-
-
-
Amount
-
- - - -
-
-
- -
-
-
  
-
  
-
-
-
-
-
- -
-
Remaining
-
- - -
-
-
-
-
-
-
-
- - - - - - - -
-
-
- - - - -
-
Valid Amount!
-
Invalid Amount!
-
-
-
-
- -
- - - - - - - -
- - - - -

- -
-
- -
-
- - - shop_layout: Donation Style - qweb - p_donation_theme.shop_layout - - - - - row row-cols-#{1 if _config_product_item.get('style') == '3' else 2} - row-cols-md-#{ppr >= 3 and 3 or ppr} row-cols-lg-#{ppr} g-2 g-lg-3 mt-0 - - - - - - - - - - - - - - -
+ + + + + Product Item Grid: Donation Style + qweb + theme_prime.product_item_grid_3 + + +
+ + + + +
+ + +
+
+
+
+
+
+
+ +
+
Target
+
+ + +
+
+
+
+
+
+
Amount
+
+ + + +
+
+
+ +
+
+
  
+
  
+
+
+
+
+
+ +
+
Remaining
+
+ + +
+
+
+
+
+
+
+
+ + + + + + + +
+
+
+ + + + +
+
Valid Amount!
+
Invalid Amount!
+
+
+
+
+ +
+ + + + + + + +
+ + + + +

+ +
+
+ +
+
+ + + shop_layout: Donation Style + qweb + p_donation_theme.shop_layout + + + + + row row-cols-#{1 if _config_product_item.get('style') == '3' else 2} + row-cols-md-#{ppr >= 3 and 3 or ppr} row-cols-lg-#{ppr} g-2 g-lg-3 mt-0 + + + + + + + + + + + + + + + + + + + + +
diff --git a/odex25_donation/p_donation_theme/views/templates.zip b/odex25_donation/p_donation_theme/views/templates.zip deleted file mode 100644 index e1e8cb2d9..000000000 Binary files a/odex25_donation/p_donation_theme/views/templates.zip and /dev/null differ diff --git a/odex25_donation/p_donation_theme/views/views.xml b/odex25_donation/p_donation_theme/views/views.xml index 55a81499d..6aedd93a5 100644 --- a/odex25_donation/p_donation_theme/views/views.xml +++ b/odex25_donation/p_donation_theme/views/views.xml @@ -64,5 +64,22 @@ + +