<?php
namespace App\Controller;
use App\Entity\DeclarationAnnuelle;
use App\Entity\Ecriture;
use App\Entity\Immeuble;
use App\Entity\Local;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\Entity;
use League\Csv\Info;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use League\Csv\Reader;
use League\Csv\Statement;
use League\Csv\Writer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Constraints\Json;
class MainController extends AbstractController
{
#[Route('/', name: 'app_main')]
public function index(): Response
{
return $this->render('main/index.html.twig', [
'controller_name' => 'MainController',
]);
}
#[Route('/api/uploads/{type}', name: 'uploads')]
public function uploads(Request $request, $type)
{
$files = $request->files->get($type);
$userId = $this->getUser()->getId();
$filesOut = [];
/** @var \Symfony\Component\HttpFoundation\File\File $file */
foreach($files as $file) {
$ext = $file->getClientOriginalExtension();
$name = uuid_create() . '.' . $ext;
$file = $file->move('uploads/docs/' . $userId . '/' . $type , $name );
$filesOut[] = 'uploads/docs/' . $userId . '/' . $type . '/' . $name ;
}
return new JsonResponse($filesOut);
}
#[Route('/api/ecritures/preview', name: 'previewecriture')]
public function previewEcriture(Request $request, SerializerInterface $serializer)
{
$obj = $serializer->deserialize($request->getContent(), Ecriture::class, 'json');
$obj->setId(999999);
$response = new Response($serializer->serialize($obj, 'json'));
$response->headers->set('Content-type', 'application/json');
return $response;
}
#[Route('/api/declaration_annuelles_getcurrent', name: 'annuelle_current')]
public function getCurrentDeclaration(Request $request, SerializerInterface $serializer, EntityManagerInterface $manager)
{
$user = $manager->find(User::class, $request->query->get('user_id'));
$declaration = $manager->getRepository(DeclarationAnnuelle::class)->findOneBy(['annee' => date('Y'), 'user' => $user]);
if (!$declaration) {
$declaration = new DeclarationAnnuelle();
$declaration->setUser($user);
$manager->persist($declaration);
$manager->flush();
}
$response = new Response($serializer->serialize($declaration, 'json'));
$response->headers->set('Content-type', 'application/json');
return $response;
}
#[Route('/api/ecritures/compare', name: 'compareecriture')]
public function compareEcriture(Request $request, EntityManagerInterface $manager)
{
$data = ['find' => false];
$datas = json_decode($request->getContent(),true);
$dateEffectif = date_create_from_format('Y/m/d', $datas['dateEffectif']);
$find = $manager->getRepository(Ecriture::class)->compare([
'dateEffectif' => $dateEffectif,
'user' => $datas['user'],
'montant' => $datas['montant']
]);
$data['find'] = !!$find;
return new JsonResponse($data);
}
#[Route('/api/downloads_profil/{user}', name: 'downloads_profil')]
public function downloadProfil($user, Request $request, EntityManagerInterface $manager)
{
// TODO : finir
$user = $manager->find(User::class, $user);
$file = uniqid() . '-' . $user->getId();
$fullpath= 'cache/'.$file.'.zip';
touch($fullpath);
$data['link'] = '/'.$fullpath;
return new JsonResponse($data);
}
private function detectCsvProvider($data) {
if (strpos($data[0][0], 'Téléchargement du ') > -1) return 'CA';
}
private function handleProviderCA($data, &$step) {
$lineToSkip = 10;
$headers = [
'Date', 'Libellé', 'Débit euros', 'Crédit euros'
];
$labelToKeep = 1;
// On prend la deuxième ligne en libelle
$data = array_slice($data, 10);
$data = array_map(function($item) {
$date = date_create_from_format('d/m/Y', $item[0]);
$item[2] = str_replace([' ', ' '], '', $item[2]);
$item[3] = str_replace([' ', ' '], '', $item[3]);
$item[2] = str_replace([','], '.', $item[2]);
$item[3] = str_replace([','], '.', $item[3]);
$montant = ($item[2]) ? floatval($item[2]) * -1 : floatval($item[3]) ;
$libelle = $item[1];
$libelle = explode("\n", $libelle);
if (count($libelle) > 1) {
$libelle = $libelle[1];
} else {
$libelle = implode(' ', $libelle);
}
$findFournisseurs = [];
// TODO : finir
return [
'nom' => trim($libelle),
'montant' => $montant,
'description' => $item[1],
'dateReglement' => $date->format('Y/m/d'),
'dateEffectif' => $date->format('Y/m/d'),
'hasReglement' => true,
'rapprochement' => $findFournisseurs,
'id' => null
];
}, $data);
return [
'step' => $step,
'steps' => count($data),
'output' => $data
];
}
#[Route('/api/launch_wizard', name: 'launch_wizard')]
public function launchWizard(Request $request, EntityManagerInterface $manager)
{
$file = $request->query->get('file');
$reader = Reader::createFromPath($file, 'r');
$resultDelimiter = Info::getDelimiterStats($reader, [',', ';'], 1);
$delimiter = array_search(max($resultDelimiter), $resultDelimiter) ;
$reader->setDelimiter($delimiter);
$results = $reader->getRecords();
$results = iterator_to_array($results, true);
$provider = $this->detectCsvProvider($results);
$callable = 'handleProvider' . $provider;
$step= 1;
if (!is_callable([$this, $callable])) {
return new JsonResponse(['error' => 'Prestataire bancaire pas encore implémenté']);
}
$data = [];
$data = $this->$callable($results, $step);
return new JsonResponse($data);
}
#[Route('/api/ecritures/bulk_edit', name: 'bulk')]
public function bulkEdit(Request $request, EntityManagerInterface $manager)
{
$datas = json_decode($request->getContent(),true);
foreach ($datas['ids'] as $id) {
$reference = $manager->find(Ecriture::class, $id);
if ($request->query->get('type') == 'blockAt') {
$reference->setBlockAt(new \DateTimeImmutable());
$manager->persist($reference);
}
if ($request->query->get('type') == 'archivedAt') {
$reference->setArchivedAt(new \DateTimeImmutable());
$manager->persist($reference);
}
if ($request->query->get('type') == 'delete') {
$manager->remove($reference);
}
$manager->flush();
}
return new JsonResponse(['action' => true]);
}
#[Route('/api/search', name: 'search')]
public function search(Request $request, EntityManagerInterface $entityManager)
{
/** @var mixed[] $data */
$data = [];
// local
// immeuble
// user ==> si comptable
// employés si comptable et ROLE ADMIN
// cabinet ==> psa besoin, un comptable n'a normalement qu'un seul cabinet
/** @var User $user */
$user = $this->getUser();
// todo: chercher pour les clientx normaux
if ($user->getType() != "compta") die();
/** @var \App\Entity\Cabinet $cabinet */
$cabinet = $user->getCabinet();
$search = $request->query->get('q');
/** @var \App\Repository\UserRepository $userRepository */
$userRepository = $entityManager->getRepository(User::class);
if ($this->isGranted('ROLE_GESTION_COMPTABLE')) {
$data['employes'] = $userRepository->findEmployeByCabinet($search, $cabinet->getId(), $this->isGranted('ROLE_GESTION_COMPTABLE'));
}
$data['clients'] = $userRepository->findClientByCabinet($search, $cabinet->getId(), $this->isGranted('ROLE_GESTION_COMPTABLE'));
$data['immeubles'] = $entityManager->getRepository(Immeuble::class)->findByCabinet($search, $cabinet->getId(), $this->isGranted('ROLE_GESTION_COMPTABLE'));
$data['locaux'] = $entityManager->getRepository(Local::class)->findByCabinet($search, $cabinet->getId(), $this->isGranted('ROLE_GESTION_COMPTABLE'));
$dataOutput = [];
foreach ($data as $key => $d) {
foreach ($d as $arr) {
$arr['typeElement'] = $key;
$dataOutput[] = $arr;
}
}
/*
$dataTmp = $serializer->normalize($data, 'json', [
AbstractNormalizer::CIRCULAR_REFERENCE_LIMIT => 0
]);
foreach($dataTmp as $type => $element) {
foreach ($element as $el) {
$el['typeElement'] = $type;
$dataOutput[] = $el;
}
}
*/
return new JsonResponse($dataOutput);
}
#[Route('/api/ecritures_download/{client}', name: 'ecritures_download')]
public function downloadEcriture(Request $request, EntityManagerInterface $entityManager, $client)
{
$reader = Reader::createFromPath('plan_comptable.csv', 'r');
$reader->setDelimiter(' ');
$results = $reader->getRecords();
$planComptable = [];
foreach ($results as $result) {
$code = str_pad($result[0], 7, '0');
$planComptable[$code] = $result[2] ;
}
//do something here
/** @var User $user */
$user = $entityManager->getRepository(User::class)->find($client);
$locals = $user->getLocals();
$ecritures = $user->getExportEcritureDernierExcercice();
$file = uniqid();
$csv = Writer::createFromFileObject(new \SplFileObject('cache/' . $file.'.csv', 'a+'), 'w+');
$headers = [
'N° Comptes',
'Intitulé de comptes',
'Solde compta 31-dec',
'Déd./Réint. RF',
'Augmentation',
'Diminution',
'Revenus fonctiers',
];
foreach ($locals as $local) {
$headers[] = $local->getAdresse();
}
$csv->insertOne($headers);
foreach ($ecritures as $ecriture) {
$numerCompte = $ecriture['numeroCompte'];
$intitule = '';
if (isset($planComptable[$numerCompte])) {
$intitule = $planComptable[$numerCompte];
}
if (!$intitule) {
$pad = '';
$numsec = $numerCompte;
while(!$intitule && strlen($pad) < 6 ) {
$pad .= '0';
$numsec = substr($numsec, 0, strlen($numsec) -1 );
if (isset($planComptable[$numsec . $pad])) {
$intitule = $planComptable[$numsec . $pad];
}
}
}
$csv->insertOne([
$numerCompte,
$intitule,
]
);
}
// We insert the CSV header
$csv->insertOne(['firstname', 'lastname', 'email']);
// Because you are providing the filename you don't have to
// set the HTTP headers Writer::output can
// directly set them for you
// The file is downloadable
// rename($file .'.csv', 'cache/' . $file.'.csv');
$data['link'] = '/cache/'.$file.'.csv';
return new JsonResponse($data);
}
}
// TODO : Fix Invalid credentials. translation