def send_mail_change_auto(login, profile, mode, new_amount, comment, lang): """ Envoi mail à Euskal Moneta lorsque le montant du change automatique à été modifié. """ # Activate user pre-selected language activate(lang) if mode == 'delete': subject = _('Arrêt du change mensuel automatique') else: subject = _( 'Modification du montant du change mensuel automatique') body = render_to_string( 'mails/send_mail_change_auto.txt', { 'login': login, 'mode': mode, 'profile_firstname': str(profile.firstname), 'profile_lastname': str(profile.lastname), 'profile_companyname': str(profile.companyname), 'new_amount': new_amount, 'comment': comment }) sendmail_euskalmoneta(subject=subject, body=body)
def notifier_crediteur(request, mandat, template): """ Envoi d'une notification par email au créditeur. """ # On cherche le créditeur dans Cyclos par son numéro de compte, pour avoir son numéro d'adhérent, puis on # charge les informations de cet adhérent dans Dolibarr et enfin, on lui envoie un email. try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) except DolibarrAPIException: return Response({'error': 'Unable to connect to Dolibarr!'}, status=status.HTTP_400_BAD_REQUEST) try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='cel') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) data = cyclos.post(method='user/search', data={'keywords': mandat.numero_compte_crediteur}) crediteur = data['result']['pageItems'][0] crediteur_dolibarr = dolibarr.get(model='members', sqlfilters="login='******'".format(crediteur['shortDisplay']))[0] # Activation de la langue choisie par l'adhérent et traduction du sujet et du corps de l'email. activate(crediteur_dolibarr['array_options']['options_langue']) subject = _("Compte Eusko : demande d'autorisation de prélèvements") body = render_to_string('mails/{}.txt'.format(template), {'user': crediteur_dolibarr, 'debiteur': mandat.nom_debiteur}) # Envoi de l'email sendmail_euskalmoneta(subject=subject, body=body, to_email=crediteur_dolibarr['email'])
def refuse_cgu(request): try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) member_data = dolibarr.get(model='members', sqlfilters="login='******'".format( request.user))[0] data = {'array_options': member_data['array_options']} data['array_options'].update( {'options_accepte_cgu_eusko_numerique': False}) dolibarr.put(model='members/{}'.format(member_data['id']), data=data) # Activate user pre-selected language activate(member_data['array_options']['options_langue']) # Translate subject & body for this email subject = _('Refus des CGU') body = render_to_string('mails/refuse_cgu.txt', {'user': member_data}) sendmail_euskalmoneta(subject=subject, body=body) return Response({'status': 'OK'}) except (DolibarrAPIException, KeyError, IndexError): return Response({'error': 'Unable to update CGU field!'}, status=status.HTTP_400_BAD_REQUEST)
def create(self, request): data = request.data serializer = MemberSerializer(data=data) if serializer.is_valid(): data = Member.validate_data(data) else: log.critical(serializer.errors) return Response( { 'error': 'Oops! Something is wrong in your request data: {}'.format( serializer.errors) }, status=status.HTTP_400_BAD_REQUEST) log.info('posted data: {}'.format(data)) # #841 : We need to connect to Cyclos before doing Dolibarr calls, making sure Cyclos token is still valid. # This way, we avoid creating a member in Dolibarr if it's not the case. try: self.cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='bdc') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # Dolibarr: Register member response_obj = self.dolibarr.post( model=self.model, data=data, api_key=request.user.profile.dolibarr_token) log.info(response_obj) # Cyclos: Register member create_user_data = { 'group': str(settings.CYCLOS_CONSTANTS['groups']['adherents_sans_compte']), 'name': '{} {}'.format(data['firstname'], data['lastname']), 'username': data['login'], 'skipActivationEmail': True, } self.cyclos.post(method='user/register', data=create_user_data) if data['email']: # Activate user pre-selected language # TODO: Ask member for his prefered lang # activate(data['options_langue']) # Translate subject & body for this email subject = _('Votre adhésion à Euskal Moneta') body = render_to_string('mails/create_member.txt', {'user': data}) sendmail_euskalmoneta(subject=subject, body=body, to_email=data['email']) return Response(response_obj, status=status.HTTP_201_CREATED)
def send_mail_newsletter(login, profile, new_status, lang): """ Envoi mail à Euskal Moneta lorsque l'option "Je souhaite être informé..." à été modifiée. """ # Activate user pre-selected language activate(lang) # Translate subject & body for this email subject = _("Changement d'option pour l'abonnement aux actualités") body = render_to_string('mails/send_mail_newsletter.txt', {'login': login, 'profile_firstname': str(profile.firstname), 'profile_lastname': str(profile.lastname), 'profile_companyname': str(profile.companyname), 'new_status': new_status}) sendmail_euskalmoneta(subject=subject, body=body)
def partial_update(self, request, pk=None): serializer = MemberPartialSerializer(data=request.data) if serializer.is_valid(): member = self.dolibarr.get(model='members/{}'.format(pk), api_key=request.user.profile.dolibarr_token) # Validate / modify data (serialize to match Dolibarr formats) data = Member.validate_data(request.data, mode='update', base_options=member['array_options']) try: # Envoi d'un email lorsque l'option "Recevoir les actualités liées à l'Eusko" est modifiée if (member['array_options']['options_recevoir_actus'] != data['array_options']['options_recevoir_actus']): Member.send_mail_newsletter( login=str(request.user), profile=request.user.profile, new_status=data['array_options']['options_recevoir_actus'], lang=member['array_options']['options_langue']) # Envoi d'un email lorsque l'option "Montant du change automatique" est modifiée if (float(member['array_options']['options_prelevement_change_montant']) != float(data['array_options']['options_prelevement_change_montant'])): Member.send_mail_change_auto( login=str(request.user), profile=request.user.profile, mode=data['mode'], new_amount=data['array_options']['options_prelevement_change_montant'], comment=data['prelevement_change_comment'], email=member['email'], lang=member['array_options']['options_langue']) # Envoi d'un email lorsque l'option "IBAN" est modifiée. if (member['array_options']['options_iban'] != data['array_options']['options_iban']): sujet = _("Modification de l'IBAN pour le change automatique mensuel") texte = render_to_string('mails/modification_iban.txt', {'dolibarr_member': member, 'nouvel_iban': data['array_options']['options_iban']}).strip('\n') sendmail_euskalmoneta(subject=sujet, body=texte) except KeyError: pass else: log.critical(serializer.errors) return Response({'error': 'Oops! Something is wrong in your request data: {}'.format(serializer.errors)}, status=status.HTTP_400_BAD_REQUEST) return Response(self.dolibarr.put(model='members/{}'.format(pk), data=data, api_key=request.user.profile.dolibarr_token))
def euskokart_update_pin(request): try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='cel') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) serializer = serializers.UpdatePinSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) query_data = { 'user': cyclos.user_id, 'type': str(settings.CYCLOS_CONSTANTS['password_types']['pin']), 'newPassword': serializer.data['pin1'], 'confirmNewPassword': serializer.data['pin2'] } try: query_data.update({'oldPassword': serializer.data['ex_pin']}) mode = 'modifiy' except KeyError: mode = 'add' try: cyclos.post(method='password/change', data=query_data) except CyclosAPIException: return Response({'error': 'Unable to set your pin code!'}, status=status.HTTP_401_UNAUTHORIZED) try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) response = dolibarr.get(model='members', login=str(request.user)) # Activate user pre-selected language activate(response[0]['array_options']['options_langue']) if mode == 'modifiy': subject = _('Modification du code secret de votre euskokart') response_data = {'status': 'Pin modified!'} elif mode == 'add': subject = _('Choix du code secret de votre euskokart') response_data = {'status': 'Pin added!'} body = render_to_string('mails/euskokart_update_pin.txt', { 'mode': mode, 'user': response[0] }) sendmail_euskalmoneta(subject=subject, body=body, to_email=response[0]['email']) except DolibarrAPIException as e: return Response( { 'error': 'Unable to resolve user in dolibarr! error : {}'.format(e) }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({'error': 'Unable to send mail! error : {}'.format(e)}, status=status.HTTP_400_BAD_REQUEST) return Response(response_data, status=status.HTTP_202_ACCEPTED)
def first_connection(request): """ First connection """ serializer = serializers.FirstConnectionSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) try: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login( login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) valid_login = Member.validate_num_adherent(request.data['login']) try: dolibarr.get(model='users', login=request.data['login'], api_key=dolibarr_token) return Response({'error': 'User already exist!'}, status=status.HTTP_201_CREATED) except DolibarrAPIException: pass if valid_login: # We want to search in members by login (N° Adhérent) response = dolibarr.get(model='members', login=request.data['login'], api_key=dolibarr_token) user_data = [ item for item in response if item['login'] == request.data['login'] ][0] if user_data['email'] == request.data['email']: # We got a match! # We need to mail a token etc... payload = { 'login': request.data['login'], 'aud': 'guest', 'iss': 'first-connection', 'jti': str(uuid4()), 'iat': datetime.utcnow(), 'nbf': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(hours=1) } jwt_token = jwt.encode(payload, settings.JWT_SECRET) confirm_url = '{}/valide-premiere-connexion?token={}'.format( settings.CEL_PUBLIC_URL, jwt_token.decode("utf-8")) # Activate user pre-selected language activate(user_data['array_options']['options_langue']) # Translate subject & body for this email subject = _('Première connexion à votre compte en ligne Eusko') body = render_to_string('mails/first_connection.txt', { 'token': confirm_url, 'user': user_data }) sendmail_euskalmoneta(subject=subject, body=body, to_email=request.data['email']) return Response({'member': 'OK'}) else: return Response(status=status.HTTP_400_BAD_REQUEST) else: return Response( { 'error': 'You need to provide a *VALID* login parameter! (Format: E12345)' }, status=status.HTTP_400_BAD_REQUEST) except (DolibarrAPIException, KeyError, IndexError): return Response({'error': 'Unable to get user data for this login!'}, status=status.HTTP_400_BAD_REQUEST)
def create(self, request): """ Créer un mandat. C'est le créditeur qui crée le mandat, en donnant le numéro de compte du débiteur. """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) numero_compte_debiteur = serializer.validated_data['numero_compte_debiteur'] # Le créditeur est l'utilisateur courant. On récupère son numéro de compte dans Cyclos. numero_compte_crediteur = get_current_user_account_number(request) # Si ce mandat existe déjà, on renvoie simplement OK. try: mandat = Mandat.objects.get(numero_compte_crediteur=numero_compte_crediteur, numero_compte_debiteur=numero_compte_debiteur) if mandat: serializer = self.get_serializer(mandat) return Response(serializer.data, status=status.HTTP_200_OK) except Mandat.DoesNotExist: pass # Le mandat n'existe pas, on va le créer. try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) except DolibarrAPIException: return Response({'error': 'Unable to connect to Dolibarr!'}, status=status.HTTP_400_BAD_REQUEST) try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='cel') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # Pour avoir le nom du débiteur, on fait une recherche dans Cyclos par son numéro de compte. data = cyclos.post(method='user/search', data={'keywords': numero_compte_debiteur}) if data['result']['totalCount'] == 0: return Response({'error': _("Ce numéro de compte n'existe pas")}, status=status.HTTP_422_UNPROCESSABLE_ENTITY) debiteur = data['result']['pageItems'][0] # Enregistrement du mandat en base de données. mandat = serializer.save( nom_debiteur=debiteur['display'], numero_compte_crediteur=numero_compte_crediteur, nom_crediteur=cyclos.user_profile['result']['display'] ) # Notification par email au débiteur. debiteur_dolibarr = dolibarr.get(model='members', sqlfilters="login='******'".format(debiteur['shortDisplay']))[0] # Activation de la langue choisie par l'adhérent et traduction du sujet et du corps de l'email. activate(debiteur_dolibarr['array_options']['options_langue']) subject = _("Compte Eusko : demande d'autorisation de prélèvements") body = render_to_string('mails/demande_autorisation_prelevements.txt', {'user': debiteur_dolibarr, 'crediteur': cyclos.user_profile['result']['display']}) sendmail_euskalmoneta(subject=subject, body=body, to_email=debiteur_dolibarr['email']) # Le mandat créé est envoyé dans la réponse. serializer = self.get_serializer(mandat) return Response(serializer.data, status=status.HTTP_201_CREATED)
def create(self, request): data = request.data dolibarr_token = request.user.profile.dolibarr_token log.info("data: {}".format(data)) serializer = MembersSubscriptionsSerializer(data=data) if not serializer.is_valid(): log.critical("serializer.errors: {}".format(serializer.errors)) return Response( { 'error': 'Oops! Something is wrong in your request data: {}'.format( serializer.errors) }, status=status.HTTP_400_BAD_REQUEST) member_id = data.get('member_id', '') if not member_id: log.critical('A member_id must be provided!') return Response({'error': 'A member_id must be provided!'}, status=status.HTTP_400_BAD_REQUEST) # #841 : We need to connect to Cyclos before doing Dolibarr calls, making sure Cyclos token is still valid. # This way, we avoid creating a subscription in Dolibarr if it's not the case. try: self.cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='bdc') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) try: member = self.dolibarr.get(model='members', id=member_id, api_key=dolibarr_token) except DolibarrAPIException as e: log.critical("member_id: {}".format(member_id)) log.critical(e) log.critical('This member_id was not found in the database!') return Response( {'error': 'This member_id was not found in the database!'}, status=status.HTTP_400_BAD_REQUEST) data['start_date'] = Subscription.calculate_start_date( member['datefin']) data['end_date'] = Subscription.calculate_end_date(data['start_date']) data['label'] = Subscription.calculate_label(data['end_date']) log.info("data after: {}".format(data)) # Register new subscription data_res_subscription = { 'start_date': data['start_date'], 'end_date': data['end_date'], 'amount': data['amount'], 'label': data['label'] } self.model = self.model.replace('%_%', member_id) try: res_id_subscription = self.dolibarr.post( model=self.model, data=data_res_subscription, api_key=dolibarr_token) log.info("res_id_subscription: {}".format(res_id_subscription)) except DolibarrAPIException as e: log.critical("model: {}".format(self.model)) log.critical( "data_res_subscription: {}".format(data_res_subscription)) log.critical(e) return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) # Register new payment payment_account, payment_type, payment_label = Subscription.account_and_type_from_payment_mode( data['payment_mode']) # noqa if not payment_account or not payment_type: log.critical('This payment_mode is invalid!') return Response({'error': 'This payment_mode is invalid!'}, status=status.HTTP_400_BAD_REQUEST) data_res_payment = { 'date': arrow.now('Europe/Paris').timestamp, 'type': payment_type, 'label': data['label'], 'amount': data['amount'] } model_res_payment = 'accounts/{}/lines'.format(payment_account) try: res_id_payment = self.dolibarr.post(model=model_res_payment, data=data_res_payment, api_key=dolibarr_token) log.info("res_id_payment: {}".format(res_id_payment)) except DolibarrAPIException as e: log.critical("model: {}".format(model_res_payment)) log.critical("data_res_payment: {}".format(data_res_payment)) log.critical(e) return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) # Link this new subscription with this new payment data_link_sub_payment = {'fk_bank': res_id_payment} model_link_sub_payment = 'subscriptions/{}'.format(res_id_subscription) try: res_id_link_sub_payment = self.dolibarr.patch( model=model_link_sub_payment, data=data_link_sub_payment, api_key=dolibarr_token) log.info( "res_id_link_sub_payment: {}".format(res_id_link_sub_payment)) except DolibarrAPIException as e: log.critical("model: {}".format(model_link_sub_payment)) log.critical( "data_link_sub_payment: {}".format(data_link_sub_payment)) log.critical(e) return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) # Link this payment with the related-member data_link_payment_member = { 'label': '{} {}'.format(member['firstname'], member['lastname']), 'type': 'member', 'url_id': member_id, 'url': '{}/adherents/card.php?rowid={}'.format( settings.DOLIBARR_PUBLIC_URL, member_id) } model_link_payment_member = 'accounts/{}/lines/{}/links'.format( payment_account, res_id_payment) try: res_id_link_payment_member = self.dolibarr.post( model=model_link_payment_member, data=data_link_payment_member, api_key=dolibarr_token) log.info("res_id_link_payment_member: {}".format( res_id_link_payment_member)) except DolibarrAPIException as e: log.critical("model: {}".format(model_link_payment_member)) log.critical("data_link_payment_member: {}".format( data_link_payment_member)) log.critical(e) return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) current_member = self.dolibarr.get(model='members', id=member_id, api_key=dolibarr_token) res = { 'id_subscription': res_id_subscription, 'id_payment': res_id_payment, 'link_sub_payment': res_id_link_sub_payment, 'id_link_payment_member': res_id_link_payment_member, 'member': current_member } # Cyclos: Register member subscription payment member_cyclos_id = self.cyclos.get_member_id_from_login( current_member['login']) if current_member['type'].lower() == 'particulier': member_name = '{} {}'.format(current_member['firstname'], current_member['lastname']) else: member_name = current_member['company'] query_data = {} if 'Eusko' in data['payment_mode']: query_data.update({ 'type': str(settings.CYCLOS_CONSTANTS['payment_types'] ['cotisation_en_eusko']), 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'customValues': [{ 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields'] ['adherent']), 'linkedEntityValue': member_cyclos_id }], 'description': 'Cotisation - {} - {}'.format(current_member['login'], member_name), }) currency = 'eusko' elif 'Euro' in data['payment_mode']: query_data.update({ 'type': str(settings.CYCLOS_CONSTANTS['payment_types'] ['cotisation_en_euro']), 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['euro']), 'customValues': [{ 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields'] ['adherent']), 'linkedEntityValue': member_cyclos_id }, { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields'] ['mode_de_paiement']), 'enumeratedValues': data['cyclos_id_payment_mode'] }], 'description': 'Cotisation - {} - {} - {}'.format(current_member['login'], member_name, payment_label), }) currency = '€' else: return Response({'error': 'This payment_mode is invalid!'}, status=status.HTTP_400_BAD_REQUEST) query_data.update({ 'amount': data['amount'], 'from': 'SYSTEM', 'to': self.cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change }) self.cyclos.post(method='payment/perform', data=query_data) if current_member['email']: # Activate user pre-selected language # TODO: Ask member for his prefered lang # activate(data['options_langue']) # Translate subject & body for this email subject = _('Votre cotisation à Euskal Moneta') body = render_to_string( 'mails/subscription.txt', { 'user': current_member, 'amount': data['amount'], 'currency': currency, 'enddate': arrow.get(current_member['datefin']).to( 'Europe/Paris').format('DD/MM/YYYY') }) sendmail_euskalmoneta(subject=subject, body=body, to_email=current_member['email']) return Response(res, status=status.HTTP_201_CREATED)