# -*- coding: utf-8 -*- from odoo import http,_ from odoo.http import request from odoo.osv import expression import logging from odoo import models, fields, api import werkzeug from werkzeug.datastructures import OrderedMultiDict from datetime import datetime,timedelta from odoo.tools import format_datetime, format_date, is_html_empty from dateutil.relativedelta import relativedelta from odoo.exceptions import UserError from collections import defaultdict import babel import babel.dates from odoo.addons.web.controllers.main import ensure_db, Home from odoo.addons.website_event.controllers.main import WebsiteEventController from odoo.addons.website.controllers.main import QueryURL from odoo.addons.payment.controllers.portal import PaymentProcessing #from odoo.addons.sale.controllers.portal import CustomerPortal from odoo.addons.account.controllers.portal import CustomerPortal from odoo.tools.misc import formatLang, format_date as odoo_format_date, get_lang from odoo.addons.portal.controllers.portal import pager as portal_pager, get_records_pager from odoo.addons.auth_signup.models.res_users import SignupError from odoo.addons.auth_signup.controllers.main import AuthSignupHome import json from collections import OrderedDict _logger = logging.getLogger(__name__) def create_donation(self): return True class Kalachakra_PortalAccount(CustomerPortal): @http.route(['/my/invoices', '/my/invoices/page/'], type='http', auth="user", website=True) def kalachakra_portal_my_invoices(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw): values = self._prepare_portal_layout_values() user_id=int(request.env.context.get('uid')) user=request.env['res.users'].search([('id','=',user_id)]) #KALACHAKRA : on affiche que les factures de l'utilisateur liées à une retraite booking_events=request.env['event.event'].sudo().search([('booking_event','=',True)]) booking_registrations=request.env['event.registration'].sudo().search(['|','&',('partner_id','=',int(user.partner_id)),('online','=',True),'&',('event_id','in',booking_events.ids),('partner_id','=',int(user.partner_id))]) invoice_ids=booking_registrations.invoice_id.ids down_payment_invoice_ids=booking_registrations.down_payment_invoice_id.ids balance_invoice_ids=booking_registrations.balance_invoice_id.ids domain = ['&','&',('id','in',invoice_ids+down_payment_invoice_ids+balance_invoice_ids),('move_type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'))] searchbar_sortings = { 'date': {'label': _('Date'), 'order': 'invoice_date desc'}, 'duedate': {'label': _('Due Date'), 'order': 'invoice_date_due desc'}, 'name': {'label': _('Reference'), 'order': 'name desc'}, 'state': {'label': _('Status'), 'order': 'state'}, } # default sort by order if not sortby: sortby = 'date' order = searchbar_sortings[sortby]['order'] searchbar_filters = { 'all': {'label': _('All'), 'domain': [('move_type', 'in', ['in_invoice', 'out_invoice'])]}, 'invoices': {'label': _('Invoices'), 'domain': [('move_type', '=', 'out_invoice')]}, 'bills': {'label': _('Bills'), 'domain': [('move_type', '=', 'in_invoice')]}, } # default filter by value if not filterby: filterby = 'all' domain += searchbar_filters[filterby]['domain'] if date_begin and date_end: domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)] # count for pager invoice_count = request.env['account.move'].search_count(domain) # pager pager = portal_pager( url="/my/invoices", url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby}, total=invoice_count, page=page, step=self._items_per_page ) # content according to pager and archive selected invoices = request.env['account.move'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset']) request.session['my_invoices_history'] = invoices.ids[:100] values.update({ 'date': date_begin, 'invoices': invoices, 'page_name': 'invoice', 'pager': pager, 'default_url': '/my/invoices', 'searchbar_sortings': searchbar_sortings, 'sortby': sortby, 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())), 'filterby':filterby, }) return request.render("account.portal_my_invoices", values) def _prepare_home_portal_values(self, counters): values = super()._prepare_home_portal_values(counters) if 'invoice_count' in counters: #KALACHAKRA : on compte que les factures de l'utilisateur ( idem pour les admins) user_id=int(request.env.context.get('uid')) user=request.env['res.users'].search([('id','=',user_id)]) booking_events=request.env['event.event'].sudo().search([('booking_event','=',True)]) booking_registrations=request.env['event.registration'].sudo().search(['|','&',('partner_id','=',int(user.partner_id)),('online','=',True),'&',('event_id','in',booking_events.ids),('partner_id','=',int(user.partner_id))]) invoice_ids=booking_registrations.invoice_id.ids down_payment_invoice_ids=booking_registrations.down_payment_invoice_id.ids balance_invoice_ids=booking_registrations.balance_invoice_id.ids invoice_count = request.env['account.move'].search_count([('id','in',invoice_ids+down_payment_invoice_ids+balance_invoice_ids), ('move_type', 'in', ('out_invoice', 'in_invoice', 'out_refund', 'in_refund', 'out_receipt', 'in_receipt')), ]) if request.env['account.move'].check_access_rights('read', raise_exception=False) else 0 values['invoice_count'] = invoice_count return values class KalaAuthSignupHome(Home): @http.route('/web/signup', type='http', auth='public', website=True, sitemap=False) def kalachakra_web_auth_signup(self, *args, **kw): qcontext = self.get_auth_signup_qcontext() if not qcontext.get('token') and not qcontext.get('signup_enabled'): raise werkzeug.exceptions.NotFound() if 'error' not in qcontext and request.httprequest.method == 'POST': try: self.do_signup(qcontext) # Send an account creation confirmation email if qcontext.get('token'): User = request.env['res.users'] user_sudo = User.sudo().search( User._get_login_domain(qcontext.get('login')), order=User._get_login_order(), limit=1 ) template = request.env.ref('auth_signup.mail_template_user_signup_account_created', raise_if_not_found=False) if user_sudo and template: template.sudo().send_mail(user_sudo.id, force_send=True) return self.web_login(*args, **kw) except UserError as e: qcontext['error'] = e.args[0] except (SignupError, AssertionError) as e: if request.env["res.users"].sudo().search([("login", "=", qcontext.get("login"))]): qcontext["error"] = _("Another user is already registered using this email address.") else: _logger.error("%s", e) if e=='Invalid email': qcontext['error'] = _("Invalid email") else: qcontext['error'] = _(e) response = request.render('auth_signup.signup', qcontext) response.headers['X-Frame-Options'] = 'DENY' return response class kalachakra_event(WebsiteEventController,PaymentProcessing): def sitemap_event(env, rule, qs): if not qs or qs.lower() in '/events': yield {'loc': '/events'} #afficher la liste des prochains événement sur la home page (sans les retraites ! ) @http.route('/event/csv_booking_registrants', website=False, auth='user',methods=['GET']) def export_csv_booking_registrants(self,id,*args,**kw): data=request.env['event.event'].sudo().generate_csv_booking_registrants(id) #csv = str.encode('Nom & Prénom;Rôle;Options;Montant retraite;Adhésion;Autre options;Montant à payer;Statut commande;Type de paiement;Règlement\n', 'utf-8') #csv =csv+ str.encode('1;2\n', 'utf-8') filename = 'Events - {}.csv'.format( datetime.now().strftime("%m/%d/%Y")) headers = [ ('Content-Type', 'application/octet-stream'), ('Content-Disposition', 'attachment; filename="%s"' % (filename)) ] return request.make_response(data, headers=headers) #afficher la liste des prochains événement sur la home page (sans les retraites ! ) @http.route('/event/get_country_booking_event_list', type='json', auth='public', website=True) def get_country_booking_events(self, **post): Event = request.env['event.event'] country_code = request.session['geoip'].get('country_code') result = {'events': [], 'country': False} events = None domain = request.website.website_domain() if country_code: country = request.env['res.country'].search([('code', '=', country_code)], limit=1) events = Event.search(domain + ['&','|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', '%s 00:00:00' % fields.Date.today()),('booking_event','=',True)], order="date_begin") if not events: events = Event.search(domain + [('booking_event','=',True),('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") for event in events: if country_code and event.country_id.code == country_code: result['country'] = country result['events'].append({ "date": self.get_formated_date2(event), "event": event, "url": event.website_url}) return request.env['ir.ui.view']._render_template("kalachakra.country_booking_events_list", result) @http.route('/event/get_country_event_list', type='json', auth='public', website=True) def get_country_events(self, **post): Event = request.env['event.event'] country_code = request.session['geoip'].get('country_code') result = {'events': [], 'country': False} events = None domain = request.website.website_domain() if country_code: country = request.env['res.country'].search([('code', '=', country_code)], limit=1) events = Event.search(domain + ['&','|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', '%s 00:00:00' % fields.Date.today()),('booking_event','=',False)], order="date_begin") if not events: events = Event.search(domain + [('booking_event','=',False),('date_begin', '>=', '%s 00:00:00' % fields.Date.today())], order="date_begin") result['date_next_week_saturday']=self.onDay(datetime.today(),5) result['date_next_week_sunday']=self.onDay(datetime.today(),6) for event in events: next_weekend_evt=0 delta1=event.date_begin- result['date_next_week_saturday'] delta2=event.date_begin- result['date_next_week_sunday'] if delta1.days==-1:next_weekend_evt=1 if delta2.days==-1:next_weekend_evt=1 if country_code and event.country_id.code == country_code: result['country'] = country result['events'].append({ "next_weekend_evt":next_weekend_evt, "d_day":delta2, "date": self.get_formated_date2(event), "event": event, "url": event.website_url}) return request.env['ir.ui.view']._render_template("website_event.country_events_list", result) def onDay(self,date, day): """ Returns the date of the next given weekday after the given date. For example, the date of next Monday. NB: if it IS the day we're looking for, this returns 0. consider then doing onDay(foo, day + 1). """ days = (day - date.weekday() + 7) % 7 if days==0: date=date+timedelta(days = 1) days=(day - date.weekday() + 7) % 7 return date + timedelta(days=days) def get_formated_date2(self, event): start_date = fields.Datetime.from_string(event.date_begin).date() end_date = fields.Datetime.from_string(event.date_end).date() month_start = babel.dates.get_month_names('abbreviated', locale=get_lang(event.env).code)[start_date.month] month_end = babel.dates.get_month_names('abbreviated', locale=get_lang(event.env).code)[end_date.month] if month_start==month_end: return ('%s%s %s') % (start_date.strftime("%e"), (end_date != start_date and ("-" + end_date.strftime("%e")) or ""),month_start) else: return ('%s %s %s %s') % (start_date.strftime("%e"),month_start, "-"+end_date.strftime("%e"),month_end) def _extract_searched_event_tags(self, searches): tags = request.env['event.tag'] lst_tags=searches['tags'].split("|") if searches.get('tags'): tags = request.env['event.tag'].search([('name', 'in',lst_tags)]) return tags @http.route(['/kalachakra/mediatheque/event'], type='http', auth="public", website=True, sitemap=sitemap_event) def kalachakraMediathequeEvent(self,**id): id=id.get('id') event = request.env['event.event'].sudo().search([('id','=',int(id))]) data={} data['event']=event return request.render("kalachakra.website_mediatheque_event",data) @http.route(['/kalachakra/mediatheque','/kalachakra/mediatheque/page/'], type='http', auth="public", website=True, sitemap=sitemap_event) def kalachakraMediatheque(self,page=1,**searches): Event = request.env['event.event'] SudoEventType = request.env['event.type'].sudo() searches.setdefault('search', '') searches.setdefault('date', 'old') searches.setdefault('tags', 'enregistrements') searches.setdefault('type', 'all') searches.setdefault('country', 'all') website = request.website today = fields.Datetime.today() def sdn(date): return fields.Datetime.to_string(date.replace(hour=23, minute=59, second=59)) def sd(date): return fields.Datetime.to_string(date) def get_month_filter_domain(filter_name, months_delta): first_day_of_the_month = today.replace(day=1) filter_string = _('This month') if months_delta == 0 \ else format_date(request.env, value=today + relativedelta(months=months_delta), date_format='LLLL', lang_code=get_lang(request.env).code).capitalize() return [filter_name, filter_string, [ ("date_end", ">=", sd(first_day_of_the_month + relativedelta(months=months_delta))), ("date_begin", "<", sd(first_day_of_the_month + relativedelta(months=months_delta+1)))], 0] dates = [ ['all', _('Upcoming Events'), [("date_end", ">", sd(today))], 0], ['today', _('Today'), [ ("date_end", ">", sd(today)), ("date_begin", "<", sdn(today))], 0], get_month_filter_domain('month', 0), ['old', _('Past Events'), [ ("date_end", "<", sd(today))], 0], ] # search domains domain_search = {'website_specific': website.website_domain()} if searches['search']: domain_search['search'] = [('name', 'ilike', searches['search'])] search_tags = self._extract_searched_event_tags(searches) if search_tags: # Example: You filter on age: 10-12 and activity: football. # Doing it this way allows to only get events who are tagged "age: 10-12" AND "activity: football". # Add another tag "age: 12-15" to the search and it would fetch the ones who are tagged: # ("age: 10-12" OR "age: 12-15") AND "activity: football grouped_tags = defaultdict(list) for tag in search_tags: grouped_tags[tag.category_id].append(tag) domain_search['tags'] = [] for group in grouped_tags: domain_search['tags'] = expression.AND([domain_search['tags'], [('tag_ids', 'in', [tag.id for tag in grouped_tags[group]])]]) current_date = None current_type = None current_country = None for date in dates: if searches["date"] == date[0]: domain_search["date"] = date[2] if date[0] != 'all': current_date = date[1] if searches["type"] != 'all': current_type = SudoEventType.browse(int(searches['type'])) domain_search["type"] = [("event_type_id", "=", int(searches["type"]))] if searches["country"] != 'all' and searches["country"] != 'online': current_country = request.env['res.country'].browse(int(searches['country'])) domain_search["country"] = ['|', ("country_id", "=", int(searches["country"])), ("country_id", "=", False)] elif searches["country"] == 'online': domain_search["country"] = [("country_id", "=", False)] def dom_without(without): domain = [] for key, search in domain_search.items(): if key != without: domain += search return domain # count by domains without self search for date in dates: if date[0] != 'old': date[3] = Event.search_count(dom_without('date') + date[2]) domain = dom_without('type') domain = dom_without('country') countries = Event.read_group(domain, ["id", "country_id"], groupby="country_id", orderby="country_id") countries.insert(0, { 'country_id_count': sum([int(country['country_id_count']) for country in countries]), 'country_id': ("all", _("All Countries")) }) step = 12 # Number of events per page event_count = Event.search_count(dom_without("none")) pager = website.pager( url="/kalachakra/mediatheque", url_args=searches, total=event_count, page=page, step=step, scope=5) order = 'date_begin' if searches.get('date', 'all') == 'old': order = 'date_begin desc' order = 'is_published desc, ' + order events = Event.search(dom_without("none"), limit=step, offset=pager['offset'], order=order) keep = QueryURL('/kalachakra/mediatheque', **{key: value for key, value in searches.items() if (key == 'search' or value != 'all')}) #search_tags=['enregistrement'] values = { 'current_date': current_date, 'current_country': current_country, 'current_type': current_type, 'event_ids': events, # event_ids used in website_event_track so we keep name as it is 'dates': dates, 'categories': request.env['event.tag.category'].search([]), 'countries': countries, 'pager': pager, 'searches': searches, 'search_tags': search_tags, 'keep': keep, } if searches['date'] == 'old': # the only way to display this content is to set date=old so it must be canonical values['canonical_params'] = OrderedMultiDict([('date', 'old')]) return request.render("kalachakra.website_mediatheque", values) @http.route(['/notre-centre-de-retraite/presentation-du-centre'], type='http', auth='public', website=True, sitemap=False,csrf=False) def kalachakracentreretraite(self,**post): return http.request.redirect('/saint-cosme') @http.route(['/calendrier'], type='http', auth='public', website=True, sitemap=False,csrf=False) def kalachakcalendrier(self,**post): return http.request.redirect('/event') @http.route(['/event/calendar'], type='http', auth='public', website=True, sitemap=False,csrf=False) def eventCalendar(self,**post): url='https://calendar.google.com/calendar/embed?height=600&wkst=2&bgcolor=%23ffffff&ctz=Europe%2FParis&mode=WEEK&src=aXRrYWxhY2hha3JhQGdtYWlsLmNvbQ&src=bjYxODA1OXQ2dmRwNmp0Y3Foa3FjMTMwdWtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=MnJzc2VvY3MzcGNiaDliaGFvNXZ1a3JpM3NAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=cGJ0YjBtbTBja2NsMDZmdTNvb2ViMDJpOXNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=ZnIuZnJlbmNoI2hvbGlkYXlAZ3JvdXAudi5jYWxlbmRhci5nb29nbGUuY29t&color=%23039BE5&color=%238E24AA&color=%23E4C441&color=%237CB342&color=%230B8043" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"' url='https://calendar.google.com/calendar/embed?height=600&wkst=1&bgcolor=%23ffffff&ctz=Europe%2FParis&src=aXRrYWxhY2hha3JhQGdtYWlsLmNvbQ&src=c3VtbHRqdnNsdTRhYjB2MXMyMTdkYmI3azBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=OTVxa25nMDBwY2NxMmhuOTQ2N2F1MWptZzRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=dTViZ3E1bnM3NmFzZ3Ztb2VzZGlwaHZudTBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=bjYxODA1OXQ2dmRwNmp0Y3Foa3FjMTMwdWtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=MnJzc2VvY3MzcGNiaDliaGFvNXZ1a3JpM3NAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=ZWFoMDk3YnZzcmQ0N2ZhNW5qZ3BncDZscDBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=czNudTlodnZ1NjY0bW1wMnRncmJmOXUzazhAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=cGJ0YjBtbTBja2NsMDZmdTNvb2ViMDJpOXNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=b3Mwc2VhbzVmNG9zczFqZmF2Z20wdmdvZTRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%23039BE5&color=%234285F4&color=%23D81B60&color=%23EF6C00&color=%238E24AA&color=%23E4C441&color=%230B8043&color=%23F6BF26&color=%237CB342&color=%239E69AF" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"' url='https://calendar.google.com/calendar/embed?height=600&wkst=1&bgcolor=%23ffffff&ctz=Europe%2FParis&src=aXRrYWxhY2hha3JhQGdtYWlsLmNvbQ&src=c3VtbHRqdnNsdTRhYjB2MXMyMTdkYmI3azBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=OTVxa25nMDBwY2NxMmhuOTQ2N2F1MWptZzRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=dTViZ3E1bnM3NmFzZ3Ztb2VzZGlwaHZudTBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=bjYxODA1OXQ2dmRwNmp0Y3Foa3FjMTMwdWtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=MnJzc2VvY3MzcGNiaDliaGFvNXZ1a3JpM3NAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=ZWFoMDk3YnZzcmQ0N2ZhNW5qZ3BncDZscDBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=czNudTlodnZ1NjY0bW1wMnRncmJmOXUzazhAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=cGJ0YjBtbTBja2NsMDZmdTNvb2ViMDJpOXNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&src=b3Mwc2VhbzVmNG9zczFqZmF2Z20wdmdvZTRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%23039BE5&color=%234285F4&color=%23D81B60&color=%23EF6C00&color=%238E24AA&color=%23E4C441&color=%230B8043&color=%23F6BF26&color=%237CB342&color=%239E69AF" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"' return http.request.render('kalachakra.event_calendar',{'url':url}) @http.route(['/event/calendartui'], type='http', auth='public', website=True, sitemap=False,csrf=False) def eventCalendartui(self,**post): return http.request.render('kalachakra.event_calendartui') @http.route(['/kalachakra/contactus'], type='http', auth='public', website=True, sitemap=False,csrf=False) def kalachakracontactus(self,**post): return http.request.render('kalachakra.contactus') @http.route(['/kalachakra/thankyou'], type='http', auth='public', website=True, sitemap=False,csrf=False) def kalachakrathankyou(self,**post): return http.request.render('kalachakra.thankyou') @http.route(['/kalachakra/programme'], type='http', auth='public', website=True, sitemap=False,csrf=False) def kalachakracontactus(self,**post): return http.request.redirect('https://www.dropbox.com/s/ijsd6n82oyp0gw8/programme_Paris.pdf?dl=0') @http.route(['/kalachakra/object'], type='http', auth='public', website=True, sitemap=False,csrf=False) def object(self,model,id,*args,**kw): field_list=request.env[model].sudo().fields_get() objet=request.env[model].search([('id','=',int(id))]) # result=[] # for key in field_list: # result.append((key,str(objet[key]))) # result.sort() # return json.dumps(result) result="" for key in field_list: result=result+str(key)+':'+str(objet[key])+'
' return result return model_id+ record_id @http.route(['/kalachakra/inv'], type='http', auth='public', website=True, sitemap=False,csrf=False) def object3(self,id,*args,**kw): move=request.env['account.move'].search([('id','=',int(id))]) if move.state != 'posted' \ or move.payment_state not in ('not_paid', 'partial') \ or not move.is_invoice(include_receipts=True): return "KO" pay_term_lines = move.line_ids\ .filtered(lambda line: line.account_id.user_type_id.type in ('receivable', 'payable')) domain = [ ('account_id', 'in', pay_term_lines.account_id.ids), ('move_id.state', '=', 'posted'), ('partner_id', '=', move.commercial_partner_id.id), ('reconciled', '=', False), '|', ('amount_residual', '!=', 0.0), ('amount_residual_currency', '!=', 0.0), ] payments_widget_vals = {'outstanding': True, 'content': [], 'move_id': move.id} if move.is_inbound(): domain.append(('balance', '<', 0.0)) payments_widget_vals['title'] = _('Outstanding credits') else: domain.append(('balance', '>', 0.0)) payments_widget_vals['title'] = _('Outstanding debits') result="currency_id="+str(move.currency_id)+'
' result=result+"is_invoice="+str(move.is_invoice())+'
' result=result+"state="+str(move.state)+'
' result=result+"currency.is_zero(invoice.amount_residual)="+str(move.amount_residual)+'
' for line in move.line_ids: amount = move.company_currency_id._convert( abs(line.amount_residual), move.currency_id, move.company_id, line.date, ) amount = abs(line.amount_residual_currency) result=result+"id="+str(line.id)+'
' result=result+"account_id="+str(line.account_id)+'
' result=result+"domain="+json.dumps(domain)+'
' result=result+"move_id.state="+str(line.move_id.state)+'
' result=result+"partner_id="+str(line.partner_id)+'
' result=result+"reconciled="+str(line.reconciled)+'
' result=result+"amount_residual="+str(line.amount_residual)+'
' result=result+"amount_residual_currency="+str(line.amount_residual_currency)+'
' result=result+"domain="+str(domain)+'
' result=result+"amount="+str(amount)+'
' result=result+"move.currency_id.is_zero(amount)="+str(move.currency_id.is_zero(amount))+'
' result=result+"currency_id="+str(line.currency_id)+'
' result=result+"line.account_id.reconcile="+str(line.account_id.reconcile)+'
' result=result+"line.account_id.user_type_id.type="+str(line.account_id.user_type_id.type)+'
' result=result+"line.amount_residual"+str(line.amount_residual)+'
' result=result+"balance="+str(line.balance)+'
' #if line.id and (line.account_id.reconcile or line.account_id.internal_type == 'liquidity'): result=result+"OK
" reconciled_balance = sum(line.matched_credit_ids.mapped('amount')) \ - sum(line.matched_debit_ids.mapped('amount')) reconciled_amount_currency = sum(line.matched_credit_ids.mapped('debit_amount_currency'))\ - sum(line.matched_debit_ids.mapped('credit_amount_currency')) result=result+str(reconciled_balance)+'
' result=result+str(reconciled_amount_currency)+'
' result=result+'

' return result @http.route(['/kalachakra/update'], type='http', auth='public', website=True, sitemap=False,csrf=False) def object2(self,*args,**kw): objet=request.env['account.move'].search([('id','=',108)]) #objet.payment_reference='REC108' objet.posted_before=True return "ok" return http.request.redirect('https://www.dropbox.com/s/ijsd6n82oyp0gw8/programme_Paris.pdf?dl=0') @http.route(['/event/registration/step1'], type='http', auth='user', website=True, sitemap=False,csrf=False) def event_registration_step1(self,event_id,*args,**kw): data={} #contact lié à l'utilisateur userid=request.env.context.get('uid') user=request.env['res.users'].search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) data['partner']=partner #évenement event=request.env['event.event'].sudo().search([('id','=',int(event_id))]) request.session['event_id']=int(event_id) data['event']=event #si le pays n'est pas renseigné, on le renseigne avec France if not partner.country_id: country=request.env['res.country'].search([('name','=','France')]) partner.country_id=country.id data['status']=partner.member_status if data['status']=='not member':data['status']='non adhérent' if data['status']=='member':data['status']='adhérent' if data['status']=='super member':data['status']='adhérent de soutien' data['form_action']='step2' if event.headphone_option :data['form_action']='step1b' request.session['status']=partner.member_status return http.request.render('kalachakra.registration_step1',data) @http.route(['/event/registration/contactform'], type='http', auth='user', website=True, sitemap=False,csrf=False) #def event_registration_contactform(self,event_id,*args,**kw): def event_registration_contactform(self,*args,**kw): data={} #contact lié à l'utilisateur userid=request.env.context.get('uid') data['lang']=request.env.context.get('lang') user=request.env['res.users'].search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) data['partner']=partner #évenement # event=request.env['event.event'].sudo().search([('id','=',int(event_id))]) # request.session['event_id']=int(event_id) #data['event']=event return http.request.render('kalachakra.registration_contactform',data) @http.route(['/event/registration/step1b'], type='http', auth='user', website=True, sitemap=False,csrf=False) def event_registration_step1b(self,event_id,*args,**kw): data={} #contact lié à l'utilisateur userid=request.env.context.get('uid') user=request.env['res.users'].search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) data['partner']=partner #évenement event=request.env['event.event'].sudo().search([('id','=',int(event_id))]) request.session['event_id']=int(event_id) data['event']=event return http.request.render('kalachakra.registration_step1b',data) @http.route(['/event/registration/step2'], type='http', auth='user', website=True, sitemap=False,csrf=False) def event_registration_step2(self,event_id,**post): data={} #contact lié à l'utilisateur userid=request.env.context.get('uid') user=request.env['res.users'].search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) request.session['partner_id']=int(partner.id) request.session['status']=partner.member_status data['partner']=partner #évenement event=request.env['event.event'].sudo().search([('id','=',int(event_id))]) request.session['event_id']=int(event_id) data['event']=event data['online']=False data['headphone']=False if post.get('headphone')=='true' :data['headphone']=True if event.online_event: if post.get('online')=='yes':data['online']=True if event.online_only:data['online']=True data['status']=request.session['status'] data['price']='' if partner.member_status=='not member':data['participation_amount']=int(event.participation_standard_price) if partner.member_status=='member':data['participation_amount']=int(event.participation_member_price) if partner.member_status=='super member':data['participation_amount']=int(event.participation_super_member_price) membership_product=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1) if not membership_product: raise UserError(_('No membership product, please add one')) data['membership_amount']=membership_product.list_price data['standard_amount']=event.participation_standard_price data['membership_and_participation_amount']=str(int(data['membership_amount'])+int(event.participation_member_price)) +' ('+str(int(data['membership_amount']))+'+'+str(int(event.participation_member_price))+')' #enregistrement de l'inscription si pas déjà inscrit : res=request.env['event.registration'].sudo().search([('event_id','=',int(request.session['event_id'])),('partner_id','=',int(request.session['partner_id']))],limit=1) data['already_registered']=True data['payment_status']=res.payment_status if not res: data['already_registered']=False vals={} vals['event_id']=request.session['event_id'] vals['partner_id']=request.session['partner_id'] if post.get('headphone')=='true':vals['headphone']=True else:vals['headphone']=False if event.online_event: if post.get('online')=='yes':vals['online']=True else:vals['online']=False if event.online_only:vals['online']=True else: vals['online']=False vals['state']='open' res=request.env['event.registration'].sudo().create(vals) #création de la facture à régler if not event.free_participation: membership=False invoice_id=request.env['event.registration'].sudo().action_generate_participation_invoice(int(res.id),'CB',membership) else: data['headphone']=False if (post.get('headphone')=='true') : data['headphone']=True res.headphone=True request.session['res_id']=res.id return http.request.render('kalachakra.registration_step2',data) @http.route(['/kalachakra/onthespotpayment'], type='http', auth='public', website=True, sitemap=False,csrf=False) def onthespotparticipation(self,type=None,**post): res=request.env['event.registration'].sudo().search([('id','=',request.session['res_id'])]) res.onthespot_payment=True return http.request.render('kalachakra.onthespotpayment') @http.route(['/kalachakra/participation'], type='http', auth='public', website=True, sitemap=False,csrf=False) def participation(self,type=None,**post): data={} request.session['kalachakra_transaction']='' if type=='participation': res=request.env['event.registration'].sudo().search([('id','=',request.session['res_id'])]) invoice_id=res.invoice_id invoice=request.env['account.move'].sudo().search([('id','=',int(invoice_id))]) invoice.state='posted' #redirection sur la page de paiement de la facture : url="/my/invoices/"+str(int(res.invoice_id)) return request.redirect(url) if type=='membership_and_participation': res=request.env['event.registration'].sudo().search([('id','=',request.session['res_id'])]) #suppression de la facture sans adhésion invoice_id=res.invoice_id res.invoice_id=False request.env['account.move'].sudo().search([('id','=',int(invoice_id))]).unlink() #creation de la facture avec adhésion membership=True invoice_id=request.env['event.registration'].sudo().action_generate_participation_invoice(int(res.id),'CB',membership) invoice=request.env['account.move'].sudo().search([('id','=',int(invoice_id))]) res.invoice_id=invoice.id res.with_membership=True invoice.state='posted' #création de l'adhésion à régler #ajout de l'adhésion membership_product=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1) if not membership_product: raise UserError(_('No membership product, please add one')) vals={} vals['invoice_id']=int(invoice.id) vals['partner_id']=int(res.partner_id) vals['product_id']=int(membership_product.id) vals['start_date']=datetime.now() vals['end_date']=datetime.now()+relativedelta(years=1) vals['amount']=membership_product.list_price membership=request.env['kalachakra.membership'].sudo().create(vals) #redirection sur la page de paiement de la facture : url="/my/invoices/"+str(int(res.invoice_id)) return request.redirect(url) if type=='donation': request.session['kalachakra_transaction']='donation' data['kalachakra_transaction']='donation' data['title']='make donation' data['amount']=0 #donation product data['products']=request.env['product.product'].sudo().search([('donation','=',True),('booking_option_product','=',False)]) if type=='membership': request.session['kalachakra_transaction']='membership' data['kalachakra_transaction']='membership' data['title']='Become a member' p=request.env['product.product'].sudo().search([('membership_product','=',True)],limit=1) if not p: raise UserError(_('No membership product, please add one')) data['amount']=p.list_price #membership product data['products']=p if type=='super_membership': request.session['kalachakra_transaction']='super_membership' data['kalachakra_transaction']='super_membership' data['title']='Become a super member' p=request.env['product.product'].sudo().search([('super_membership_product','=',True)],limit=1) if not p: raise UserError(_('No membership product, please add one')) data['amount']=p.list_price #super membership product data['products']=p userid=request.env.context.get('uid') #title options title=request.env['res.partner.title'].sudo().search([]) data['titles']=title if userid: user=request.env['res.users'].sudo().search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) request.session['partner_id']=int(partner.id) data['partner']=partner data['registred']=True country=request.env['res.country'].sudo().search([]) data['countries']=country data['country_id']=int(partner.country_id) # si pas connecté else: data['registred']=False title_male=request.env['res.partner.title'].sudo().search([('name','=','Monsieur')]) #country options country=request.env['res.country'].sudo().search([]) data['countries']=country country_france=request.env['res.country'].sudo().search([('name','=','France')]) partner=request.env['res.partner'] partner.email='' partner.title=title_male.id partner.country_id=int(country_france.id) partner.firstname='' partner.name='' partner.street='' partner.street2='' partner.zip='' partner.city='' data['partner']=partner data['country_id']=int(country_france.id) return http.request.render('kalachakra.participation_form',data) @http.route(['/kalachakra/payment_choice'], type='http', auth='public', website=True, sitemap=False,csrf=False) def payment_choice(self,**post): #gestion du retour page précédente depuis page de paiement : on supprime les éléments générés ( don , adhésion) if not post.get('product_id'): if request.session['kalachakra_transaction']=='donation': request.env['donation.donation'].sudo().search([('id','=',int(request.session['donation_id']))]).unlink() if request.session['kalachakra_transaction']=='membership': request.env['kalachakra.membership'].sudo().search([('id','=',int(request.session['membership_id']))]).unlink() return request.redirect('/kalachakra/participation?type='+request.session['kalachakra_transaction']) userid=request.env.context.get('uid') if userid: user=request.env['res.users'].search([('id','=',int(userid))]) partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))]) request.session['partner_id']=int(partner.id) #mise à jour des informations du contact lié à l'utilisateur vals={} vals['name']=post.get('name') vals['firstname']=post.get('firstname') vals['title']=int(post.get('title_id')) vals['street']=post.get('street') vals['street2']=post.get('street2') vals['zip']=post.get('zip') vals['country_id']=int(post.get('country_id')) vals['phone']=post.get('phone') partner.sudo().write(vals) else: #si pas connecté on cherche le contact indiqué par l'email partner=request.env['res.partner'].sudo().search([('email','=',post.get('email'))],limit=1) #si pas de contact on le créé dans la base if not partner: vals={} vals['email']=post.get('email') vals['name']=post.get('name') vals['firstname']=post.get('firstname') vals['title']=int(post.get('title_id')) vals['street']=post.get('street') vals['street2']=post.get('street2') vals['zip']=post.get('zip') vals['country_id']=int(post.get('country_id')) vals['phone']=post.get('phone') partner=request.env['res.partner'].sudo().create(vals) user=request.env['res.users'].sudo().search([('email','=',partner.email)]) group_portal=request.env.ref('base.group_portal') if not user: request.env['res.users'].sudo().create({ 'name': partner.name, 'login': partner.email, 'email': partner.email, 'partner_id':partner.id, 'groups_id': [(4, group_portal.id)] }) user.sudo().action_reset_password() #si le contact existe : #on met à jour ses informations else: vals={} vals['name']=post.get('name') vals['firstname']=post.get('firstname') vals['title']=int(post.get('title_id')) vals['street']=post.get('street') vals['street2']=post.get('street2') vals['zip']=post.get('zip') vals['country_id']=int(post.get('country_id')) vals['phone']=post.get('phone') partner.sudo().write(vals) user=request.env['res.users'].sudo().search([('email','=',partner.email)]) group_portal=request.env.ref('base.group_portal') #création du compte utilisateur if not user: request.env['res.users'].sudo().create({ 'name': partner.name, 'login': partner.email, 'email': partner.email, 'partner_id':partner.id, 'groups_id': [(4, group_portal.id)] }) user.sudo().action_reset_password() #demande d'adhésion : on vérifie qu'il n'est pas déjà adhérent si demande d'adhésion if partner.member_status in ('member','super member') and request.session['kalachakra_transaction']=='membership': data={} data['email']=partner.email return http.request.render('kalachakra.already_member',data) data={} if request.session['kalachakra_transaction']=='donation': data['submit_txt']='Faire un don' if request.session['kalachakra_transaction']=='membership': data['submit_txt']='Régler maintenant' data['success_url']='/kalachakra/payment/success' data['error_url']='/kalachakra/payment/error' if request.session['kalachakra_transaction'] in ['donation','membership']: data['acquirers'] = list(request.env['payment.acquirer'].sudo().search([ ('state', 'in', ['enabled', 'test']), ('company_id', '=', request.env.company.id), ('provider', '!=', 'transfer') ],order="provider desc")) else: data['acquirers'] = list(request.env['payment.acquirer'].sudo().search([ ('state', 'in', ['enabled', 'test']), ('company_id', '=', request.env.company.id) ])) payment_tokens = partner.payment_token_ids payment_tokens |= partner.commercial_partner_id.sudo().payment_token_ids data['payment_tokens']=payment_tokens #create donation if request.session['kalachakra_transaction'] in ['donation']: vals={} vals['partner_id']=partner.id vals['donation_date']=datetime.now() vals['tax_receipt_option']='annual' #mode de paiement CB electronic_method=request.env['account.payment.method'].sudo().search([('code','=','electronic')],limit=1) if electronic_method: cb_mode=request.env['account.payment.mode'].sudo().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={} #create line donation vals['donation_id']=donation_draft.id product=request.env['product.template'].sudo().search([('id','=',int(post.get('product_id')))]) vals['product_id']=int(post.get('product_id')) 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) data['order_id']=donation_draft.id request.session['donation_id'] = donation_draft.id #create membership if request.session['kalachakra_transaction'] in ['membership']: vals={} vals['partner_id']=partner.id vals['product_id']=int(post.get('product_id')) vals['start_date']=datetime.now() vals['end_date']=datetime.now()+relativedelta(years=1) vals['amount']=post.get('amount') membership=request.env['kalachakra.membership'].sudo().create(vals) data['order_id']=membership.id request.session['membership_id'] = membership.id return http.request.render('kalachakra.kalachakra_payment_choice_form',data) @http.route(['/kalachakra/payment/transaction/', '/kalachakra/payment/transaction/', '/kalachakra/payment/transaction//'], type='json', auth="public", website=True) def kalachakra_payment_transaction(self, acquirer_id,order_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 if request.session['kalachakra_transaction'] in ['donation']: # Retrieve the donation donation_id=order_id donation=request.env['donation.donation'].sudo().search([('id','=',int(donation_id))], limit=1) # Ensure there is something to proceed if not donation or (donation and not donation.line_ids): return False assert donation.partner_id.id != request.website.partner_id.id # Create transaction vals = {'acquirer_id': acquirer_id, 'return_url': '/kalachakra/payment/validate'} if save_token: vals['type'] = 'form_save' if token: vals['payment_token_id'] = int(token) transaction = donation.sudo()._create_payment_transaction(vals) donation.transaction_id=transaction.id # 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.sudo().render_donation_button(donation) if request.session['kalachakra_transaction'] in ['membership']: # Retrieve the membeship membership_id=order_id membership=request.env['kalachakra.membership'].sudo().search([('id','=',int(membership_id))], limit=1) # Ensure there is something to proceed if not membership : return False assert membership.partner_id.id != request.website.partner_id.id # Create transaction vals = {'acquirer_id': acquirer_id, 'return_url': '/kalachakra/payment/validate'} if save_token: vals['type'] = 'form_save' if token: vals['payment_token_id'] = int(token) transaction = membership.sudo()._create_payment_transaction(vals) membership.transaction_id=transaction.id # 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.sudo().render_membership_button(membership) http.route('/kalachakra/payment/token', type='http', auth='public', website=True, sitemap=False) def kalachakra_payment_token(self, pm_id=None, **kwargs): """ Method that handles payment using saved tokens :param int pm_id: id of the payment.token that we want to use to pay. """ try: pm_id = int(pm_id) except ValueError: return request.redirect('/shop/?error=invalid_token_id') # We retrieve the token the user want to use to pay if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]): return request.redirect('/shop/?error=token_not_found') # Create transaction vals = {'payment_token_id': pm_id, 'return_url': '/kalachakra/payment/validate'} if request.session['kalachakra_transaction'] in ['donation']: tx = donation.sudo()._create_payment_transaction(vals) if request.session['kalachakra_transaction'] in ['membership']: tx = membership.sudo()._create_payment_transaction(vals) request.session['transaction_id']=tx.id PaymentProcessing.add_payment_transaction(tx) return request.redirect('kalachakra/payment/process') @http.route(['/kalachakra/payment/process'], type="http", auth="public", website=True, sitemap=False) def kalachakra_payment_status_page(self, **kwargs): # When the customer is redirect to this website page, # we retrieve the payment transaction list from his session tx_ids_list = self.get_payment_transaction_ids() payment_transaction_ids = request.env['payment.transaction'].sudo().browse(tx_ids_list).exists() render_ctx = { 'payment_tx_ids': payment_transaction_ids.ids, } return request.render("payment.payment_process_page", render_ctx) @http.route('/kalachakra/payment/validate', type='http', auth="public", website=True, sitemap=False) def kalachakra_payment_validate(self, transaction_id=None, sale_order_id=None, **post): """ Method that should be called by the server when receiving an update for a transaction. State at this point : - UDPATE ME """ if request.session['kalachakra_transaction'] in ['donation']: # donation_id=int(request.session['donation_id']) # #validation du don car la tranasction est ok # donation=request.env['donation.donation'].sudo().search([('id','=',donation_id)]) # donation.state='done' request.session['donation_id']=None #_logger.error("donor="+donation.partner_id.name+" donation_id="+str(donation_id)+" state="+donation.state) if request.session['kalachakra_transaction'] in ['membership']: # membership_id=int(request.session['membership_id']) # #validation du don car la tranasction est ok # membership=request.env['kalachakra.membership'].sudo().search([('id','=',membership_id)]) # membership.state='done' request.session['membership_id']=None # _logger.error("membership partner="+membership.partner_id.name+" state="+membership.state) transaction_id=int(request.session['__website_sale_last_tx_id'] ) tx = request.env['payment.transaction'].sudo().browse(transaction_id) PaymentProcessing.remove_payment_transaction(tx) return request.redirect('/kalachakra/payment/confirmation') @http.route(['/kalachakra/payment/confirmation'], type='http', auth="public", website=True, sitemap=False) def kalachakra_payment_confirmation(self, **post): return request.render("kalachakra.thankyou")