Thanasoft-H2F/gestion/lib/Service/GestionService.php

489 lines
21 KiB
PHP

<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Gestion\Service;
use GuzzleHttp\Exception\GuzzleException;
use OCP\DB\Exception;
use OCP\IUserSession;
use OCP\Mail\IMailer;
use OCA\Gestion\Db\Bdd;
use OC\Files\Filesystem;
use OCP\Files\IRootFolder;
use OCA\Gestion\Db\OrderBdd;
use Psr\Log\LoggerInterface;
use OCA\Gestion\Constants\BddConstant;
use OCA\Gestion\Helpers\FolderHelpers;
use OCA\Gestion\Helpers\VCalendarHelpers;
use OCA\Gestion\Constants\OrderStatusConstant;
use OCA\Gestion\Constants\ThanatoTypeConstant;
use OCA\Gestion\Service\Order\OrderPdfService;
use OCA\Gestion\Constants\DevisMentionConstant;
use OCA\Gestion\Service\Devis\Pdf\DevisPdfService;
use OCP\IConfig;
use Ramsey\Uuid\Uuid;
class GestionService {
/** @var Bdd */
private $gestionBdd;
/** @var LoggerInterface */
private $logger;
/** @var \OCA\Gestion\Db\OrderBdd */
private $orderBdd;
private TalkService $talkService;
private $orderPdfService;
private $devisPdfService;
private $userSession;
private string $userConnectedUuid;
private $userConnectedStorage;
private $mailer;
protected $config;
public function __construct(
Bdd $gestionBdd,
OrderBdd $orderBdd,
LoggerInterface $logger,
OrderPdfService $orderPdfService,
DevisPdfService $devisPdfService,
TalkService $talkService,
IUserSession $userSession,
IRootFolder $rootFolder,
IMailer $mailer,
IConfig $config,
) {
$this->orderBdd = $orderBdd;
$this->logger = $logger;
$this->gestionBdd = $gestionBdd;
$this->orderPdfService = $orderPdfService;
$this->devisPdfService = $devisPdfService;
$this->talkService = $talkService;
$this->userSession = $userSession;
$this->userConnectedUuid = $userSession->getUser()?->getUID() ?? BddConstant::DEFAULT_ADMIN_APP_ID_NEXTCLOUD;
$this->userConnectedStorage = $rootFolder->getUserFolder($this->userConnectedUuid);
$this->mailer = $mailer;
$this->config = $config;
}
private function GetCalendarSummaryFromVCalendarString(string $vCalendarString): string
{
$summaryValue = "Nom du défunt";
$value = VCalendarHelpers::GetValueFromKeyInVCalendarString("SUMMARY", $vCalendarString);
if($value !== ""){
$summaryValue = trim($value);
}
return $summaryValue;
}
private function GetThanatoFromVCalendarString(string $vCalendarString){
$thanato = null;
$thanatoNames = $this->GetAttendeesNameFromVCalendarString($vCalendarString);
if(count($thanatoNames) > 0){
$thanatoName = $thanatoNames[0];
$thanatoFromDb = $this->gestionBdd->getThanatoByUserUuid($thanatoName);
if($thanatoFromDb != null){
$thanato = $thanatoFromDb;
}
}
else{
//get from calendar object
$organizerName = $this->getPrincipalUsernameFromVCalendarString($vCalendarString);
if($organizerName != null){
$thanatoFromDb = $this->gestionBdd->getThanatoByUserUuid($organizerName);
if($thanatoFromDb != null){
$thanato = $thanatoFromDb;
}
}
}
return $thanato;
}
private function GetThanatoIdFromVCalendarString(string $vCalendarString)
{
$thanatoId = 0;
$thanatoNames = $this->GetAttendeesNameFromVCalendarString($vCalendarString);
if(count($thanatoNames) > 0){
$thanatoName = $thanatoNames[0];
$thanatoIdFromDb = $this->gestionBdd->getThanatoIdByUserUuid($thanatoName);
if($thanatoIdFromDb != null){
$thanatoId = $thanatoIdFromDb;
}
}
else{
//get from calendar object
$organizerName = $this->getPrincipalUsernameFromVCalendarString($vCalendarString);
if($organizerName != null){
$thanatoIdFromDb = $this->gestionBdd->getThanatoIdByUserUuid($organizerName);
if($thanatoIdFromDb != null){
$thanatoId = $thanatoIdFromDb;
}
}
}
return $thanatoId;
}
private function getPrincipalUsernameFromVCalendarString(string $vCalendarString){
$calendarUuid = VCalendarHelpers::GetValueFromKeyInVCalendarString("UID", $vCalendarString);
$principalUsername = $this->gestionBdd->getCalendarOrganizerNameByCalendarObjectUuid($calendarUuid);
return $principalUsername;
}
private function GetAttendeesNameFromVCalendarString(string $vCalendarString): array
{
$names = [];
preg_match_all('/CN=([^;]+)/', $vCalendarString, $matches);
if (isset($matches[1])) {
$names = $matches[1];
}
return $names;
}
private function IsDevisAlreadyCreated($clientId,$locationId,$thanatoId,$defuntName,$calendarUuid="not-related"){
$defuntId = $this->gestionBdd->getLastDefuntIdByName($defuntName);
$devisId = $this->gestionBdd->getLastDevisIdFromVCalendarProperty($thanatoId,$clientId,$locationId,$defuntId,$calendarUuid);
return $devisId != null;
}
private function GetCalendarUuidFromVCalendarString(string $vCalendarString): string
{
$calendarUuid = VCalendarHelpers::GetValueFromKeyInVCalendarString("UID", $vCalendarString);
if($calendarUuid == ""){
$calendarUuid = $this->gestionBdd::DEFAULT_CALENDAR_UUID_FOR_DEVIS;
}
return $calendarUuid;
}
private function GetCalendarDateFromVCalendarString(string $vCalendarString){
$calendarStartDate = VCalendarHelpers::GetDateStartOrDateEndFromVCalendarString('DTSTART',$vCalendarString);
return $calendarStartDate;
}
public function HandleCreatedCalendarObject(string $vCalendarString ,$cookie){
try{
$thanato = $this->GetThanatoFromVCalendarString($vCalendarString);
if($thanato != null){
$thanatoId = $thanato["id"];
}
else{
$thanatoId = 0;
}
$calendarSummary = $this->GetCalendarSummaryFromVCalendarString($vCalendarString);
$clientId = $this->GetClientIdFromVCalendarString($vCalendarString);
$locationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
$devisAlreadyCreated = $this->IsDevisAlreadyCreated($clientId,$locationId,$thanatoId,$calendarSummary,$calendarUuid);
if($devisAlreadyCreated){
return;
}
$defuntId = $this->gestionBdd->insertDefuntByNameAndReturnId($calendarSummary);
$calendarStartDate = $this->GetCalendarDateFromVCalendarString($vCalendarString);
$devisDate = $calendarStartDate->format('Y-m-d');
$devisId = $this->gestionBdd->insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$calendarUuid,$devisDate,$userName);
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
if(!empty($articlesValue)){
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
$this->gestionBdd->insertDevisArticleFromDevisIdAndArticlesIdArray($devisId, $articleIds);
}
$thanatoIsSubcontractor = $thanato["fk_thanato_type_key"] === ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR;
if($thanatoIsSubcontractor){
$orderCreated = $this->orderBdd->createOrderFromDevisIdAndDate($devisId,$calendarStartDate,$userName);
if($orderCreated){
$order = $this->orderBdd->getOrderByDevisId($devisId);
$this->logger->debug(json_encode($order));
if($order != null){
$this->orderPdfService->generateOrderPdfByOrderId($order['id'],$this->userConnectedUuid);
}
}
}
$devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devisId,$userName);
$this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid);
$this->devisPdfService->generateDevisPdfByDevisId($devisId,$this->userConnectedUuid);
//Move calendar attachment file to defunt folder
if (VCalendarHelpers::hasAttachment($vCalendarString)) {
$devis = $this->gestionBdd->getDevisByDevisId($devisId);
if($devis != null && $devis["client_entreprise"] != null){
$destinationFolderAttachment = FolderHelpers::GetDefuntFolder($devis["client_entreprise"],$devis["defunt_nom"]);
$attachments = VCalendarHelpers::extractAttachments($vCalendarString);
$this->moveCalendarAttachmentFile($attachments,$destinationFolderAttachment);
if ($thanatoIsSubcontractor) {
$thanatoHasEmail = $thanato["thanato_email"] != null;
if($thanatoHasEmail){
$this->sendEmailAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$attachments);
}
}else {
$roomToken = $this->talkService->getRoomTokenBeetwenTwoUser($this->userConnectedUuid, $userName);
foreach ( $attachments as $attachment) {
$this->userConnectedStorage->getFullPath("/");
$path = Filesystem::getPath($attachment['file_id']);
$destination = 'Talk/';
Filesystem::copy($path, $destination . $attachment['name']);
$this->sendFileAttachmentToTalk($roomToken,$cookie , $attachment['name']);
}
}
}
}
$this->gestionBdd->createDevisTrajetFromVCalendar($devisId,$userName);
}
catch(Exception $e){
$this->logger->debug("error creating devis");
}
}
public function moveCalendarAttachmentFile(array $attachments ,string $destinationFolder ){
$this->userConnectedStorage->getFullPath("/");
foreach ($attachments as $attachment) {
$path = Filesystem::getPath($attachment['file_id']);
Filesystem::copy($path, $destinationFolder . $attachment['name']);
}
}
private function GetThanatoNameFromVCalendarString($vCalendarString){
$thanatoName = null;
$thanatoNames = $this->GetAttendeesNameFromVCalendarString($vCalendarString);
if(count($thanatoNames) > 0){
$thanatoName = $thanatoNames[0];
}
else{
//get from calendar object
$thanatoName = $this->getPrincipalUsernameFromVCalendarString($vCalendarString);
}
return $thanatoName;
}
private function GetClientIdFromVCalendarString(string $vCalendarString){
$this->logger->debug($vCalendarString);
$clientValue = VCalendarHelpers::GetValueFromKeyInVCalendarString("CLIENT", $vCalendarString);
if($clientValue == null || $clientValue == ""){
$clientValue = 0;
}
return (int)$clientValue;
}
private function GetLocationIdFromVCalendarString(string $vCalendarString){
$locationValue = VCalendarHelpers::GetValueFromKeyInVCalendarString("LOCATION", $vCalendarString);
if($locationValue == null || $locationValue == ""){
$locationValue = 0;
}
return (int)$locationValue;
}
private function GetArticlesNameFromVCalendarString(string $vCalendarString): array {
$devisArticleValue = VCalendarHelpers::GetValueFromKeyInVCalendarString("DESCRIPTION", $vCalendarString);
$articles = explode('\;', $devisArticleValue);
$mapped = array_map('trim', $articles);
return $mapped;
}
public function HandleCalendarObjectMovedToTrash(string $vCalendarString){
$thanato = $this->GetThanatoFromVCalendarString($vCalendarString);
if($thanato == null){
return;
}
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
$thanatoIsSubcontractor = $thanato["fk_thanato_type_key"] === ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR;
if($thanatoIsSubcontractor){
$order = $this->orderBdd->getOrderByCalendarUuid($calendarUuid);
if($order != null){
$this->orderBdd->updateOrderStatus($order['id'],OrderStatusConstant::CANCELED_KEY);
}
}
else{
$devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid);
if($devis != null){
$this->gestionBdd->updateDevisMentionToCanceled($devis['id']);
}
}
return true;
}
private function CheckIfDevisIsAlreadyUpdated($devis,$vCalendarString){
$requestedDefuntName = $this->GetCalendarSummaryFromVCalendarString($vCalendarString);
$requestedClientId = $this->GetClientIdFromVCalendarString($vCalendarString);
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
$requestedArticleReferences = $this->GetArticlesNameFromVCalendarString($vCalendarString);
$requestedArticleIds = $this->gestionBdd->getArticleIdsByArticleReferences($requestedArticleReferences);
$articleDevis = $this->gestionBdd->getProduitDevisByDevisId($devis['id']);
$articleDevisIds = [];
foreach($articleDevis as $currentArticleDevis){
$articleDevisIds[] = $currentArticleDevis['produit_id'];
}
sort($requestedArticleIds);
sort($articleDevisIds);
return
$devis['defunt_nom'] == $requestedDefuntName &&
$devis['client_id'] == $requestedClientId &&
$devis['lieu_id'] == $requestLocationId &&
$requestedArticleIds == $articleDevisIds;
}
private function UpdateDevisDataByVCalendarString($devis,$vCalendarString){
$requestedDefuntName = $this->GetCalendarSummaryFromVCalendarString($vCalendarString);
$defuntId = $this->gestionBdd->createOrUpdateDefuntByNameAndReturnDefuntId($devis['defunt_id'],$devis['defunt_nom'],$requestedDefuntName);
$this->gestionBdd->updateDevisDefunt($devis['id'],$defuntId,$devis['defunt_id']);
$requestedClientId = $this->GetClientIdFromVCalendarString($vCalendarString);
$this->gestionBdd->updateDevisClient($devis['id'],$requestedClientId,$devis['client_id']);
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
$this->gestionBdd->updateDevisLieu($devis['id'],$requestLocationId,$devis['lieu_id']);
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
if(!empty($articlesValue)){
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
$this->gestionBdd->updateDevisArticles($devis['id'],$articleIds);
}
}
public function HandleUpdatedCalendarObject(string $vCalendarString , $cookie){
try{
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
$devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid);
if($devis != null){
$this->gestionBdd->updateDevisMention($devis['id'],DevisMentionConstant::NEW);
$isDevisAlreadyUpdated = $this->CheckIfDevisIsAlreadyUpdated($devis,$vCalendarString);
if($isDevisAlreadyUpdated){
return true;
}
$this->UpdateDevisDataByVCalendarString($devis,$vCalendarString);
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
$devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devis['id'],$userName);
$this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid);
$this->devisPdfService->generateDevisPdfByDevisId($devis['id'],$this->userConnectedUuid);
if (VCalendarHelpers::hasAttachment($vCalendarString)) {
$thanato = $this->gestionBdd->getThanatoByThanatoId($devis['id_thanato']);
$thanatoIsSubcontractor = $thanato["fk_thanato_type_key"] === ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR;
$devis = $this->gestionBdd->getDevisByDevisId($devis['id']);
if($devis != null && $devis["client_entreprise"] != null){
$destinationFolderAttachment = FolderHelpers::GetDefuntFolder($devis["client_entreprise"],$devis["defunt_nom"]);
$attachments = VCalendarHelpers::extractAttachments($vCalendarString);
$this->moveCalendarAttachmentFile($attachments , $destinationFolderAttachment);
if ($thanatoIsSubcontractor ) {
$thanatoHasEmail = $thanato["thanato_email"] != null;
if($thanatoHasEmail){
$this->sendEmailAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$attachments);
}
}else{
$roomToken = $this->talkService->getRoomTokenBeetwenTwoUser($this->userConnectedUuid, $userName);
foreach ( $attachments as $attachment) {
$this->userConnectedStorage->getFullPath("/");
$path = Filesystem::getPath($attachment['file_id']);
$destination = 'Talk/';
Filesystem::copy($path, $destination . $attachment['name']);
//sendFileAttachmentToTalk
$this->sendFileAttachmentToTalk($roomToken,$cookie , $attachment['name']);
}
}
}
}
}
return true;
}
catch(Exception $e){
$this->logger->debug("error creating devis");
}
}
public function sendEmailAttachment($to , $defunt_nom ,$attachments = []){
$this->userConnectedStorage->getFullPath("/");
$subject = "Piece jointe";
$body = "
<p>Bonjour.</p>
<p>Vous trouverez en pièce jointe les documents concernant de « $defunt_nom ».</p>
<p>Vous en souhaitant bonne réception</p>
<p>Cordialement</p>
";
$message = $this->mailer->createMessage();
$message->setSubject($subject);
$message->setTo(recipients: [$to]);
foreach ($attachments as $attachment) {
$path = Filesystem::getPath($attachment['file_id']);
$content = $this->mailer->createAttachment( Filesystem::file_get_contents($path),$attachment['name'],$attachment['mime_type']);
$message->attach($content);
}
$message->setHtmlBody( $body);
$this->mailer->send($message);
}
public function sendFileAttachmentToTalk($roomToken, $cookie , $fileName ) {
try{
$host = 'http://127.0.0.1';
$client = \OC::$server->getHTTPClientService()->newClient();
$token = file_get_contents("$host/ocs/v2.php/core/getcsrftoken", false, stream_context_create([
'http' => [
'header' => "OCS-APIRequest: true\r\n"
]
]));
$client->post("$host/ocs/v2.php/apps/files_sharing/api/v1/shares", [
'body' => [
"path" => "//Talk/$fileName",
"referenceId" => Uuid::uuid4()->toString(),
"shareWith" => $roomToken,
"shareType" => 10,
'talkMetaData' => "{\"messageType\":\"\"}"
],
'headers' => [
'Cookie' =>$cookie,
'OCS-APIRequest' => 'true',
'requesttoken' => $token
]
]);
}
catch(GuzzleException $e){
$this->logger->debug("error sending file to talk");
}
catch(Exception $e){
$this->logger->debug("error sending file to talk");
}
}
}