Merge remote-tracking branch 'origin/releases/release-h2f' into feature/conge-auto-full-day
This commit is contained in:
commit
b6f363829e
@ -63,6 +63,10 @@ return [
|
|||||||
['name' => 'settings#setConfig', 'url' => '/v1/config/{key}', 'verb' => 'POST'],
|
['name' => 'settings#setConfig', 'url' => '/v1/config/{key}', 'verb' => 'POST'],
|
||||||
// Tools
|
// Tools
|
||||||
['name' => 'email#sendEmailPublicLink', 'url' => '/v1/public/sendmail', 'verb' => 'POST'],
|
['name' => 'email#sendEmailPublicLink', 'url' => '/v1/public/sendmail', 'verb' => 'POST'],
|
||||||
|
|
||||||
|
//Email box
|
||||||
|
['name' => 'emailBox#loadEmailboxMessage', 'url' => '/load-email-box', 'verb' => 'GET'],
|
||||||
|
['name' => 'emailBox#loadEmailboxAttachement', 'url' => '/load-email-attachement/{messageId}', 'verb' => 'GET'],
|
||||||
],
|
],
|
||||||
'resources' => [
|
'resources' => [
|
||||||
'appointmentConfig' => ['url' => '/v1/appointment_configs']
|
'appointmentConfig' => ['url' => '/v1/appointment_configs']
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
328621
calendar/js/calendar-main.js
328621
calendar/js/calendar-main.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
211
calendar/lib/Controller/EmailBoxController.php
Normal file
211
calendar/lib/Controller/EmailBoxController.php
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\Calendar\Controller;
|
||||||
|
|
||||||
|
use OCP\IRequest;
|
||||||
|
use Horde_Imap_Client;
|
||||||
|
use OCA\Calendar\Db\MailRepository;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\Files\IMimeTypeDetector;
|
||||||
|
use OCA\Mail\Contracts\IMailSearch;
|
||||||
|
use OCP\AppFramework\Http\Response;
|
||||||
|
use OCA\Mail\Contracts\IMailManager;
|
||||||
|
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||||
|
use OCA\Mail\Service\AccountService;
|
||||||
|
use OCA\Mail\Service\Sync\SyncService;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
use OCA\Mail\Contracts\IUserPreferences;
|
||||||
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
|
||||||
|
class EmailBoxController extends Controller {
|
||||||
|
private ?string $currentUserId;
|
||||||
|
|
||||||
|
private IMailManager $mailManager;
|
||||||
|
|
||||||
|
private IUserPreferences $preferences;
|
||||||
|
|
||||||
|
private IMailSearch $mailSearch;
|
||||||
|
|
||||||
|
private AccountService $accountService;
|
||||||
|
|
||||||
|
private IURLGenerator $urlGenerator;
|
||||||
|
|
||||||
|
private IMimeTypeDetector $mimeTypeDetector;
|
||||||
|
|
||||||
|
private IMAPClientFactory $clientFactory;
|
||||||
|
|
||||||
|
private SyncService $syncService;
|
||||||
|
|
||||||
|
private MailRepository $mailRepository;
|
||||||
|
|
||||||
|
public function __construct(string $appName,
|
||||||
|
IRequest $request,
|
||||||
|
?string $UserId,
|
||||||
|
IMailManager $mailManager,
|
||||||
|
IUserPreferences $preferences,
|
||||||
|
IMailSearch $mailSearch,
|
||||||
|
AccountService $accountService,
|
||||||
|
IURLGenerator $urlGenerator,
|
||||||
|
IMimeTypeDetector $mimeTypeDetector,
|
||||||
|
IMAPClientFactory $clientFactory,
|
||||||
|
SyncService $syncService,
|
||||||
|
MailRepository $mailRepository,
|
||||||
|
|
||||||
|
) {
|
||||||
|
parent::__construct($appName, $request);
|
||||||
|
$this->currentUserId = $UserId;
|
||||||
|
$this->mailManager = $mailManager;
|
||||||
|
$this->preferences = $preferences;
|
||||||
|
$this->mailSearch = $mailSearch;
|
||||||
|
$this->accountService = $accountService;
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
$this->mimeTypeDetector = $mimeTypeDetector;
|
||||||
|
$this->clientFactory = $clientFactory;
|
||||||
|
$this->syncService = $syncService;
|
||||||
|
$this->mailRepository = $mailRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function loadEmailboxMessage(): JSONResponse {
|
||||||
|
|
||||||
|
$mailboxId = $this->mailRepository->getCurrentUserMailBoxId($this->currentUserId);
|
||||||
|
if($mailboxId == null){
|
||||||
|
return new JSONResponse([
|
||||||
|
"success" => false,
|
||||||
|
"message" => "MAILBOX_NOT_FOUND",
|
||||||
|
], Http::STATUS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastMessageTimestamp = null;
|
||||||
|
$init = true;
|
||||||
|
$sortOrder = 'newest';
|
||||||
|
$query = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $mailboxId);
|
||||||
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
||||||
|
// try {
|
||||||
|
// if (boolval($this->request->getParam('withSync'))) {
|
||||||
|
// $this->syncService->syncMailbox(
|
||||||
|
// $account,
|
||||||
|
// $mailbox,
|
||||||
|
// Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
|
||||||
|
// null,
|
||||||
|
// $lastMessageTimestamp,
|
||||||
|
// $init,
|
||||||
|
// $sortOrder,
|
||||||
|
// $query
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// } catch (\Throwable $th) {
|
||||||
|
// // on ignioir car il n'est pas est deja synchronise
|
||||||
|
// }
|
||||||
|
} catch (DoesNotExistException $e) {
|
||||||
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = $this->preferences->getPreference($this->currentUserId, 'sort-order', 'newest') === 'newest' ? 'DESC': 'ASC';
|
||||||
|
return new JSONResponse(
|
||||||
|
$this->mailSearch->findMessages(
|
||||||
|
$account,
|
||||||
|
$mailbox,
|
||||||
|
$order,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
400,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function loadEmailboxAttachement(int $messageId = 0): Response {
|
||||||
|
$data = [];
|
||||||
|
try {
|
||||||
|
$message = $this->mailManager->getMessage($this->currentUserId, $messageId);
|
||||||
|
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
|
||||||
|
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
|
||||||
|
|
||||||
|
// $data["messageObject"] = $message ?? null;
|
||||||
|
} catch (DoesNotExistException $e) {
|
||||||
|
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$client = $this->clientFactory->getClient($account);
|
||||||
|
try {
|
||||||
|
$imapMessage = $this->mailManager->getImapMessage(
|
||||||
|
$client,
|
||||||
|
$account,
|
||||||
|
$mailbox,
|
||||||
|
$message->getUid(), true
|
||||||
|
);
|
||||||
|
$json = $imapMessage->getFullMessage($messageId);
|
||||||
|
} finally {
|
||||||
|
$client->logout();
|
||||||
|
}
|
||||||
|
$data['attachments'] = array_map(function ($a) use ($messageId) {
|
||||||
|
return $this->enrichDownloadUrl(
|
||||||
|
$messageId,
|
||||||
|
$a
|
||||||
|
);
|
||||||
|
}, $json['attachments']);
|
||||||
|
return new JSONResponse(($data));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
* @param array $attachment
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function enrichDownloadUrl(int $id,
|
||||||
|
array $attachment) {
|
||||||
|
$downloadUrl = $this->urlGenerator->linkToRoute('mail.messages.downloadAttachment',
|
||||||
|
[
|
||||||
|
'id' => $id,
|
||||||
|
'attachmentId' => $attachment['id'],
|
||||||
|
]);
|
||||||
|
$downloadUrl = $this->urlGenerator->getAbsoluteURL($downloadUrl);
|
||||||
|
$attachment['downloadUrl'] = $downloadUrl;
|
||||||
|
$attachment['mimeUrl'] = $this->mimeTypeDetector->mimeTypeIcon($attachment['mime']);
|
||||||
|
|
||||||
|
$attachment['isImage'] = $this->attachmentIsImage($attachment);
|
||||||
|
$attachment['isCalendarEvent'] = $this->attachmentIsCalendarEvent($attachment);
|
||||||
|
|
||||||
|
return $attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the content of this attachment is an image
|
||||||
|
*
|
||||||
|
* @param array $attachment
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private function attachmentIsImage(array $attachment): bool {
|
||||||
|
return in_array(
|
||||||
|
$attachment['mime'], [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/png',
|
||||||
|
'image/gif'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $attachment
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private function attachmentIsCalendarEvent(array $attachment): bool {
|
||||||
|
return in_array($attachment['mime'], ['text/calendar', 'application/ics'], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,19 +26,24 @@ declare(strict_types=1);
|
|||||||
*/
|
*/
|
||||||
namespace OCA\Calendar\Controller;
|
namespace OCA\Calendar\Controller;
|
||||||
|
|
||||||
use OCP\AppFramework\Controller;
|
|
||||||
use OCP\AppFramework\Http;
|
|
||||||
use OCP\AppFramework\Http\JSONResponse;
|
|
||||||
use OCP\Defaults;
|
|
||||||
use OCP\IConfig;
|
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\Defaults;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IURLGenerator;
|
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
use OCP\IUserSession;
|
use OCP\IUserSession;
|
||||||
use OCP\Mail\IEMailTemplate;
|
|
||||||
use OCP\Mail\IMailer;
|
use OCP\Mail\IMailer;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
use OCP\Mail\IMessage;
|
use OCP\Mail\IMessage;
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\Mail\IEMailTemplate;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCA\Mail\Contracts\IMailSearch;
|
||||||
|
use OCA\Mail\Contracts\IMailManager;
|
||||||
|
use OCA\Mail\Service\AccountService;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
use OCA\Mail\Contracts\IUserPreferences;
|
||||||
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class EmailController
|
* Class EmailController
|
||||||
@ -67,6 +72,18 @@ class EmailController extends Controller {
|
|||||||
/** @var IUserManager */
|
/** @var IUserManager */
|
||||||
private $userManager;
|
private $userManager;
|
||||||
|
|
||||||
|
|
||||||
|
private ?string $currentUserId;
|
||||||
|
|
||||||
|
|
||||||
|
private IMailManager $mailManager;
|
||||||
|
|
||||||
|
private IUserPreferences $preferences;
|
||||||
|
|
||||||
|
private IMailSearch $mailSearch;
|
||||||
|
|
||||||
|
private AccountService $accountService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EmailController constructor.
|
* EmailController constructor.
|
||||||
*
|
*
|
||||||
@ -88,7 +105,15 @@ class EmailController extends Controller {
|
|||||||
IL10N $l10N,
|
IL10N $l10N,
|
||||||
Defaults $defaults,
|
Defaults $defaults,
|
||||||
IURLGenerator $urlGenerator,
|
IURLGenerator $urlGenerator,
|
||||||
IUserManager $userManager) {
|
IUserManager $userManager,
|
||||||
|
?string $UserId,
|
||||||
|
IMailManager $mailManager,
|
||||||
|
IUserPreferences $preferences,
|
||||||
|
IMailSearch $mailSearch,
|
||||||
|
AccountService $accountService,
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
@ -97,6 +122,11 @@ class EmailController extends Controller {
|
|||||||
$this->defaults = $defaults;
|
$this->defaults = $defaults;
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
|
$this->currentUserId = $UserId;
|
||||||
|
$this->mailManager = $mailManager;
|
||||||
|
$this->preferences = $preferences;
|
||||||
|
$this->mailSearch = $mailSearch;
|
||||||
|
$this->accountService = $accountService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,4 +256,7 @@ class EmailController extends Controller {
|
|||||||
'token' => $token,
|
'token' => $token,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
52
calendar/lib/Db/MailRepository.php
Normal file
52
calendar/lib/Db/MailRepository.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
namespace OCA\Calendar\Db;
|
||||||
|
|
||||||
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
|
class MailRepository {
|
||||||
|
|
||||||
|
private IDbConnection $pdo;
|
||||||
|
|
||||||
|
public function __construct(IDbConnection $db) {
|
||||||
|
$this->pdo = $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function execSQL($sql, $conditions){
|
||||||
|
$stmt = $this->pdo->prepare($sql);
|
||||||
|
$stmt->execute($conditions);
|
||||||
|
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
|
$stmt->closeCursor();
|
||||||
|
return json_encode($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function execSQLNoData($sql, $conditions){
|
||||||
|
$stmt = $this->pdo->prepare($sql);
|
||||||
|
$stmt->execute($conditions);
|
||||||
|
$stmt->closeCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function execSQLNoJsonReturn($sql, $conditions){
|
||||||
|
$stmt = $this->pdo->prepare($sql);
|
||||||
|
$stmt->execute($conditions);
|
||||||
|
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
|
$stmt->closeCursor();
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrentUserMailBoxId(string $currentUserId ) {
|
||||||
|
$sql = 'SELECT mail_mailbox.id as mail_box_id
|
||||||
|
FROM oc_mail_accounts as mail_account
|
||||||
|
LEFT JOIN oc_mail_mailboxes as mail_mailbox ON mail_account.id = mail_mailbox.account_id
|
||||||
|
WHERE mail_account.user_id = ?
|
||||||
|
AND mail_mailbox.name = ?';
|
||||||
|
|
||||||
|
$result = $this->execSQLNoJsonReturn($sql, [$currentUserId,"INBOX"]);
|
||||||
|
if(!empty($result)){
|
||||||
|
return $result[0]['mail_box_id'];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -187,6 +187,7 @@ export default {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
isEditable() {
|
isEditable() {
|
||||||
|
console.log("this.isAuthenticatedUser" + this.isAuthenticatedUser)
|
||||||
// We do not allow drag and drop when the editor is open.
|
// We do not allow drag and drop when the editor is open.
|
||||||
return this.isAuthenticatedUser
|
return this.isAuthenticatedUser
|
||||||
&& this.$route?.name !== 'EditPopoverView'
|
&& this.$route?.name !== 'EditPopoverView'
|
||||||
|
|||||||
@ -32,6 +32,12 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ t('calendar', 'Upload from device') }}
|
{{ t('calendar', 'Upload from device') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
|
<NcActionButton @click="openEmailBoxModal">
|
||||||
|
<template #icon>
|
||||||
|
<Email :size="20" />
|
||||||
|
</template>
|
||||||
|
{{ t('calendar', 'Depuis un email') }}
|
||||||
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="attachments.length > 0">
|
<div v-if="attachments.length > 0">
|
||||||
@ -58,13 +64,93 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NcDialog :open.sync="showOpenConfirmation"
|
<NcDialog :open.sync="showOpenConfirmation"
|
||||||
:name="t('calendar', 'Confirmation')"
|
:name="t('calendar', 'Confirmation')"
|
||||||
:buttons="openConfirmationButtons">
|
:buttons="openConfirmationButtons">
|
||||||
<p class="external-link-message">
|
<p class="external-link-message">
|
||||||
{{ openConfirmationMessage }}
|
{{ openConfirmationMessage }}
|
||||||
</p>
|
</p>
|
||||||
</NcDialog>
|
</NcDialog>
|
||||||
|
<NcModal v-if="showModal" name="" size='large' @close="resetMailBoxModal">
|
||||||
|
|
||||||
|
<div class="modal__content" v-if="!showAttachmentsSection && !showAttachmentsSection">
|
||||||
|
<NcButton style="text-align: center;" @click="syncEmailBox()" v-if="!loadingDataEmailBox">
|
||||||
|
<template #icon>
|
||||||
|
<Reload :size="20" />
|
||||||
|
</template>
|
||||||
|
Actualiser
|
||||||
|
</NcButton>
|
||||||
|
<template v-if="mailBoxData.length > 0" v-for="mail in mailBoxData">
|
||||||
|
<ul>
|
||||||
|
<NcListItem
|
||||||
|
@click="getAttachments(mail)"
|
||||||
|
:name="getLabelEmailBox(mail.from) + ' : ' + mail.subject"
|
||||||
|
:bold="false"
|
||||||
|
counterType="outlined">
|
||||||
|
<template #subname>
|
||||||
|
{{ getSubstringText(mail.previewText ,50) }}
|
||||||
|
</template>
|
||||||
|
<template v-if="hasAttachements(mail)" #icon>
|
||||||
|
<Paperclip :size="20" />
|
||||||
|
</template>
|
||||||
|
</NcListItem>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="modal__content__attachments" v-if="showAttachmentsSection">
|
||||||
|
<ul class="attachments-list">
|
||||||
|
<NcActionButton @click="displayAttachmentsSection()">
|
||||||
|
<template #icon>
|
||||||
|
<ArrowLeft :size="20" />
|
||||||
|
</template>
|
||||||
|
Revenir dans la listes des emails
|
||||||
|
</NcActionButton>
|
||||||
|
<div v-if="selectedMail" >
|
||||||
|
<div class="mailHeader">
|
||||||
|
{{ getLabelEmailBox(selectedMail.from) + ' : ' + selectedMail.subject }}
|
||||||
|
</div>
|
||||||
|
<div class="mailContent">
|
||||||
|
{{ selectedMail.previewText }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mailHeader">
|
||||||
|
Pièces jointes :
|
||||||
|
</div>
|
||||||
|
<div class="image-list-attachement " v-if="!loadingDataEmailBox && mailAttachmentData.length > 0" v-for="attachment in mailAttachmentData">
|
||||||
|
<div v-if="attachment.isImage" class="image-item-attachement " @click="selectAttachement(attachment.id)">
|
||||||
|
<img :src="attachment.downloadUrl" :alt="attachment.fileName ">
|
||||||
|
<label>{{ attachment.fileName }} <span v-if="isInSelectedAttachment(attachment.id)"> ✔</span> </label>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="! attachment.isImage && !attachment.isCalendarEvent" class="image-item-attachement " @click="selectAttachement(attachment.id)">
|
||||||
|
<label>{{ attachment.fileName }}
|
||||||
|
<span v-if="isInSelectedAttachment(attachment.id)"> ✔</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="attachment.isCalendarEvent" class="image-item-attachement " >
|
||||||
|
<label>{{ attachment.fileName }} ( Non allouée)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-if="!mailAttachmentData.length && !loadingDataEmailBox" >
|
||||||
|
<p> Pas d'attachements</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal__content" v-if="selectedAttachements.length && !loadingDataEmailBox" >
|
||||||
|
<NcButton style="text-align: center;" @click="pickEmailAttachement()" >
|
||||||
|
Ajouter ({{ selectedAttachements.length }})
|
||||||
|
</NcButton>
|
||||||
|
</div>
|
||||||
|
<div class="modal__content" v-if="loadingDataEmailBox" >
|
||||||
|
<div >
|
||||||
|
<NcLoadingIcon :size="40" appearance="light" :name="loadingText" />
|
||||||
|
</div>
|
||||||
|
<p style="text-align: center;"> {{ loadingText }}</p>
|
||||||
|
</div>
|
||||||
|
</NcModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -74,13 +160,23 @@ import {
|
|||||||
NcActions,
|
NcActions,
|
||||||
NcActionButton,
|
NcActionButton,
|
||||||
NcDialog,
|
NcDialog,
|
||||||
|
NcModal,
|
||||||
|
NcButton,
|
||||||
|
NcAvatar,
|
||||||
|
NcLoadingIcon,
|
||||||
|
NcCheckboxRadioSwitch
|
||||||
} from '@nextcloud/vue'
|
} from '@nextcloud/vue'
|
||||||
|
|
||||||
|
import axios from "@nextcloud/axios";
|
||||||
|
|
||||||
import Upload from 'vue-material-design-icons/Upload.vue'
|
import Upload from 'vue-material-design-icons/Upload.vue'
|
||||||
import Close from 'vue-material-design-icons/Close.vue'
|
import Close from 'vue-material-design-icons/Close.vue'
|
||||||
import Folder from 'vue-material-design-icons/Folder.vue'
|
import Folder from 'vue-material-design-icons/Folder.vue'
|
||||||
import Paperclip from 'vue-material-design-icons/Paperclip.vue'
|
import Paperclip from 'vue-material-design-icons/Paperclip.vue'
|
||||||
import Plus from 'vue-material-design-icons/Plus.vue'
|
import Plus from 'vue-material-design-icons/Plus.vue'
|
||||||
|
import Email from 'vue-material-design-icons/Email.vue'
|
||||||
|
import ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'
|
||||||
|
import Reload from 'vue-material-design-icons/Reload.vue'
|
||||||
|
|
||||||
import { generateUrl, getBaseUrl } from '@nextcloud/router'
|
import { generateUrl, getBaseUrl } from '@nextcloud/router'
|
||||||
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
|
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
|
||||||
@ -88,8 +184,10 @@ import logger from '../../../utils/logger.js'
|
|||||||
import {
|
import {
|
||||||
uploadLocalAttachment,
|
uploadLocalAttachment,
|
||||||
getFileInfo,
|
getFileInfo,
|
||||||
|
uploadRemoteFile
|
||||||
} from '../../../services/attachmentService.js'
|
} from '../../../services/attachmentService.js'
|
||||||
import { parseXML } from 'webdav'
|
import { parseXML } from 'webdav'
|
||||||
|
import { size } from 'lodash';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AttachmentsList',
|
name: 'AttachmentsList',
|
||||||
@ -103,6 +201,14 @@ export default {
|
|||||||
Paperclip,
|
Paperclip,
|
||||||
Plus,
|
Plus,
|
||||||
NcDialog,
|
NcDialog,
|
||||||
|
NcModal,
|
||||||
|
NcButton,
|
||||||
|
Email,
|
||||||
|
ArrowLeft,
|
||||||
|
Reload,
|
||||||
|
NcAvatar,
|
||||||
|
NcLoadingIcon,
|
||||||
|
NcCheckboxRadioSwitch
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
calendarObjectInstance: {
|
calendarObjectInstance: {
|
||||||
@ -120,6 +226,14 @@ export default {
|
|||||||
showOpenConfirmation: false,
|
showOpenConfirmation: false,
|
||||||
openConfirmationMessage: '',
|
openConfirmationMessage: '',
|
||||||
openConfirmationButtons: [],
|
openConfirmationButtons: [],
|
||||||
|
showModal: false,
|
||||||
|
showAttachmentsSection: false,
|
||||||
|
loadingDataEmailBox: false,
|
||||||
|
mailBoxData: [],
|
||||||
|
mailAttachmentData: [],
|
||||||
|
selectedAttachements: [],
|
||||||
|
loadingText: 'Chargement ...',
|
||||||
|
selectedMail: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -255,6 +369,150 @@ export default {
|
|||||||
]
|
]
|
||||||
this.showOpenConfirmation = true
|
this.showOpenConfirmation = true
|
||||||
},
|
},
|
||||||
|
async syncEmailBox(){
|
||||||
|
this.loadingText = 'Synchronisation encours ...'
|
||||||
|
this.loadingDataEmailBox = true
|
||||||
|
this.mailBoxData = [];
|
||||||
|
await this.loadEmailsBox(true)
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
},
|
||||||
|
async openEmailBoxModal(){
|
||||||
|
this.loadingText = 'Chargement des emails ...'
|
||||||
|
this.showModal = true
|
||||||
|
this.loadingDataEmailBox = true
|
||||||
|
await this.loadEmailsBox()
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
},
|
||||||
|
async getAttachments(mail){
|
||||||
|
this.loadingText = 'Récupération des piecs jointes ...'
|
||||||
|
this.selectedMail = mail
|
||||||
|
this.loadingDataEmailBox = true
|
||||||
|
this.showAttachmentsSection = true
|
||||||
|
this.mailAttachmentData = [] ;
|
||||||
|
await this.loadAttachments(mail)
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
},
|
||||||
|
selectAttachement(attachementId){
|
||||||
|
if(this.isInSelectedAttachment(attachementId)){
|
||||||
|
console.log("remove")
|
||||||
|
this.selectedAttachements = this.selectedAttachements.filter(id => id !== attachementId)
|
||||||
|
}else{
|
||||||
|
console.log("add")
|
||||||
|
this.selectedAttachements.push(attachementId)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
isInSelectedAttachment(attachementId){
|
||||||
|
return this.selectedAttachements.find(id => id === attachementId)
|
||||||
|
},
|
||||||
|
async pickEmailAttachement(){
|
||||||
|
this.loadingText = 'Ajout de l\'attachement encours ...'
|
||||||
|
this.loadingDataEmailBox = true
|
||||||
|
//upload only attachmen if id is in selectedAttachements
|
||||||
|
const selectedAttachements = this.selectedAttachements.map(id => this.mailAttachmentData.find(attachement => attachement.id === id))
|
||||||
|
await this.uploadAttachment(selectedAttachements)
|
||||||
|
|
||||||
|
this.closeMailBoxModal()
|
||||||
|
this.resetMailBoxModal()
|
||||||
|
},
|
||||||
|
async uploadAttachment(attachements = []){
|
||||||
|
await Promise.all(attachements.map(async attachement => {
|
||||||
|
await this.uploadEmailAttachementTodavFile(attachement)
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
resetMailBoxModal() {
|
||||||
|
this.mailBoxData = []
|
||||||
|
this.mailAttachmentData = []
|
||||||
|
this.showModal = false
|
||||||
|
this.showAttachmentsSection = false
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
this.loadingText = 'Chargement ...'
|
||||||
|
this.selectedAttachements = []
|
||||||
|
},
|
||||||
|
displayAttachmentsSection() {
|
||||||
|
this.showAttachmentsSection = false
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
},
|
||||||
|
closeMailBoxModal() {
|
||||||
|
this.showModal = false
|
||||||
|
this.showAttachmentsSection = false
|
||||||
|
this.loadingDataEmailBox = false
|
||||||
|
this.loadingText = 'Chargement ...'
|
||||||
|
},
|
||||||
|
async loadEmailsBox(withSync = false) {
|
||||||
|
const ajaxUrl = generateUrl('/apps/calendar/load-email-box')
|
||||||
|
await axios.get(ajaxUrl , { params: { withSync } })
|
||||||
|
.then(response => {
|
||||||
|
console.log(response.data.success);
|
||||||
|
if (!response.data.success && response.data.message == "MAILBOX_NOT_FOUND") {
|
||||||
|
this.closeMailBoxModal();
|
||||||
|
showError(t('calendar', 'Veuillez configurer le compte apps email pour pouvoir utiliser cette fonctionnalité.' , {
|
||||||
|
timeout : 7000,
|
||||||
|
}))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.mailBoxData = response.data;
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async loadAttachments(mail) {
|
||||||
|
// if (!this.hasAttachements(mail)) {
|
||||||
|
// this.mailAttachmentData = [] ;
|
||||||
|
// this.loadingDataEmailBox = false
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
const ajaxUrl = generateUrl('/apps/calendar/load-email-attachement/' + mail.databaseId)
|
||||||
|
|
||||||
|
await axios.get(ajaxUrl)
|
||||||
|
.then(response => {
|
||||||
|
|
||||||
|
// response.data.attachments.forEach(attachement => {
|
||||||
|
// this.mailAttachmentData.push({
|
||||||
|
// id : attachement.id,
|
||||||
|
// fileName : attachement.fileName,
|
||||||
|
// downloadUrl : attachement.downloadUrl,
|
||||||
|
// id : attachement.id,
|
||||||
|
// isImage : attachement.isImage,
|
||||||
|
// isCalendarEvent : attachement.isCalendarEvent,
|
||||||
|
// size : attachement.size,
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
this.mailAttachmentData = response.data.attachments
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async uploadEmailAttachementTodavFile(attachement) {
|
||||||
|
const attachmentsFolder = await this.$store.dispatch('createAttachmentsFolder')
|
||||||
|
const attachment = await uploadRemoteFile(attachmentsFolder, attachement.downloadUrl, attachement.fileName ,this.currentUser.dav)
|
||||||
|
// TODO do not share file, move to PHP
|
||||||
|
const data = await getFileInfo(`${attachmentsFolder}/${attachment.path}`, this.currentUser.dav.userId)
|
||||||
|
const davRes = await parseXML(data)
|
||||||
|
const davRespObj = davRes?.multistatus?.response[0]?.propstat?.prop
|
||||||
|
davRespObj.fileName = attachment.path
|
||||||
|
davRespObj.url = generateUrl(`/f/${davRespObj.fileid}`)
|
||||||
|
davRespObj.value = davRespObj.url
|
||||||
|
this.addAttachmentWithProperty(this.calendarObjectInstance, davRespObj)
|
||||||
|
},
|
||||||
|
getLabelEmailBox(from = []) {
|
||||||
|
if (from.length) {
|
||||||
|
return from[0].label ?? from[0].email
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
getSubstringText(text = '' , length = 20) {
|
||||||
|
if (text.length < length) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return text.substring(0, length) + '...'
|
||||||
|
},
|
||||||
|
hasAttachements(mail) {
|
||||||
|
return mail.flags.hasAttachments;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -332,4 +590,55 @@ export default {
|
|||||||
.external-link-message {
|
.external-link-message {
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
.modal__content {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
.modal__content__attachments {
|
||||||
|
margin: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.attachments-list{
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-list-attachement {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item-attachement {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item-attachement img {
|
||||||
|
width: 100px; /* Largeur de l'image */
|
||||||
|
height: auto; /* Hauteur automatique pour garder le ratio */
|
||||||
|
margin-right: 10px; /* Espace entre l'image et la légende */
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 16px; /* Taille de police pour la légende */
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailHeader{
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailContent{
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="!isReadOnly" class="property-title-time-picker">
|
||||||
|
<div class="property-title-time-picker__all-day">
|
||||||
|
<NcCheckboxRadioSwitch :checked="isPrivate"
|
||||||
|
@update:checked="toggleIsPrivate">
|
||||||
|
{{ $t('calendar', 'Privé') }}
|
||||||
|
</NcCheckboxRadioSwitch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ getIsPrivateLabel }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
|
||||||
|
export default {
|
||||||
|
name: "PropertyIsPrivate",
|
||||||
|
components: {
|
||||||
|
NcCheckboxRadioSwitch,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isPrivate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getIsPrivateLabel() {
|
||||||
|
return this.isPrivate ? this.$t('calendar', 'Privé') : this.$t('calendar', 'Mettre en privé');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleIsPrivate() {
|
||||||
|
const newState = !this.isPrivate;
|
||||||
|
this.$emit('toggle-is-private',newState)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.checkbox-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@ -41,7 +41,9 @@ import { getAllObjectsInTimeRange } from '../../utils/calendarObject.js'
|
|||||||
*/
|
*/
|
||||||
export function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {
|
export function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {
|
||||||
const fcEvents = []
|
const fcEvents = []
|
||||||
|
const authUser = OC.currentUser;
|
||||||
for (const calendarObject of calendarObjects) {
|
for (const calendarObject of calendarObjects) {
|
||||||
|
|
||||||
let allObjectsInTimeRange
|
let allObjectsInTimeRange
|
||||||
try {
|
try {
|
||||||
allObjectsInTimeRange = getAllObjectsInTimeRange(calendarObject, start, end)
|
allObjectsInTimeRange = getAllObjectsInTimeRange(calendarObject, start, end)
|
||||||
@ -52,7 +54,7 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
|
|||||||
|
|
||||||
for (const object of allObjectsInTimeRange) {
|
for (const object of allObjectsInTimeRange) {
|
||||||
const classNames = []
|
const classNames = []
|
||||||
|
|
||||||
if (object.status === 'CANCELLED') {
|
if (object.status === 'CANCELLED') {
|
||||||
classNames.push('fc-event-nc-cancelled')
|
classNames.push('fc-event-nc-cancelled')
|
||||||
} else if (object.status === 'TENTATIVE') {
|
} else if (object.status === 'TENTATIVE') {
|
||||||
@ -100,6 +102,8 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let title
|
let title
|
||||||
if (object.name === 'VEVENT') {
|
if (object.name === 'VEVENT') {
|
||||||
if (object.title) {
|
if (object.title) {
|
||||||
@ -119,6 +123,27 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isPrivateEvent = false;
|
||||||
|
let objectProperties = object._properties.get('ISPRIVATE');
|
||||||
|
if (objectProperties && objectProperties.length > 0) {
|
||||||
|
isPrivateEvent = objectProperties[0]._value == "1" ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get owen object's user
|
||||||
|
let owenUrl = calendarObject.dav._parent.owner
|
||||||
|
let owenUser = owenUrl.replace('/remote.php/dav/principals/users/','').split('/')[0]
|
||||||
|
if (!owenUser) {
|
||||||
|
//Get from url shared calendar
|
||||||
|
owenUrl = calendarObject.dav._parent.url
|
||||||
|
owenUser = owenUrl.replace('/remote.php/dav/calendars/' + authUser + '/personal_shared_by_' ,'').split('/')[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOwenOfEvent = owenUser == authUser
|
||||||
|
|
||||||
|
if (isPrivateEvent && !isOwenOfEvent ) {
|
||||||
|
title = t('calendar', `Absent (${owenUser})`)
|
||||||
|
}
|
||||||
|
|
||||||
const fcEvent = {
|
const fcEvent = {
|
||||||
id: [calendarObject.id, object.id].join('###'),
|
id: [calendarObject.id, object.id].join('###'),
|
||||||
title,
|
title,
|
||||||
@ -143,6 +168,9 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
|
|||||||
davUrl: calendarObject.dav.url,
|
davUrl: calendarObject.dav.url,
|
||||||
location: object.location,
|
location: object.location,
|
||||||
description: object.description,
|
description: object.description,
|
||||||
|
isPrivate: isPrivateEvent,
|
||||||
|
calendarObjectOwen : owenUser ,
|
||||||
|
calendarObjectIsOwen : isOwenOfEvent,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,10 @@ export default function(store, router, route, window, isWidget = false, ref = un
|
|||||||
* @param {boolean} isWidget Whether the calendar is embedded in a widget
|
* @param {boolean} isWidget Whether the calendar is embedded in a widget
|
||||||
*/
|
*/
|
||||||
function handleEventClick(event, store, router, route, window, isWidget = false) {
|
function handleEventClick(event, store, router, route, window, isWidget = false) {
|
||||||
|
|
||||||
|
if(event.extendedProps.isPrivate && !event.extendedProps.calendarObjectIsOwen ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isWidget) {
|
if (isWidget) {
|
||||||
store.commit('setSelectedEvent', { object: event.extendedProps.objectId, recurrenceId: event.extendedProps.recurrenceId })
|
store.commit('setSelectedEvent', { object: event.extendedProps.objectId, recurrenceId: event.extendedProps.recurrenceId })
|
||||||
return
|
return
|
||||||
|
|||||||
@ -118,6 +118,24 @@ export default {
|
|||||||
return this.calendarObjectInstance?.embalmer ?? null
|
return this.calendarObjectInstance?.embalmer ?? null
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the comment or null if the event is still loading
|
||||||
|
*
|
||||||
|
* @return {string|null}
|
||||||
|
*/
|
||||||
|
comment() {
|
||||||
|
return this.calendarObjectInstance?.comment ?? null
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the isPrivate property
|
||||||
|
*
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isPrivate() {
|
||||||
|
return this.calendarObjectInstance?.isPrivate ?? false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the description or null if the event is still loading
|
* Returns the description or null if the event is still loading
|
||||||
@ -342,7 +360,7 @@ export default {
|
|||||||
* Returns an object with properties from RFCs including
|
* Returns an object with properties from RFCs including
|
||||||
* their displayName, a description, options, etc.
|
* their displayName, a description, options, etc.
|
||||||
*
|
*
|
||||||
* @return {{geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
|
* @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
|
||||||
*/
|
*/
|
||||||
rfcProps() {
|
rfcProps() {
|
||||||
return getRFCProperties()
|
return getRFCProperties()
|
||||||
@ -623,6 +641,18 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the comments of this event
|
||||||
|
*
|
||||||
|
* @param {string} comment New comments
|
||||||
|
*/
|
||||||
|
updateComment(comment) {
|
||||||
|
this.$store.commit('changeComment', {
|
||||||
|
calendarObjectInstance: this.calendarObjectInstance,
|
||||||
|
comment,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the client of the event
|
* Updates the client of the event
|
||||||
*
|
*
|
||||||
@ -707,6 +737,16 @@ export default {
|
|||||||
calendarObjectInstance: this.calendarObjectInstance,
|
calendarObjectInstance: this.calendarObjectInstance,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the event to private
|
||||||
|
*/
|
||||||
|
toggleIsPrivate(isPrivate) {
|
||||||
|
this.$store.commit('toggleIsPrivate', {
|
||||||
|
calendarObjectInstance: this.calendarObjectInstance,
|
||||||
|
isPrivate
|
||||||
|
})
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Resets the internal state after changing the viewed calendar-object
|
* Resets the internal state after changing the viewed calendar-object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -60,6 +60,10 @@ const getDefaultEventObject = (props = {}) => Object.assign({}, {
|
|||||||
client : null,
|
client : null,
|
||||||
//embalmer(Thanato) of the event
|
//embalmer(Thanato) of the event
|
||||||
embalmer : null,
|
embalmer : null,
|
||||||
|
//Private
|
||||||
|
isPrivate: false,
|
||||||
|
//comment of the event
|
||||||
|
comment : null,
|
||||||
// description of the event
|
// description of the event
|
||||||
description: null,
|
description: null,
|
||||||
// Access class of the event (PUBLIC, PRIVATE, CONFIDENTIAL)
|
// Access class of the event (PUBLIC, PRIVATE, CONFIDENTIAL)
|
||||||
@ -104,10 +108,12 @@ const mapEventComponentToEventObject = (eventComponent) => {
|
|||||||
eventComponent,
|
eventComponent,
|
||||||
title: eventComponent.title,
|
title: eventComponent.title,
|
||||||
isAllDay: eventComponent.isAllDay(),
|
isAllDay: eventComponent.isAllDay(),
|
||||||
|
isPrivate: false,
|
||||||
canModifyAllDay: eventComponent.canModifyAllDay(),
|
canModifyAllDay: eventComponent.canModifyAllDay(),
|
||||||
location: eventComponent.location,
|
location: eventComponent.location,
|
||||||
client : "CLIENT",
|
client : "CLIENT",
|
||||||
embalmer : "TEST",
|
embalmer : "TEST",
|
||||||
|
comment : "",
|
||||||
description: eventComponent.description,
|
description: eventComponent.description,
|
||||||
accessClass: eventComponent.accessClass,
|
accessClass: eventComponent.accessClass,
|
||||||
status: eventComponent.status,
|
status: eventComponent.status,
|
||||||
@ -197,10 +203,18 @@ const mapEventComponentToEventObject = (eventComponent) => {
|
|||||||
eventObject.client = eventComponent.getFirstPropertyFirstValue('CLIENT');
|
eventObject.client = eventComponent.getFirstPropertyFirstValue('CLIENT');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(eventComponent.hasProperty('ISPRIVATE')){
|
||||||
|
eventObject.isPrivate = eventComponent.getFirstPropertyFirstValue('ISPRIVATE') === '1' ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
if(eventComponent.hasProperty('EMBALMER')){
|
if(eventComponent.hasProperty('EMBALMER')){
|
||||||
eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER');
|
eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(eventComponent.hasProperty('COMMENT')){
|
||||||
|
eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT');
|
||||||
|
}
|
||||||
|
|
||||||
return eventObject;
|
return eventObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +229,8 @@ const copyCalendarObjectInstanceIntoEventComponent = (eventObject, eventComponen
|
|||||||
eventComponent.location = eventObject.location
|
eventComponent.location = eventObject.location
|
||||||
eventComponent.client = eventObject.client
|
eventComponent.client = eventObject.client
|
||||||
eventComponent.embalmer = eventObject.embalmer
|
eventComponent.embalmer = eventObject.embalmer
|
||||||
|
eventComponent.isPrivate = eventObject.isPrivate
|
||||||
|
eventComponent.comment = eventObject.comment
|
||||||
eventComponent.description = eventObject.description
|
eventComponent.description = eventObject.description
|
||||||
eventComponent.accessClass = eventObject.accessClass
|
eventComponent.accessClass = eventObject.accessClass
|
||||||
eventComponent.status = eventObject.status
|
eventComponent.status = eventObject.status
|
||||||
|
|||||||
@ -169,6 +169,15 @@ const getRFCProperties = () => {
|
|||||||
tagPlaceholder: t('calendar', 'Choisir les soins'),
|
tagPlaceholder: t('calendar', 'Choisir les soins'),
|
||||||
options: [],
|
options: [],
|
||||||
},
|
},
|
||||||
|
comment: {
|
||||||
|
readableName: t('calendar', 'Comment'),
|
||||||
|
icon: 'TextBoxOutline',
|
||||||
|
info: t('calendar', 'Commentaires.'),
|
||||||
|
placeholder: t('calendar', 'Commentaires'),
|
||||||
|
tagPlaceholder: t('calendar', 'Commentaires'),
|
||||||
|
options: [],
|
||||||
|
defaultNumberOfRows: 4
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -167,7 +167,34 @@ const uploadLocalAttachment = async function(folder, files, dav, componentAttach
|
|||||||
return attachments
|
return attachments
|
||||||
|
|
||||||
}
|
}
|
||||||
|
const uploadRemoteFile = async function(folder , fileUrl, fileName , dav) {
|
||||||
|
try {
|
||||||
|
// Télécharger le fichier distant
|
||||||
|
const response = await axios.get(fileUrl, { responseType: 'blob' });
|
||||||
|
|
||||||
|
// Envoyer le fichier récupéré en PUT vers WebDAV
|
||||||
|
const url = generateRemoteUrl(`dav/files/${dav.userId}/${folder}/${fileName}`)
|
||||||
|
const uploadResponse = await axios.put(url, response.data, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': response.data.type, // Utilise le type MIME du fichier
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (uploadResponse.status === 204 || uploadResponse.status === 201) {
|
||||||
|
showSuccess(t('calendar', 'Attachment {fileName} added!', { fileName: fileName }));
|
||||||
|
return {
|
||||||
|
fileName: fileName,
|
||||||
|
formatType: response.data.type,
|
||||||
|
uri: url,
|
||||||
|
value: url,
|
||||||
|
path: `/${fileName}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showError(t('calendar', 'An error occurred during uploading file {fileName}', { fileName: fileName }));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO is shared or not @share-types@
|
// TODO is shared or not @share-types@
|
||||||
const getFileInfo = async function(path, userId) {
|
const getFileInfo = async function(path, userId) {
|
||||||
const url = generateRemoteUrl(`dav/files/${userId}/${path}`)
|
const url = generateRemoteUrl(`dav/files/${userId}/${path}`)
|
||||||
@ -200,4 +227,5 @@ export {
|
|||||||
shareFileWith,
|
shareFileWith,
|
||||||
uploadLocalAttachment,
|
uploadLocalAttachment,
|
||||||
createFolder,
|
createFolder,
|
||||||
|
uploadRemoteFile
|
||||||
}
|
}
|
||||||
|
|||||||
@ -286,6 +286,21 @@ const mutations = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is private
|
||||||
|
*
|
||||||
|
* @param {object} state The Vuex state
|
||||||
|
* @param {object} data The destructuring object
|
||||||
|
* @param {object} data.calendarObjectInstance The calendarObjectInstance object
|
||||||
|
*/
|
||||||
|
toggleIsPrivate(state, { calendarObjectInstance, isPrivate }) {
|
||||||
|
calendarObjectInstance.eventComponent.isPrivate = isPrivate
|
||||||
|
calendarObjectInstance.isPrivate = isPrivate
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the time of a timed event to the default values
|
* Changes the time of a timed event to the default values
|
||||||
*
|
*
|
||||||
@ -321,6 +336,19 @@ const mutations = {
|
|||||||
calendarObjectInstance.location = location
|
calendarObjectInstance.location = location
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the comment of an event
|
||||||
|
*
|
||||||
|
* @param {object} state The Vuex state
|
||||||
|
* @param {object} data The destructuring object
|
||||||
|
* @param {object} data.calendarObjectInstance The calendarObjectInstance object
|
||||||
|
* @param {string} data.comment New comment to set
|
||||||
|
*/
|
||||||
|
changeComment(state, { calendarObjectInstance, comment }) {
|
||||||
|
calendarObjectInstance.eventComponent.comment = comment
|
||||||
|
calendarObjectInstance.comment = comment
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the client of an event
|
* Change the client of an event
|
||||||
*
|
*
|
||||||
@ -1693,7 +1721,9 @@ const actions = {
|
|||||||
updateAlarms(eventComponent)
|
updateAlarms(eventComponent)
|
||||||
updateTalkParticipants(eventComponent)
|
updateTalkParticipants(eventComponent)
|
||||||
let additionalFieldWasUpdated =
|
let additionalFieldWasUpdated =
|
||||||
eventComponent.client != null;
|
eventComponent.client != null ||
|
||||||
|
eventComponent.isPrivate != null ||
|
||||||
|
eventComponent.comment != null ;
|
||||||
if (eventComponent.isDirty() || additionalFieldWasUpdated) {
|
if (eventComponent.isDirty() || additionalFieldWasUpdated) {
|
||||||
const isForkedItem = eventComponent.primaryItem !== null
|
const isForkedItem = eventComponent.primaryItem !== null
|
||||||
let original = null
|
let original = null
|
||||||
|
|||||||
@ -230,8 +230,50 @@ const actions = {
|
|||||||
if(eventComponent != null){
|
if(eventComponent != null){
|
||||||
if(eventComponent.client != null){
|
if(eventComponent.client != null){
|
||||||
let newClientKeyValue = "CLIENT:"+eventComponent.client;
|
let newClientKeyValue = "CLIENT:"+eventComponent.client;
|
||||||
icsValue = icsValue.replace(/CLIENT:\d+/, newClientKeyValue);
|
let regexEmptyClient = /CLIENT:(?!\d)(?=\s*[\r\n])/g;
|
||||||
|
if (regexEmptyClient.test(icsValue)) {
|
||||||
|
icsValue = icsValue.replace(regexEmptyClient, newClientKeyValue);
|
||||||
|
}
|
||||||
|
let regex = /CLIENT:\d+/;
|
||||||
|
if(regex.test(icsValue)){
|
||||||
|
icsValue = icsValue.replace(regex, newClientKeyValue);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const customKeyValue = {
|
||||||
|
"CLIENT": eventComponent.client
|
||||||
|
};
|
||||||
|
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(eventComponent.comment != null){
|
||||||
|
let newCommentKeyValue = "COMMENT:"+eventComponent.comment;
|
||||||
|
let regex = /^COMMENT:.*$/m;
|
||||||
|
if(regex.test(icsValue)){
|
||||||
|
icsValue = icsValue.replace(regex, newCommentKeyValue);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const customKeyValue = {
|
||||||
|
"COMMENT": eventComponent.comment
|
||||||
|
};
|
||||||
|
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eventComponent.isPrivate != null){
|
||||||
|
let isPrivateValue = eventComponent.isPrivate ? "1" : "0";
|
||||||
|
let newIsPrivateKeyValue = "ISPRIVATE:"+isPrivateValue;
|
||||||
|
let regex = /ISPRIVATE:\d+/;
|
||||||
|
if(regex.test(icsValue)){
|
||||||
|
icsValue = icsValue.replace(regex, newIsPrivateKeyValue);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const customKeyValue = {
|
||||||
|
"ISPRIVATE": isPrivateValue
|
||||||
|
};
|
||||||
|
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
calendarObject.dav.data = icsValue;
|
calendarObject.dav.data = icsValue;
|
||||||
await calendarObject.dav.update()
|
await calendarObject.dav.update()
|
||||||
@ -247,7 +289,12 @@ const actions = {
|
|||||||
const calendar = context.getters.getCalendarById(calendarObject.calendarId)
|
const calendar = context.getters.getCalendarById(calendarObject.calendarId)
|
||||||
let icsValue = calendarObject.calendarComponent.toICS();
|
let icsValue = calendarObject.calendarComponent.toICS();
|
||||||
if(eventComponent != null){
|
if(eventComponent != null){
|
||||||
const customKeyValue = {"CLIENT": eventComponent.client, "EMBALMER": eventComponent.embalmer};
|
const customKeyValue = {
|
||||||
|
"CLIENT": eventComponent.client,
|
||||||
|
"EMBALMER": eventComponent.embalmer ,
|
||||||
|
"ISPRIVATE": eventComponent.isPrivate ? "1" : "0",
|
||||||
|
"COMMENT": eventComponent.comment
|
||||||
|
};
|
||||||
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
|
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
|
||||||
}
|
}
|
||||||
calendarObject.dav = await calendar.dav.createVObject(icsValue);
|
calendarObject.dav = await calendar.dav.createVObject(icsValue);
|
||||||
|
|||||||
@ -20,15 +20,13 @@
|
|||||||
-
|
-
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="isWidget" class="calendar-Widget calendar-Widget-Custom">
|
<div v-if="isWidget" class="calendar-Widget calendar-Widget-Custom">
|
||||||
<EmbedTopNavigation v-if="!showEmptyCalendarScreen" :is-widget="true" :can-access-previous-event="canAccessPreviousEvent"/>
|
<EmbedTopNavigation v-if="!showEmptyCalendarScreen" :is-widget="true"
|
||||||
|
:can-access-previous-event="canAccessPreviousEvent" />
|
||||||
|
|
||||||
<CalendarGrid v-if="!showEmptyCalendarScreen"
|
<CalendarGrid v-if="!showEmptyCalendarScreen" ref="calendarGridWidget" :is-widget="isWidget"
|
||||||
ref="calendarGridWidget"
|
:can-access-previous-event="canAccessPreviousEvent" :is-authenticated-user="isAuthenticatedUser" />
|
||||||
:is-widget="isWidget"
|
|
||||||
:can-access-previous-event="canAccessPreviousEvent"
|
|
||||||
:is-authenticated-user="isAuthenticatedUser" />
|
|
||||||
<EmptyCalendar v-else />
|
<EmptyCalendar v-else />
|
||||||
|
|
||||||
<EditSimple v-if="showWidgetEventDetails" :is-widget="true" :locations="locations" />
|
<EditSimple v-if="showWidgetEventDetails" :is-widget="true" :locations="locations" />
|
||||||
@ -37,17 +35,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NcContent v-else app-name="calendar calendar-custom" :class="classNames">
|
<NcContent v-else app-name="calendar calendar-custom" :class="classNames">
|
||||||
<AppNavigation v-if="!isWidget &&!isEmbedded && !showEmptyCalendarScreen">
|
<AppNavigation v-if="!isWidget && !isEmbedded && !showEmptyCalendarScreen">
|
||||||
<!-- Date Picker, View Buttons, Today Button -->
|
<!-- Date Picker, View Buttons, Today Button -->
|
||||||
<AppNavigationHeader :is-public="!isAuthenticatedUser" :can-access-previous-event="canAccessPreviousEvent" />
|
<AppNavigationHeader :is-public="!isAuthenticatedUser"
|
||||||
|
:can-access-previous-event="canAccessPreviousEvent" />
|
||||||
<template #list>
|
<template #list>
|
||||||
<AppNavigationSpacer />
|
<AppNavigationSpacer />
|
||||||
|
|
||||||
<!-- Calendar / Subscription List -->
|
<!-- Calendar / Subscription List -->
|
||||||
<CalendarList :is-public="!isAuthenticatedUser"
|
<CalendarList :is-public="!isAuthenticatedUser" :loading-calendars="loadingCalendars" />
|
||||||
:loading-calendars="loadingCalendars" />
|
<CalendarListNew v-if="!loadingCalendars && isAuthenticatedUser" :disabled="loadingCalendars" />
|
||||||
<CalendarListNew v-if="!loadingCalendars && isAuthenticatedUser"
|
|
||||||
:disabled="loadingCalendars" />
|
|
||||||
<EditCalendarModal />
|
<EditCalendarModal />
|
||||||
|
|
||||||
<!-- Appointment Configuration List -->
|
<!-- Appointment Configuration List -->
|
||||||
@ -61,14 +58,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- Settings and import -->
|
<!-- Settings and import -->
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<Settings v-if="isAuthenticatedUser"
|
<Settings v-if="isAuthenticatedUser" :loading-calendars="loadingCalendars" />
|
||||||
:loading-calendars="loadingCalendars" />
|
|
||||||
</template>
|
</template>
|
||||||
</AppNavigation>
|
</AppNavigation>
|
||||||
<EmbedTopNavigation v-if="isEmbedded" :is-admin="false" />
|
<EmbedTopNavigation v-if="isEmbedded" :is-admin="false" />
|
||||||
<AppContent>
|
<AppContent>
|
||||||
<CalendarGrid v-if="!showEmptyCalendarScreen"
|
<CalendarGrid v-if="!showEmptyCalendarScreen" :can-access-previous-event="canAccessPreviousEvent"
|
||||||
:can-access-previous-event="canAccessPreviousEvent"
|
|
||||||
:is-authenticated-user="isAuthenticatedUser" />
|
:is-authenticated-user="isAuthenticatedUser" />
|
||||||
<EmptyCalendar v-else />
|
<EmptyCalendar v-else />
|
||||||
</AppContent>
|
</AppContent>
|
||||||
@ -123,7 +118,8 @@ import {
|
|||||||
import '@nextcloud/dialogs/dist/index.css'
|
import '@nextcloud/dialogs/dist/index.css'
|
||||||
import Trashbin from '../components/AppNavigation/CalendarList/Trashbin.vue'
|
import Trashbin from '../components/AppNavigation/CalendarList/Trashbin.vue'
|
||||||
import AppointmentConfigList from '../components/AppNavigation/AppointmentConfigList.vue'
|
import AppointmentConfigList from '../components/AppNavigation/AppointmentConfigList.vue'
|
||||||
|
import axios from "@nextcloud/axios";
|
||||||
|
import { generateUrl } from '@nextcloud/router'
|
||||||
export default {
|
export default {
|
||||||
name: 'Calendar',
|
name: 'Calendar',
|
||||||
components: {
|
components: {
|
||||||
@ -311,6 +307,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.loadingCalendars = false
|
this.loadingCalendars = false
|
||||||
|
await this.fetchUserTypesAndUpdateCalendars(calendars);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -345,7 +342,7 @@ export default {
|
|||||||
const calendarOwner = calendar.owner;
|
const calendarOwner = calendar.owner;
|
||||||
const userPrincipalId = calendarOwner.split('/').filter(Boolean).pop();
|
const userPrincipalId = calendarOwner.split('/').filter(Boolean).pop();
|
||||||
const userType = await this.fetchUserTypeForCalendar(userPrincipalId);
|
const userType = await this.fetchUserTypeForCalendar(userPrincipalId);
|
||||||
if(userType !=""){
|
if (userType != "") {
|
||||||
calendar.displayName = `${calendar.displayName} (${userType})`;
|
calendar.displayName = `${calendar.displayName} (${userType})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,12 @@
|
|||||||
@update-end-timezone="updateEndTimezone"
|
@update-end-timezone="updateEndTimezone"
|
||||||
@toggle-all-day="toggleAllDay" />
|
@toggle-all-day="toggleAllDay" />
|
||||||
|
|
||||||
|
<PropertyIsPrivate
|
||||||
|
:is-read-only="isReadOnly"
|
||||||
|
:is-private="isPrivate"
|
||||||
|
@toggle-is-private="toggleIsPrivate"
|
||||||
|
/>
|
||||||
|
|
||||||
<PropertySelectClient class="property-location"
|
<PropertySelectClient class="property-location"
|
||||||
url="/apps/gestion/ajaxGetClientsName"
|
url="/apps/gestion/ajaxGetClientsName"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
@ -129,6 +135,13 @@
|
|||||||
@add-single-value="addArticle"
|
@add-single-value="addArticle"
|
||||||
@remove-single-value="removeArticle" />
|
@remove-single-value="removeArticle" />
|
||||||
|
|
||||||
|
<PropertyText
|
||||||
|
:is-read-only="isReadOnly"
|
||||||
|
:prop-model="rfcProps.comment"
|
||||||
|
:value="comment"
|
||||||
|
:linkify-links="false"
|
||||||
|
@update:value="updateComment" />
|
||||||
|
|
||||||
<InvitationResponseButtons v-if="isViewedByAttendee"
|
<InvitationResponseButtons v-if="isViewedByAttendee"
|
||||||
:attendee="userAsAttendee"
|
:attendee="userAsAttendee"
|
||||||
:calendar-id="calendarId"
|
:calendar-id="calendarId"
|
||||||
@ -188,7 +201,7 @@
|
|||||||
:calendar-object-instance="calendarObjectInstance"
|
:calendar-object-instance="calendarObjectInstance"
|
||||||
:is-read-only="isReadOnly" />
|
:is-read-only="isReadOnly" />
|
||||||
|
|
||||||
<NcModal v-if="showModal && !isPrivate()"
|
<NcModal v-if="showModal && !checkIsPrivate()"
|
||||||
:name="t('calendar', 'Managing shared access')"
|
:name="t('calendar', 'Managing shared access')"
|
||||||
@close="closeAttachmentsModal">
|
@close="closeAttachmentsModal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -219,7 +232,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="modal-footer-checkbox">
|
<div class="modal-footer-checkbox">
|
||||||
<NcCheckboxRadioSwitch v-if="!isPrivate()" :checked.sync="doNotShare">
|
<NcCheckboxRadioSwitch v-if="!checkIsPrivate()" :checked.sync="doNotShare">
|
||||||
{{ t('calendar', 'Deny access') }}
|
{{ t('calendar', 'Deny access') }}
|
||||||
</NcCheckboxRadioSwitch>
|
</NcCheckboxRadioSwitch>
|
||||||
</div>
|
</div>
|
||||||
@ -347,6 +360,8 @@ import PropertySelectAjaxMultiple from "../components/Editor/Properties/Property
|
|||||||
import PropertySelectLieu from "../components/Editor/Properties/PropertySelectLieu.vue";
|
import PropertySelectLieu from "../components/Editor/Properties/PropertySelectLieu.vue";
|
||||||
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
|
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
|
||||||
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
|
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
|
||||||
|
import PropertyIsPrivate from "../components/Editor/Properties/PropertyIsPrivate.vue";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EditSidebar',
|
name: 'EditSidebar',
|
||||||
@ -356,6 +371,7 @@ export default {
|
|||||||
PropertySelectLieu,
|
PropertySelectLieu,
|
||||||
PropertySelectClient,
|
PropertySelectClient,
|
||||||
PropertySelectArticle,
|
PropertySelectArticle,
|
||||||
|
PropertyIsPrivate,
|
||||||
ResourceList,
|
ResourceList,
|
||||||
PropertyColor,
|
PropertyColor,
|
||||||
PropertySelectMultiple,
|
PropertySelectMultiple,
|
||||||
@ -536,7 +552,7 @@ export default {
|
|||||||
*
|
*
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
isPrivate() {
|
checkIsPrivate() {
|
||||||
return this.calendarObjectInstance.attendees.filter((attendee) => {
|
return this.calendarObjectInstance.attendees.filter((attendee) => {
|
||||||
if (this.currentUser.emailAddress.toLowerCase() !== (
|
if (this.currentUser.emailAddress.toLowerCase() !== (
|
||||||
attendee.uri.split('mailto:').length === 2
|
attendee.uri.split('mailto:').length === 2
|
||||||
@ -560,7 +576,7 @@ export default {
|
|||||||
if (!this.doNotShare) {
|
if (!this.doNotShare) {
|
||||||
const total = this.showModalNewAttachments.length
|
const total = this.showModalNewAttachments.length
|
||||||
this.showPreloader = true
|
this.showPreloader = true
|
||||||
if (!this.isPrivate()) {
|
if (!this.checkIsPrivate()) {
|
||||||
this.showModalNewAttachments.map(async (attachment, i) => {
|
this.showModalNewAttachments.map(async (attachment, i) => {
|
||||||
// console.log('Add share', attachment)
|
// console.log('Add share', attachment)
|
||||||
this.sharedProgress = Math.ceil(100 * (i + 1) / total)
|
this.sharedProgress = Math.ceil(100 * (i + 1) / total)
|
||||||
@ -622,10 +638,10 @@ export default {
|
|||||||
const newAttachments = this.calendarObjectInstance.attachments.filter(attachment => {
|
const newAttachments = this.calendarObjectInstance.attachments.filter(attachment => {
|
||||||
// get only new attachments
|
// get only new attachments
|
||||||
// TODO get NOT only new attachments =) Maybe we should filter all attachments without share-type, 'cause event can be private and AFTER save owner could add new participant
|
// TODO get NOT only new attachments =) Maybe we should filter all attachments without share-type, 'cause event can be private and AFTER save owner could add new participant
|
||||||
return !this.isPrivate() ? attachment.isNew && attachment.shareTypes === null : attachment.isNew && attachment.shareTypes !== null
|
return !this.checkIsPrivate() ? attachment.isNew && attachment.shareTypes === null : attachment.isNew && attachment.shareTypes !== null
|
||||||
})
|
})
|
||||||
// if there are new attachment and event not saved
|
// if there are new attachment and event not saved
|
||||||
if (newAttachments.length > 0 && !this.isPrivate()) {
|
if (newAttachments.length > 0 && !this.checkIsPrivate()) {
|
||||||
// and is event NOT private,
|
// and is event NOT private,
|
||||||
// then add share to each attachment
|
// then add share to each attachment
|
||||||
// only if attachment['share-types'] is null or empty
|
// only if attachment['share-types'] is null or empty
|
||||||
|
|||||||
@ -126,6 +126,12 @@
|
|||||||
@update-end-timezone="updateEndTimezone"
|
@update-end-timezone="updateEndTimezone"
|
||||||
@toggle-all-day="toggleAllDay" />
|
@toggle-all-day="toggleAllDay" />
|
||||||
|
|
||||||
|
<PropertyIsPrivate
|
||||||
|
:is-read-only="isReadOnly"
|
||||||
|
:is-private="isPrivate"
|
||||||
|
@toggle-is-private="toggleIsPrivate"
|
||||||
|
/>
|
||||||
|
|
||||||
<PropertySelectClient class="property-location"
|
<PropertySelectClient class="property-location"
|
||||||
url="/apps/gestion/ajaxGetClientsName"
|
url="/apps/gestion/ajaxGetClientsName"
|
||||||
:is-read-only="isReadOnly"
|
:is-read-only="isReadOnly"
|
||||||
@ -151,6 +157,14 @@
|
|||||||
@add-single-value="addArticle"
|
@add-single-value="addArticle"
|
||||||
@remove-single-value="removeArticle" />
|
@remove-single-value="removeArticle" />
|
||||||
|
|
||||||
|
<PropertyText
|
||||||
|
:is-read-only="isReadOnly"
|
||||||
|
:prop-model="rfcProps.comment"
|
||||||
|
:value="comment"
|
||||||
|
:linkify-links="false"
|
||||||
|
@update:value="updateComment"
|
||||||
|
/>
|
||||||
|
|
||||||
<InviteesList class="event-popover__invitees"
|
<InviteesList class="event-popover__invitees"
|
||||||
:hide-if-empty="true"
|
:hide-if-empty="true"
|
||||||
:hide-buttons="true"
|
:hide-buttons="true"
|
||||||
@ -223,7 +237,6 @@ import Download from 'vue-material-design-icons/Download.vue'
|
|||||||
import ContentDuplicate from 'vue-material-design-icons/ContentDuplicate.vue'
|
import ContentDuplicate from 'vue-material-design-icons/ContentDuplicate.vue'
|
||||||
import EditIcon from 'vue-material-design-icons/Pencil.vue'
|
import EditIcon from 'vue-material-design-icons/Pencil.vue'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import {showError} from "@nextcloud/dialogs";
|
|
||||||
import PropertySelect from "../components/Editor/Properties/PropertySelect.vue";
|
import PropertySelect from "../components/Editor/Properties/PropertySelect.vue";
|
||||||
import PropertySelectAjax from "../components/Editor/Properties/PropertySelectAjax.vue";
|
import PropertySelectAjax from "../components/Editor/Properties/PropertySelectAjax.vue";
|
||||||
import PropertySelectAjaxMultiple from "../components/Editor/Properties/PropertySelectAjaxMultiple.vue";
|
import PropertySelectAjaxMultiple from "../components/Editor/Properties/PropertySelectAjaxMultiple.vue";
|
||||||
@ -231,6 +244,7 @@ import PropertySelectLieu from "../components/Editor/Properties/PropertySelectLi
|
|||||||
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
|
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
|
||||||
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
|
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
|
||||||
import PropertySelectAbsenceType from "../components/Editor/Properties/PropertySelectAbsenceType.vue";
|
import PropertySelectAbsenceType from "../components/Editor/Properties/PropertySelectAbsenceType.vue";
|
||||||
|
import PropertyIsPrivate from "../components/Editor/Properties/PropertyIsPrivate.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EditSimple',
|
name: 'EditSimple',
|
||||||
@ -240,6 +254,7 @@ export default {
|
|||||||
PropertySelectLieu,
|
PropertySelectLieu,
|
||||||
PropertySelectClient,
|
PropertySelectClient,
|
||||||
PropertySelectArticle,
|
PropertySelectArticle,
|
||||||
|
PropertyIsPrivate,
|
||||||
PropertySelect,
|
PropertySelect,
|
||||||
PopoverLoadingIndicator,
|
PopoverLoadingIndicator,
|
||||||
SaveButtons,
|
SaveButtons,
|
||||||
|
|||||||
@ -203,5 +203,11 @@ return [
|
|||||||
|
|
||||||
//user groups getUserConnectedGroups
|
//user groups getUserConnectedGroups
|
||||||
['name' => 'page#getUserConnectedGroups', 'url' => '/getUserConnectedGroups', 'verb' => 'GET'],
|
['name' => 'page#getUserConnectedGroups', 'url' => '/getUserConnectedGroups', 'verb' => 'GET'],
|
||||||
|
|
||||||
|
|
||||||
|
['name' => 'provider#moveAttachmentFile', 'url' => '/test-move', 'verb' => 'GET'],
|
||||||
|
['name' => 'provider#sendEmailAttachment', 'url' => '/test-send-mail-attach', 'verb' => 'GET'],
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
8
gestion/lib/Constants/VCalendarPropertyConstant.php
Normal file
8
gestion/lib/Constants/VCalendarPropertyConstant.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\Gestion\Constants;
|
||||||
|
abstract class VCalendarPropertyConstant
|
||||||
|
{
|
||||||
|
const PROPERTY_IS_LEAVE = "ISPRIVATE";
|
||||||
|
}
|
||||||
@ -2904,7 +2904,7 @@ class PageController extends Controller {
|
|||||||
return $this->myDb->getClientGroupFacturations();
|
return $this->myDb->getClientGroupFacturations();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*
|
*
|
||||||
@ -2913,6 +2913,11 @@ class PageController extends Controller {
|
|||||||
return $this->myDb->createDefaultGroupFacturation();
|
return $this->myDb->createDefaultGroupFacturation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*
|
||||||
|
*/
|
||||||
public function getUserTypeByUserUuid($userUuid){
|
public function getUserTypeByUserUuid($userUuid){
|
||||||
try{
|
try{
|
||||||
return json_encode(value: $this->myDb->getUserTypeByUserUuid($userUuid));
|
return json_encode(value: $this->myDb->getUserTypeByUserUuid($userUuid));
|
||||||
|
|||||||
@ -1,29 +1,34 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace OCA\Gestion\Controller;
|
namespace OCA\Gestion\Controller;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use OCA\Gestion\Service\ConfigurationService;
|
use OCP\IConfig;
|
||||||
use OCA\Gestion\Service\NavigationService;
|
|
||||||
use OCA\Gestion\Service\Provider\ProviderService;
|
|
||||||
use OCA\Gestion\Service\Provider\Statistic\ProviderStatisticService;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
defined("TAB1") or define("TAB1", "\t");
|
|
||||||
|
|
||||||
use OCP\IGroupManager;
|
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IUserSession;
|
use OCP\IUserSession;
|
||||||
use OCP\Mail\IMailer;
|
use OCP\Mail\IMailer;
|
||||||
use OCP\Files\IRootFolder;
|
use OCP\IGroupManager;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
defined("TAB1") or define("TAB1", "\t");
|
||||||
use OCP\AppFramework\Controller;
|
|
||||||
use OCA\Gestion\Db\Bdd;
|
|
||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
use OCP\IConfig;
|
use OCA\Gestion\Db\Bdd;
|
||||||
|
use OC\Files\Filesystem;
|
||||||
|
use OCP\Files\IRootFolder;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCA\Gestion\Service\GestionService;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCA\Gestion\Service\NavigationService;
|
||||||
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCA\Gestion\Service\ConfigurationService;
|
||||||
|
use OCA\Gestion\Service\Provider\ProviderService;
|
||||||
|
use OCA\Gestion\Service\Provider\Statistic\ProviderStatisticService;
|
||||||
|
|
||||||
date_default_timezone_set('Europe/Paris');
|
date_default_timezone_set('Europe/Paris');
|
||||||
|
|
||||||
class ProviderController extends Controller {
|
class ProviderController extends Controller
|
||||||
|
{
|
||||||
private $idNextcloud;
|
private $idNextcloud;
|
||||||
private $urlGenerator;
|
private $urlGenerator;
|
||||||
private $mailer;
|
private $mailer;
|
||||||
@ -38,31 +43,36 @@ class ProviderController extends Controller {
|
|||||||
/** @var \OCA\Gestion\Service\NavigationService */
|
/** @var \OCA\Gestion\Service\NavigationService */
|
||||||
private $navigationService;
|
private $navigationService;
|
||||||
|
|
||||||
private $providerService;
|
private $providerService;
|
||||||
|
|
||||||
private $providerStatisticService;
|
private $providerStatisticService;
|
||||||
|
|
||||||
private $logger;
|
private $logger;
|
||||||
|
//Gestion service
|
||||||
|
private $gestionService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public function __construct($AppName,
|
public function __construct(
|
||||||
IRequest $request,
|
$AppName,
|
||||||
$UserId,
|
IRequest $request,
|
||||||
Bdd $myDb,
|
$UserId,
|
||||||
IRootFolder $rootFolder,
|
Bdd $myDb,
|
||||||
IURLGenerator $urlGenerator,
|
IRootFolder $rootFolder,
|
||||||
IMailer $mailer,
|
IURLGenerator $urlGenerator,
|
||||||
Iconfig $config,
|
IMailer $mailer,
|
||||||
IUserSession $userSession,
|
Iconfig $config,
|
||||||
IGroupManager $groupManager,
|
IUserSession $userSession,
|
||||||
NavigationService $navigationService,
|
IGroupManager $groupManager,
|
||||||
ConfigurationService $configurationService,
|
NavigationService $navigationService,
|
||||||
LoggerInterface $logger,
|
ConfigurationService $configurationService,
|
||||||
ProviderService $providerService,
|
LoggerInterface $logger,
|
||||||
ProviderStatisticService $providerStatisticService
|
ProviderService $providerService,
|
||||||
){
|
ProviderStatisticService $providerStatisticService,
|
||||||
|
GestionService $gestionService
|
||||||
|
) {
|
||||||
|
|
||||||
parent::__construct($AppName, $request);
|
parent::__construct($AppName, $request);
|
||||||
|
|
||||||
@ -74,55 +84,89 @@ class ProviderController extends Controller {
|
|||||||
$this->navigationService = $navigationService;
|
$this->navigationService = $navigationService;
|
||||||
$this->configurationService = $configurationService;
|
$this->configurationService = $configurationService;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->providerService = $providerService;
|
$this->providerService = $providerService;
|
||||||
$this->providerStatisticService = $providerStatisticService;
|
$this->providerStatisticService = $providerStatisticService;
|
||||||
|
$this->gestionService = $gestionService;
|
||||||
|
|
||||||
if ($userSession->isLoggedIn()) {
|
if ($userSession->isLoggedIn()) {
|
||||||
$this->user = $userSession->getUser();
|
$this->user = $userSession->getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->user != null) {
|
if ($this->user != null) {
|
||||||
$groups = $groupManager->getUserGroups($this->user);
|
$groups = $groupManager->getUserGroups($this->user);
|
||||||
$this->groups = [];
|
$this->groups = [];
|
||||||
foreach ($groups as $group) {
|
foreach ($groups as $group) {
|
||||||
$this->groups[] = $group->getGID();
|
$this->groups[] = $group->getGID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try {
|
||||||
$this->storage = $rootFolder->getUserFolder($this->idNextcloud);
|
$this->storage = $rootFolder->getUserFolder($this->idNextcloud);
|
||||||
}catch(\OC\User\NoUserException $e){
|
} catch (\OC\User\NoUserException $e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function provider() {
|
public function provider()
|
||||||
|
{
|
||||||
return new TemplateResponse('gestion', 'provider', array('groups' => $this->groups, 'user' => $this->user, 'path' => $this->idNextcloud, 'url' => $this->navigationService->getNavigationLink()));
|
return new TemplateResponse('gestion', 'provider', array('groups' => $this->groups, 'user' => $this->user, 'path' => $this->idNextcloud, 'url' => $this->navigationService->getNavigationLink()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function getProviders() {
|
public function getProviders()
|
||||||
|
{
|
||||||
$providers = $this->providerService->getProvidersAsArray();
|
$providers = $this->providerService->getProvidersAsArray();
|
||||||
return json_encode($providers);
|
return json_encode($providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function getProvidersTest() {
|
||||||
|
|
||||||
|
$client = \OC::$server->getHTTPClientService()->newClient();
|
||||||
|
$token = file_get_contents('http://127.0.0.1/ocs/v2.php/core/getcsrftoken', false, stream_context_create([
|
||||||
|
'http' => [
|
||||||
|
'header' => "OCS-APIRequest: true\r\n"
|
||||||
|
]
|
||||||
|
]));
|
||||||
|
$response = $client->post('http://127.0.0.1/ocs/v2.php/apps/files_sharing/api/v1/shares', [
|
||||||
|
'body' => [
|
||||||
|
"path" => "//Talk/narindra-dev.png",
|
||||||
|
"referenceId" => "dkzcesdsdhae",
|
||||||
|
"shareWith" => "dkzcehae",
|
||||||
|
"shareType" => 10,
|
||||||
|
'talkMetaData' => "{\"messageType\":\"\"}"
|
||||||
|
],
|
||||||
|
'headers' => [
|
||||||
|
'Cookie' =>"_ga=GA1.1.259457270.1732194936; _ga_699NE13B0K=GS1.1.1732203040.2.0.1732203040.0.0.0; nc_sameSiteCookielax=true; nc_sameSiteCookiestrict=true; nc_username=Tiavina; oc_sessionPassphrase=v7ncJ0h%2BYxrmzJViNygGkErBa9cSDs1m3mpgW4M6wZ%2BqphceZK2S7PMELp%2BlHgxQxcZuGPrpzZSwzp2SQCXADxDehB7OkwdBEr3DtG8ZzlnXZWzB%2Fbfl7xsuQYTnvmLU; oczp8j7d6k88=1b54a2ea877ffca7154bea254f70886c; nc_token=OEez5vu%2FWTz7FsafIbVDbAXA7lSdkG9U; nc_session_id=1b54a2ea877ffca7154bea254f70886c",
|
||||||
|
'OCS-APIRequest' => 'true',
|
||||||
|
'requesttoken' => $token
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
var_dump($response);die;
|
||||||
|
return json_encode($providers);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function createDefaultProvider() {
|
public function createDefaultProvider()
|
||||||
try{
|
{
|
||||||
|
try {
|
||||||
$this->providerService->createDefaultProvider($this->idNextcloud);
|
$this->providerService->createDefaultProvider($this->idNextcloud);
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,14 +174,18 @@ class ProviderController extends Controller {
|
|||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function exportProvidersStatistic(array $providerIds,$year){
|
public function exportProvidersStatistic(array $providerIds, $year)
|
||||||
try{
|
{
|
||||||
$filenames = $this->providerStatisticService->exportProvidersStatisticByYear($providerIds,$year,$this->idNextcloud);
|
try {
|
||||||
|
$filenames = $this->providerStatisticService->exportProvidersStatisticByYear($providerIds, $year, $this->idNextcloud);
|
||||||
return $filenames;
|
return $filenames;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e){
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1988,7 +1988,7 @@ class Bdd {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$calendarUuid = self::DEFAULT_CALENDAR_UUID_FOR_DEVIS,$date = null,$idNextcloud = "admin"){
|
public function insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$devisComment,$calendarUuid = self::DEFAULT_CALENDAR_UUID_FOR_DEVIS,$date = null,$idNextcloud = "admin"){
|
||||||
|
|
||||||
if($date == null){
|
if($date == null){
|
||||||
$dateTime = new Datetime();
|
$dateTime = new Datetime();
|
||||||
@ -2032,7 +2032,7 @@ class Bdd {
|
|||||||
$this->l->t('New'),
|
$this->l->t('New'),
|
||||||
$locationId,
|
$locationId,
|
||||||
$this->l->t('Mention'),
|
$this->l->t('Mention'),
|
||||||
$this->l->t('Comment'),
|
$devisComment,
|
||||||
$last,
|
$last,
|
||||||
$devisNumber,
|
$devisNumber,
|
||||||
$devisFullNumber
|
$devisFullNumber
|
||||||
@ -2933,6 +2933,7 @@ class Bdd {
|
|||||||
}
|
}
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
devis.id,
|
devis.id,
|
||||||
|
devis.date,
|
||||||
devis.id_thanato,
|
devis.id_thanato,
|
||||||
devis.id_defunt as defunt_id,
|
devis.id_defunt as defunt_id,
|
||||||
devis.num,
|
devis.num,
|
||||||
@ -3031,6 +3032,23 @@ class Bdd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateDevisComment($devisId,$requestedComment,$currentComment = null){
|
||||||
|
$commentIsUpdated = $currentComment != $requestedComment;
|
||||||
|
if($commentIsUpdated){
|
||||||
|
$sql= "UPDATE ".$this->tableprefix."devis as devis
|
||||||
|
SET devis.comment = ?
|
||||||
|
WHERE devis.id = ?";
|
||||||
|
$this->execSQLNoData($sql,[$requestedComment,$devisId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateDevisDate($devisId,$requestedDate){
|
||||||
|
$sql= "UPDATE ".$this->tableprefix."devis as devis
|
||||||
|
SET devis.date = ?
|
||||||
|
WHERE devis.id = ?";
|
||||||
|
$this->execSQLNoData($sql,[$requestedDate,$devisId]);
|
||||||
|
}
|
||||||
|
|
||||||
public function deleteDevisProduit($devisProductId){
|
public function deleteDevisProduit($devisProductId){
|
||||||
$sql = "DELETE FROM ".$this->tableprefix."produit_devis WHERE id = ?;";
|
$sql = "DELETE FROM ".$this->tableprefix."produit_devis WHERE id = ?;";
|
||||||
$this->execSQLNoData($sql, array($devisProductId));
|
$this->execSQLNoData($sql, array($devisProductId));
|
||||||
|
|||||||
@ -195,9 +195,9 @@ class TalkDb {
|
|||||||
[$messageId,$roomId,$idNextCloud]);
|
[$messageId,$roomId,$idNextCloud]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createDevisTalkRoomMessageAndReturnMessage($roomId,$message){
|
public function createDevisTalkRoomMessageAndReturnMessage($roomId,$message,$senderUser){
|
||||||
$this->createDevisTalkRoomMessage(
|
$this->createDevisTalkRoomMessage(
|
||||||
BddConstant::DEFAULT_ADMIN_APP_ID_NEXTCLOUD,
|
$senderUser,
|
||||||
$message,
|
$message,
|
||||||
self::DEVIS_TALK_ROOM_VERB_COMMENT,
|
self::DEVIS_TALK_ROOM_VERB_COMMENT,
|
||||||
$roomId,
|
$roomId,
|
||||||
|
|||||||
12
gestion/lib/Helpers/FolderHelpers.php
Normal file
12
gestion/lib/Helpers/FolderHelpers.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\Gestion\Helpers;
|
||||||
|
|
||||||
|
class FolderHelpers
|
||||||
|
{
|
||||||
|
public static function GetDefuntFolder(string $clientEntreprise,string $defuntNom){
|
||||||
|
$clientRacineFolder = 'CLIENTS/'.strtoupper($clientEntreprise).'/';
|
||||||
|
$defuntFolder = $clientRacineFolder.'DEFUNTS/'.strtoupper($defuntNom).'/';
|
||||||
|
return $defuntFolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,57 +8,80 @@ use Exception;
|
|||||||
|
|
||||||
class VCalendarHelpers
|
class VCalendarHelpers
|
||||||
{
|
{
|
||||||
|
|
||||||
public static function GetValueFromKeyInVCalendarString(string $key, string $vCalendarString): string
|
public static function GetValueFromKeyInVCalendarString(string $key, string $vCalendarString): string
|
||||||
{
|
{
|
||||||
$value = "";
|
$value = "";
|
||||||
preg_match("/$key:(.*)\r\n/", $vCalendarString, $matches);
|
preg_match("/$key:(.*)\r\n/", $vCalendarString, $matches);
|
||||||
if (isset($matches[1])) {
|
if (isset($matches[1])) {
|
||||||
$value = trim($matches[1]);
|
$value = trim($matches[1]);
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetDateStartOrDateEndFromVCalendarString(string $key, string $vCalendarString)
|
public static function GetDateStartOrDateEndFromVCalendarString(string $key, string $vCalendarString)
|
||||||
{
|
{
|
||||||
preg_match("/$key;TZID=([^:]+):(\d+T\d+)/", $vCalendarString, $matches);
|
preg_match("/$key;TZID=([^:]+):(\d+T\d+)/", $vCalendarString, $matches);
|
||||||
if(!$matches){
|
if (!$matches) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try{
|
try {
|
||||||
$dateTz = $matches[1];
|
$dateTz = $matches[1];
|
||||||
$datetimeString = $matches[2];
|
$datetimeString = $matches[2];
|
||||||
$datetimeValue = new DateTime($datetimeString, new DateTimeZone($dateTz));
|
$datetimeValue = new DateTime($datetimeString, new DateTimeZone($dateTz));
|
||||||
return $datetimeValue;
|
return $datetimeValue;
|
||||||
}
|
} catch (Exception $e) {
|
||||||
catch(Exception $e){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString){
|
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString)
|
||||||
|
{
|
||||||
$startTimeValue = "";
|
$startTimeValue = "";
|
||||||
$endTimeValue = "";
|
$endTimeValue = "";
|
||||||
if($vCalendarString != ""){
|
if ($vCalendarString != "") {
|
||||||
$dateStart = self::GetDateStartOrDateEndFromVCalendarString("DTSTART", $vCalendarString);
|
$dateStart = self::GetDateStartOrDateEndFromVCalendarString("DTSTART", $vCalendarString);
|
||||||
if($dateStart != null){
|
if ($dateStart != null) {
|
||||||
$startTimeValue = $dateStart->format("H") . "h";
|
$startTimeValue = $dateStart->format("H") . "h";
|
||||||
}
|
}
|
||||||
$dateEnd = self::GetDateStartOrDateEndFromVCalendarString("DTEND", $vCalendarString);
|
$dateEnd = self::GetDateStartOrDateEndFromVCalendarString("DTEND", $vCalendarString);
|
||||||
if($dateEnd != null){
|
if ($dateEnd != null) {
|
||||||
$endTimeValue = $dateEnd->format("H") . "h";
|
$endTimeValue = $dateEnd->format("H") . "h";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
"startTime" => $startTimeValue,
|
"startTime" => $startTimeValue,
|
||||||
"endTime" => $endTimeValue
|
"endTime" => $endTimeValue
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function ReadVCalendarDataBlob($vCalendarData){
|
public static function ReadVCalendarDataBlob($vCalendarData)
|
||||||
|
{
|
||||||
if (is_resource($vCalendarData)) {
|
if (is_resource($vCalendarData)) {
|
||||||
return stream_get_contents($vCalendarData);
|
return stream_get_contents($vCalendarData);
|
||||||
}
|
}
|
||||||
return $vCalendarData;
|
return $vCalendarData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function hasAttachment(string $vCalendarString): bool
|
||||||
|
{
|
||||||
|
return str_contains($vCalendarString, 'ATTACH;FMTTYPE');
|
||||||
|
}
|
||||||
|
public static function extractAttachments(string $vCalendarString): array
|
||||||
|
{
|
||||||
|
$attachments = [];
|
||||||
|
$vCalendarString = preg_replace("/\r\n|\n|\r/", "\n", $vCalendarString);
|
||||||
|
$vCalendarString = preg_replace("/\n[ \t]/", "", $vCalendarString);
|
||||||
|
preg_match_all('/ATTACH;FMTTYPE=([^;]+);FILENAME=([^;]+);X-NC-FILE-ID=(\d+)/', $vCalendarString, $matches, PREG_SET_ORDER);
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$attachments[] = [
|
||||||
|
'type' => explode("/", $match[1])[0],
|
||||||
|
'mime_type' => $match[1],
|
||||||
|
'name' => trim($match[2], '/'),
|
||||||
|
'file_id' => (int) $match[3],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $attachments;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ use OCA\DAV\Events\CalendarObjectCreatedEvent;
|
|||||||
use OCA\Gestion\Service\GestionService;
|
use OCA\Gestion\Service\GestionService;
|
||||||
use OCP\EventDispatcher\Event;
|
use OCP\EventDispatcher\Event;
|
||||||
use OCP\EventDispatcher\IEventListener;
|
use OCP\EventDispatcher\IEventListener;
|
||||||
|
use OCP\IRequest;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class CalendarObjectCreatedListener implements IEventListener {
|
class CalendarObjectCreatedListener implements IEventListener {
|
||||||
@ -39,9 +40,14 @@ class CalendarObjectCreatedListener implements IEventListener {
|
|||||||
/** @var GestionService */
|
/** @var GestionService */
|
||||||
private $gestionService;
|
private $gestionService;
|
||||||
|
|
||||||
|
/** @var IRequest */
|
||||||
|
private $request;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
IRequest $request,
|
||||||
LoggerInterface $logger,GestionService $gestionService) {
|
LoggerInterface $logger,GestionService $gestionService) {
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->request = $request;
|
||||||
$this->gestionService = $gestionService;
|
$this->gestionService = $gestionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,9 +55,12 @@ class CalendarObjectCreatedListener implements IEventListener {
|
|||||||
if (!($event instanceof CalendarObjectCreatedEvent)) {
|
if (!($event instanceof CalendarObjectCreatedEvent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$cookie = $this->request->getHeader("Cookie");
|
||||||
|
|
||||||
|
|
||||||
$calendarData = $event->getObjectData();
|
$calendarData = $event->getObjectData();
|
||||||
$vCalendarString = $calendarData["calendardata"];
|
$vCalendarString = $calendarData["calendardata"];
|
||||||
$this->gestionService->HandleCreatedCalendarObject($vCalendarString);
|
$this->gestionService->HandleCreatedCalendarObject($vCalendarString , $cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ use OCA\DAV\Events\CalendarObjectUpdatedEvent;
|
|||||||
use OCA\Gestion\Service\GestionService;
|
use OCA\Gestion\Service\GestionService;
|
||||||
use OCP\EventDispatcher\Event;
|
use OCP\EventDispatcher\Event;
|
||||||
use OCP\EventDispatcher\IEventListener;
|
use OCP\EventDispatcher\IEventListener;
|
||||||
|
use OCP\IRequest;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class CalendarObjectUpdatedListener implements IEventListener {
|
class CalendarObjectUpdatedListener implements IEventListener {
|
||||||
@ -40,19 +41,25 @@ class CalendarObjectUpdatedListener implements IEventListener {
|
|||||||
/** @var GestionService */
|
/** @var GestionService */
|
||||||
private $gestionService;
|
private $gestionService;
|
||||||
|
|
||||||
|
/** @var IRequest */
|
||||||
|
private $request;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
IRequest $request,
|
||||||
LoggerInterface $logger,GestionService $gestionService) {
|
LoggerInterface $logger,GestionService $gestionService) {
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->gestionService = $gestionService;
|
$this->gestionService = $gestionService;
|
||||||
|
$this->request = $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(Event $event): void {
|
public function handle(Event $event): void {
|
||||||
if (!($event instanceof CalendarObjectUpdatedEvent)) {
|
if (!($event instanceof CalendarObjectUpdatedEvent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
$cookie = $this->request->getHeader("Cookie");
|
||||||
$calendarData = $event->getObjectData();
|
$calendarData = $event->getObjectData();
|
||||||
$vCalendarString = $calendarData["calendardata"];
|
$vCalendarString = $calendarData["calendardata"];
|
||||||
$this->gestionService->HandleUpdatedCalendarObject($vCalendarString);
|
$this->gestionService->HandleUpdatedCalendarObject($vCalendarString,$cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,18 +26,26 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace OCA\Gestion\Service;
|
namespace OCA\Gestion\Service;
|
||||||
|
|
||||||
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\DB\Exception;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
use OCP\Mail\IMailer;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
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\Constants\BddConstant;
|
||||||
use OCA\Gestion\Constants\DevisMentionConstant;
|
use OCA\Gestion\Helpers\FolderHelpers;
|
||||||
|
use OCA\Gestion\Helpers\VCalendarHelpers;
|
||||||
use OCA\Gestion\Constants\OrderStatusConstant;
|
use OCA\Gestion\Constants\OrderStatusConstant;
|
||||||
use OCA\Gestion\Constants\ThanatoTypeConstant;
|
use OCA\Gestion\Constants\ThanatoTypeConstant;
|
||||||
use OCA\Gestion\Db\Bdd;
|
|
||||||
use OCA\Gestion\Db\OrderBdd;
|
|
||||||
use OCA\Gestion\Service\Devis\Pdf\DevisPdfService;
|
|
||||||
use OCA\Gestion\Service\Order\OrderPdfService;
|
use OCA\Gestion\Service\Order\OrderPdfService;
|
||||||
use OCP\DB\Exception;
|
use OCA\Gestion\Constants\DevisMentionConstant;
|
||||||
use Psr\Log\LoggerInterface;
|
use OCA\Gestion\Service\Devis\Pdf\DevisPdfService;
|
||||||
use OCA\Gestion\Helpers\VCalendarHelpers;
|
use OCA\Gestion\Constants\VCalendarPropertyConstant;
|
||||||
use OCP\IUserSession;
|
|
||||||
|
|
||||||
class GestionService {
|
class GestionService {
|
||||||
/** @var Bdd */
|
/** @var Bdd */
|
||||||
@ -58,6 +66,13 @@ class GestionService {
|
|||||||
|
|
||||||
private string $userConnectedUuid;
|
private string $userConnectedUuid;
|
||||||
|
|
||||||
|
private $userConnectedStorage;
|
||||||
|
|
||||||
|
private $mailer;
|
||||||
|
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Bdd $gestionBdd,
|
Bdd $gestionBdd,
|
||||||
OrderBdd $orderBdd,
|
OrderBdd $orderBdd,
|
||||||
@ -65,7 +80,11 @@ class GestionService {
|
|||||||
OrderPdfService $orderPdfService,
|
OrderPdfService $orderPdfService,
|
||||||
DevisPdfService $devisPdfService,
|
DevisPdfService $devisPdfService,
|
||||||
TalkService $talkService,
|
TalkService $talkService,
|
||||||
IUserSession $userSession
|
IUserSession $userSession,
|
||||||
|
IRootFolder $rootFolder,
|
||||||
|
IMailer $mailer,
|
||||||
|
IConfig $config,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
$this->orderBdd = $orderBdd;
|
$this->orderBdd = $orderBdd;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
@ -75,6 +94,11 @@ class GestionService {
|
|||||||
$this->talkService = $talkService;
|
$this->talkService = $talkService;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
$this->userConnectedUuid = $userSession->getUser()?->getUID() ?? BddConstant::DEFAULT_ADMIN_APP_ID_NEXTCLOUD;
|
$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
|
private function GetCalendarSummaryFromVCalendarString(string $vCalendarString): string
|
||||||
@ -169,8 +193,27 @@ class GestionService {
|
|||||||
return $calendarStartDate;
|
return $calendarStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function HandleCreatedCalendarObject(string $vCalendarString){
|
private function GetIsPivateFromVCalendarString(string $vCalendarString): bool{
|
||||||
|
$isPrivateValue = VCalendarHelpers::GetValueFromKeyInVCalendarString(VCalendarPropertyConstant::PROPERTY_IS_LEAVE, $vCalendarString);
|
||||||
|
return $isPrivateValue === "1" ? true : false;
|
||||||
|
}
|
||||||
|
private function GetDevisCommentFromVCalendarString(string $vCalendarString){
|
||||||
|
$commentValue = VCalendarHelpers::GetValueFromKeyInVCalendarString("COMMENT", $vCalendarString);
|
||||||
|
if($commentValue == ""){
|
||||||
|
$commentValue = "Commentaire";
|
||||||
|
}
|
||||||
|
return $commentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function HandleCreatedCalendarObject(string $vCalendarString ,$cookie){
|
||||||
try{
|
try{
|
||||||
|
|
||||||
|
$isPrivate = $this->GetIsPivateFromVCalendarString($vCalendarString);
|
||||||
|
if($isPrivate){
|
||||||
|
//Nothing to do manage fo a private calendar
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$thanato = $this->GetThanatoFromVCalendarString($vCalendarString);
|
$thanato = $this->GetThanatoFromVCalendarString($vCalendarString);
|
||||||
if($thanato != null){
|
if($thanato != null){
|
||||||
$thanatoId = $thanato["id"];
|
$thanatoId = $thanato["id"];
|
||||||
@ -184,13 +227,16 @@ class GestionService {
|
|||||||
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
|
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
|
||||||
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
|
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
|
||||||
$devisAlreadyCreated = $this->IsDevisAlreadyCreated($clientId,$locationId,$thanatoId,$calendarSummary,$calendarUuid);
|
$devisAlreadyCreated = $this->IsDevisAlreadyCreated($clientId,$locationId,$thanatoId,$calendarSummary,$calendarUuid);
|
||||||
|
|
||||||
|
|
||||||
if($devisAlreadyCreated){
|
if($devisAlreadyCreated){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$defuntId = $this->gestionBdd->insertDefuntByNameAndReturnId($calendarSummary);
|
$defuntId = $this->gestionBdd->insertDefuntByNameAndReturnId($calendarSummary);
|
||||||
$calendarStartDate = $this->GetCalendarDateFromVCalendarString($vCalendarString);
|
$calendarStartDate = $this->GetCalendarDateFromVCalendarString($vCalendarString);
|
||||||
$devisDate = $calendarStartDate->format('Y-m-d');
|
$devisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString);
|
||||||
$devisId = $this->gestionBdd->insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$calendarUuid,$devisDate,$userName);
|
$devisDate = $calendarStartDate->format(format: 'Y-m-d');
|
||||||
|
$devisId = $this->gestionBdd->insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$devisComment,$calendarUuid,$devisDate,$userName);
|
||||||
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
||||||
if(!empty($articlesValue)){
|
if(!empty($articlesValue)){
|
||||||
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
|
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
|
||||||
@ -210,6 +256,34 @@ class GestionService {
|
|||||||
$devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devisId,$userName);
|
$devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devisId,$userName);
|
||||||
$this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid);
|
$this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid);
|
||||||
$this->devisPdfService->generateDevisPdfByDevisId($devisId,$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);
|
||||||
|
if($roomToken != null){
|
||||||
|
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);
|
$this->gestionBdd->createDevisTrajetFromVCalendar($devisId,$userName);
|
||||||
}
|
}
|
||||||
catch(Exception $e){
|
catch(Exception $e){
|
||||||
@ -217,6 +291,14 @@ class GestionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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){
|
private function GetThanatoNameFromVCalendarString($vCalendarString){
|
||||||
$thanatoName = null;
|
$thanatoName = null;
|
||||||
$thanatoNames = $this->GetAttendeesNameFromVCalendarString($vCalendarString);
|
$thanatoNames = $this->GetAttendeesNameFromVCalendarString($vCalendarString);
|
||||||
@ -281,7 +363,10 @@ class GestionService {
|
|||||||
$requestedClientId = $this->GetClientIdFromVCalendarString($vCalendarString);
|
$requestedClientId = $this->GetClientIdFromVCalendarString($vCalendarString);
|
||||||
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
|
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
|
||||||
$requestedArticleReferences = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
$requestedArticleReferences = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
||||||
|
$requestedDevisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString);
|
||||||
$requestedArticleIds = $this->gestionBdd->getArticleIdsByArticleReferences($requestedArticleReferences);
|
$requestedArticleIds = $this->gestionBdd->getArticleIdsByArticleReferences($requestedArticleReferences);
|
||||||
|
$requestedDevisDate = $this->GetCalendarDateFromVCalendarString($vCalendarString);
|
||||||
|
$requestedDevisDate = $requestedDevisDate->format('Y-m-d');
|
||||||
$articleDevis = $this->gestionBdd->getProduitDevisByDevisId($devis['id']);
|
$articleDevis = $this->gestionBdd->getProduitDevisByDevisId($devis['id']);
|
||||||
$articleDevisIds = [];
|
$articleDevisIds = [];
|
||||||
foreach($articleDevis as $currentArticleDevis){
|
foreach($articleDevis as $currentArticleDevis){
|
||||||
@ -294,6 +379,8 @@ class GestionService {
|
|||||||
$devis['defunt_nom'] == $requestedDefuntName &&
|
$devis['defunt_nom'] == $requestedDefuntName &&
|
||||||
$devis['client_id'] == $requestedClientId &&
|
$devis['client_id'] == $requestedClientId &&
|
||||||
$devis['lieu_id'] == $requestLocationId &&
|
$devis['lieu_id'] == $requestLocationId &&
|
||||||
|
$devis['comment'] == $requestedDevisComment &&
|
||||||
|
$devis['date'] == $requestedDevisDate &&
|
||||||
$requestedArticleIds == $articleDevisIds;
|
$requestedArticleIds == $articleDevisIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +395,13 @@ class GestionService {
|
|||||||
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
|
$requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString);
|
||||||
$this->gestionBdd->updateDevisLieu($devis['id'],$requestLocationId,$devis['lieu_id']);
|
$this->gestionBdd->updateDevisLieu($devis['id'],$requestLocationId,$devis['lieu_id']);
|
||||||
|
|
||||||
|
$requestedDevisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString);
|
||||||
|
$this->gestionBdd->updateDevisComment($devis['id'],$requestedDevisComment,$devis['comment']);
|
||||||
|
|
||||||
|
$requestedDevisDate = $this->GetCalendarDateFromVCalendarString($vCalendarString);
|
||||||
|
$requestedDevisDate = $requestedDevisDate->format('Y-m-d');
|
||||||
|
$this->gestionBdd->updateDevisDate($devis['id'],$requestedDevisDate);
|
||||||
|
|
||||||
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
$articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString);
|
||||||
if(!empty($articlesValue)){
|
if(!empty($articlesValue)){
|
||||||
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
|
$articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue);
|
||||||
@ -315,26 +409,126 @@ class GestionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function HandleUpdatedCalendarObject(string $vCalendarString){
|
public function HandleUpdatedCalendarObject(string $vCalendarString , $cookie){
|
||||||
try{
|
try{
|
||||||
|
$isPrivate = $this->GetIsPivateFromVCalendarString($vCalendarString);
|
||||||
|
if($isPrivate){
|
||||||
|
//Nothing to do manage fo a private calendar
|
||||||
|
return;
|
||||||
|
}
|
||||||
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
|
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
|
||||||
$devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid);
|
$devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid);
|
||||||
if($devis != null){
|
if($devis != null){
|
||||||
$this->gestionBdd->updateDevisMention($devis['id'],DevisMentionConstant::NEW);
|
|
||||||
$isDevisAlreadyUpdated = $this->CheckIfDevisIsAlreadyUpdated($devis,$vCalendarString);
|
$isDevisAlreadyUpdated = $this->CheckIfDevisIsAlreadyUpdated($devis,$vCalendarString);
|
||||||
if($isDevisAlreadyUpdated){
|
if($isDevisAlreadyUpdated){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
$devisIsAlreadyFactured = $devis['mentions'] == DevisMentionConstant::FACTURED || $devis['mentions'] == DevisMentionConstant::FACTURED_FORMATTED;
|
||||||
$this->UpdateDevisDataByVCalendarString($devis,$vCalendarString);
|
$this->UpdateDevisDataByVCalendarString($devis,$vCalendarString);
|
||||||
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
|
$userName = $this->GetThanatoNameFromVCalendarString($vCalendarString);
|
||||||
$devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devis['id'],$userName);
|
if($devisIsAlreadyFactured == false){
|
||||||
$this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid);
|
$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);
|
||||||
|
if($roomToken != null){
|
||||||
|
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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$this->HandleCreatedCalendarObject($vCalendarString,$cookie);
|
||||||
}
|
}
|
||||||
$this->devisPdfService->generateDevisPdfByDevisId($devis['id'],$this->userConnectedUuid);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch(Exception $e){
|
catch(Exception $e){
|
||||||
$this->logger->debug("error creating devis");
|
$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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,12 +89,12 @@ class TalkService {
|
|||||||
if($room == null){
|
if($room == null){
|
||||||
$roomToken = $this->generateTalkRandomToken();
|
$roomToken = $this->generateTalkRandomToken();
|
||||||
$room = $this->talkDb->createDevisTalkRoomAndReturnDevisTalkRoom($targetUser,$senderUser, $roomToken);
|
$room = $this->talkDb->createDevisTalkRoomAndReturnDevisTalkRoom($targetUser,$senderUser, $roomToken);
|
||||||
$initialMessage = $this->talkDb->setDevisTalkRoomInitialMessageAndReturnMessage($room['id'],$targetUser);
|
$this->talkDb->setDevisTalkRoomInitialMessageAndReturnMessage($room['id'],$targetUser);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$roomToken = $room['token'];
|
$roomToken = $room['token'];
|
||||||
}
|
}
|
||||||
$devisMessage = $this->talkDb->createDevisTalkRoomMessageAndReturnMessage($room['id'],$message);
|
$devisMessage = $this->talkDb->createDevisTalkRoomMessageAndReturnMessage($room['id'],$message,$senderUser);
|
||||||
$this->talkDb->updateRoomLastMessage($room['id'],$devisMessage['id']);
|
$this->talkDb->updateRoomLastMessage($room['id'],$devisMessage['id']);
|
||||||
$this->talkDb->setAttendeeLastReadMessage($room['id'],$devisMessage['id'],$senderUser);
|
$this->talkDb->setAttendeeLastReadMessage($room['id'],$devisMessage['id'],$senderUser);
|
||||||
//send notifications
|
//send notifications
|
||||||
@ -103,4 +103,24 @@ class TalkService {
|
|||||||
$this->talkDb->sendAttendeeNotifications($targetUser,$roomToken,$notificationsSubjectsParameters,$notificationsMessageParameters);
|
$this->talkDb->sendAttendeeNotifications($targetUser,$roomToken,$notificationsSubjectsParameters,$notificationsMessageParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRoomTokenBeetwenTwoUser( $senderUser , $targetUser){
|
||||||
|
$senderAndTargetIsTheSameUser = $targetUser == $senderUser;
|
||||||
|
$senderUser = $senderAndTargetIsTheSameUser ? BddConstant::DEFAULT_ADMIN_ID_NEXTCLOUD : $senderUser;
|
||||||
|
if( $targetUser === BddConstant::DEFAULT_ADMIN_ID_NEXTCLOUD && $senderUser === BddConstant::DEFAULT_ADMIN_ID_NEXTCLOUD){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$roomNames = $this->getUserDevisTalkRoomNames($targetUser , $senderUser);
|
||||||
|
$room = $this->talkDb->getDevisTalkRoomByNames($roomNames);
|
||||||
|
if($room == null){
|
||||||
|
$roomToken = $this->generateTalkRandomToken();
|
||||||
|
$room = $this->talkDb->createDevisTalkRoomAndReturnDevisTalkRoom($targetUser,$senderUser, $roomToken);
|
||||||
|
$this->talkDb->setDevisTalkRoomInitialMessageAndReturnMessage($room['id'],$targetUser);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$roomToken = $room['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $roomToken;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,22 +25,22 @@ $currentUserIsAdmin = (isset($_['groups']) && in_array(OCA\Gestion\Constants\Use
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="app-navigation-entry-submenu">
|
||||||
|
<span class="navmarg icon-toggle-pictures"></span>
|
||||||
|
<a class="a-entry-submenu" href="<?php echo ($_['url']['lieu']); ?>">
|
||||||
|
<?php p($l->t('Lieux')); ?>
|
||||||
|
</a>
|
||||||
|
<div class="app-navigation-entry-utils-submenu">
|
||||||
|
<ul>
|
||||||
|
<li class="app-navigation-entry-utils-counter">
|
||||||
|
<span id="statslieu">
|
||||||
|
<div class="loader"></div>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<?php if ($currentUserIsAdmin): ?>
|
<?php if ($currentUserIsAdmin): ?>
|
||||||
<li class="app-navigation-entry-submenu">
|
|
||||||
<span class="navmarg icon-toggle-pictures"></span>
|
|
||||||
<a class="a-entry-submenu" href="<?php echo ($_['url']['lieu']); ?>">
|
|
||||||
<?php p($l->t('Lieux')); ?>
|
|
||||||
</a>
|
|
||||||
<div class="app-navigation-entry-utils-submenu">
|
|
||||||
<ul>
|
|
||||||
<li class="app-navigation-entry-utils-counter">
|
|
||||||
<span id="statslieu">
|
|
||||||
<div class="loader"></div>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="app-navigation-entry-submenu">
|
<li class="app-navigation-entry-submenu">
|
||||||
<span class="navmarg icon-category-integration"></span>
|
<span class="navmarg icon-category-integration"></span>
|
||||||
<a class="a-entry-submenu" href="<?php echo ($_['url']['produit']); ?>">
|
<a class="a-entry-submenu" href="<?php echo ($_['url']['produit']); ?>">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user