<?php
namespace App\Controller;
use App\Entity\BalanceTransactions;
use App\Entity\Campaign;
use App\Entity\Company;
use App\Entity\Mission;
use App\Entity\Product;
use App\Entity\SubContractorCompany;
use App\Entity\User;
use App\Entity\CreditHistory;
use App\Enum\BillingMethod;
use App\Enum\CommandeLoggingType;
use App\Repository\ProductRepository;
use App\Service\ContractService;
use App\Enum\CompanyContract;
use App\Enum\TypePack;
use App\Enum\ProductType;
use App\Event\Client\NoticeOfInsufficientBudgetEvent;
use App\Event\ClientUpdatedEvent;
use App\Event\CompanyUpdatedEvent;
use App\Event\SubContractor\SubContractorReferencedEvent;
use App\Event\SubContractorUpdatedEvent;
use App\Form\CompanyType;
use App\Form\SubContractorCompanyType;
use App\Form\AddCreditCompanyType;
use App\Repository\BalanceTransactionsRepository;
use App\Repository\CampaignRepository;
use App\Repository\CompanyRepository;
use App\Repository\CreditHistoryRepository;
use App\Repository\ServiceRepository;
use App\Repository\SubContractorCompanyRepository;
use App\Repository\UserRepository;
use App\Service\ClientSoldService;
use App\Service\CompanyService;
use App\Service\MissionService;
use App\Service\ServiceService;
use App\Service\UserService;
use App\Service\CreditService;
use App\Service\EmailService;
use App\Service\MyFlowMarginService;
use App\Service\NumberFormatService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use GuzzleHttp\Client;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use App\Service\PackService;
use App\Service\FrontAPIService;
use App\Service\GoogleStorageService;
use App\Service\SharedResourceCategoryService;
use function PHPUnit\Framework\matches;
use App\Service\DynamicHostService;
use App\Service\PriceService;
use App\Entity\noteCompany;
use App\Enum\Note;
class CompanyController extends AbstractController
{
public function __construct(
private NumberFormatService $numberFormatService,
private CompanyService $companyService,
private FrontAPIService $frontAPIService,
private DynamicHostService $dynamicHostService,
private BalanceTransactionsRepository $balanceTransactionsRepository,
private ContractService $contractService,
private PriceService $priceService,
private SharedResourceCategoryService $sharedResourceCategoryService,
)
{
}
#[Route('/admin/resume/contract/{id}', name: 'contract_resume')]
public function resumeContract(Request $request, string $id, CreditHistoryRepository $creditHistoryRepository, EntityManagerInterface $entityManager, PackService $packService): Response|RedirectResponse
{
$listCampaings = [];
$creditHistory = $creditHistoryRepository->findOneBy(['id' => $id]);
$totalAmountInBalance = 0;
$totalPrice = 0;
$priceCampaing = 0;
if (count($creditHistory?->getCampaigns()) > 0) {
foreach ($creditHistory?->getCampaigns() as $campaign) {
$refMission = "";
$idMission = '';
$priceCampaing += $this->priceService->totalPriceCampaign($campaign);
foreach ($campaign->getMissions() as $mission) {
$idMission = $mission->getId();
$refMission = $mission->getReference();
$balanceTransaction = $this->balanceTransactionsRepository->soldeByMission($creditHistory,$mission);
if (null !== $balanceTransaction) {
$totalAmountInBalance += $balanceTransaction->getAmount();
$totalPrice+= $balanceTransaction->getAmount();
}
}
$listCampaings[$campaign->getId()][] = [
'idCampaing'=>$campaign->getId(),
'nameCampaign' => $campaign->getName(),
'price' => $totalAmountInBalance,
'reference' => $refMission,
'idMission' => $idMission,
'priceCampaing' => $this->priceService->totalPriceCampaign($campaign),
];
$totalAmountInBalance = 0;
}
}
return $this->render(
'company/_resume_contract.html.twig',
[
'campaigns' => $listCampaings,
'creditHistory' => $creditHistory,
'totalPrice' => $priceCampaing,
]
);
}
#[Route('/admin/contract/{id}', name: 'contract_edit')]
public function companyContractEdit(Request $request, string $id, CreditHistoryRepository $creditHistoryRepository, EntityManagerInterface $entityManager, PackService $packService): Response|RedirectResponse
{
$creditHistory = $creditHistoryRepository->findOneBy(['id' => $id]);
$form4 = $this->createForm(AddCreditCompanyType::class, $creditHistory);
$form4->handleRequest($request);
if ($form4->isSubmitted()) {
$nbCredits = $form4->getData()->getCredit();
$typePack = $form4->getData()->getTypePack();
$dateStartContract = $form4->getData()->getStartDateContract();
$endDateContract = $form4->getData()->getendDateContract();
$creditHistory = $entityManager->getRepository(CreditHistory::class)->find($form4->getData()->getId());
$creditHistory->setName($form4->getData()->getName())
->setAutomaticRenewal($form4->getData()->getAutomaticRenewal())
->setStartDateContract($dateStartContract)
->setEndDateContract($endDateContract)
->setOrderedBy($this->getUser());
$entityManager->persist($creditHistory);
$entityManager->flush();
$packService->initialize($creditHistory->getId());
$dataSolde = $packService->getSolde();
$nbSolde = count($dataSolde);
$dateEnd = $dataSolde[$nbSolde]['dateEnd'];
if ($typePack == 0) {
$creditHistory->setCreditExpiredAt($dateEnd);
} else {
$creditHistory->setCreditExpiredAt($dateEnd);
}
//do reflush
$entityManager->flush();
$this->addFlash(
type: 'success',
message: "Contrat modifié avec succès "
);
return new RedirectResponse($this->generateUrl('company_edit', ['id' => $creditHistory->getCompany()->getId()]));
}
return $this->render(
'company/_form_edit_contract.html.twig',
[
'form4' => $form4->createView(),
'company' => $creditHistory->getCompany()
]
);
}
#[Route('/admin/contract/delete/{id}', name: 'contract_delete', methods: ['GET'])]
/**
* @param CreditHistory $creditHistory
* @param EntityManagerInterface $entityManager
*
* @return RedirectResponse
*/
public function companyContractdelete(CreditHistory $creditHistory, EntityManagerInterface $entityManager): RedirectResponse
{
if (in_array("ROLE_ADMIN", $this->getUser()->getRoles())) {
try {
//find facturation individual pack for company
$newPackToReaffect = $entityManager->getRepository(CreditHistory::class)->findOneBy(['company'=>$creditHistory->getCompany(),'typePack'=>4]);
$oldPack = $creditHistory;
//faire une reaffectation de solde
foreach ($creditHistory?->getCampaigns() as $campaign) {
$campaign->setCreditHistory($newPackToReaffect);
$this->contractService->balanceAllocation($campaign, $oldPack,$newPackToReaffect);
}
$creditHistory->setDeleted(true);
$entityManager->persist($creditHistory);
$entityManager->flush();
$this->addFlash(
type: "success",
message: "Contrat supprimé avec succès et la réaffectation a été lancé avec succès"
);
return $this->redirectToRoute('company_edit', ['id' => $creditHistory->getCompany()->getId()], Response::HTTP_SEE_OTHER);
} catch (\Throwable $th) {
$this->addFlash(
type: "error",
message: "Une érreur est survenue lors de la suppréssion de ce contrat"
);
return $this->redirectToRoute('company_index', [], Response::HTTP_SEE_OTHER);
}
}else{
$this->addFlash(
type: "error",
message: "Vous êtes pas autorisé de supprimer ce contract"
);
}
return $this->redirectToRoute('company_index', [], Response::HTTP_SEE_OTHER);
}
/**
* @param CompanyRepository $companyRepository
* @return Response template company/index.html.twig
*/
#[Route('/admin/entreprises', name: 'company_index', methods: ['GET'])]
public function index(CompanyRepository $companyRepository,GoogleStorageService $googleStorageService): Response
{
$company = $this->dynamicHostService->getCompany();
return $this->render('company/index.html.twig', [
'companys' => $companyRepository->findOnlyCompany($company),
]);
}
/**
* @param User|null $user
* @param CreditHistory|null $creditHistory
* @param CreditService $creditService
* @param Company|null $company
* @param Request $request
* @param UserService $userService
* @param UserPasswordEncoderInterface $encoder
* @param UserRepository $userRepository
* @param CreditHistoryRepository $creditHistoryRepository
* @param CampaignRepository $campaignRepository
* @param ParameterBagInterface $parameter
*
* @return Response template company/handle.html.twig
*/
#[Route('/admin/entreprise/ajouter', name: 'company_new', methods: ['GET', 'POST'])]
#[Route('/admin/entreprise/{id}', name: 'company_edit', methods: ['GET', 'POST'])]
#[Route('/my-admin/entreprise/{id}', name: 'my_company_edit', methods: ['GET', 'POST'])]
public function handleCompany(SubContractorCompany $subContractorCompany = null,CompanyService $companyService, MyFlowMarginService $myFlowMarginService, User $user = null, CreditHistory $creditHistory = null, CreditService $creditService, Company $company = null, Request $request, UserService $userService, UserPasswordEncoderInterface $encoder, UserRepository $userRepository, CreditHistoryRepository $creditHistoryRepository, CampaignRepository $campaignRepository, SerializerInterface $serializer, EmailService $emailService, EntityManagerInterface $entityManager, SubContractorCompanyRepository $subContractorCompanyRepository, EventDispatcherInterface $dispatcher, ValidatorInterface $validator, ServiceRepository $serviceRepository, ServiceService $serviceService, ParameterBagInterface $parameter, PackService $packService,GoogleStorageService $googleStorageService): Response
{
$agency = !is_null($request->query->get('type')) ? true : false;
$userConnected = $this->getUser();
$thisCompany = null;
$oldServiceSubcontractor = [];
$creditsHistoryCompany = [];
$modifSubcontractor = (null !== $request->query->get('modifSubcontractor')) and ($request->query->get('modifSubcontractor') == 1) ? 1 : 0;
if (null == $company) {
$company = new Company();
if ($agency) {
$company->setTypeCompany(true)->setCustomerDiscount(0)->setCostOfDiscountedCredit(0);
}
$company->setContract(CompanyContract::CASH->value);
$listClients = null;
$listSubContractors = null;
$listServices = null;
$creditHistory = new CreditHistory();
$allCredit = 0;
$roleSubContractor = 'ROLE_SUBCONTRACTOR';
} else {
$roleCLient = 'ROLE_CLIENT';
$roleCLientAdmin = 'ROLE_CLIENT_ADMIN';
$roleSubContractor = 'ROLE_SUBCONTRACTOR';
$roleManager = 'ROLE_MANAGER';
$thisCompany = $company->getId();
$listClients = $userRepository->findClientByCompany($thisCompany, $roleCLient, $roleCLientAdmin, $roleManager);
$listSubContractors = $subContractorCompanyRepository->findBy(['company' => $company]);
// $listServices = $serviceRepository->findServiceByUser($thisCompany);
$creditAvailable = $creditService->CreditAvailable($company);
$allCredit = 0;
foreach ($creditAvailable as $credit) {
$allCredit += $credit->getCredit();
}
$creditsHistoryCompany = $creditHistoryRepository->findByCompanyWithDeletedState($company, false);
$campainsHistory = $campaignRepository->findBy(['company' => $company]);
$sorted = [];
foreach ($creditsHistoryCompany as $creditHistoryCompany) {
$date = $creditHistoryCompany->getCreatedAt()->format('YmdHis');
$sorted[$date] = $creditHistoryCompany;
}
foreach ($campainsHistory as $campainHistory) {
$date = $campainHistory->getCreatedAt()->format('YmdHis');
$sorted[$date] = $campainHistory;
}
foreach ($company->getCommandeLoggings() as $commandeLogging) {
$date = $commandeLogging->getCreatedAt()->format('YmdHis');
$sorted[$date] = $commandeLogging;
}
ksort($sorted);
$sorted = array_reverse($sorted);
}
/**
* Form for add company
*/
//$isAdmin = in_array('ROLE_ADMIN',$userConnected->getRoles()) ? true : false;
$form = $this->createForm(CompanyType::class, $company,['admin' => $this->isGranted('ROLE_ADMIN'),'clientAdmin'=>$this->isGranted('ROLE_CLIENT_ADMIN'),'selectedCompany'=>$thisCompany]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$dataInMapped = $request->request->all();
$note = $dataInMapped['note_company']['content'] ?? null;
if (!is_null($note) and !empty($note)) {
$newNote = new noteCompany();
$newNote->setContent($note);
$newNote->setCreatedAt(new \DateTime());
$newNote->setType(Note::NOTE_PRIVATE->value);
$newNote->setUserToCommented($this->getUser());
$entityManager->persist($newNote);
$entityManager->flush();
$company->addNoteCompany($newNote);
}
if ($request->get('_route') === 'company_new') {
$company->setCreatedAt(new \DateTime());
$company->setLogoFile($form->get('logoFile')->getData());
$creditHistory = new CreditHistory();
$creditHistory->setCompany($company)
->setName("Facturation individuelle")
->setTypePack(TypePack::CASH->value)
->setOrderedBy($this->getUser())
->setIdentifier($creditService->getNewReference())
;
$entityManager->persist($company);
$entityManager->persist($creditHistory);
//si gestionnaire alors liées directement le gestinnaire a l'entreprise
if (in_array("ROLE_MANAGER", $userConnected->getRoles())) {
//ajouter l'entreprise au gestinnaire qui le créent
$userConnected->addOtherCompany($company);
$entityManager->persist($userConnected);
$entityManager->flush();
}
$this->sharedResourceCategoryService->setDefaultSharedResourceCategory($company);
$this->addFlash('success', 'L\'entreprise a bien été ajoutée');
//ajouter parent si agence
$companyParent = $this->dynamicHostService->getCompany();
if (null !== $companyParent) {
$company->setParent($companyParent);
}
//fin ajout
} else {
$company->setLogoFile($form->get('logoFile')->getData());
$company->setUpdatedAt(new \DateTime());
$this->addFlash('success', 'L\'entreprise a bien été modifiée');
}
if (!empty($form->getData()->getExtensionDomain())) {
$extensions = $form->getData()->getExtensionDomain();
if ($this->checkString($extensions)) {
$company->setExtensionDomain($extensions);
} else {
$this->addFlash('error', 'Les formats des extensions de domaine associés ne sont pas valides');
}
}
$entityManager->flush();
// dispatch the company.update event
$company->setLogoFile(null);
$event = new CompanyUpdatedEvent($company);
$dispatcher->dispatch($event, CompanyUpdatedEvent::NAME);
if($this->isGranted("ROLE_ADMIN")){
// return $this->redirectToRoute('company_index', [], Response::HTTP_SEE_OTHER);
if ($request->get('_route') === 'company_new'){
return $this->redirectToRoute('company_index', [], Response::HTTP_SEE_OTHER);
}
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}else{
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
}
/**
* Form for add subContractor that does not exist to company
*/
$form2 = $this->createForm(SubContractorCompanyType::class, $user);
$form2->handleRequest($request);
$allSubContractorsEmails = $userRepository->findByRole($roleSubContractor);
if ($form2->isSubmitted() && $form2->isValid()) {
$isAlreadyExist = false;
$oldServiceSubcontractor = [];
$oldJobSubcontractor = [];
$email = $request->request->get('emailSubContractor');
$modifSubcontractor = $request->request->get('modification_subcontractor');
if ($validator->validate($email, [new Email()])->count() > 0) {
$this->addFlash('error', 'L\'adresse ' . $email . ' n\'est pas valide. Nous vous invitons à vérifier votre saisie');
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
$checkEmail = $userRepository->findOneBy(['email' => $email]);
$subContractorCompany = new SubContractorCompany();
$separateEmail = explode(" ", $email);
$email = $separateEmail[0];
if (empty($checkEmail)) {
$user = new User();
$password = $userService->generatePassword();
$encodedPassword = $encoder->encodePassword($user, $password);
$user->setPassword($encodedPassword);
$user->setEmail($email);
$user->setRoles([$roleSubContractor]);
$user->setEnabled(false);
} else {
$user = $userRepository->findOneBy(['email' => $email]);
//Si pas vide vérifié si l'utilisateur éxiste déja sur d'autre agence ou sur MyFlow
if (null != $user->getCompany()) {
$isAlreadyExist = true;
//alors creez un utilisateur enfant parceque l'utilisateur est dans un autre entreprise
//create new user
$userGenerate = new User;//for just generate the id automaticly
$userChild = clone $user;
$emailUniq = uniqid().$user->getEmail();
$userChild->setId($userGenerate->getId())->setEmail($emailUniq)->setEnabled($user->getEnabled())->setNewAdd(false)->setParent($user)->setPassword($user->getPassword())->setOriginalEmail($user->getEmail())->setCompany(null);
$user->addChild($userChild);
$entityManager->persist($user);
$user = $userChild;
//need to add user in child
}
}
$subconctractors = $subContractorCompanyRepository->findBy(['user'=>$user,'company' => $company]);
if ($modifSubcontractor == 1) {
foreach ($user->getSubContractorCompanies() as $subCompany) {
if($company == $subCompany->getCompany())
$subContractorCompany = $subCompany;
}
}
//get all old product of subcontractor // no need to control perte if product already link
foreach ($subconctractors as $sub) {
foreach ($sub->getProducts() as $product) {
$oldServiceSubcontractor[] = $product->getId();
}
}
if ($request->query->get('perte') == null) {
$listServicesForSubcontractor = $serviceRepository->findBy(['user' => $checkEmail]);
$allJob = [];
$allProduct = [];
foreach ($form2->getData()->getJobs() as $jobName) {
$nameJob = $jobName->getId();
$allJob[] =$jobName->getId();
}
foreach ($form2->getData()->getProducts() as $productName) {
$allProduct[] = $productName->getId();
}
if (!empty($user->getResaleRate() || empty($checkEmail)) && (!$isAlreadyExist)) {
$flag = false;
foreach ($form2->getData()->getProducts() as $productName) {
$name = $productName->getId();
foreach ($listServicesForSubcontractor as $service) {
if ($service->getProduct()->getId() === $name) {
$flag = true;
}
}
if ($flag !== true and !$isAlreadyExist) {
$this->addFlash('error', 'Veuillez ajouter le produit et le prix pratique par ce partenaire au niveau de sa fiche.');
return $this->redirectToRoute('company_edit', ['id' => $company->getId(),'modifSubcontractor' => $modifSubcontractor], Response::HTTP_SEE_OTHER);
}
foreach ($listServicesForSubcontractor as $service) {
if ($user->isEnabled()) {
if ($service->getProduct()->getId() === $name and !in_array($service->getProduct()->getId(),$oldServiceSubcontractor)) {
if ($service->getProduct()->getType() === ProductType::AU_FORFAIT) {
$currentMarge = $this->numberFormatService->format($myFlowMarginService->getMarge($service, $company));
}else{
$currentMarge = $this->numberFormatService->format($myFlowMarginService->getMargeTJM($user));
}
$service->getProduct()->getName();
$fullName = $user->getFullName();
if ($currentMarge < 30) {
$this->addFlash(
"error",
"En ajoutant $fullName pour le service $productName, le total de marge pour le(s) sous-traitant(s) est de $currentMarge %");
return $this->redirectToRoute('company_edit', ['id' => $company->getId(), 'perte' => $currentMarge, 'email' => $email, 'product' => implode(",", $allProduct), 'job' => implode(",", $allJob),'modifSubcontractor' => $modifSubcontractor ], Response::HTTP_SEE_OTHER);
}
}
} else {
$this->addFlash('error', 'Ce partenaire a un profil incomplet, nous vous invitons à vous rendre sur sa fiche pour compléter son profil et l’activer');
return $this->redirectToRoute('company_edit', ['id' => $company->getId(),'modifSubcontractor' => $modifSubcontractor], Response::HTTP_SEE_OTHER);
}
}
}
} else {
$this->addFlash('error', 'Le tarif revente doit obligatoirement être renseigné. Nous vous invitons à vous rendre sur la fiche du partenaire pour compléter son profil.');
return $this->redirectToRoute('company_edit', ['id' => $company->getId(),'modifSubcontractor' => $modifSubcontractor], Response::HTTP_SEE_OTHER);
}
}
$verifyEmailSend = $subContractorCompanyRepository->findBy(['user' => $user, 'company' => $company]);
$flagSend = false;
foreach ($verifyEmailSend as $verify) {
if ($verify->getEmailSend() == true) {
$flagSend = true;
}
}
//delte product/job before add in modification
if ($modifSubcontractor == 1) {
foreach ($subContractorCompany->getJobs() as $jobs) {
$subContractorCompany->removeJob($jobs);
}
foreach ($subContractorCompany->getProducts() as $product) {
$subContractorCompany->removeProduct($product);
}
}
foreach ($form2->getData()->getJobs() as $job) {
$subContractorCompany->addJob($job);
}
foreach ($form2->getData()->getProducts() as $product) {
$subContractorCompany->addProduct($product);
}
$subContractorCompany->setCompany($company)
->setUser($user)
->setEmailSend(true);
if ($modifSubcontractor == 0) {
$user->addSubContractorCompany($subContractorCompany);
}
if (!empty($listSubContractors)) {
$newListOfSubcontractor = [];
//if modification , don't take a subcontractor in test
if ($modifSubcontractor == 1 ) {
foreach ($listSubContractors as $subContractor) {
if ($subContractor->getUser()->getId() != $user->getId()) {
$newListOfSubcontractor[] = $subContractor;
}
}
}else{
$newListOfSubcontractor = $listSubContractors;
}
//verify if subcontractor is already linked job and product
foreach ($form2->getData()->getJobs() as $job) {
foreach ($newListOfSubcontractor as $subContractor) {
foreach ($subContractor->getJobs() as $jobSubcontractor) {
if ($jobSubcontractor === $job ) {
$alreadyLinkJob = true;
//after job is already linked verify is already link a product
foreach ($subContractor->getProducts() as $product) {
foreach ($form2->getData()->getProducts() as $productInForm ) {
if ($productInForm === $product) {
$this->addFlash('error', 'Un sous traitant est déjà associé à cette entreprise pour ce produit et ce metier. Nous vous invitons à retirer le partenaire actuel avant d\'en ajouter un nouveau');
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
}
}
}
}
}
}
$entityManager->persist($user);
//if ($modifSubcontractor == 0) {
$entityManager->persist($subContractorCompany);
//}
$entityManager->flush();
} else {
$entityManager->persist($user);
//if ($modifSubcontractor == 0) {
$entityManager->persist($subContractorCompany);
//}
$entityManager->flush();
}
//$this->companyService->syncSubcontractorsForAllMissions(subContractorCompany : $subContractorCompany);
$event = true;
foreach ($user->getServices() as $service) {
if (empty($service->getResale())) {
$event = false;
}
}
if ($event && $flagSend == false) {
$event = new SubContractorReferencedEvent($user);
$dispatcher->dispatch($event, SubContractorReferencedEvent::NAME);
}
// dispatch the subonctractor.updated event
$event = new SubContractorUpdatedEvent($user, empty($checkEmail));
$dispatcher->dispatch($event, SubContractorUpdatedEvent::NAME);
if ($modifSubcontractor == 1) {
$this->addFlash('success', 'L\'utilisateur a bien été modifié');
}else{
$this->addFlash('success', 'L\'utilisateur a bien été ajouté');
}
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
/**
* Add credit for company
*/
$creditHistory = new CreditHistory();
$form4 = $this->createForm(AddCreditCompanyType::class, $creditHistory);
$form4->handleRequest($request);
if ($form4->isSubmitted() && $form4->isValid()) {
$nbCredits = $form4->getData()->getCredit();
$typePack = $form4->getData()->getTypePack();
//dd($form4->getData()->getStartDateContract());
$dateStartContract = $form4->getData()->getStartDateContract();
if ($typePack == 0) {
$dateStartContractModified = clone $dateStartContract;
$endDateContract = $dateStartContractModified;
} else {
$endDateContract = $form4->getData()->getendDateContract();
}
$orderPrice = match ($typePack) {
'0' => $nbCredits,
'1' => $form4->getData()->getMensualite(),
'2' => $form4->getData()->getAnnuite(),
//if conctract is fin de mois, we set as a annuite
'3' => 0,
};
$cost = 0;
if ($typePack == 0) {
$cost = $company->getCostOfDiscountedCredit() * $nbCredits;
} else {
$cost = $orderPrice;
}
$creditHistory->setCompany($company)
->setCredit($nbCredits)
->setName($form4->getData()->getName())
->setTypePack($typePack)
->setAnnuite($form4->getData()->getAnnuite())
->setMensualite($form4->getData()->getMensualite())
->setReport($form4->getData()->getReport())
->setCurrentBalance($orderPrice)
->setOrderPrice($orderPrice)
->setAutomaticRenewal($form4->getData()->getAutomaticRenewal())
->setStartDateContract($dateStartContract)
->setEndDateContract($endDateContract)
->setCost($cost)
->setIdentifier($creditService->getNewReference())
->setAvailabilityDuration($form4->getData()->getAvailabilityDuration())
->setOrderedBy($this->getUser());
$balanceTransaction = new BalanceTransactions();
$balanceTransaction->setName("Initialisation solde contrat type $typePack")
->setType('credit')
->setOrderBy($this->getUser())
->setCreditHistory($creditHistory)
->setAmount($creditHistory->getCurrentBalance())
->setCurrentBalance($creditHistory->getCurrentBalance());
$entityManager->persist($company);
$entityManager->persist($balanceTransaction);
$entityManager->persist($creditHistory);
$entityManager->flush();
$packService->initialize($creditHistory->getId());
$dataSolde = $packService->getSolde();
$nbSolde = count($dataSolde);
$dateEnd = $dataSolde[$nbSolde]['dateEnd'];
if ($typePack == 0) {
$creditHistory->setCreditExpiredAt($dateEnd)->setEndDateContract($dateStartContractModified);
} else {
$creditHistory->setCreditExpiredAt($dateEnd);
}
//do reflush
$entityManager->flush();
$this->addFlash(
type: 'success',
message: "La campagne reprend avec succès ",
);
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
$clients = $userRepository->findBy([], ['email' => 'ASC']);
$mailClientToCommand = "";
if ($thisCompany != null) {
$clientListForOrderAs = $userRepository->findClientByCompany($thisCompany, $roleCLient, $roleCLientAdmin);
}
if (!empty($clientListForOrderAs)) {
foreach ($clientListForOrderAs as $client) {
if (($client->isEnabled())) {
$mailClientToCommand = $client->getEmail();
break;
}
}
}
$orderAsLink = !empty($mailClientToCommand) ? $parameter->get('url_redirect_to_front') . '?tsso=' . hash('sha256', $mailClientToCommand . $mailClientToCommand) : null;
//data in modal company ---------------------------------------------------------------
$allCampaign = $campaignRepository->findAllCampaingByCompany($company);
$listOfFilesByDate = [];
$dataSummaryByDate = [];
$nameOfBucket = "company-".strtolower($company->getId());
foreach ($allCampaign as $campaign) {
foreach ($campaign->getMessages() as $message) {
foreach ($message->getFileMessages() as $file) {
if ($file->isIsNew()) {
$year = $message->getCreatedAt()->format('Y');
$month = $message->getCreatedAt()->format('m');
$listOfFilesByDate["{$year}-{$month}"][] = "Campaigns/{$campaign->getId()}/{$file->getName()}";
}
}
}
foreach ($campaign->getFileMissions() as $file) {
if ($file->isIsNew()) {
$year = $file->getCreatedAt()->format('Y');
$month = $file->getCreatedAt()->format('m');
$listOfFilesByDate["{$year}-{$month}"][] = "Campaigns/{$campaign->getId()}/{$file->getName()}";
}
}
}
//prendre toutes les tailles selon le mois et l'années
foreach ($listOfFilesByDate as $key => $list) {
$size = $googleStorageService->sizeOfBucketByFile($nameOfBucket,$list);
$dataSummaryByDate[$key] = $size;
krsort($dataSummaryByDate);
}
return $this->renderForm('company/handle.html.twig', [
'isAgency' => $this->dynamicHostService->isAgency(),
'hideInfoifIsAgency' => $agency ? "style=display:none" : "",
'form' => $form,
'form2' => $form2,
'dataSummaryStorage' => $dataSummaryByDate,
'modifSubcontractor' => $modifSubcontractor,
'form4' => $form4,
'company' => $company,
'listClients' => $listClients,
'listSubContractors' => $listSubContractors,
'listServices' => $listServices ?? [],
'allCredit' => $allCredit,
'creditHistories' => $creditsHistoryCompany,
'clients' => $serializer->serialize($clients, 'json', [AbstractNormalizer::ATTRIBUTES => ['email']]),
'sorted' => $sorted ?? [],
'allSubContractorsEmails' => $serializer->serialize($allSubContractorsEmails, 'json', [AbstractNormalizer::ATTRIBUTES => ['email']]),
'orderAsLink' => $orderAsLink,
'clientsList' => $userRepository->findBy(['company'=>$company, 'deleted'=>false, 'enabled'=>true]),
'avalaiblecreditHistories' => $companyService->getAvailableContract($creditHistoryRepository->findAvailableServiceHistory($company, new \DateTime()), true)
]);
}
/**
* @param Request $request
* @param UserRepository $userRepository
* @param CompanyRepository $companyRepository
* @param EmailService $emailService
* @param EntityManagerInterface $entityManager
* @param UserService $userService
* @param UserPasswordEncoderInterface $encoder
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
#[Route('/admin/client-company/ajouter', name: 'company_add_client', methods: ['GET', 'POST'])]
public function addClientCompany(Request $request, UserRepository $userRepository, CompanyRepository $companyRepository, EntityManagerInterface $entityManager, UserService $userService, UserPasswordHasherInterface $passwordHasher, EventDispatcherInterface $dispatcher, ValidatorInterface $validator)
{
/**
* We get the user and the company in the query and then register them
*/
$email = str_replace(" ", "+", $request->query->get('email'));
$email = explode("+", $email)[0];
$agency = !is_null($request->query->get('agency')) ? true : false;
$isAgencyModification = $this->dynamicHostService->isAgency();
$user = $userRepository->findOneBy(['email' => $email]);
$company = $companyRepository->findOneBy(['id' => $request->query->get('company')]);
// check if a email is already in company,
//$company = !$isAgencyModification ? null : $company;
$isCompanyAgency = $this->dynamicHostService->isAgencyByCompany($company);
//test if same user already exist in myflow or agency / dont repeat secondly
$userExist = $userRepository->getUniqUserByCompanyByEmail($email,$company);
if (!is_null($userExist)) {
$this->addFlash('error', "Cette adresse email existe déjà dans la liste");
if ($agency) {
return $this->redirectToRoute('agency_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
//end test
$users = $company->getUsers();
$userExist = false;
if (!empty($user)) {
//create new user
$userGenerate = new User;//for just generate the id automaticly
$userChild = clone $user;
$emailUniq = uniqid().$user->getEmail();
$token = hash('sha256', uniqid(preg_replace('/\s/','-',$userChild->getFullName())));
$userChild->setId($userGenerate->getId())->setEmail($emailUniq)->setEnabled($user->getEnabled())->setNewAdd(false)->setParent($user)->setPassword($user->getPassword())->setOriginalEmail($user->getEmail())->setCompany($company)->setOneTimeLoginToken($token);
//need to add user in child
$userChild->setRoles(['ROLE_CLIENT']);
if ($isCompanyAgency and in_array("ROLE_ADMIN", $this->getUser()->getRoles()) ) {
$userChild->setRoles(['ROLE_ADMIN_AGENCY']);
}
$user->addChild($userChild);
$entityManager->persist($user);
$userExist = true;
} else {
$user = new User();
$password = $userService->generatePassword();
$encodedPassword = $passwordHasher->hashPassword($user, $password);
$user->setPassword($encodedPassword);
$user->setEmail($email);
$user->setRoles(['ROLE_CLIENT']);
if ($isCompanyAgency and in_array("ROLE_ADMIN", $this->getUser()->getRoles())) {
$user->setRoles(['ROLE_ADMIN_AGENCY']);
}
$user->setEnabled(false);
$user->setCompany($company);
}
if ($validator->validate($email, [new Email()])->count() > 0) {
$this->addFlash('error', 'L\'adresse ' . $email . ' n\'est pas valide. Nous vous invitons à vérifier votre saisie');
if ($agency) {
return $this->redirectToRoute('agency_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
} else {
$entityManager->persist($user);
$entityManager->flush();
if ($isCompanyAgency) {
$this->addFlash('success', "L'administrateur à bien été ajouté");
}else{
$this->addFlash('success', "Le client à bien été ajouté");
}
if (!$userExist) {
$event = new ClientUpdatedEvent($user, true);
$dispatcher->dispatch($event, ClientUpdatedEvent::NAME);
}
}
if ($agency) {
return $this->redirectToRoute('agency_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
/**
* @param Request $request
* @param UserRepository $userRepository
* @param CompanyRepository $companyRepository
* @param EmailService $emailService
* @param EntityManagerInterface $entityManager
* @param UserService $userService
* @param UserPasswordEncoderInterface $encoder
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
#[Route('/admin/subcontractor-company/ajouter', name: 'company_add_subcontractor', methods: ['GET', 'POST'])]
public function addSubContractorCompany(Request $request, SubContractorCompany $subContractorCompany = null, UserRepository $userRepository, CompanyRepository $companyRepository, EmailService $emailService, EntityManagerInterface $entityManager, UserService $userService, UserPasswordEncoderInterface $encoder)
{
/**
* We get the subContractor and the company in the query and then register them
*/
$subContractorCompany = new SubContractorCompany();
$user = $userRepository->findOneBy(['email' => $request->query->get('email')]);
$company = $companyRepository->findOneBy(['id' => $request->query->get('company')]);
$subContractorCompany->setCompany($company)
->setUser($user);
$subContractorCompany->addJob();
$subContractorCompany->addProduct();
$user->setRoles(['ROLE_SUBCONTRACTOR']);
$entityManager->persist($user);
$entityManager->persist($subContractorCompany);
$entityManager->flush();
$this->addFlash('success', 'Le sous-traitant à bien été ajouté');
return $this->redirectToRoute('company_edit', ['id' => $company->getId()], Response::HTTP_SEE_OTHER);
}
#[Route('/admin/entreprise/delete/{id}', name: 'company_delete', methods: ['GET'])]
public function deleteCompany(Company $company,EventDispatcherInterface $dispatcher, SubContractorCompanyRepository $subContractorCompanyRepository, UserRepository $userRepository, EntityManagerInterface $entityManager){
if($this->isGranted("ROLE_ADMIN")){
$users= $userRepository->findBy(['company'=>$company]);
$subcontractorsCompany = $subContractorCompanyRepository->findBy(['company'=>$company]);
foreach ($users as $user) {
$user->setCompany(null);
$user->setDeleted(true);
$entityManager->flush();
$this->frontAPIService->pushClientToFront($user, $user->getPassword());
}
foreach ( $subcontractorsCompany as $subcontractorCompany) {
$user= $subcontractorCompany->getUser();
$event = new SubContractorUpdatedEvent($user);
$dispatcher->dispatch($event, SubContractorUpdatedEvent::NAME);
$entityManager->remove($subcontractorCompany);
$entityManager->flush();
}
$company->setDeleted(true);
$entityManager->flush();
}else{
$this->addFlash("error", "Impossible de supprimer l'entreprise");
}
$this->addFlash("success", "Entreprise supprimée avec succès");
return$this->redirectToRoute('company_index', [], Response::HTTP_SEE_OTHER);
}
#[Route('/admin/entreprise/command/add/{id}', name: 'add_command_company', methods: ['POST'])]
public function addCommand(Company $company,UserRepository $userRepository,EventDispatcherInterface $dispatcher, Request $request,ClientSoldService $clientSoldService,EntityManagerInterface $em,BalanceTransactionsRepository $balanceTransactionsRepository, CreditHistoryRepository $creditHistoryRepository, ProductRepository $productRepository, MissionService $missionService ){
$creditHistory = $creditHistoryRepository->findOneBy(['id'=>$request->request->get('creditHistory')]);
$amount = $amountCredit = floatval($request->request->get('amount'));
$description = $request->request->get('description');
$orderById =$request->request->get('orderedBy', null) ;
$orderBy = $orderById != null ? $userRepository->findOneBy(['id'=> $orderById]) : $this->getUser();
$individualBilling = null;
if($creditHistory->getTypePack() == TypePack::CREDIT->value ){
$amountCredit /= $creditHistory->getCost()/$creditHistory->getCredit() ;
}
if(in_array($creditHistory->getTypePack(), [TypePack::CASH, TypePack::FACTURATION_FIN_DU_MOIS])){
$newCurrentBalance = $creditHistory->getCurrentBalance() + $amountCredit;
}else{
$newCurrentBalance = $creditHistory->getCurrentBalance() - $amountCredit;
}
if ($newCurrentBalance < 0) {
$individualBilling = $amountCredit - $creditHistory->getCurrentBalance();
$event = new NoticeOfInsufficientBudgetEvent($company,null, null, [ $orderBy ]);
$dispatcher->dispatch($event, NoticeOfInsufficientBudgetEvent::NAME);
}
$creditHistory->setCurrentBalance($newCurrentBalance);
$product = $productRepository->findOneBy(['name'=>'autre commande']);
$referenceMission = $missionService->generateReference($this->getUser()) ;
if( $product === null ){
$product = new Product();
$product->setName('autre commande');
$product ->setDeleted(true);
$product->setType(ProductType::AU_TEMPS_PASSE);
$product ->setTemplate(false);
;
}
$mission = new Mission();
$mission->setPriceSale($amount);
$mission->setReference($referenceMission);
$mission->setQuantity(1);
$mission->setProduct($product);
$mission->setState('finalized');
;
$campaign = new Campaign();
$campaign->setState('closed');
$campaign->setBrief('Autre commande');
$campaign->setName('Autre commande');
$campaign->setCreditHistory($creditHistory);
$campaign->setIsToBeinvoiced(true);
$campaign->setCompany($creditHistory->getCompany());
$campaign->setOrderedBy($this->getUser());
$campaign->setTypeInitiation(1);
$campaign->addMission($mission);
;
$em->persist($product);
$em->persist($mission);
$em->persist($campaign);
$em->flush();
$clientSoldService->addbanlanceTransation(
creditHistory:$creditHistory,
name: $description,
type: 'debit',
amount: $amountCredit,
currentBalance: $creditHistory->getCurrentBalance(),
individualBilling: $individualBilling,
mission: $mission,
otherCommand: null,
orderBy: $orderBy
);
$this->addFlash('success', 'Commande enregistrée avec succès');
$clientSoldService->addCommandeLogging(company: $company,detail: [
'name'=> 'Autre commande',
'description'=> $description,
'type'=> CommandeLoggingType::ADDITIONAL_DEBIT->value,
'amount' => $amountCredit,
'typePack' =>$creditHistory->getTypePack(),
'user'=>$orderBy,
'creditHistory' => $creditHistory
]);
$clientSoldService->updateTotalConsumptionCreditHistory($creditHistory);
return $this->redirectToRoute('company_edit',[
'id'=>$company->getId()
]);
}
#[Route('/admin/entreprise/toggle-role/{id}', name: 'toogleRole', methods: ['POST'])]
public function toogleRole(Request $request, User $user, EntityManagerInterface $entityManager){
$user->setRoles([$request->request->get('role')]);
$entityManager->flush();
return new JsonResponse([
'status'=>'ok'
]) ;
}
private function checkString($input) {
$parts = array_map('trim', explode(',', $input));
foreach ($parts as $part) {
if (empty($part) || strpos($part, ' ') !== false) {
return false;
}
}
return !empty($parts) ? true : false;
}
#[Route('/note-company-modified/{id}', name: 'note_company_modified', methods: ['GET','POST'])]
public function noteModificationCompany(noteCompany $note, Request $request,EntityManagerInterface $entityManager): Response
{
$content = $request->request->get('info_mission_edit')['content'];
if (!is_null($content) and !empty($content)) {
$note->setContent($content);
$entityManager->persist($note);
$entityManager->flush();
}
$this->addFlash(
type: 'success',
message: 'Modification effectuée'
);
return $this->redirect($request->headers->get('referer'));
}
#[Route('/note-company-deleted/{id}', name: 'note_company_deleted', methods: ['GET','POST'])]
public function noteDeletedCompany(noteCompany $note, Request $request,EntityManagerInterface $entityManager): Response
{
$entityManager->remove($note);
$entityManager->flush();
$this->addFlash(
type: 'success',
message: 'Suppression effectuée'
);
return $this->redirect($request->headers->get('referer'));
}
}