<?php
namespace App\Manager;
use App\Entity\ContactSheet\ContactSheet;
use App\Entity\ContactSheet\InterruptionContact;
use App\Entity\ContactSheet\PriorityContact;
use App\Entity\User;
use App\Exception\ContactSheetFileException;
use App\Repository\App\ContactSheet\ContactSheetRepository;
use App\Repository\App\ContactSheet\InterruptionContactRepository;
use App\Repository\App\ContactSheet\PriorityContactRepository;
use App\Repository\Scp\BillingContactRepository;
use App\Repository\Scp\ContactRepository;
use App\Repository\Scp\ContractRepository;
use App\Repository\Scp\UserRepository;
use App\Traits\TranslatorByDomainTrait;
use Doctrine\ORM\EntityManagerInterface;
use mikehaertl\pdftk\Pdf;
use Symfony\Contracts\Translation\TranslatorInterface;
class ContactSheetManager
{
private const CONTACT_MAPPING = [
PriorityContact::FIRST_CONTACT => 1,
PriorityContact::SECOND_CONTACT => 2,
PriorityContact::THIRD_CONTACT => 3,
PriorityContact::FOURTH_CONTACT => 4,
PriorityContact::CRISIS_CONTACT => 5,
];
use TranslatorByDomainTrait;
protected $contactSheetRepository;
protected $contractRepository;
protected $contractManager;
protected $billingContactRepository;
protected $pdftkPath;
protected $contactSheetEIEELayoutPath;
protected $contactSheetEUECLayoutPath;
protected $exportPath;
protected $objectManager;
protected $interruptionContactRepository;
protected $priorityContactRepository;
public function __construct(
TranslatorInterface $translator,
ContactSheetRepository $contactSheetRepository,
ContractRepository $contractRepository,
ContractManager $contractManager,
BillingContactRepository $billingContactRepository,
string $contactSheetEIEELayoutPath,
string $contactSheetEUECLayoutPath,
string $pdftkPath,
string $exportPath,
EntityManagerInterface $objectManager,
InterruptionContactRepository $interruptionContactRepository,
PriorityContactRepository $priorityContactRepository,
UserRepository $userRepository
)
{
$this->contactSheetRepository = $contactSheetRepository;
$this->contactSheetEIEELayoutPath = $contactSheetEIEELayoutPath;
$this->contactSheetEUECLayoutPath = $contactSheetEUECLayoutPath;
$this->contractManager = $contractManager;
$this->contractRepository = $contractRepository;
$this->billingContactRepository = $billingContactRepository;
$this->pdftkPath = $pdftkPath;
$this->exportPath = $exportPath;
$this->translator = $translator;
$this->objectManager = $objectManager;
$this->interruptionContactRepository = $interruptionContactRepository;
$this->priorityContactRepository = $priorityContactRepository;
$this->userRepository = $userRepository;
}
public function getContactSheet(string $id, User $user): ?ContactSheet
{
$customerNumber = $user->isMainAccount() ? $user->getCustomerNumber() : $user->getMainAccount()->getCustomerNumber();
return $this->contactSheetRepository->findOneBy([
'id' => $id,
'customerNumber' => $customerNumber,
]);
}
public function getContactSheetByDeliverationsStations(array $deliveryStationsIds, User $user): array
{
$customerNumber = $user->isMainAccount() ? $user->getCustomerNumber() : $user->getMainAccount()->getCustomerNumber();
return $this->contactSheetRepository->findAllByDeliveryStationIds($deliveryStationsIds, $customerNumber);
}
public function generateFile(ContactSheet $contactSheet, User $user): ContactSheet
{
$donneesCompteClient = $this->userRepository->findDonneesCompteClientByCustomerNumber($user->getCustomerNumber());
$deliveryStation = $this->contractRepository->findOneByContractNumberAndDeliveryStation($contactSheet->getContractNumber(), $contactSheet->getDeliveryStationId());
if (null === $deliveryStation) {
throw new ContactSheetFileException(sprintf(
'Contact sheet %s of customer %s : Missing contract %s or delivery station %s',
$contactSheet->getId(),
$contactSheet->getCustomerNumber(),
$contactSheet->getContractNumber(),
$contactSheet->getDeliveryStationId()
));
}
$pdf = new Pdf($this->getLayout($deliveryStation), [
'command' => $this->pdftkPath,
]);
$data = [
'p1_actualise_le' => Date('d-m-Y'),
'p1_numero_client' => $user->getCustomerNumber(),
'p1_prenom_nom' => $donneesCompteClient['nom'] . ' ' . $donneesCompteClient['prenom'],
'p2_prenom_nom' => $donneesCompteClient['nom'] . ' ' . $donneesCompteClient['prenom'],
'p1_numero_du_poste' => $contactSheet->getDeliveryStationId(),
'p1_nom_du_poste' => $deliveryStation ? $deliveryStation['Reperage'] : 'reperage',
'p2_ information_complementaires' => $contactSheet->getAdditionalInformation(),
'p2_numero_poste' => $contactSheet->getDeliveryStationId(),
'p2_nom_poste' => $deliveryStation ? $deliveryStation['Reperage'] : 'reperage',
'p2_numero_client' => $user->getCustomerNumber(),
'p1_nom_du_contrat' => $deliveryStation['Libelle'],
'p2_nom_du_contrat' => $deliveryStation['Libelle'],
];
$data = array_merge($data, $this->getBillingContact());
$data = array_merge($data, $this->getOtherContact($contactSheet, $user));
$data = array_merge($data, $this->getProjectContact($contactSheet, $user));
$data = array_merge($data, $this->getPriorityContact($contactSheet));
$data = array_merge($data, $this->getInterruptionContact($contactSheet));
$pdf->fillForm($data);
$customerNumber = $user->isMainAccount() ? $user->getCustomerNumber() : $user->getMainAccount()->getCustomerNumber();
$fileName = sprintf('%s-%s.pdf', $customerNumber, $contactSheet->getDeliveryStationId());
$fileName = str_replace('/', '_', $fileName);
$path = $this->getPathDirectory() . $fileName;
$pdf->flatten()->saveAs($path);
if (!empty($pdf->getError())) {
throw new ContactSheetFileException($pdf->getError());
}
$date = \DateTimeImmutable::createFromFormat('d-m-Y', $data["p1_actualise_le"]);
$contactSheet->setUpdatedAt($date);
$contactSheet->setFileName($fileName);
$contactSheet->setFileSize(filesize($path));
return $contactSheet;
}
public function getFilePath(ContactSheet $contactSheet): string
{
return $this->getPathDirectory() . $contactSheet->getFileName();
}
public function deleteFromUser(User $user)
{
$this->contactSheetRepository->deleteFromCustomerNumber($user->getCustomerNumber());
$this->priorityContactRepository->deleteFormUserId($user->getId());
$this->interruptionContactRepository->deleteFormUserId($user->getId());
}
public function isUserUsedInContactSheet(User $user): bool
{
return 0 < ($this->interruptionContactRepository->count(['user' => $user]) + $this->priorityContactRepository->count(['user' => $user]));
}
protected function getLayout(array $deliveryStation): string
{
if (in_array($deliveryStation['TypeFicheContact'], ContactSheetRepository::CONTACT_SHEET_TYPE_EE_EI_GLF)
) {
return $this->contactSheetEIEELayoutPath;
}
return $this->contactSheetEUECLayoutPath;
}
protected function getProjectContact(ContactSheet $contactSheet, User $user): array
{
$principalContact = $this->contractManager->getPrincipalContactsByContractNumberAndType(
$contactSheet->getContractNumber(),
ContactRepository::TYPE_COMMERCIAL,
$user
);
if (null === $principalContact) {
return [];
}
return [
'p1_interlocuteur_dedie_prenom' => $principalContact['Prenom'],
'p1_interlocuteur_dedie_nom' => $principalContact['Nom'],
'p1_votre_interlocuteur_dedie_fixe' => $principalContact['Telephone'],
'p1_votre_interlocuteur_dedie_portable' => $principalContact['Portable'],
'p1_votre_interlocuteur_dedie_email' => $principalContact['Email'],
];
}
protected function getOtherContact(ContactSheet $contactSheet, User $user): array
{
$technicalContact = $this->contractManager->getPrincipalContactsByContractNumberAndType(
$contactSheet->getContractNumber(),
ContactRepository::TYPE_TECHNICAL,
$user
);
if (null === $technicalContact) {
return [];
}
return [
'p1_urgence_nom_centre' => $technicalContact['NomCE'],
'p1_urgence_telephone' => $technicalContact['Telephone'],
'p1_autres_contacts_responsable_technique_prenom' => $technicalContact['Prenom'],
'p1_autres_contacts_responsable_technique_nom' => $technicalContact['Nom'],
'p1_autres_contacts_responsable_technique_tel_fixe' => $technicalContact['Telephone'],
'p1_autres_contacts_responsable_technique_tel_portable' => $technicalContact['Portable'],
'p1_autres_contacts_responsable_technique_email' => $technicalContact['Email'],
];
}
protected function getBillingContact(): array
{
$billingContact = $this->billingContactRepository->findOneByContactType(BillingContactRepository::TYPE_CONTACT_SHEET);
if (null === $billingContact) {
return [];
}
return [
'p1_autres_contacts_facturation_prenom' => $billingContact['Prenom'],
'p1_autres_contacts_facturation_nom' => $billingContact['Nom'],
'p1_autres_contacts_facturation_service' => $billingContact['Titre'],
'p1_autres_contacts_facturation_email' => $billingContact['Email'],
'p1_autres_contacts_facturation_tel_fixe' => $billingContact['Telephone'],
];
}
protected function getInterruptionContact(ContactSheet $contactSheet): array
{
$data = [];
$interruptionContacts = $contactSheet->getInterruptionContacts();
$types = [
InterruptionContact::BEFORE_SCHEDULE_INTERVENTION => 'p2_interruption_programme_preparation_intervention_numero_contact',
InterruptionContact::D10_BEFORE_SCHEDULE_INTERVENTION => 'p2_interruption_programme_avant_intervention_numero_contact',
InterruptionContact::AFTER_SCHEDULE_INTERVENTION => 'p2_interruption_programme_remise_en_eau_numero_contact',
InterruptionContact::DURING_NOT_SCHEDULE_INTERVENTION => 'p2_interruption_non_programme_des_que_possible_numero_contact',
InterruptionContact::AFTER_NOT_SCHEDULE_INTERVENTION => 'p2_interruption_non_programme_remise_en_eau_numero_contact',
];
foreach ($types as $type => $key) {
$contacts = $interruptionContacts->filter(function (InterruptionContact $contact) use ($type) {
return $contact->getType() === $type;
});
$contactsNumber = $contacts->map(function (InterruptionContact $contact) use ($contactSheet) {
$contacts = $contactSheet->getPriorityContacts()->filter(function (PriorityContact $priorityContact) use ($contact) {
return $priorityContact->getUser()->getId() === $contact->getUser()->getId();
});
$contactPriority = $contacts->count() > 0 ? $contacts->first()->getPriority() : null;
return (null !== $contactPriority) ? static::CONTACT_MAPPING[$contactPriority] : null;
});
$data[$key] = 'N° ' . implode('-', $contactsNumber->toArray());
}
return $data;
}
protected function getPriorityContact(ContactSheet $contactSheet): array
{
$data = [];
foreach ($contactSheet->getPriorityContacts() as $priorityContact) {
$number = static::CONTACT_MAPPING[$priorityContact->getPriority()] ?? null;
$user = $priorityContact->getUser();
$contactInformation = null !== $user ? $user->getContactInformation() : null;
if (null === $number || null === $user || null === $contactInformation) {
break;
}
$priorityContactData = [
'p2_interlocuteur_livraison_N' . $number . '_prenom_et_nom' => $user->getUsername(),
'p2_interlocuteur_livraison_N' . $number . '_fonction' => $contactInformation->getJob(),
'p2_interlocuteur_livraison_N' . $number . '_organisme' => $contactInformation->getOrganization(),
'p2_interlocuteur_livraison_N' . $number . '_Tel_fixe' => $contactInformation->getPhone(),
'p2_interlocuteur_livraison_N' . $number . '_Tel_portable' => $contactInformation->getCellPhone(),
'p2_interlocuteur_livraison_N' . $number . '_email' => $contactInformation->getEmail(),
'p2_interlocuteur_livraison_N' . $number . '_adresse' => $contactInformation->getAddress(),
'p2_interlocuteur_livraison_N' . $number . '_adresse_code_postale' => $contactInformation->getZipCode(),
'p2_interlocuteur_livraison_N' . $number . '_adresse_ville' => $contactInformation->getCity(),
];
$data = array_merge($data, $priorityContactData);
}
return $data;
}
protected function getPathDirectory(): string
{
return $this->exportPath . DIRECTORY_SEPARATOR . 'contact_sheet' . DIRECTORY_SEPARATOR;
}
}