Compare commits
10 Commits
7c5928ccb6
...
5c1db6f948
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c1db6f948 | ||
|
|
93f9a0dd18 | ||
|
|
60bc3e6e99 | ||
|
|
2a12b62d40 | ||
|
|
815534749a | ||
|
|
ccdf80a007 | ||
|
|
18563c439a | ||
|
|
7317407c66 | ||
|
|
da9613d6b2 | ||
|
|
849061ffb4 |
32
migrations/Version20251018142349.php
Normal file
32
migrations/Version20251018142349.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251018142349 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE contacts ALTER gateway_response TYPE VARCHAR(65535)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE contacts ALTER gateway_response TYPE VARCHAR(255)');
|
||||
}
|
||||
}
|
||||
32
migrations/Version20251022085244.php
Normal file
32
migrations/Version20251022085244.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251022085244 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE contacts ADD msg_content_type INT DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE contacts DROP msg_content_type');
|
||||
}
|
||||
}
|
||||
34
migrations/Version20251022090715.php
Normal file
34
migrations/Version20251022090715.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251022090715 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE contacts ALTER msg_content_type SET DEFAULT 1');
|
||||
$this->addSql('ALTER TABLE contacts ALTER msg_content_type SET NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE contacts ALTER msg_content_type DROP DEFAULT');
|
||||
$this->addSql('ALTER TABLE contacts ALTER msg_content_type DROP NOT NULL');
|
||||
}
|
||||
}
|
||||
32
migrations/Version20251022160213.php
Normal file
32
migrations/Version20251022160213.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251022160213 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE contacts ADD study_id_short VARCHAR(50) DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE contacts DROP study_id_short');
|
||||
}
|
||||
}
|
||||
|
|
@ -87,11 +87,31 @@ final class CleanMobileCommand extends Command
|
|||
// 3️⃣ German mobile prefixes (the part *after* the leading 0)
|
||||
// -------------------------------------------------------------
|
||||
$germanMobilePrefixes = [
|
||||
'151','152','155','157','159',
|
||||
'160','162','163','164','165','166','167','168','169',
|
||||
'170','171','172','173','174','175','176','177','178','179',
|
||||
'15',
|
||||
'16',
|
||||
'17',
|
||||
];
|
||||
|
||||
$sanitiseUtf8 = static function(?string $raw): ?string {
|
||||
$utf8 = null;
|
||||
if (mb_check_encoding($raw, 'UTF-8')) {
|
||||
$utf8 = $raw;
|
||||
} else {
|
||||
$encodings = ['Windows-1252', 'ISO-8859-1', 'CP1252', 'ASCII'];
|
||||
foreach ($encodings as $src) {
|
||||
$utf8 = @iconv($src, 'UTF-8//TRANSLIT//IGNORE', $raw);
|
||||
if ($utf8 !== false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($utf8 === false) {
|
||||
// Could not be converted – treat it as “invalid”.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $utf8;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// 4️⃣ Helper closures
|
||||
// -------------------------------------------------------------
|
||||
|
|
@ -138,16 +158,18 @@ final class CleanMobileCommand extends Command
|
|||
}
|
||||
|
||||
// Extract the 3‑digit network prefix and the subscriber part
|
||||
$prefix = substr($e164, 4, 3); // after 0049
|
||||
$subscriber = substr($e164, 7);
|
||||
$prefix = substr($e164, 4, 2); // after 0049
|
||||
$subscriber = substr($e164, 6);
|
||||
|
||||
// Prefix must be one of the known mobile prefixes
|
||||
if (!in_array($prefix, $germanMobilePrefixes, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subscriber must be 6‑10 digits long and consist only of digits
|
||||
return preg_match('/^\d{6,10}$/', $subscriber) === 1;
|
||||
// Subscriber must be 6‑11 digits long and consist only of digits
|
||||
// (technically 6-10, but for simplification we consider first two as prefix,
|
||||
// and the last digit of the prefix belongs to the subscriber)
|
||||
return preg_match('/^\d{6,11}$/', $subscriber) === 1;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
|
@ -192,25 +214,33 @@ final class CleanMobileCommand extends Command
|
|||
if ($row['HANDY_E164']) {
|
||||
$uuid = Uuid::v4();
|
||||
$study_id = "QMBEFR-" . $uuid->toString();
|
||||
$study_id_chain = "QMBEFR-SPENDE-" . $uuid->toString();
|
||||
|
||||
// Create a Contact entity for DB insertion
|
||||
$contact = new Contacts();
|
||||
$contact->setPhoneNumber($row['HANDY_E164']);
|
||||
$dueDate = (new \DateTime('tomorrow'))->setTime(16, 0, 0);
|
||||
$dueDate = (new \DateTime('today'))->setTime(12, 0, 0);
|
||||
$contact->setDueDate($dueDate);
|
||||
$contact->setContacted(false);
|
||||
$contact->setParsedFilename($inputPath);
|
||||
$contact->setParsedAt(new \DateTimeImmutable());
|
||||
$contact->setStudyId($study_id);
|
||||
$contact->setParsedFileLinenum($rowCount + 1);
|
||||
$contact->setParsedFileLine(implode(';', $row));
|
||||
$contact->setParsedFileLine($sanitiseUtf8(implode(';', $row)));
|
||||
$contact->setMsgContentType($rowCount % 2 ? 1 : 2);
|
||||
|
||||
try {
|
||||
$this->http->request('POST', $this->backendApiURL . "/" . $study_id, [
|
||||
$result = $this->http->request('POST', $this->backendApiURL . "/" . $study_id . "/" . $study_id_chain, [
|
||||
'body' => '',
|
||||
'headers' => [],
|
||||
]);
|
||||
|
||||
if ($result->getStatusCode() == 200) {
|
||||
$response = json_decode($result->getContent());
|
||||
$shortCode = $response->{'subject_id_short'};
|
||||
$contact->setStudyIdShort($shortCode);
|
||||
}
|
||||
|
||||
$validContacts[] = $contact;
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$backendErrorCount++;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class ContactUncontactedCommand extends Command
|
|||
|
||||
// 1. Get uncontacted rows with a date in the past
|
||||
$now = new DateTime();
|
||||
/** @var Contacts[] $phoneNumbersToContact */
|
||||
$phoneNumbersToContact = $this->entityManager->getRepository(Contacts::class)->createQueryBuilder('p')
|
||||
->where('p.contacted = :state_contacted')
|
||||
->andWhere('p.due_date < :now')
|
||||
|
|
@ -82,6 +83,17 @@ class ContactUncontactedCommand extends Command
|
|||
// 3. Contact the HTTP REST API
|
||||
try {
|
||||
$study_id = $phoneContact->getStudyId();
|
||||
$msgContentType = $phoneContact->getMsgContentType();
|
||||
$message_1 = "Liebe Patientin, lieber Patient, \ngerne möchten wir von Ihnen erfahren, wie zufrieden Sie mit uns sind. Wir freuen uns, wenn Sie sich die Zeit nehmen und uns Ihre Eindrücke mitteilen.\nIhre Anregungen gehen direkt zum Qualitäts- und Risikomanagement.\n\nhttps://umfragetool.ukbonn.de/login?id={$study_id} \n\nIhr UKB.\n\nSMS vom UKB abbestellen per E-Mail an: datenschutz@ukbonn.de";
|
||||
$message_2 = "Liebe/r Patient, bitte teilen Sie kurz Ihre Zufriedenheit mit dem UKB mit: https://k.ukbonn.de/{$phoneContact->getStudyIdShort()} Vielen Dank! Abmeldung per datenschutz@ukbonn.de";
|
||||
$message = $message_1;
|
||||
switch ($msgContentType) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
$message = $message_2;
|
||||
break;
|
||||
}
|
||||
$response = $this->httpClient->request('POST', self::$apiEndpoint, [
|
||||
'headers' => [
|
||||
'X-CM-PRODUCTTOKEN' => $this->sms_gateway_api_key,
|
||||
|
|
@ -98,7 +110,7 @@ class ContactUncontactedCommand extends Command
|
|||
],
|
||||
'body': {
|
||||
'type': 'auto',
|
||||
'content': 'Liebe Patientin, lieber Patient, \ngerne möchten wir von Ihnen erfahren, wie zufrieden Sie mit uns sind. Wir freuen uns, wenn Sie sich die Zeit nehmen und uns Ihre Eindrücke mitteilen.\nIhre Anregungen landen über den direkten Weg beim Qualitäts- und Risikomanagement.\n\nhttps://umfragetool.ukbonn.de/login?id={$study_id} \n\nIhr UKB.\n\nSMS vom UKB abbestellen per E-Mail an: datenschutz@ukbonn.de'
|
||||
'content': '$message'
|
||||
},
|
||||
'minimumNumberOfMessageParts': 1,
|
||||
'maximumNumberOfMessageParts': 8,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Contacts
|
|||
#[ORM\Column]
|
||||
private ?bool $contacted = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[ORM\Column(length: 65535, nullable: true)]
|
||||
private ?string $gateway_response = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
|
|
@ -43,6 +43,12 @@ class Contacts
|
|||
#[ORM\Column(length: 50, nullable: true)]
|
||||
private ?string $study_id = null;
|
||||
|
||||
#[ORM\Column(length: 50, nullable: true)]
|
||||
private ?string $study_id_short = null;
|
||||
|
||||
#[ORM\Column(nullable: false, options: ['default' => 1])]
|
||||
private ?int $msg_content_type = 1;
|
||||
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
|
|
@ -158,4 +164,24 @@ class Contacts
|
|||
{
|
||||
$this->parsed_file_line = $parsed_file_line;
|
||||
}
|
||||
|
||||
public function getMsgContentType(): ?int
|
||||
{
|
||||
return $this->msg_content_type;
|
||||
}
|
||||
|
||||
public function setMsgContentType(?int $msg_content_type): void
|
||||
{
|
||||
$this->msg_content_type = $msg_content_type;
|
||||
}
|
||||
|
||||
public function getStudyIdShort(): ?string
|
||||
{
|
||||
return $this->study_id_short;
|
||||
}
|
||||
|
||||
public function setStudyIdShort(?string $study_id_short): void
|
||||
{
|
||||
$this->study_id_short = $study_id_short;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user