forked from Lokavaluto/dev-pack
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
460 lines
18 KiB
460 lines
18 KiB
# coding: utf-8
|
|
from __future__ import unicode_literals
|
|
|
|
import os
|
|
import argparse
|
|
import base64
|
|
import logging
|
|
|
|
import requests
|
|
import yaml # PyYAML
|
|
from datetime import datetime
|
|
from datetime import timedelta
|
|
|
|
logging.basicConfig()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def check_request_status(r):
|
|
if r.status_code == requests.codes.ok:
|
|
logger.info('OK')
|
|
else:
|
|
logger.error(r.text)
|
|
r.raise_for_status()
|
|
|
|
# Ensemble des constantes nécessaires au fonctionnement du script.
|
|
ENV = os.environ.get('ENV')
|
|
|
|
LOCAL_CURRENCY_INTERNAL_NAME = os.environ.get('CURRENCY_SLUG')
|
|
NETWORK_INTERNAL_NAME = LOCAL_CURRENCY_INTERNAL_NAME
|
|
|
|
if ENV != 'prod':
|
|
NETWORK_INTERNAL_NAME = ENV + LOCAL_CURRENCY_INTERNAL_NAME
|
|
|
|
LOCAL_CURRENCY_SYMBOL = os.environ.get('CURRENCY_SYMBOL')
|
|
|
|
# Arguments à fournir dans la ligne de commande
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('url', help='URL of Cyclos')
|
|
parser.add_argument('authorization',
|
|
help='string to use for Basic Authentication')
|
|
parser.add_argument('--debug',
|
|
help='enable debug messages',
|
|
action='store_true')
|
|
args = parser.parse_args()
|
|
|
|
if not args.url.endswith('/'):
|
|
args.url = args.url + '/'
|
|
if args.debug:
|
|
logger.setLevel(logging.DEBUG)
|
|
else:
|
|
logger.setLevel(logging.INFO)
|
|
|
|
for k, v in vars(args).items():
|
|
logger.debug('args.%s = %s', k, v)
|
|
|
|
# URLs des web services
|
|
global_web_services = args.url + 'global/web-rpc/'
|
|
network_web_services = args.url + '/' + NETWORK_INTERNAL_NAME + '/web-rpc/'
|
|
|
|
# En-têtes pour toutes les requêtes (il n'y a qu'un en-tête, pour
|
|
# l'authentification).
|
|
headers = {'Authorization': 'Basic ' + args.authorization}
|
|
|
|
# On fait une 1ère requête en lecture seule uniquement pour vérifier
|
|
# si les paramètres fournis sont corrects.
|
|
logger.info('Vérification des paramètres fournis...')
|
|
r = requests.post(global_web_services + 'network/search',
|
|
headers=headers, json={})
|
|
check_request_status(r)
|
|
|
|
|
|
########################################################################
|
|
# Création des utilisateurs pour les banques de dépôt et les comptes
|
|
# dédiés.
|
|
#
|
|
def create_user(group, name, login, email=None, password=None,city=None, custom_values=None):
|
|
logger.info('Création de l\'utilisateur "%s" (groupe "%s")...', name, group)
|
|
# FIXME code à déplacer pour ne pas l'exécuter à chaque fois
|
|
r = requests.post(network_web_services + 'group/search',
|
|
headers=headers, json={})
|
|
check_request_status(r)
|
|
groups = r.json()['result']['pageItems']
|
|
for g in groups:
|
|
if g['name'] == group:
|
|
group_id = g['id']
|
|
if not city:
|
|
city = 'Grenoble'
|
|
user_registration = {
|
|
'group': group_id,
|
|
'name': name,
|
|
'username': login,
|
|
'skipActivationEmail': True,
|
|
'addresses':[
|
|
{
|
|
'name': 'work',
|
|
'addressLine1': '10 rue du test',
|
|
'city': city,
|
|
'defaultAddress': True,
|
|
'hidden': False
|
|
}
|
|
]
|
|
}
|
|
if email:
|
|
user_registration['email'] = email
|
|
if password:
|
|
user_registration['passwords'] = [
|
|
{
|
|
'type': 'login',
|
|
'value': password,
|
|
'confirmationValue': password,
|
|
'assign': True,
|
|
'forceChange': False,
|
|
},
|
|
]
|
|
if custom_values:
|
|
user_registration['customValues'] = []
|
|
for field_id, value in custom_values.items():
|
|
r = requests.get(network_web_services + 'userCustomField/load/' + field_id, headers=headers)
|
|
check_request_status(r)
|
|
custom_field_type = r.json()['result']['type']
|
|
if custom_field_type == 'LINKED_ENTITY':
|
|
value_key = 'linkedEntityValue'
|
|
user_registration['customValues'].append({
|
|
'field': field_id,
|
|
value_key: value,
|
|
})
|
|
logger.debug('create_user : json = %s', user_registration)
|
|
r = requests.post(network_web_services + 'user/register',
|
|
headers=headers,
|
|
json=user_registration)
|
|
check_request_status(r)
|
|
logger.debug('result = %s', r.json()['result'])
|
|
user_id = r.json()['result']['user']['id']
|
|
logger.debug('user_id = %s', user_id)
|
|
return user_id
|
|
|
|
create_user(
|
|
group='Network administrators',
|
|
name= 'Administrator',
|
|
login= 'admin_network',
|
|
email= 'administrator@localhost.fr',
|
|
password= '@@bbccdd' #@WARNING : nécessité d'avoir ce mot de passe pour les tests appli CEL du Cairn
|
|
)
|
|
|
|
create_user(
|
|
group='Banques de dépôt',
|
|
name='Banque de dépôt 1',
|
|
login='BDP1',
|
|
)
|
|
create_user(
|
|
group='Banques de dépôt',
|
|
name='Banque de dépôt 2',
|
|
login='BDP2',
|
|
)
|
|
|
|
|
|
########################################################################
|
|
# Création des utilisateurs pour les tests.
|
|
if ENV != 'prod':
|
|
# On récupère l'id du champ perso 'BDC'.
|
|
r = requests.get(network_web_services + 'userCustomField/list', headers=headers)
|
|
check_request_status(r)
|
|
user_custom_fields = r.json()['result']
|
|
for field in user_custom_fields:
|
|
if field['internalName'] == 'bdc':
|
|
id_user_custom_field_bdc = field['id']
|
|
|
|
gestion_interne = {
|
|
'demo': 'Demo',
|
|
'demo2': 'Demo2',
|
|
}
|
|
for login, name in gestion_interne.items():
|
|
create_user(
|
|
group='Gestion interne',
|
|
name=name,
|
|
login=login,
|
|
password=login,
|
|
)
|
|
|
|
bureaux_de_change = {
|
|
'B000': 'Association Monnaie Locale',
|
|
'B001': 'Bureau de change 1',
|
|
'B002': 'Bureau de change 2',
|
|
}
|
|
for login, name in bureaux_de_change.items():
|
|
id_bdc = create_user(
|
|
group='Bureaux de change',
|
|
name=name + ' (BDC)',
|
|
login=login + '_BDC',
|
|
password=login,
|
|
)
|
|
create_user(
|
|
group='Opérateurs BDC',
|
|
name=name,
|
|
login=login,
|
|
password=login,
|
|
custom_values={
|
|
id_user_custom_field_bdc: id_bdc,
|
|
}
|
|
)
|
|
|
|
create_user(
|
|
group='Anonyme',
|
|
name='Anonyme',
|
|
login='anonyme',
|
|
password='anonyme',
|
|
)
|
|
|
|
adherents_utilisateurs = [
|
|
['gjanssens', 'Janssens Gaetan'],
|
|
['cretine_agnes', 'Créttine Agnès'],
|
|
['alberto_malik', 'Malik Alberto'],
|
|
['noire_aliss', 'La noire Aliss'],
|
|
['tous_andre', 'Tous Ensemble André'],
|
|
['speedy_andrew', 'Speedy Andrew'],
|
|
['stuart_andrew', 'Stuart Andrew'],
|
|
['crabe_arnold', 'Le Crabe Arnold'],
|
|
['barbare_cohen', 'le Barbare Cohen'],
|
|
['lacreuse_desiderata', 'Lacreuse Desiderata'],
|
|
['comblant_michel', 'Comblant Michel'],
|
|
['nico_faus_perso', 'Le Caméléon Nicolas'],
|
|
['benoit_perso', 'Le Rigolo Benoît'],
|
|
]
|
|
|
|
adherents_prestataires = [
|
|
['asso_mlc', 'Association Monnaie Locale','Grenoble'],
|
|
['maltobar', 'MaltOBar','Grenoble'],
|
|
['labonnepioche', 'La Bonne Pioche','Grenoble'],
|
|
['DrDBrew', 'DocteurD Brew Pub','Grenoble'],
|
|
['apogee_du_vin', 'Apogée du vin','Grenoble'],
|
|
['tout_1_fromage', 'Tout un fromage','Grenoble'],
|
|
['vie_integrative', 'vie intégrative','Voiron'],
|
|
['denis_ketels', 'Denis Ketels','Voiron'], #used only for changePassword test
|
|
['nico_faus_prod', 'Nico Faus Production','Grenoble'],
|
|
['hirundo_archi', 'Hirundo Architecture','Villard-de-Lans'],
|
|
['maison_bambous', 'Maison aux Bambous','Vinay'],
|
|
['recycleco', 'Recycleco','Saint-Marcellin'],
|
|
['elotine_photo', 'Elotine Photo','Grenoble'],
|
|
['boule_antan', 'La Boule d Antan','Villard-de-Lans'],
|
|
['la_remise', 'La Remise','Grenoble'],
|
|
['episol', 'Episol','Grenoble'],
|
|
['alter_mag', 'Alter Mag','Saint-Marcellin'],
|
|
['verre_a_soi', 'Le Verre à soi','Bilieu'],
|
|
['FluoDelik', 'Fluodélik','Méaudre'],
|
|
['1001_saveurs', '1001 Saveurs','Villard-de-Lans'],
|
|
['belle_verte', 'La Belle Verte','Susville'],
|
|
['kheops_boutique', 'Khéops boutique','Saint-Marcellin'],
|
|
['ferme_bressot', 'La ferme du Bressot','Beaulieu'],
|
|
['atelier_eltilo', 'Atelier Eltilo','Grenoble'],
|
|
['la_belle_verte', 'Belle Verte Permaculture','Sillans'],
|
|
['mon_vrac', 'Mon Vrac','Voiron'],
|
|
['le_marque_page', 'Le Marque Page','Saint-Marcellin'],
|
|
['boutik_creative', 'La Boutik Creative','Rives'],
|
|
['pain_beauvoir', 'Le Pain de Beauvoir','Beauvoir-en-Royans'],
|
|
['la_mandragore', 'La Mandragore','Grenoble'],
|
|
['jardins_epices', 'Les jardins epicés tout','Herbeys'],
|
|
['lib_colibri', 'Librairie Colibri','Voiron'],
|
|
['Claire_Dode', 'La Vie Claire Dode','Voiron'],
|
|
['fil_chantant', 'Le Fil qui Chante','Voiron'],
|
|
['epicerie_sol', 'Epicerie Solidaire Amandine','Voiron'],
|
|
['NaturaVie', 'Naturavie','Voiron'],
|
|
['montagne_arts', 'Les montagnarts','Valbonnais'],
|
|
['Biocoop', 'Biocoop','Chatte'],
|
|
['Alpes_EcoTour', 'Alpes Ecotourisme','Grenoble'],
|
|
['trankilou', 'Le Trankilou','Grenoble']
|
|
]
|
|
|
|
groupes_locaux = [
|
|
['gl_grenoble', 'Groupe Local Grenoble','Grenoble'],
|
|
['gl_voiron', 'Groupe Local Voiron','Voiron'],
|
|
['gl_tullins', 'Groupe Local Tullins','Tullins'],
|
|
]
|
|
|
|
for member in adherents_utilisateurs:
|
|
create_user(
|
|
group='Adhérents utilisateurs',
|
|
name=member[1],
|
|
login=member[0],
|
|
email = member[0] + '@test.fr',
|
|
password = '@@bbccdd',
|
|
)
|
|
|
|
create_user(
|
|
group='Adhérents utilisateurs',
|
|
name='Max Maz',
|
|
login='mazmax',
|
|
email = 'maxime.mazouth-laurol@cairn-monnaie.com',
|
|
password = '@@bbccdd',
|
|
)
|
|
|
|
for member in adherents_prestataires:
|
|
create_user(
|
|
group='Adhérents prestataires',
|
|
name=member[1],
|
|
login=member[0],
|
|
email = member[0] + '@test.fr',
|
|
city = member[2],
|
|
password = '@@bbccdd',
|
|
)
|
|
|
|
for member in groupes_locaux:
|
|
create_user(
|
|
group='Network administrators',
|
|
name=member[1],
|
|
login=member[0],
|
|
email = member[0] + '@test.fr',
|
|
city = member[2],
|
|
password = '@@bbccdd',
|
|
)
|
|
|
|
porteurs = {
|
|
'P001': 'Porteur 1',
|
|
'P002': 'Porteur 2',
|
|
'P003': 'Porteur 3',
|
|
'P004': 'Porteur 4',
|
|
}
|
|
for login, name in porteurs.items():
|
|
create_user(
|
|
group='Porteurs',
|
|
name=name,
|
|
login=login,
|
|
)
|
|
|
|
# Récupération des constantes
|
|
|
|
logger.info('Récupération des constantes depuis le YAML...')
|
|
CYCLOS_CONSTANTS = None
|
|
with open("/cyclos/cyclos_constants_"+ENV+".yml", 'r') as cyclos_stream:
|
|
try:
|
|
CYCLOS_CONSTANTS = yaml.load(cyclos_stream)
|
|
except yaml.YAMLError as exc:
|
|
assert False, exc
|
|
|
|
# Impression billets mlc
|
|
logger.info('Impression billets '+ LOCAL_CURRENCY_INTERNAL_NAME +'...')
|
|
logger.debug(str(CYCLOS_CONSTANTS['payment_types']['impression_de_billets_mlc']) + "\r\n" +
|
|
str(CYCLOS_CONSTANTS['currencies']['mlc']) + "\r\n" +
|
|
str(CYCLOS_CONSTANTS['account_types']['compte_de_debit_mlc_billet']) + "\r\n" +
|
|
str(CYCLOS_CONSTANTS['account_types']['stock_de_billets']))
|
|
|
|
|
|
r = requests.post(network_web_services + 'payment/perform',
|
|
headers={'Authorization': 'Basic {}'.format(base64.standard_b64encode(b'demo:demo').decode('utf-8'))}, # noqa
|
|
json={
|
|
'type': CYCLOS_CONSTANTS['payment_types']['impression_de_billets_mlc'],
|
|
'amount': 126500,
|
|
'currency': CYCLOS_CONSTANTS['currencies']['mlc'],
|
|
'from': 'SYSTEM',
|
|
'to': 'SYSTEM',
|
|
})
|
|
|
|
logger.info('Impression billets ' + LOCAL_CURRENCY_INTERNAL_NAME + '... Terminé !')
|
|
logger.debug(r.json())
|
|
|
|
#@WARNING : specifique au cairn, à supprimer dans le rendu au mvt Sol
|
|
today = datetime.now()
|
|
|
|
def date_modify(nb_days):
|
|
today = datetime.now()
|
|
date = today + timedelta(days=nb_days)
|
|
return date.strftime("%Y")+ '-' + date.strftime("%m")+'-'+date.strftime("%d")
|
|
|
|
|
|
def credit_numeric_money_safe(amount):
|
|
logger.info('Creation de MLC numeriques ...')
|
|
r = requests.post(network_web_services + 'payment/perform',
|
|
headers={'Authorization': 'Basic {}'.format(base64.standard_b64encode(b'admin_network:@@bbccdd').decode('utf-8'))},
|
|
json={
|
|
'type': CYCLOS_CONSTANTS['payment_types']['creation_mlc_numeriques'],
|
|
'amount': amount,
|
|
'currency': CYCLOS_CONSTANTS['currencies']['mlc'],
|
|
'from': 'SYSTEM',
|
|
'to': 'SYSTEM',
|
|
'description': 'creation initiale de ' + LOCAL_CURRENCY_INTERNAL_NAME ,
|
|
})
|
|
logger.info('Creation de MLC numeriques... Terminé !')
|
|
logger.debug(r.json())
|
|
|
|
def credit_de_compte(member,amount):
|
|
logger.info('Change numérique pour ' + member[1] + ' ...')
|
|
r = requests.post(network_web_services + 'payment/perform',
|
|
headers={'Authorization': 'Basic {}'.format(base64.standard_b64encode(b'admin_network:@@bbccdd').decode('utf-8'))},
|
|
json={
|
|
'type': CYCLOS_CONSTANTS['payment_types']['credit_du_compte'],
|
|
'amount': amount,
|
|
'currency': CYCLOS_CONSTANTS['currencies']['mlc'],
|
|
'from': 'SYSTEM',
|
|
'to': member[0],
|
|
'description': 'dépôt ' + LOCAL_CURRENCY_INTERNAL_NAME ,
|
|
'customValues': [
|
|
{
|
|
'field': str(CYCLOS_CONSTANTS['transaction_custom_fields']['bdc']),
|
|
'linkedEntityValue': id_bdc # ID de l'utilisateur Bureau de change
|
|
},
|
|
]
|
|
})
|
|
logger.info('Change numérique pour ' + member[1] + '... Terminé !')
|
|
logger.debug(r.json())
|
|
|
|
def payment_inter_adherent(debitor, creditor, amount, offset):
|
|
logger.info('Virement de ' + str(amount) + ' ' + LOCAL_CURRENCY_INTERNAL_NAME + ' ' + debitor + ' vers ' + creditor + ' ...')
|
|
|
|
if offset == 0:
|
|
cyclos_method = 'payment/perform'
|
|
else:
|
|
cyclos_method = 'scheduledPayment/perform'
|
|
|
|
r = requests.post(network_web_services + cyclos_method,
|
|
headers={'Authorization': 'Basic {}'.format(base64.standard_b64encode(b'admin_network:@@bbccdd').decode('utf-8'))},
|
|
json={
|
|
'type': CYCLOS_CONSTANTS['payment_types']['virement_inter_adherent'],
|
|
'amount': amount,
|
|
'currency': CYCLOS_CONSTANTS['currencies']['mlc'],
|
|
'description': 'virement ' + LOCAL_CURRENCY_INTERNAL_NAME ,
|
|
'firstInstallmentDate': date_modify(offset),
|
|
'installmentsCount': 1,
|
|
'from': debitor,
|
|
'to': creditor,
|
|
})
|
|
logger.info('Virement de ' + str(amount) + ' ' + LOCAL_CURRENCY_INTERNAL_NAME + ' ' + debitor + ' vers ' + creditor + ' ... Terminé !')
|
|
logger.debug(r.json())
|
|
|
|
#Creation initiale de MLC numeriques
|
|
credit_numeric_money_safe(10000000000)
|
|
|
|
# Changes numériques afin d'avoir des comptes avec des soldes non nuls + des opérations à injecter dans l'appli CEL
|
|
logger.info('Changes numériques en '+ LOCAL_CURRENCY_INTERNAL_NAME +' pour tous les pros à Grenoble...')
|
|
logger.debug(str(CYCLOS_CONSTANTS['payment_types']['credit_du_compte']) + "\r\n" +
|
|
str(CYCLOS_CONSTANTS['account_types']['compte_de_debit_mlc_numerique']) + "\r\n" +
|
|
str(CYCLOS_CONSTANTS['account_types']['compte_d_adherent']))
|
|
|
|
initial_credit = 1000
|
|
|
|
for pro in adherents_prestataires:
|
|
if pro[2] == 'Grenoble':
|
|
credit_de_compte(pro, initial_credit)
|
|
|
|
for person in adherents_utilisateurs:
|
|
credit_de_compte(person, initial_credit)
|
|
|
|
logger.info('Changes numériques en ' + LOCAL_CURRENCY_INTERNAL_NAME + '... Terminé !')
|
|
|
|
logger.info('Virements immédiats de compte à compte en '+ LOCAL_CURRENCY_INTERNAL_NAME +' ...')
|
|
|
|
#trankilou has null account again
|
|
logger.info('"Le Trankilou" réalise un virement vers "la Remise" remettant son solde à 0')
|
|
payment_inter_adherent('trankilou','la_remise',initial_credit,0)
|
|
|
|
# for i in range(0,10):
|
|
# payment_inter_adherent('DrDBrew','apogee_du_vin',10,0)
|
|
|
|
logger.info('Virements immédiats de compte à compte en '+ LOCAL_CURRENCY_INTERNAL_NAME +'... Terminé !')
|
|
|
|
logger.info('Virements programmés en '+ LOCAL_CURRENCY_INTERNAL_NAME +' de La Bonne Pioche vers AlterMag...')
|
|
for i in range(0,5):
|
|
payment_inter_adherent('labonnepioche','alter_mag',10,2)
|
|
|
|
logger.info('Virements programmés en '+ LOCAL_CURRENCY_INTERNAL_NAME +' ... Terminé !!')
|
|
|
|
logger.info('Fin du script !')
|