Commit 0654f9ed authored by Bastien Le Querrec's avatar Bastien Le Querrec

Merge branch 'preprod'

parents 632c578f 5619a40c
......@@ -12,6 +12,7 @@ app/env
.php_cs.cache
.DS_Store
__MAC
.vscode/
tests/_data
tests/_output
......
before_script:
- '[[ -d /srv/soutien/ ]] || mkdir -p /srv/soutien/'
- 'which git || (apt-get update -yq && apt-get install git -yqq)'
stages:
- test
- cleanup_test
- deploy
job test:
stage: test
variables:
GIT_SUBMODULE_STRATEGY: normal
SQL_HOST: "localhost"
SQL_PORT: "3306"
SQL_DATABASE: "test_$CI_BUILD_REF"
SQL_USER: "soutien"
SQL_PASSWORD: "soutien"
PHINX_PASSWORD: "$SQL_PASSWORD"
PHINX_USER: "$SQL_USER"
PHINX_DATABASE: "test_$CI_BUILD_REF"
PHINX_HOST: "$SQL_HOST"
PHINX_PORT: "$SQL_PORT"
SYSADMIN: "gitlab@email.com"
FDNNURL1: "https://secure.fd2n.org/fd2n/cb"
FDNNURL2: "https://secure.fdn2.org/fdn2/don"
BASE_DOMAIN: "dev.laquadrature.net"
SITE_ID: "XXXXXXXX"
CERTIFICATE: "XXXXXXXXXXXXXXXXXXXXXXXXx"
CTX_MODE: "TEST"
PIPLOME_PATH: "/var/www/site/pdf/"
PIPLOME_URL: "https://www.laquadrature.net/pdf/"
CAMPAIGN_START_DATE: "2016-11-10"
CAMPAIGN_BUDGET: "321000"
LOGS: "./"
SMTP_HOST: "smtp.example.com"
SMTP_PORT: "25"
SMTP_SECURITY: "none"
SMTP_USER: "user"
SMTP_PW: "password"
DEBUG: "0"
ENV: "test"
script:
- echo "SQL_PASSWORD=${SQL_PASSWORD}" > app/env
- echo "SQL_USER=${SQL_USER}" >> app/env
- echo "SQL_DATABASE=${SQL_DATABASE}" >> app/env
- make install
- make server-start
- make -k test
- make server-stop
- mysql -u $SQL_USER -p$SQL_PASSWORD -e "DROP DATABASE $SQL_DATABASE"
tags:
- preprod
cleanup test:
stage: cleanup_test
variables:
SQL_DATABASE: "test_$CI_BUILD_REF"
SQL_USER: "soutien"
SQL_PASSWORD: "soutien"
script:
- make server-stop
- mysql -u $SQL_USER -p$SQL_PASSWORD -e "DROP DATABASE $SQL_DATABASE"
when: on_failure
tags:
- preprod
job install:
stage: deploy
environment: preprod
variables:
PHINX_ENVIRONMENT: "development"
PROD_HOME: "/home/don/don/"
script:
- chmod a+x ci/install.sh
- ./ci/install.sh
stage: deploy
tags:
- preprod
only:
- preprod
job deploy:
stage: deploy
environment: production
variables:
PHINX_ENVIRONMENT: "production"
PROD_HOME: "/home/don/don/"
script:
- chmod a+x ci/install.sh
- ./ci/install.sh
stage: deploy
tags:
- prod
only:
- master
......@@ -44,7 +44,7 @@ and for developers you may also need :
This software uses:
* **PHP7.3** currently
* **PHP7.3**
* **phinx** to inject database schema and initial data / accounts into MySQL see https://phinx.org/
* **php-cs-fixer** to check php code for errors and fix coding standard issues, see https://github.com/FriendsOfPHP/PHP-CS-Fixer
* **doctrine/dbal** as ORM see https://github.com/doctrine/dbal
......@@ -63,7 +63,8 @@ Nginx configuration sample:
```
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php5.sock;
fastcgi_read_timeout 1d; #avoid timeout when importing bank data
fastcgi_pass unix:/run/php7.3.sock;
}
location / {
# try to serve file directly, fallback to index.php
......
......@@ -14,6 +14,7 @@ use LQDN\Command\UserCreateCommand;
use LQDN\Command\UserUpdateCumulCommand;
use LQDN\Command\AdminUpdateParentCommand;
use LQDN\Command\AdminUpdateTotalUsersCommand;
use LQDN\Exception\InvalidEmailException;
class Admin extends Controller
{
......@@ -34,6 +35,7 @@ class Admin extends Controller
100 => "Récurrent non validé",
101 => "Récurrent validé",
102 => "Récurrent remis",
//! 103 => "Refusé"
));
$f3->set('CT_STATUTS', array(
......@@ -1163,12 +1165,12 @@ class Admin extends Controller
break;
case 'update':
if ($f3->get('POST.test')=='1') {
$datas = $this->banque_update($f3, $_FILES['file']['tmp_name']);
$result = $datas['update'] . " dons récurrents mis à jour sur un total de ". $datas['total']." dons récurrents.";
$datas = $this->banque_update($f3, $_FILES['file']);
$result = $datas['update'] . " dons récurrents mis à jour sur un total de ". $datas['total']." dons récurrents (fichier : \"" . htmlentities($_FILES['file']['name']) . "\").";
$message = "Il s'agit d'un <b>test</b><br />";
} else {
$datas = $this->banque_update($f3, $_FILES['file']['tmp_name'], false);
$result = $datas['update'] . " dons récurrents mis à jour sur un total de ". $datas['total']." dons récurrents.";
$datas = $this->banque_update($f3, $_FILES['file'], false);
$result = $datas['update'] . " dons récurrents mis à jour sur un total de ". $datas['total']." dons récurrents (fichier : \"" . htmlentities($_FILES['file']['name']) . "\").";
}
if (count($datas['comptabilise'])>0 or count($datas['sans_cumul'])>0) {
$error = count($datas['comptabilise']) . " dons récurrents déjà comptabilisés et ". count($datas['sans_cumul'])." dons récurrents sans cumul.";
......@@ -1374,8 +1376,12 @@ class Admin extends Controller
return $datas;
}
public function banque_update($f3, $filename, $testing=true)
public function banque_update($f3, $file, $testing=true)
{
$log = new \Log('/banque_update.log');
$log->write('Processing recurrent donations on file "' . $file['name'] . '" (testing: ' . ($testing ? 'true' : 'false') . ')');
$filename = $file['tmp_name'];
$separator = ";";
$datas = array();
$update = 0;
......@@ -1412,7 +1418,7 @@ class Admin extends Controller
}
// On lit maintenant tout, ligne par ligne, afin de vérifier les informations bancaires pour chaque don.
while (($data = fgetcsv($handle, 1000, $separator)) !== false) {
while (($data = fgetcsv($handle, 10000, $separator)) !== false) {
if (count($data) <= 0) {
continue;
}
......@@ -1425,6 +1431,7 @@ class Admin extends Controller
if ($identifier && $transaction && $effect && $amount && $statut == false) {
continue;
}
//! "Refusé" status seems not be present in csv, is this really used?
if ($statut == 'Refusé' and !$testing) {
$db->query("UPDATE dons SET status = 103 WHERE id='".$transaction."'");
continue;
......@@ -1435,6 +1442,8 @@ class Admin extends Controller
$total ++;
$email = '';
$time_struct = strptime($effect, "%d/%m/%Y %H:%M:%S");
//! XXX WHY? month + 1 can make sense, but hour (always 00) + 1 or year (2020) + 1900 does not
//! what is the rationale, is this the next due date?
$new_effect = strftime("%Y-%m-%d %H:%M:%S", mktime(
$time_struct['tm_hour']+1,
$time_struct['tm_min'],
......@@ -1465,7 +1474,8 @@ class Admin extends Controller
if ($user and !$testing) {
$db->query("INSERT INTO identifiers(user_id, identifier) VALUES ('".$user['id']."', '".$identifier."')");
$email = $user['email'];
} else {
} elseif (!$testing) {
$log->write('Cannot find user for transaction id ' . $identifier . ', creating it...');
// No user, let's try to create the user
$email = '';
$pseudo = '';
......@@ -1476,16 +1486,22 @@ class Admin extends Controller
$email = $user_field . "@example.org";
$pseudo = $user_field;
}
//! hash seems to identify one email at one time
$hash = hash('sha256', date("%Y-%m-%d %H:%i:%d").$email);
if (!$testing) {
$log->write('Insert user: email "'.$email.'" pseudo "'.$pseudo.'" identifier "'.$identifier.'"');
try {
$f3->get('container')['command_handler']->handle(new UserCreateCommand($email, $hash, $pseudo, 0, 0));
};
} catch (InvalidEmailException $e) { // \Exception
$log->write("exception: ".$e);
throw $e;
}
}
} else {
$email = $result->fetch(\PDO::FETCH_ASSOC);
$email = $email['email'];
// On stocke l'email pour comptabiliser les dons
}
//! Counting email duplicates
if (array_key_exists($email, $emails)) {
$emails[$email] ++;
} else {
......@@ -1494,6 +1510,7 @@ class Admin extends Controller
// On a besoin de l'utilisateur
$user = $f3->get('container')['user_finder']->findByEmail($email);
// Récupération de l'id du bon abonnement
//! look for a validated donation, see if the recurrent donation is already scheduled
$stmt = $db->query("SELECT d.id AS id
FROM dons d
JOIN users u ON u.id = d.user_id
......@@ -1503,10 +1520,13 @@ class Admin extends Controller
$result = $stmt->fetch(\PDO::FETCH_ASSOC);
if (!$result) {
if ($testing) {
//! XXX WTF random transaction id!
$cumul = rand(50000, 70000);
} else {
// don non trouvé en statut 101. On le crée (la banque à raison)
// statut = cumul
//! FIXME bad naming cumul for transactions
//! It means that don.cumul is the id of parent transaction with 101 status
$f3->get('container')['command_handler']
->handle(new DonationCreateCommand(
$user['id'],
......@@ -1532,10 +1552,12 @@ class Admin extends Controller
AND d.datec='".$new_effect."'
AND d.cumul=".$cumul."
");
//! Does not sound like a good idea to match on a creation date...
if ($result) {
$combien = $result->fetch();
if ($combien[0]==0) {
$update ++;
$log->write('Insert don: user_id "'.$user['id'].'" identifier "'.$identifier.'" new effect "'.$new_effect.'" parent "'.$cumul.'"');
// Don récurrent non comptabilisé, on l'ajoute
if (!$testing) {
$query = "INSERT INTO dons (status,
......@@ -1551,8 +1573,6 @@ class Admin extends Controller
'".$user['id']."',
'".$cumul."',
'".$identifier."')";
}
if (!$testing) {
$db->query($query);
// On met alors à jour le cumul et le total de l'utilisateur concerné
$result = $db->query("UPDATE users
......@@ -1568,10 +1588,11 @@ class Admin extends Controller
}
fclose($handle);
}
$datas['update'] = $update;
$datas['total'] = $total;
$datas['comptabilise'] = $comptabilise;
$datas['sans_cumul'] = $sans_cumul;
$datas['total'] = $total; //! all recurrent transactions (validées + remisées)
$datas['update'] = $update; //! recurrent transactions remisées just added
$datas['comptabilise'] = $comptabilise; //! recurrent transactions remisées already added
$datas['sans_cumul'] = $sans_cumul; //! empty
$log->write('Processing recurrent donations finished on file "' . $file['name'] . '"');
return $datas;
}
......
......@@ -155,6 +155,7 @@ class Bank extends Controller
$user = $f3->get('container')['user_finder']->findById($don['user_id']);
$cb_log->write("Utilisation d'un utilisateur existant");
//! FIXME What if user not found? Must check it
// Ajout du nouveau don au cumul actuel
if ($status!=101) {
$cb_log->write("Ajout de ".$don['somme']);
......
......@@ -162,7 +162,7 @@ class Campaign extends Controller
"vads_action_mode" => "INTERACTIVE",
"vads_ctx_mode" => CTX_MODE,
// Autres codes possibles (page 16)
"vads_trans_id" => str_repeat("0", 6-strlen($id)).$id,
"vads_trans_id" => str_repeat("0", 6-strlen($id)).$id, // fill left zeros to have length 6
"vads_version" => "V2",
// Champs facultatifs
"vads_language" => $f3->get('lang'),
......
......@@ -58,8 +58,14 @@ class Controller
putenv("LANGUAGE=".$lang);
if (!setlocale(LC_ALL, $lang)) {
// try the UTF8 version
putenv("LC_MESSAGES=".$lang.".utf8");
putenv("LANG=".$lang.".utf8");
putenv("LANGUAGE=".$lang.".utf8");
if (!setlocale(LC_ALL, $lang.".utf8")) {
echo "<!-- setlocale $lang failed -->";
}
}
if (!textdomain("messages")) {
echo "<!-- textdomain failed -->";
......
......@@ -2,8 +2,8 @@
<h2>Gestion banque</h2>
<check if="{{@result}}"><p class="result">{{@result | raw}}</p></check>
<check if="{{@SESSION.error}}"><message messages="{{@SESSION.error}}" class="alert alert-danger"/></check>
<check if="{{@SESSION.message}}"><message messages="{{@SESSION.message}}" class="alert alert-danger" /></p></check>
<check if="{{@SESSION.error}}"><message messages="{{@SESSION.error| raw }}" class="alert alert-danger"/></check>
<check if="{{@SESSION.message}}"><message messages="{{@SESSION.message| raw }}" class="alert alert-danger" /></p></check>
<section id="cbs">
<h3 >Mise à jour des dates d'expiration des CB</h3>
......
......@@ -22,6 +22,8 @@ git submodule update
composer install --no-dev
composer update
rm tmp/*.php
# Let's run the migrations
if [ -e "$HOME/phinx.yml" ]
then
......
......@@ -2,17 +2,17 @@
"name": "lqdn/soutien",
"description": "Site de soutien LQDN",
"require": {
"bcosca/fatfree": "^3.5",
"robmorgan/phinx": "^0.10.0",
"vlucas/phpdotenv": "^2.4",
"bcosca/fatfree": "^3.7.2",
"robmorgan/phinx": "^0.10.8",
"vlucas/phpdotenv": "^v2.6.6",
"pimple/pimple": "^3.0",
"doctrine/dbal": "^2.5",
"symfony/http-foundation": "^3.2",
"sentry/sentry": "^1.9"
"symfony/http-foundation": "^3.4.46",
"sentry/sentry": "^1.11.0"
},
"require-dev": {
"codeception/codeception": "^2.2",
"friendsofphp/php-cs-fixer": "^2.1"
"codeception/codeception": "^2.5.6",
"friendsofphp/php-cs-fixer": "^2.16.5"
},
"autoload": {
"psr-4": {
......@@ -27,7 +27,7 @@
"config": {
"preferred-install": "dist",
"platform": {
"php": "5.6.27"
"php": "7.3.0"
}
}
}
This diff is collapsed.
<?php
use Phinx\Migration\AbstractMigration;
class AddDefaultValues extends AbstractMigration
{
public function up()
{
$this->adapter->execute("ALTER TABLE contreparties ALTER datec SET DEFAULT '0000-00-00 00:00:00';");
$this->adapter->execute("ALTER TABLE contreparties ALTER commentaire SET DEFAULT '';");
$this->adapter->execute("ALTER TABLE dons ALTER datec SET DEFAULT '0000-00-00 00:00:00';");
$this->adapter->execute("ALTER TABLE dons ALTER cadeau SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER abo SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER taille SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER public SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER pdf SET DEFAULT \"\";");
$this->adapter->execute("ALTER TABLE dons ALTER decimale SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER datee SET DEFAULT '0000-00-00 00:00:00';");
$this->adapter->execute("ALTER TABLE dons ALTER pi_x SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER pi_y SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE dons ALTER hash SET DEFAULT \"\";");
$this->adapter->execute("ALTER TABLE dons ALTER taille_h SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE users ALTER total SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE users ALTER cumul SET DEFAULT '0';");
$this->adapter->execute("ALTER TABLE users ALTER pseudo SET DEFAULT \"\";");
$this->adapter->execute("ALTER TABLE users ALTER commentaire SET DEFAULT \"\";");
}
}
<?php
use Phinx\Migration\AbstractMigration;
class IncreaseIdentifierLength extends AbstractMigration
{
public function up()
{
$this->adapter->execute("ALTER TABLE dons modify COLUMN identifier VARCHAR(255) NULL;");
}
}
......@@ -2,6 +2,6 @@
namespace LQDN\Exception;
class AddressAlreadyExistsException extends \RuntimeException
class AddressAlreadyExistsException extends \LogicException
{
}
......@@ -2,6 +2,6 @@
namespace LQDN\Exception;
class AddressUsedException extends \RuntimeException
class AddressUsedException extends \LogicException
{
}
......@@ -2,6 +2,6 @@
namespace LQDN\Exception;
class InvalidEmailException extends \RuntimeException
class InvalidEmailException extends \LogicException
{
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment