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) return Response(response_obj, status=status.HTTP_201_CREATED)
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 authenticate(username, password): user = None username = get_username_from_username_or_email(username) if not username: raise AuthenticationFailed() try: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login(login=username, password=password, reset=True) except (DolibarrAPIException): raise AuthenticationFailed() try: cyclos = CyclosAPI(mode='login') cyclos_token = cyclos.login(auth_string=b64encode( bytes('{}:{}'.format(username, password), 'utf-8')).decode( 'ascii')) except CyclosAPIException: raise AuthenticationFailed() try: user_results = dolibarr.get(model='users', sqlfilters="login='******'".format(username), api_key=dolibarr_token) dolibarr_user = [ item for item in user_results if item['login'] == username ][0] except (DolibarrAPIException, KeyError, IndexError): raise AuthenticationFailed() user, created = User.objects.get_or_create(username=username) user_profile = user.profile user_profile.cyclos_token = cyclos_token user_profile.dolibarr_token = dolibarr_token # if there is a member linked to this user, load it in order to retrieve its company name user_profile.companyname = '' if dolibarr_user['fk_member']: try: member = dolibarr.get(model='members', id=dolibarr_user['fk_member'], api_key=dolibarr_token) if member['company']: user_profile.companyname = member['company'] except DolibarrAPIException: pass try: user_profile.firstname = dolibarr_user['firstname'] user_profile.lastname = dolibarr_user['lastname'] except KeyError: raise AuthenticationFailed() user_profile.save() return user
def has_account(request): try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='cel') # Determine whether or not our user is an "utilisateur" or a "prestataire" group_constants_without_account = [ str(settings.CYCLOS_CONSTANTS['groups']['adherents_sans_compte']) ] group_constants_with_account = [ str(settings.CYCLOS_CONSTANTS['groups']['adherents_prestataires']), str(settings.CYCLOS_CONSTANTS['groups']['adherents_utilisateurs']) ] # Fetching info for our current user (we look for his groups) data = cyclos.post(method='user/load', data=[cyclos.user_id], token=request.user.profile.cyclos_token) # Determine whether or not our user is part of the appropriate group if data['result']['group']['id'] in group_constants_without_account: return Response({'status': False}) elif data['result']['group']['id'] in group_constants_with_account: return Response({'status': True}) else: raise PermissionDenied() except KeyError: raise PermissionDenied()
def change_password(request): """ change_password """ serializer = serializers.ChangePasswordSerializer(data=request.data) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) try: cyclos_mode = request.data['cyclos_mode'] except KeyError: cyclos_mode = 'bdc' try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode=cyclos_mode) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # password/change change_password_data = { 'user': cyclos.user_id, # ID de l'utilisateur 'type': str(settings.CYCLOS_CONSTANTS['password_types']['login_password']), 'oldPassword': request.data['old_password'], # saisi par l'utilisateur 'newPassword': request.data['new_password'], # saisi par l'utilisateur 'confirmNewPassword': request.data['confirm_password'], # saisi par l'utilisateur } return Response(cyclos.post(method='password/change', data=change_password_data))
def dedicated_accounts_summaries(request): """ Accounts summaries for dedicated accounts. """ try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='gi_bdc') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) query_data = [] # Compte dédié Eusko billet: compte_dedie_eusko_billet # Compte dédié Eusko numérique: compte_dedie_eusko_numerique query_data_billet = [str(settings.CYCLOS_CONSTANTS['users']['compte_dedie_eusko_billet']), None] query_data.extend(cyclos.post(method='account/getAccountsSummary', data=query_data_billet)['result']) query_data_numerique = [str(settings.CYCLOS_CONSTANTS['users']['compte_dedie_eusko_numerique']), None] query_data.extend(cyclos.post(method='account/getAccountsSummary', data=query_data_numerique)['result']) res = {} filter_keys = ['compte_dedie_eusko_billet', 'compte_dedie_eusko_numerique'] for filter_key in filter_keys: data = [item for item in query_data if item['owner']['id'] == str(settings.CYCLOS_CONSTANTS['users'][filter_key])][0] res[filter_key] = {} res[filter_key]['id'] = data['id'] res[filter_key]['balance'] = float(data['status']['balance']) res[filter_key]['currency'] = data['currency']['symbol'] res[filter_key]['type'] = {'name': data['type']['name'], 'id': filter_key} return Response(res)
def export_rie_adherent(request): serializer = serializers.ExportRIESerializer(data=request.query_params) serializer.is_valid(raise_exception=True) 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) query_data = [cyclos.user_id, None] accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=query_data) for account in (accounts_summaries_data['result']): if account['number'] == request.query_params['account']: # add loop to context to display rie 6 times context = {'account': account, 'loop': range(0, 3)} response = wkhtmltopdf_views.PDFTemplateResponse( request=request, context=context, template="summary/rie.html") pdf_content = response.rendered_content headers = { 'Content-Disposition': 'filename="pdf_id.pdf"', 'Content-Length': len(pdf_content), } return Response(pdf_content, headers=headers)
def accounts_summaries(request, login_bdc=None): """ List all accounts_summaries for this BDC user. """ cyclos_mode = 'gi_bdc' if login_bdc else 'bdc' try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode=cyclos_mode, login_bdc=login_bdc) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # account/getAccountsSummary query_data = [cyclos.user_bdc_id, None] # ID de l'utilisateur Bureau de change accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=query_data) # Stock de billets: stock_de_billets_bdc # Caisse euros: caisse_euro_bdc # Caisse eusko: caisse_eusko_bdc # Retour eusko: retours_d_eusko_bdc res = {} filter_keys = ['stock_de_billets_bdc', 'caisse_euro_bdc', 'caisse_eusko_bdc', 'retours_d_eusko_bdc'] for filter_key in filter_keys: data = [item for item in accounts_summaries_data['result'] if item['type']['id'] == str(settings.CYCLOS_CONSTANTS['account_types'][filter_key])][0] res[filter_key] = {} res[filter_key]['id'] = data['id'] res[filter_key]['balance'] = float(data['status']['balance']) res[filter_key]['currency'] = data['currency']['symbol'] res[filter_key]['type'] = {'name': data['type']['name'], 'id': filter_key} return Response(res)
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 system_accounts_summaries(request): """ List all system_accounts_summaries. """ try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='gi_bdc') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # account/getAccountsSummary query_data = ['SYSTEM', None] accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=query_data) # Stock de billets: stock_de_billets # Compte de transit: compte_de_transit res = {} filter_keys = ['stock_de_billets', 'compte_de_transit'] for filter_key in filter_keys: data = [item for item in accounts_summaries_data['result'] if item['type']['id'] == str(settings.CYCLOS_CONSTANTS['account_types'][filter_key])][0] res[filter_key] = {} res[filter_key]['id'] = data['id'] res[filter_key]['balance'] = float(data['status']['balance']) res[filter_key]['currency'] = data['currency']['symbol'] res[filter_key]['type'] = {'name': data['type']['name'], 'id': filter_key} return Response(res)
def reconvert_eusko(request): """ Transfer d'eusko entre compte de particulier. """ 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.ReconvertEuskoSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) # payment/perform query_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types'] ['reconversion_numerique']), 'amount': serializer.data['amount'], 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': serializer.data['debit'], 'to': 'SYSTEM', 'description': serializer.data['description'], } return Response(cyclos.post(method='payment/perform', data=query_data))
def one_time_transfer(request): """ Transfer d'eusko entre compte d'adhérent. """ 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.OneTimeTransferSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) # payment/perform query_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types'] ['virement_inter_adherent']), 'amount': serializer.data['amount'], 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': serializer.data['debit'], 'to': serializer.data['beneficiaire'], 'description': serializer.data['description'], } return Response(cyclos.post(method='payment/perform', data=query_data))
def __init__(self, **kwargs): self.__dict__.update(kwargs) self.cyclos = CyclosAPI() try: if self.model: self.dolibarr = DolibarrAPI(model=self.model) except AttributeError: self.dolibarr = DolibarrAPI()
def get_current_user_account_number(request): """ Renvoie le numéro de compte de l'utilisateur courant (i.e. l'utilisateur qui a fait la requête). """ 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) accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=[cyclos.user_id, None]) return accounts_summaries_data['result'][0]['number']
def euskokart_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) response = cyclos.post(method='password/getData', data=cyclos.user_id) pin_code = [ p for p in response['result']['passwords'] if p['type']['id'] == str( settings.CYCLOS_CONSTANTS['password_types']['pin']) ][0] return Response(pin_code['status'])
def account_summary_for_adherents(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) query_data = [cyclos.user_id, None] accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=query_data) return Response(accounts_summaries_data)
def change_euro_eusko(request): """ Change d'€ en eusko pour un adhérent via un BDC. """ try: 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) serializer = serializers.ChangeEuroEuskoSerializer(data=request.data) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) member_cyclos_id = cyclos.get_member_id_from_login(request.data['member_login']) try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) dolibarr_member = dolibarr.get(model='members', sqlfilters="login='******'".format(request.data['member_login']))[0] except DolibarrAPIException: return Response({'error': 'Unable to connect to Dolibarr!'}, status=status.HTTP_400_BAD_REQUEST) except IndexError: return Response({'error': 'Unable to fetch Dolibarr data! Maybe your credentials are invalid!?'}, status=status.HTTP_400_BAD_REQUEST) if dolibarr_member['type'].lower() == 'particulier': member_name = '{} {}'.format(dolibarr_member['firstname'], dolibarr_member['lastname']) else: member_name = dolibarr_member['company'] # payment/perform query_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types']['change_billets_versement_des_euro']), 'amount': request.data['amount'], 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['euro']), 'from': 'SYSTEM', 'to': cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change 'customValues': [ { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['adherent']), 'linkedEntityValue': member_cyclos_id # ID de l'adhérent }, { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['mode_de_paiement']), 'enumeratedValues': request.data['payment_mode'] # ID du mode de paiement (chèque ou espèces) }, ], # "Change - E12345 - Nom de l'adhérent - Mode de paiement" 'description': 'Change billets - {} - {} - {}'.format( request.data['member_login'], member_name, request.data['payment_mode_name']), } return Response(cyclos.post(method='payment/perform', data=query_data))
def euskokart_unblock(request): serializer = serializers.EuskokartLockSerializer(data=request.query_params) serializer.is_valid(raise_exception=True) 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) query_data = [serializer.data['id']] euskokart_data = cyclos.post(method='token/unblock', data=query_data) return Response(euskokart_data)
def payments_available_for_adherents(request): serializer = serializers.HistorySerializer(data=request.query_params) serializer.is_valid(raise_exception=True) 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) begin_date = serializer.data['begin'].replace(hour=0, minute=0, second=0).isoformat() end_date = serializer.data['end'].replace(hour=23, minute=59, second=59).isoformat() query_data = [cyclos.user_id, end_date] accounts_summaries_data = cyclos.post(method='account/getAccountsSummary', data=query_data) search_history_data = { 'orderBy': 'DATE_DESC', 'pageSize': 1000, # maximum pageSize: 1000 'currentPage': 0, 'period': { 'begin': begin_date, 'end': end_date, }, } try: search_history_data.update( {'account': request.query_params['account']}) except KeyError: search_history_data.update({ 'account': accounts_summaries_data['result'][0]['status']['accountId'] }) try: search_history_data.update( {'description': request.query_params['description']}) except KeyError: pass accounts_history_res = cyclos.post(method='account/searchAccountHistory', data=search_history_data) return Response([ accounts_history_res, accounts_summaries_data['result'][0]['status']['balance'] ])
def reconversion(request): """ Reconversion eusko en euros pour un adhérent (prestataire) via un BDC. """ try: 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) serializer = serializers.ReconversionSerializer(data=request.data) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) dolibarr_member = dolibarr.get(model='members', sqlfilters="login='******'".format(request.data['member_login']))[0] except DolibarrAPIException: return Response({'error': 'Unable to connect to Dolibarr!'}, status=status.HTTP_400_BAD_REQUEST) except IndexError: return Response({'error': 'Unable to fetch Dolibarr data! Maybe your credentials are invalid!?'}, status=status.HTTP_400_BAD_REQUEST) if dolibarr_member['type'].lower() == 'particulier': return Response({'error': 'Forbidden, reconversion is not available for non-business members!'}, status=status.HTTP_403_FORBIDDEN) member_cyclos_id = cyclos.get_member_id_from_login(request.data['member_login']) # payment/perform query_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types']['reconversion_billets_versement_des_eusko']), 'amount': request.data['amount'], 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': 'SYSTEM', 'to': cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change 'customValues': [ { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['adherent']), 'linkedEntityValue': member_cyclos_id # ID de l'adhérent }, { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['numero_de_facture']), 'stringValue': request.data['facture'] # ID Facture }, ], 'description': 'Reconversion - {} - {}'.format(request.data['member_login'], dolibarr_member['company']), } return Response(cyclos.post(method='payment/perform', data=query_data))
def payments_available_for_entree_stock(request): """ payments_available_for_entree_stock """ serializer = serializers.PaymentsAvailableEntreeStockSerializer(data=request.query_params) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) try: login_bdc = request.query_params['login_bdc'] cyclos_mode = 'gi_bdc' except KeyError: login_bdc = None cyclos_mode = 'bdc' try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode=cyclos_mode, login_bdc=login_bdc) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # account/searchAccountHistory search_history_data = { 'account': str(settings.CYCLOS_CONSTANTS['system_accounts']['compte_de_transit']), 'orderBy': 'DATE_DESC', 'direction': 'CREDIT', 'fromNature': 'SYSTEM', 'statuses': [ str(settings.CYCLOS_CONSTANTS['transfer_statuses']['a_rapprocher']) ], 'pageSize': 1000, # maximum pageSize: 1000 'currentPage': 0, } accounts_summaries_res = cyclos.post(method='account/searchAccountHistory', data=search_history_data) # Filter out the results that are not "Sortie coffre" and items that are not for this BDC accounts_summaries_data = [ item for item in accounts_summaries_res['result']['pageItems'] for value in item['customValues'] if item['type']['id'] == str(settings.CYCLOS_CONSTANTS['payment_types']['sortie_coffre']) and value['field']['internalName'] == 'bdc' and value['linkedEntityValue']['id'] == cyclos.user_bdc_id ] return Response(accounts_summaries_data)
def euskokart_list(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) query_data = [ str(settings.CYCLOS_CONSTANTS['tokens']['carte_nfc']), cyclos.user_id ] euskokart_data = cyclos.post(method='token/getListData', data=query_data) try: euskokart_res = [item for item in euskokart_data['result']['tokens']] except KeyError: return Response({'error': 'Unable to fetch euskokart data!'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response(euskokart_res)
def create(self, request, *args, **kwargs): """ Créer un bénéficiaire en donnant son numéro de compte. """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) cyclos_account_number = serializer.validated_data[ 'cyclos_account_number'] # Si ce bénéficiaire existe déjà, on renvoie simplement OK. try: beneficiaire = Beneficiaire.objects.get( owner=self.request.user, cyclos_account_number=cyclos_account_number) if beneficiaire: serializer = self.get_serializer(beneficiaire) return Response(serializer.data, status=status.HTTP_200_OK) except Beneficiaire.DoesNotExist: pass # Le bénéficiaire n'existe pas, on va le créer. # On cherche dans Cyclos l'utilisateur correspondant au numéro de compte du bénéficiaire à créer. 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': cyclos_account_number}) if data['result']['totalCount'] == 0: return Response({'error': _("Ce numéro de compte n'existe pas")}, status=status.HTTP_422_UNPROCESSABLE_ENTITY) cyclos_user = data['result']['pageItems'][0] # Enregistrement du bénéficiaire en base de données. beneficiaire = serializer.save(owner=str(request.user), cyclos_id=cyclos_user['id'], cyclos_name=cyclos_user['display']) # Le bénéficiaire créé est envoyé dans la réponse. serializer = self.get_serializer(beneficiaire) return Response(serializer.data, status=status.HTTP_201_CREATED)
def porteurs_eusko(request): """ List porteurs d'euskos. """ try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # user/search for group = 'Porteurs' porteurs_data = cyclos.post( method='user/search', data={'groups': [settings.CYCLOS_CONSTANTS['groups']['porteurs']]}) res = [{ 'label': item['display'], 'value': item['id'] } for item in porteurs_data['result']['pageItems']] return Response(res)
def sortie_stock(request): """ Enregistre une sortie dans le stock billets d'un BDC. """ serializer = serializers.SortieStockBDCSerializer(data=request.data) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) try: login_bdc = request.data['login_bdc'] cyclos_mode = 'gi_bdc' except KeyError: login_bdc = None cyclos_mode = 'bdc' try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode=cyclos_mode, login_bdc=login_bdc) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # payment/perform query_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types']['sortie_stock_bdc']), 'amount': request.data['amount'], 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change 'to': 'SYSTEM', 'customValues': [ { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['porteur']), 'linkedEntityValue': request.data['porteur'] # ID du porteur }, ], 'description': request.data['description'], } return Response(cyclos.post(method='payment/perform', data=query_data))
def search(self, request, *args, **kwargs): query = request.query_params.get('number', False) res = None if not query or len(query) != 9: return exceptions.ParseError() try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='cel') # user/search by account number only data = cyclos.post( method='user/search', data={'keywords': str(request.query_params['number'])}) res = [{ 'label': item['display'], 'id': item['id'] } for item in data['result']['pageItems']][0] except (KeyError, IndexError, CyclosAPIException): Response(status=status.HTTP_204_NO_CONTENT) return Response(res) if res else Response( status=status.HTTP_204_NO_CONTENT)
def deposit_banks(request): """ List available banks. """ try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token) except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # user/search for group = 'Banques de dépot' banks_data = cyclos.post( method='user/search', data={ 'groups': [settings.CYCLOS_CONSTANTS['groups']['banques_de_depot']] }) res = [{ 'label': item['display'], 'value': item['id'], 'shortLabel': item['shortDisplay'] } for item in banks_data['result']['pageItems']] return Response(res)
def deposit_banks_summaries(request): """ Accounts summaries for deposit banks. """ try: cyclos = CyclosAPI(token=request.user.profile.cyclos_token, mode='gi_bdc') except CyclosAPIException: return Response({'error': 'Unable to connect to Cyclos!'}, status=status.HTTP_400_BAD_REQUEST) # user/search for group = 'Banques de dépot' banks_data = cyclos.post(method='user/search', data={'groups': [settings.CYCLOS_CONSTANTS['groups']['banques_de_depot']]}) bank_names = [{'label': item['display'], 'value': item['id'], 'shortLabel': item['shortDisplay']} for item in banks_data['result']['pageItems']] res = {} for bank in bank_names: bank_user_query = { 'keywords': bank['shortLabel'], # shortLabel = shortDisplay from Cyclos } try: bank_user_data = cyclos.post(method='user/search', data=bank_user_query)['result']['pageItems'][0] bank_account_query = [bank_user_data['id'], None] bank_data = cyclos.post(method='account/getAccountsSummary', data=bank_account_query)['result'][0] except (KeyError, IndexError): return Response({'error': 'Unable to get bank data for one of the depositbank!'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) res[bank['shortLabel']] = bank res[bank['shortLabel']]['balance'] = float(bank_data['status']['balance']) res[bank['shortLabel']]['currency'] = bank_data['currency']['symbol'] res[bank['shortLabel']]['type'] = {'name': bank_data['type']['name'], 'id': bank_data['type']['id']} return Response(res)
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 = 'bankaccounts/{}/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.put( 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 = 'bankaccounts/{}/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} if current_member['type'].lower() in ('particulier', 'touriste'): member_name = '{} {}'.format(current_member['firstname'], current_member['lastname']) else: member_name = current_member['company'] # Get Cyclos member and create it if it does not exist. try: member_cyclos_id = self.cyclos.get_member_id_from_login(current_member['login']) except CyclosAPIException: log.debug("Member not found in Cyclos, will create it.") create_user_data = { 'group': str(settings.CYCLOS_CONSTANTS['groups']['adherents_sans_compte']), 'name': '{} {}'.format(current_member['firstname'], current_member['lastname']), 'username': current_member['login'], 'skipActivationEmail': True, } log.debug("create_user_data = {}".format(create_user_data)) response_data = self.cyclos.post(method='user/register', data=create_user_data) member_cyclos_id = response_data['result']['user']['id'] log.debug("member_cyclos_id = {}".format(member_cyclos_id)) # Cyclos: Register member subscription payment 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) return Response(res, status=status.HTTP_201_CREATED)
def retrait_eusko_numerique(request): """ Retrait eusko: numerique vers billets """ try: 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) serializer = serializers.RetraitEuskoNumeriqueSerializer(data=request.data) serializer.is_valid(raise_exception=True) # log.critical(serializer.errors) member_cyclos_id = cyclos.get_member_id_from_login(request.data['member_login']) try: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) dolibarr_member = dolibarr.get(model='members', sqlfilters="login='******'".format(request.data['member_login']))[0] except DolibarrAPIException: return Response({'error': 'Unable to connect to Dolibarr!'}, status=status.HTTP_400_BAD_REQUEST) except IndexError: return Response({'error': 'Unable to fetch Dolibarr data! Maybe your credentials are invalid!?'}, status=status.HTTP_400_BAD_REQUEST) if dolibarr_member['type'].lower() == 'particulier': member_name = '{} {}'.format(dolibarr_member['firstname'], dolibarr_member['lastname']) else: member_name = dolibarr_member['company'] # Verify whether or not member account has enough money member_account_summary_query = [member_cyclos_id, None] # ID de l'adhérent member_account_summary_res = cyclos.post(method='account/getAccountsSummary', data=member_account_summary_query) try: if (member_account_summary_res['result'][0]['type']['id'] != str(settings.CYCLOS_CONSTANTS['account_types']['compte_d_adherent'])): return Response({'error': "Unable to fetch account data!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except (KeyError, IndexError): return Response({'error': "Unable to fetch account data!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) try: if float(member_account_summary_res['result'][0]['status']['balance']) < float(request.data['amount']): return Response({'error': "error-member-not-enough-money"}) except (KeyError, IndexError): return Response({'error': "Unable to fetch account data!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # Verify whether or not bdc cash stock have enough money bdc_account_summary_query = [cyclos.user_bdc_id, None] # ID de l'utilisateur Bureau de change bdc_account_summary_res = cyclos.post(method='account/getAccountsSummary', data=bdc_account_summary_query) bdc_account_summary_data = [ item for item in bdc_account_summary_res['result'] if item['type']['id'] == str(settings.CYCLOS_CONSTANTS['account_types']['stock_de_billets_bdc'])][0] if float(bdc_account_summary_data['status']['balance']) < float(request.data['amount']): return Response({'error': "error-bureau-not-enough-money"}) # Débit du compte debit_compte_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types']['retrait_du_compte']), 'amount': request.data['amount'], # montant saisi 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': member_cyclos_id, # ID de l'adhérent 'to': 'SYSTEM', 'customValues': [ { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['bdc']), 'linkedEntityValue': cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change }, ], 'description': 'Retrait', } cyclos.post(method='payment/perform', data=debit_compte_data) # Retrait des billets retrait_billets_data = { 'type': str(settings.CYCLOS_CONSTANTS['payment_types']['retrait_de_billets']), 'amount': request.data['amount'], # montant saisi 'currency': str(settings.CYCLOS_CONSTANTS['currencies']['eusko']), 'from': cyclos.user_bdc_id, # ID de l'utilisateur Bureau de change 'to': 'SYSTEM', 'customValues': [ { 'field': str(settings.CYCLOS_CONSTANTS['transaction_custom_fields']['adherent']), 'linkedEntityValue': member_cyclos_id, # ID de l'adhérent }, ], 'description': 'Retrait - {} - {}'.format(request.data['member_login'], member_name), } cyclos.post(method='payment/perform', data=retrait_billets_data) return Response(retrait_billets_data)