Merge pull request #3922 from expsa/dev_odex25_donation

Dev odex25 donation
This commit is contained in:
abdurrahman-saber 2025-07-16 09:32:38 +03:00 committed by GitHub
commit 5b23012e4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 78 additions and 106 deletions

View File

@ -36,7 +36,7 @@ class WebsiteSale(WebsiteSale):
domain = [('type_id', '=', vals['type_id']), ('affiliate_method', '=', vals['affiliate_method']), ('affiliate_key', '=', vals['affiliate_key']), ('ip_address', '=', vals['ip_address'])]
visit = request.env['affiliate.visit'].sudo().search(domain)
check_unique_ppc = request.env['res.config.settings'].sudo().website_constant().get('unique_ppc_traffic')
# "check_unique_ppc" it cheacks that in config setting wheather the unique ppc is enable or not
if check_unique_ppc:
if visit:
return visit
@ -45,38 +45,29 @@ class WebsiteSale(WebsiteSale):
else:
return False
# override shop action in website_sale
@http.route([
'/shop',
'/shop/page/<int:page>',
'/shop/category/<model("product.public.category"):category>',
'/shop/category/<model("product.public.category"):category>/page/<int:page>'
], type='http', auth="public", website=True, sitemap=WebsiteSale.sitemap_shop)
@http.route()
def shop(self, page=0, category=None, search='', ppg=False, **post):
enable_ppc = request.env['res.config.settings'].sudo().website_constant().get('enable_ppc')
expire = False
expire = self.calc_cookie_expire_date()
result = super(WebsiteSale, self).shop(page=page, category=category, search=search, ppg=ppg, **post)
aff_key = request.httprequest.args.get('aff_key')
if category and aff_key:
expire = self.calc_cookie_expire_date()
path = request.httprequest.full_path
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', aff_key), ('is_affiliate', '=', True)])
vals = self.create_affiliate_visit(aff_key, partner_id, category)
vals.update({'affiliate_type': 'category'})
if (len(partner_id) == 1):
affiliate_visit = self.create_aff_visit_entry(vals) if enable_ppc else False
result.set_cookie(key='affkey_%s' % (aff_key), value='category_%s' % (category.id), expires=expire)
self.create_aff_visit_entry(vals) if enable_ppc else False
result.set_cookie(key='affkey', value=aff_key, expires=expire)
else:
_logger.info("=====affiliate_visit not created by category===========")
else:
if aff_key:
expire = self.calc_cookie_expire_date()
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', aff_key), ('is_affiliate', '=', True)])
if partner_id:
result.set_cookie(key='affkey_%s' % (aff_key), value='shop', expires=expire)
result.set_cookie(key='affkey', value=aff_key, expires=expire)
return result
@http.route(['/shop/<model("product.template"):product>'], type='http', auth="public", website=True)
@http.route()
def product(self, product, category='', search='', **kwargs):
_logger.info("=====product page=========")
_logger.info("=====product page aff_key==%r=========", request.httprequest.args)
@ -84,26 +75,21 @@ class WebsiteSale(WebsiteSale):
expire = self.calc_cookie_expire_date()
result = super(WebsiteSale, self).product(product=product, category=category, search=search, **kwargs)
if request.httprequest.args.get('aff_key'):
# path is the complete url with url = xxxx?aff_key=XXXXXXXX
path = request.httprequest.full_path
# aff_key is fetch from url
aff_key = request.httprequest.args.get('aff_key')
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', aff_key), ('is_affiliate', '=', True)])
vals = self.create_affiliate_visit(aff_key, partner_id, product)
vals.update({'affiliate_type': 'product'})
if (len(partner_id) == 1):
affiliate_visit = self.create_aff_visit_entry(vals) if enable_ppc else False
# "create_aff_visit_entry " this methods check weather the visit is already created or not or if created return the no. of existing record in object
result.set_cookie(key='affkey_%s' % (aff_key), value='product_%s' % (product.id), expires=expire)
result.set_cookie(key='affkey', value=aff_key, expires=expire)
_logger.info("============affiliate_visit created by product==%r=======", affiliate_visit)
else:
_logger.info("=====affiliate_visit not created by product===========%s %s" % (aff_key, partner_id))
return result
@http.route(['/shop/confirmation'], type='http', auth="public", website=True)
def shop_payment_confirmation(self, **post):
result = super(WebsiteSale, self).shop_payment_confirmation(**post)
# here result id http.render argument is http.render{ http.render(template, qcontext=None, lazy=True, **kw) }
@http.route()
def payment_confirmation(self, **post):
result = super(WebsiteSale, self).payment_confirmation(**post)
sale_order_id = result.qcontext.get('order')
return self.update_affiliate_visit_cookies(sale_order_id, result)
@ -125,18 +111,15 @@ class WebsiteSale(WebsiteSale):
"""update affiliate.visit from cokkies data i.e created in product and shop method"""
cookies = dict(request.httprequest.cookies)
visit = request.env['affiliate.visit']
arr = [] # contains cookies product_id
for k, v in cookies.items():
if 'affkey_' in k:
arr.append(k.split('_')[1])
if arr:
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', arr[0]), ('is_affiliate', '=', True)])
affiliate_key = cookies.get('affkey') # contains cookies product_id
if affiliate_key:
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', affiliate_key), ('is_affiliate', '=', True)])
for s in sale_order_id.order_line:
if len(arr) > 0 and partner_id:
if partner_id:
product_tmpl_id = s.product_id.product_tmpl_id.id
aff_visit = visit.sudo().create({
visit.sudo().create({
'affiliate_method': 'pps',
'affiliate_key': arr[0],
'affiliate_key': affiliate_key,
'affiliate_partner_id': partner_id.id,
'url': "",
'ip_address': request.httprequest.environ['REMOTE_ADDR'],
@ -149,11 +132,6 @@ class WebsiteSale(WebsiteSale):
'product_quantity': s.product_uom_qty,
'is_converted': True
})
# delete cookie after first sale occur
cookie_del_status = False
for k, v in cookies.items():
if 'affkey_' in k:
cookie_del_status = result.delete_cookie(key=k)
return result
def calc_cookie_expire_date(self):
@ -165,4 +143,4 @@ class WebsiteSale(WebsiteSale):
'days': cookie_expire * 24,
'months': cookie_expire * 24 * 30,
}
return datetime.datetime.utcnow() + datetime.timedelta(hours=time_dict[cookie_expire_period])
return datetime.datetime.now() + datetime.timedelta(hours=time_dict[cookie_expire_period])

View File

@ -59,14 +59,10 @@ class ResPartnerInherit(models.Model):
@api.model_create_multi
def create(self, vals_list):
aff_prgm = None
new_res_partner = None
affiliate_program_id = self.env['affiliate.program'].sudo().search([], limit=1)
for vals in vals_list:
programs = self.env['affiliate.program'].sudo().search([])
aff_prgm = programs[-1].id if len(programs) > 0 else ''
if vals.get('is_affiliate'):
vals.update({
'affiliate_program_id': aff_prgm
'affiliate_program_id': affiliate_program_id
})
new_res_partner = super(ResPartnerInherit, self).create(vals)
return new_res_partner
return super().create(vals_list)

View File

@ -7,11 +7,12 @@
'website': 'https://ensan.com',
'license': 'LGPL-3',
'category': 'Sales',
'depends': ['base', 'website_sale', 'sms', 'phone_validation'],
'depends': ['base', 'website_sale', 'sms', 'phone_validation', 'affiliate_management'],
'data': [
'security/ir.model.access.csv',
'data/sms_data.xml',
'data/ir_cron.xml',
'data/ir_sequence.xml',
'views/sale_order_views.xml',
'views/product_views.xml',
'views/sale_report.xml',

View File

@ -1,3 +1,4 @@
from datetime import datetime
from odoo.http import request, route
from odoo.addons.payment.controllers.portal import PaymentProcessing
from odoo.addons.website_sale.controllers.main import WebsiteSale
@ -5,59 +6,31 @@ from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSaleInherit(WebsiteSale):
@route()
def payment_transaction(self, acquirer_id, save_token=False, so_id=None, access_token=None, token=None, **kwargs):
""" Json method that creates a payment.transaction, used to create a
transaction when the user clicks on 'pay now' button. After having
created the transaction, the event continues and the user is redirected
to the acquirer website.
:param int acquirer_id: id of a payment.acquirer record. If not set the
user is redirected to the checkout page
"""
# Ensure a payment acquirer is selected
if not acquirer_id:
return False
try:
acquirer_id = int(acquirer_id)
except:
return False
# Retrieve the sale order
if so_id:
env = request.env['sale.order']
domain = [('id', '=', so_id)]
if access_token:
env = env.sudo()
domain.append(('access_token', '=', access_token))
order = env.search(domain, limit=1)
else:
order = request.website.sale_get_order()
# Ensure there is something to proceed
if not order or (order and not order.order_line):
return False
# assert order.partner_id.id != request.website.partner_id.id
# Create transaction
vals = {'acquirer_id': acquirer_id,
'return_url': '/shop/payment/validate'}
if save_token:
vals['type'] = 'form_save'
if token:
vals['payment_token_id'] = int(token)
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
return transaction.render_sale_button(order)
def update_affiliate_visit_cookies(self, sale_order_id, result):
"""update affiliate.visit from cokkies data i.e created in product and shop method"""
res = super().update_affiliate_visit_cookies(sale_order_id, result)
cookies = dict(request.httprequest.cookies)
visit = request.env['affiliate.visit'].sudo()
affiliate_key = cookies.get('affkey')
if affiliate_key:
partner_id = request.env['res.partner'].sudo().search([('res_affiliate_key', '=', affiliate_key), ('is_affiliate', '=', True)])
sale_order_id.partner_id.sudo().write({'affiliate_id': partner_id.id})
elif sale_order_id.partner_id.sudo().affiliate_id:
partner_id = sale_order_id.partner_id.sudo().affiliate_id
for s in sale_order_id.order_line:
visit.create({
'affiliate_method': 'pps',
'affiliate_key': affiliate_key,
'affiliate_partner_id': partner_id.id,
'url': "",
'ip_address': request.httprequest.environ['REMOTE_ADDR'],
'type_id': s.product_id.product_tmpl_id.id,
'affiliate_type': 'product',
'type_name': s.product_id.id,
'sales_order_line_id': s.id,
'convert_date': datetime.now(),
'affiliate_program_id': partner_id.affiliate_program_id.id,
'product_quantity': s.product_uom_qty,
'is_converted': True
})
return res

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="seq_crm_iap_lead_mining_request" model="ir.sequence">
<field name="name">Anonymous Donor</field>
<field name="code">anonymous.donor</field>
<field name="prefix">#</field>
<field name="padding">3</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>

View File

@ -1,10 +1,11 @@
from odoo import models, fields, api
from odoo.addons.phone_validation.tools import phone_validation
class ResPartner(models.Model):
_inherit = 'res.partner'
affiliate_id = fields.Many2one('res.partner', domain=[('is_affiliate', '=', True)])
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)

View File

@ -1,7 +1,6 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools.json import scriptsafe as json_scriptsafe
from odoo.addons.phone_validation.tools import phone_validation
class SaleOrder(models.Model):
_name = 'sale.order'
@ -28,6 +27,15 @@ class SaleOrder(models.Model):
orders.filtered(lambda o: o.order_mobile_number == vals['order_mobile_number']).write({'donor_type': 'returning'})
else:
vals['donor_type'] = 'new'
partner_sudo = self.env['res.partner'].sudo()
anonymous_partner_id = partner_sudo.search(['|', ('mobile', '=', vals['order_mobile_number']), ('phone', '=', vals['order_mobile_number'])], limit=1)
if anonymous_partner_id:
vals['partner_id'] = anonymous_partner_id.id
if 'order_name' in vals and vals['order_name']:
anonymous_partner_id.name = vals['order_name']
else:
name = vals.get('order_name', 'Anonymous Donor %s' % self.env['ir.sequence'].next_by_code('anonymous.donor'))
vals['partner_id'] = partner_sudo.create({'name': name, 'phone': vals['order_mobile_number']}).id
return super(SaleOrder, self).write(vals)
def get_sale_order_portal_url(self):