<?php
namespace App\Controller\Front;
use App\Controller\Core\BaseFrontController;
use App\Entity\FormClaim;
use App\Entity\FormContact;
use App\Entity\FormQuotation;
use App\Entity\Forms;
use App\Form\Front\FormClaimType;
use App\Form\Front\FormContactType;
use App\Form\Front\FormQuotationType;
use App\Manager\ContactManager;
use App\Manager\FormClaimManager;
use App\Manager\FormContactManager;
use App\Manager\FormQuotationManager;
use App\Manager\FormsManager;
use App\Manager\QuotationManager;
use App\Service\CRM\ApiCRM;
use App\Service\Mail\ClaimMail;
use App\Service\Mail\ContactMail;
use App\Service\Mail\QuotationMail;
use App\Service\Recaptcha\Validator as RecaptchaValidator;
use App\Traits\FormFileTrait;
use DateInterval;
use DateTime;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class FormController extends BaseFrontController
{
use FormFileTrait;
const FORM_CONTACT = 'sd_form_contact_entity';
const FORM_QUOTATION = 'sd_form_quotation_entity';
const FORM_CLAIM = 'sd_form_claim_entity';
/**
* @Route("/contacto", name="contact", methods={"GET"})
* @Template("front/form/contact.html.twig")
*/
public function contact(ContactManager $contactManager): array
{
$entity = $this->getFormSession(self::FORM_CONTACT, new FormContact());
$form = $this->getFormView(FormContactType::class, $entity, 'contact_action');
$this->locals['sd'] = $contactManager->find(1);
$this->locals['form'] = $form;
return $this->locals;
}
/**
* @Route("/contacto", name="contact_action", methods={"POST"})
*/
public function contactAction(Request $request, FormContactManager $manager, ContactMail $mail, ApiCRM $apiCRM, RecaptchaValidator $recaptchaValidator): RedirectResponse
{
$entity = new FormContact();
$form = $this->getForm(FormContactType::class, $entity, 'contact_action');
$form->handleRequest($request);
if ($form->isValid() and $recaptchaValidator->validate($this->getRecaptchaToken(), $this->getClientIp())) {
$manager->save($entity);
//$mail->load($entity)->send();
$crmLead = $entity->leadToCRM();
$result = $apiCRM->send($crmLead);
$entity->setCrmBody($crmLead->toCRM());
$entity->setCrmResult($result);
$manager->save($entity);
return $this->redirectToRoute('thanks_slug', ['slug' => 'contacto']);
}
$this->saveFormSession(self::FORM_CONTACT, $entity);
return $this->redirectToRoute('contact');
}
/**
* @Route("/cotizar", name="quotation", methods={"GET"})
* @Template("front/form/quotation.html.twig")
*/
public function quotation(QuotationManager $quotationManager): array
{
$entity = $this->getFormSession(self::FORM_QUOTATION, new FormQuotation());
$form = $this->getFormView(FormQuotationType::class, $entity, 'quotation_action');
$this->locals['sd'] = $quotationManager->find(1);
$this->locals['form'] = $form;
return $this->locals;
}
/**
* @Route("/cotizar", name="quotation_action", methods={"POST"})
*/
public function quotationAction(Request $request, FormQuotationManager $manager, QuotationMail $mail, ApiCRM $apiCRM, RecaptchaValidator $recaptchaValidator): RedirectResponse
{
$entity = new FormQuotation();
$form = $this->getForm(FormQuotationType::class, $entity, 'quotation_action');
$form->handleRequest($request);
if ($form->isValid() and $recaptchaValidator->validate($this->getRecaptchaToken(), $this->getClientIp())) {
$manager->save($entity);
//$mail->load($entity)->send();
$crmLead = $entity->leadToCRM();
$result = $apiCRM->send($crmLead);
$entity->setCrmBody($crmLead->toCRM());
$entity->setCrmResult($result);
$manager->save($entity);
return $this->redirectToRoute('thanks_slug', ['slug' => 'cotizar']);
}
$this->saveFormSession(self::FORM_QUOTATION, $entity);
return $this->redirectToRoute('quotation');
}
/**
* @Route("/libro-de-reclamaciones", name="claim", methods={"GET"})
* @Template("front/form/claim.html.twig")
*/
public function claim(FormClaimManager $formClaimManager, FormsManager $formsManager): array
{
/** @var Forms $forms */
$forms = $formsManager->find(1);
$responseDays = (int)$forms->getClaimResponseDays();
try {
$this->locals['answer_date'] = (new DateTime())->add(new DateInterval('P' . $responseDays . 'D'));
} catch (\Exception $exception) {
$this->locals['answer_date'] = new DateTime();
}
$entity = new FormClaim();
$code = $this->generateCode($formClaimManager->lastCode());
$entity->setCode($code);
$entity = $this->getFormSession(self::FORM_CLAIM, $entity);
$form = $this->getFormView(FormClaimType::class, $entity, 'claim_action');
$this->locals['form'] = $form;
$this->locals['entity'] = $entity;
return $this->locals;
}
/**
* @Route("/libro-de-reclamaciones", name="claim_action", methods={"POST"})
*/
public function claimAction(Request $request, FormClaimManager $manager, ClaimMail $mail, RecaptchaValidator $recaptchaValidator): RedirectResponse
{
$entity = new FormClaim();
$form = $this->getForm(FormClaimType::class, $entity, 'claim_action');
$entity->setFile(null);
if ($request->files->get('form_file')) {
$file = $this->saveFile($request->files->get('form_file'), 1000000, 0,'reclamos');
$entity->setFile($file);
}
$code = $this->generateCode($manager->lastCode());
$entity->setCode($code);
$form->handleRequest($request);
$firmaFromRequest = $request->request->get('form')['firma'] ?? null;
if ($firmaFromRequest) {
$entity->setFirma($firmaFromRequest);
}
if ($form->isValid()) {
$entity->setSaved(true);
$entity->setUniq(bin2hex(random_bytes(16)));
$manager->save($entity);
$mail->load($entity)->send();
$mail->loadClient($entity)->send();
$this->saveFormSession(self::FORM_CLAIM, $entity);
$this->requestStack->getSession()->remove('sd_claim_code');
return $this->redirectToRoute('thanks_claim', ['uniq' => $entity->getUniq()]);
}
$this->saveFormSession(self::FORM_CLAIM, $entity);
return $this->redirectToRoute('claim');
}
/**
* @Route("/libro-de-reclamaciones/pdf/{uniq}", name="claim_pdf", methods={"GET"})
*/
public function claimPdf(string $uniq, FormClaimManager $formClaimManager, FormsManager $formsManager): Response
{
$claim = $formClaimManager->findOneBy(['uniq' => $uniq]);
if (!$claim) {
throw $this->createNotFoundException('Reclamo no encontrado');
}
$forms = $formsManager->find(1);
$html = $this->renderView('front/pdf/claim_pdf.html.twig', [
'claim' => $claim,
'forms' => $forms,
'company_name' => $forms->getClaimCompanyName(),
'company_ruc' => $forms->getClaimCompanyRuc(),
'company_address' => $forms->getClaimCompanyAddress(),
]);
// Si es PDF, generar con mPDF
if (!isset($_GET['html'])) {
$mpdf = new \Mpdf\Mpdf([
'mode' => 'utf-8',
'format' => 'A4',
'margin_top' => 0,
'margin_bottom' => 10,
'allow_base64_images' => true,
'img_dpi' => 96,
]);
$mpdf->WriteHTML($html);
return new Response($mpdf->Output('libro_reclamaciones_' . $claim->getCode() . '.pdf', 'I'));
}
// Si es HTML, mostrar directamente
return new Response($html);
}
/**
* @Route("/libro-de-reclamaciones/pdf-preview/{uniq}", name="claim_pdf_preview_html", methods={"GET"})
*/
public function claimPdfPreviewHtml(string $uniq, FormClaimManager $formClaimManager, FormsManager $formsManager): Response
{
$claim = $formClaimManager->findOneBy(['uniq' => $uniq]);
if (!$claim) {
throw $this->createNotFoundException('Reclamo no encontrado');
}
$forms = $formsManager->find(1);
$html = $this->renderView('front/pdf/claim_pdf.html.twig', [
'claim' => $claim,
'forms' => $forms,
'company_name' => $forms->getClaimCompanyName(),
'company_ruc' => $forms->getClaimCompanyRuc(),
'company_address' => $forms->getClaimCompanyAddress(),
]);
return new Response($html);
}
/**
* @Route("/admin-preview/pdf", name="claim_pdf_preview", methods={"GET"})
*/
public function previewClaimPdf(FormsManager $formsManager): Response
{
$forms = $formsManager->find(1);
$claim = $this->createMockClaim();
$claim->setCurrency('Soles');
$html = $this->renderView('front/pdf/claim_pdf.html.twig', [
'claim' => $claim,
'forms' => $forms,
'company_name' => $forms->getClaimCompanyName(),
'company_ruc' => $forms->getClaimCompanyRuc(),
'company_address' => $forms->getClaimCompanyAddress(),
]);
$mpdf = new \Mpdf\Mpdf([
'mode' => 'utf-8',
'format' => 'A4',
'margin_top' => 0,
'margin_bottom' => 10,
'allow_base64_images' => true,
'img_dpi' => 96,
]);
$mpdf->WriteHTML($html);
$response = new Response();
$response->setContent($mpdf->Output('preview-libro-reclamaciones.pdf', 'S'));
$response->headers->set('Content-Type', 'application/pdf');
$response->headers->set('Content-Disposition', 'inline; filename="preview-libro-reclamaciones.pdf"');
return $response;
}
/**
* @Route("/admin-preview/gracias", name="preview_gracias", methods={"GET"})
*/
public function previewGracias(FormsManager $formsManager): Response
{
$forms = $formsManager->find(1);
$claim = $this->createMockClaim();
$pdfUrl = $this->generateUrl('claim_pdf_preview');
return $this->render('front/preview/preview-gracias.html.twig', [
'forms' => $forms,
'claim' => $claim,
'pdf_url' => $pdfUrl,
]);
}
/**
* @Route("/admin-preview/email", name="preview_email", methods={"GET"})
*/
public function previewEmail(FormsManager $formsManager): Response
{
$forms = $formsManager->find(1);
$claim = $this->createMockClaim();
$nombre = trim($claim->getName() . ' ' . $claim->getLastname());
$emailTitulo = $forms->getEmailTitulo();
$emailTitulo = $emailTitulo ? str_replace('%nombre%', $nombre, $emailTitulo) : $emailTitulo;
return $this->render('front/preview/preview-email.html.twig', [
'forms' => $forms,
'claim' => $claim,
'emailTitulo' => $emailTitulo,
]);
}
private function createMockClaim(): FormClaim
{
$claim = new FormClaim();
$claim->setCode('R' . date('Y') . date('m') . '-000001');
$claim->setUniq('preview-claim-test');
$claim->setName('Juan');
$claim->setLastname('Pérez García');
$claim->setApellidoMaterno('García');
$claim->setEmail('juan.perez@ejemplo.com');
$claim->setPhone('987654321');
$claim->setDocumentType('DNI');
$claim->setDocumentNumber('12345678');
$claim->setDepartment('Lima');
$claim->setProvince('Lima');
$claim->setDistrict('Miraflores');
$claim->setAddress('Av. Arequipa 1234');
$claim->setEstablishment('Tienda Principal');
$claim->setGood('Camión UD');
$claim->setDescription('Motor con ruido anormal');
$claim->setType('Reclamo');
$claim->setDetail('El motor presenta ruidos anormales desde hace una semana');
$claim->setDemand('Reparación gratuita del motor');
$claim->setAuthorization('Email');
$claim->setSaved(true);
return $claim;
}
public function generateCode($lastCode): string
{
$id = $this->lastCodeId($lastCode);
return 'R' . date('Y') . date('m') . '-' . str_pad((string)($id + 1), 6, '0', STR_PAD_LEFT);
}
public function lastCodeId($lastCode): int
{
$code = $this->lastCode($lastCode);
$array = explode('-', $code);
return count($array) == 2 ? (int)$array[1] : 0;
}
public function lastCode($lastCode): string
{
$code = $lastCode;
return is_null($code) ? 'R' . date('Y') . date('m') . '-' . '100000' : $code;
}
}