From 481de7dd898235f46368633942ca85182db28ac6 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 24 May 2022 18:46:37 +0000 Subject: [PATCH] faire un don en ligne --- __manifest__.py | 2 +- controllers/kalachakra.py | 94 ++++++++++++++++------------ models/__init__.py | 1 + models/donation.py | 127 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 models/donation.py diff --git a/__manifest__.py b/__manifest__.py index 03ff9b5..8d08163 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -20,7 +20,7 @@ 'version': '0.1', # any module necessary for this one to work correctly - 'depends': ['base','mail'], + 'depends': ['base','mail','donation'], # always loaded 'data': [ diff --git a/controllers/kalachakra.py b/controllers/kalachakra.py index 2fb9a07..790a3bc 100644 --- a/controllers/kalachakra.py +++ b/controllers/kalachakra.py @@ -2,6 +2,7 @@ from odoo import http from odoo.http import request import werkzeug +from datetime import datetime from odoo.tools import format_datetime, format_date, is_html_empty from odoo.exceptions import UserError from odoo.addons.website_event.controllers.main import WebsiteEventController @@ -191,27 +192,58 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): payment_tokens |= partner.commercial_partner_id.sudo().payment_token_ids data['payment_tokens']=payment_tokens - - #create sale order - vals={} + #create donation + vals={} vals['partner_id']=partner.id - order_draft=request.env['sale.order'].sudo().create(vals) - data['order_id']=order_draft.id - #création des lignes de devis + vals['donation_date']=datetime.now() + vals['tax_receipt_option']='annual' + #mode de paiement CB + electronic_method=request.env['account.payment.method'].search([('code','=','electronic')],limit=1) + if electronic_method: + cb_mode=request.env['account.payment.mode'].search([('payment_method_id','=',int(electronic_method.id))],limit=1) + if cb_mode: + vals['payment_mode_id']=cb_mode.id + else: + raise Warning('please configure credit card mode') + vals['state']='draft' + vals['payment_ref']='internet' + donation_draft=request.env['donation.donation'].sudo().create(vals) vals={} - vals['order_id']=order_draft.id - #ajout du produit + #create line donation + vals['donation_id']=donation_draft.id + product=request.env['product.product'].search([('id','=',int(post.get('product_id')))]) vals['product_id']=int(post.get('product_id')) - vals['product_uom_qty']=1 - vals['price_unit']=post.get('amount') + vals['display_name']=product.name + vals['quantity']=1 + vals['unit_price']=post.get('amount') + vals['tax_receipt_ok']=product.tax_receipt_ok + + + donation_line=request.env['donation.line'].sudo().create(vals) + - product=request.env['product.product'].search([('id','=',int(post.get('product_id')))]) - vals['name']=product.name + #create sale order + # vals={} + + + # vals['partner_id']=partner.id + # order_draft=request.env['sale.order'].sudo().create(vals) + # data['order_id']=order_draft.id + # #création des lignes de devis + # vals={} + # vals['order_id']=order_draft.id + # #ajout du produit + # vals['product_id']=int(post.get('product_id')) + # vals['product_uom_qty']=1 + # vals['price_unit']=post.get('amount') + + # product=request.env['product.product'].search([('id','=',int(post.get('product_id')))]) + # vals['name']=product.name - order_line=request.env['sale.order.line'].sudo().create(vals) + # order_line=request.env['sale.order.line'].sudo().create(vals) - + data['order_id']=donation_draft.id return http.request.render('kalachakra.payment_choice_form',data) @@ -229,7 +261,7 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): user is redirected to the checkout page """ # Ensure a payment acquirer is selected - + donation_id=order_id if not acquirer_id: return False @@ -239,23 +271,15 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): return False - # Retrieve the sale order - order=request.env['sale.order'].search([('id','=',int(order_id))], limit=1) - # 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() + # Retrieve the donation + donation=request.env['donation.donation'].search([('id','=',int(donation_id))], limit=1) + # Ensure there is something to proceed - if not order or (order and not order.order_line): + if not donation or (donation and not donation.line_ids): return False - assert order.partner_id.id != request.website.partner_id.id + assert donation.partner_id.id != request.website.partner_id.id # Create transaction vals = {'acquirer_id': acquirer_id, @@ -266,7 +290,7 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): if token: vals['payment_token_id'] = int(token) - transaction = order._create_payment_transaction(vals) + transaction = donation._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 @@ -276,7 +300,7 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): 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) + return transaction.render_donation_button(donation) http.route('/kalachakra/payment/token', type='http', auth='public', website=True, sitemap=False) def kalachakra_payment_token(self, pm_id=None, **kwargs): @@ -285,14 +309,6 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): :param int pm_id: id of the payment.token that we want to use to pay. """ - order = request.website.sale_get_order() - # do not crash if the user has already paid and try to pay again - - if not order: - return request.redirect('/shop/?error=no_order') - - assert order.partner_id.id != request.website.partner_id.id - try: pm_id = int(pm_id) except ValueError: @@ -305,7 +321,7 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing): # Create transaction vals = {'payment_token_id': pm_id, 'return_url': '/kalachakra/payment/validate'} - tx = order._create_payment_transaction(vals) + tx = donation._create_payment_transaction(vals) PaymentProcessing.add_payment_transaction(tx) return request.redirect('kalachakra/payment/process') diff --git a/models/__init__.py b/models/__init__.py index 807830a..1a1dd6e 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -2,4 +2,5 @@ from . import models from . import partnerimport +from . import donation #from . import partner \ No newline at end of file diff --git a/models/donation.py b/models/donation.py new file mode 100644 index 0000000..c14102b --- /dev/null +++ b/models/donation.py @@ -0,0 +1,127 @@ +from odoo import models, fields, api,_ +from odoo.exceptions import UserError, ValidationError,Warning +from psycopg2 import sql, DatabaseError +from datetime import datetime + +from werkzeug import utils +import base64 + +class PaymentTransaction(models.Model): + _inherit = 'payment.transaction' + + donation_ids = fields.Many2many('donation.donation', 'donation_transaction_rel', 'transaction_id', 'donation_id', + string='Donations', copy=False, readonly=True) + + def render_donation_button(self, donation, submit_txt=None, render_values=None): + values = { + 'partner_id': donation.partner_id.id, + 'type': self.type, + } + if render_values: + values.update(render_values) + # Not very elegant to do that here but no choice regarding the design. + self._log_payment_transaction_sent() + return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render( + self.reference, + donation.amount_total, + donation.currency_id.id, + values=values, + ) + +class DonationDonation(models.Model): + _inherit = 'donation.donation' + + # payment_transaction_id = fields.Many2one('payment.transaction', string='Payment Transaction', readonly=True) + # payment_token_id = fields.Many2one( + # 'payment.token', string="Saved payment token", + # domain="""[ + # (payment_method_code == 'electronic', '=', 1), + # ('company_id', '=', company_id), + # ('acquirer_id.capture_manually', '=', False), + # ('acquirer_id.journal_id', '=', journal_id), + # ('partner_id', 'in', related_partner_ids), + # ]""", + # help="Note that tokens from acquirers set to only authorize transactions (instead of capturing the amount) are not available.") + # def _prepare_payment_transaction_vals(self): + # self.ensure_one() + # return { + # 'amount': self.amount, + # 'reference': self.ref, + # 'currency_id': self.currency_id.id, + # 'partner_id': self.partner_id.id, + # 'partner_country_id': self.partner_id.country_id.id, + # 'payment_token_id': self.payment_token_id.id, + # 'acquirer_id': self.payment_token_id.acquirer_id.id, + # 'payment_id': self.id, + # 'type': 'server2server', + # } + + def _get_payment_type(self, tokenize=False): + self.ensure_one() + return 'form_save' if tokenize else 'form' + + def _create_payment_transaction(self, vals): + '''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the + current donation fields (e.g. the partner or the currency). + :param vals: The values to create a new payment.transaction. + :return: The newly created payment.transaction record. + ''' + # Ensure the currencies are the same. + currency = self[0].currency_id + # if any(so.pricelist_id.currency_id != currency for so in self): + # raise ValidationError(_('A transaction can\'t be linked to sales orders having different currencies.')) + + # Ensure the partner are the same. + partner = self[0].partner_id + if any(so.partner_id != partner for so in self): + raise ValidationError(_('A transaction can\'t be linked to sales orders having different partners.')) + + # Try to retrieve the acquirer. However, fallback to the token's acquirer. + acquirer_id = vals.get('acquirer_id') + acquirer = False + payment_token_id = vals.get('payment_token_id') + + if payment_token_id: + payment_token = self.env['payment.token'].sudo().browse(payment_token_id) + + # Check payment_token/acquirer matching or take the acquirer from token + if acquirer_id: + acquirer = self.env['payment.acquirer'].browse(acquirer_id) + if payment_token and payment_token.acquirer_id != acquirer: + raise ValidationError(_('Invalid token found! Token acquirer %s != %s') % ( + payment_token.acquirer_id.name, acquirer.name)) + if payment_token and payment_token.partner_id != partner: + raise ValidationError(_('Invalid token found! Token partner %s != %s') % ( + payment_token.partner.name, partner.name)) + else: + acquirer = payment_token.acquirer_id + + # Check an acquirer is there. + if not acquirer_id and not acquirer: + raise ValidationError(_('A payment acquirer is required to create a transaction.')) + + if not acquirer: + acquirer = self.env['payment.acquirer'].browse(acquirer_id) + + # Check a journal is set on acquirer. + if not acquirer.journal_id: + raise ValidationError(_('A journal must be specified for the acquirer %s.', acquirer.name)) + + if not acquirer_id and acquirer: + vals['acquirer_id'] = acquirer.id + + vals.update({ + 'amount': sum(self.mapped('amount_total')), + 'currency_id': currency.id, + 'partner_id': partner.id, + 'donation_ids': [(6, 0, self.ids)], + 'type': self[0]._get_payment_type(vals.get('type')=='form_save'), + }) + + transaction = self.env['payment.transaction'].create(vals) + + # Process directly if payment_token + if transaction.payment_token_id: + transaction.s2s_do_transaction() + + return transaction