<?php
namespace App\Controller\ModComercio\Compras;
use App\Entity\Catalogos\{MedioPago, PorcentajeIva, SubtipoGasto, TipoComprobanteCompra};
use App\Entity\Contabilidad\{ComprasInsumos, ComprobantesCompra, PagoCredito};
use App\Entity\Documentos\{DocumentosComprobantesCompra};
use App\Entity\Producto\{Proveedores};
use App\Service\{CacheService, DocumentsService};
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\{Request, ResponseHeaderBag};
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\Security\Core\User\UserInterface;
class ComprobantesCompraController extends AbstractController {
private $em;
private $cache;
private $msgCreate;
private $msgUpdate;
private $msgDelete;
public function __construct(EntityManagerInterface $em, CacheService $cache) {
date_default_timezone_set('America/Guayaquil');
$this->em = $em;
$this->cache = $cache;
$this->msgCreate = "Registro creado exitosamente.";
$this->msgUpdate = "Registro actualizado exitosamente.";
$this->msgDelete = "Registro eliminado exitosamente.";
}
// * READ FUNCTIONS *
/**
* @Route("/getInitialComprobantes", name="getInitialComprobantes")
*/
public function getInitialComprobantes(Request $request) {
$this->cache->delete('excelListComprobantesCompras');
$list = [];
$filter = $request->request->get('filter');
$comprobantesCompra = $this->em->getRepository(ComprobantesCompra::class)->findBy(['registrado' => $filter == "registrado" ? true : false], ['fecha' => 'DESC']);
foreach ($comprobantesCompra as $item) {
$list = $this->setArrayComprobanteCompra($list, $item);
}
$this->cache->add('excelListComprobantesCompras', $list);
return $this->json(['data' => $list], 200);
}
/**
* @Route("/getSubtipoGasto", name="getSubtipoGasto")
*/
public function getSubtipoGasto(Request $request) {
$list = [];
$id = $request->request->get('id');
$suptipoGasto = $this->em->getRepository(SubtipoGasto::class)->findBy(['idTipoGasto' => $id], ['nombre' => 'ASC']);
foreach ($suptipoGasto as $item) {
$list[] = [
'id' => $item->getId(),
'nombre' => $item->getNombre()
];
}
return $this->json($list, 200);
}
/**
* @Route("/getPagosCredito", name="getPagosCredito")
*/
public function getPagosCredito(Request $request) {
$list = [];
$id = $request->request->get('idCromprobantesCompra');
$pagoCredito = $this->em->getRepository(PagoCredito::class)->findBy(['idComprobantesCompra' => $id], ['fechaPago' => 'ASC']);
foreach ($pagoCredito as $indice => $item) {
$list[] = [
'indice' => $indice + 1,
'id' => $item->getId(),
'fechaPago' => $item->getFechaPagoString(),
'valor' => $item->getValor(),
'pagado' => $item->getPagado()
];
}
return $this->json(['data' => $list], 200);
}
/**
* @Route("/getFilterComprobantes", name="getFilterComprobantes")
*/
public function getFilterComprobantes(Request $request) {
$list = [];
$idSolicitud = $request->request->get('idSolicitud');
$qb = $this->em->createQueryBuilder();
$qb->select('DISTINCT cc, ci') // Se incluye también 'ci' para evitar el error
->from(ComprasInsumos::class, 'ci') // Se define el alias raíz correctamente
->join('ci.idComprobantesCompra', 'cc') // cc = ComprobantesCompra
->where('ci.idSolicitudCompra = :solicitudId')
->setParameter('solicitudId', $idSolicitud);
$result = $qb->getQuery()->getResult();
foreach ($result as $item) {
$list = $this->setArrayComprobanteCompra($list, $item->getIdComprobantesCompra());
}
$list = $this->eliminarDuplicadosPorPropiedad($list, 'id');
return $this->json(['data' => $list], 200);
}
function eliminarDuplicadosPorPropiedad($array, $propiedad) {
$unicos = [];
$vistos = [];
foreach ($array as $objeto) {
$valor = $objeto[$propiedad];
if (!in_array($valor, $vistos)) {
$vistos[] = $valor;
$unicos[] = $objeto;
}
}
return $unicos;
}
/**
* @Route("/getComprobantesListEnCompras", name="getComprobantesListEnCompras")
*/
public function getComprobantesListEnCompras() {
$list = [];
$comprobantesCompra = $this->em->getRepository(ComprobantesCompra::class)->findBy(['registrado' => false], ['id' => 'DESC']);
foreach ($comprobantesCompra as $item) {
$list = $this->setArrayComprobanteCompra($list, $item);
}
return $this->json($list, 200);
}
private function setArrayComprobanteCompra($list, $item) {
$tipoComprobanteCompra = $item->getIdTipoComprobanteCompra();
$proveedor = $item->getIdProveedores();
$medioPago = $item->getIdMedioPago();
$total = floatval($item->getValorSinIva());
$idPorcentajeIva = $this->em->getRepository(PorcentajeIva::class)->findOneBy(['porcentaje' => $item->getPorcentajeIva()]);
if ($item->getIva() == 0) {
$total = $total + floatval($item->getValorIvaCero());
} else {
$total = floatval($total + $item->getIva() + $item->getValorIvaCero());
}
array_push($list, [
'id' => $item->getId(),
'observacion' => $item->getObservacion(),
'idTipoComprobanteCompra' => [
'id' => $tipoComprobanteCompra->getId(),
'nombre' => $tipoComprobanteCompra->getNombre()
],
'idSubtipoGasto' => $item->getIdSubtipoGasto(),
'idMedioPago' => [
'id' => $medioPago->getId(),
'nombre' => $medioPago->getNombre()
],
'idProveedores' => [
'id' => $proveedor->getId(),
'nombre' => $proveedor->getNombre(),
'ruc' => $proveedor->getRuc()
],
'numero' => $item->getNumero(),
'porcentajeIva' => $item->getPorcentajeIva(),
'fecha' => $item->getFecha()->format('Y-m-d'),
'valor' => $item->getValorSinIva() == 0 ? $item->getValorIvaCero() : $item->getValorSinIva(),
'tarifa0' => $item->getValorIvaCero(),
'tarifaIVA' => $item->getValorSinIva(),
'valorIva' => $item->getIva(),
'iva' => $idPorcentajeIva,
'registrado' => $item->getRegistrado(),
'total' => $total,
'numeroPagosCredito' => $item->getNumeroPagosCredito(),
'credito' => $item->getCredito() ? 'Si' : 'No',
'estado' => $item->getPagada() ? 'PAGADO' : 'PENDIENTE',
'proveedor' => $proveedor
]);
return $list;
}
/**
* @Route("/getInitialProveedores", name="getInitialProveedores")
*/
public function getInitialProveedores() {
$list = [];
$proveedores = $this->em->getRepository(Proveedores::class)->findBy([], ['nombre' => 'ASC']);
foreach ($proveedores as $proveedor) {
array_push($list, [
'id' => $proveedor->getId(),
'ruc' => $proveedor->getRuc(),
'nombre' => $proveedor->getNombre(),
'direccion' => $proveedor->getDireccion()
]);
}
return $this->json($list, 200);
}
/**
* @Route("/getInitialPorcentajeIva", name="getInitialPorcentajeIva")
*/
public function getInitialPorcentajeIva() {
$porcentajeIva = $this->em->getRepository(PorcentajeIva::class)->findAll();
return $this->json($porcentajeIva, 200);
}
/**
* @Route("/getInitialDetalleComprobante", name="getInitialDetalleComprobante")
*/
public function getInitialDetalleComprobante(Request $request) {
$list = [];
$id = $request->request->get('id');
$comprasInsumos = $this->em->getRepository(ComprasInsumos::class)->findBy(['idComprobantesCompra' => $id], ['id' => 'DESC']);
foreach ($comprasInsumos as $compraInsumo) {
$list = $this->setArrayCompras($list, $compraInsumo);
}
return $this->json($list, 200);
}
private function setArrayCompras($list, $compraInsumo) {
$comprobante = $compraInsumo->getIdComprobantesCompra();
$solicitudCompra = $compraInsumo->getIdSolicitudCompra();
$marcaInsumo = $compraInsumo->getIdMarcaInsumo();
$presentacionInsumo = $compraInsumo->getIdPresentacionInsumos();
$porcentajeIva = $compraInsumo->getIdComprobantesCompra() ? $comprobante->getPorcentajeIva() : 0;
if ($compraInsumo->getTarifa0()) :
$iva = 0;
$total = doubleval($compraInsumo->getValorCompra());
else:
$iva = doubleval($compraInsumo->getValorCompra() * doubleval($porcentajeIva / 100));
$total = doubleval($compraInsumo->getValorCompra()) + doubleval($iva);
endif;
array_push($list, [
'id' => $compraInsumo->getId(),
'idInsumos' => [
'id' => $compraInsumo->getIdInsumos()->getId(),
'nombre' => $compraInsumo->getIdInsumos()->getNombre(),
'idUnidadesInsumos' => [
'nombre' => $compraInsumo->getIdInsumos()->getIdUnidadesInsumos()->getNombre()
],
],
'cantidadSolicitada' => $compraInsumo->getCantidadSolicitada() ?? 0,
'cantidadPresentacion' => $compraInsumo->getCantidadPresentacion(),
'unidadesPresentacion' => $compraInsumo->getUnidadesPresentacion() ?? 0,
'cantidadCompra' => $compraInsumo->getCantidadCompra(),
'valorUnitario' => $compraInsumo->getValorUnitario(),
'tarifa0' => $compraInsumo->getTarifa0(),
'idSolicitudCompra' => [
'codigoSolicitud' => $solicitudCompra->getCodigoSolicitud(),
],
'idComprobantesCompra' => $comprobante ? [
'porcentaje' => $comprobante->getPorcentajeIva() ?? 0,
'numero' => $comprobante->getNumero(),
'fecha' => $comprobante->getFecha()->format('Y-m-d'),
'idTipoComprobanteCompra' => [
'nombre' => $comprobante->getIdTipoComprobanteCompra()->getNombre(),
],
'idProveedores' => $comprobante->getIdProveedores() ? [
'nombre' => $comprobante->getIdProveedores()->getNombre(),
] : null,
] : null,
'idMarcaInsumo' => $marcaInsumo ? [
'nombre' => $marcaInsumo->getNombre(),
] : null,
'idPresentacionInsumo' => $presentacionInsumo ? [
'nombre' => $presentacionInsumo->getNombre(),
] : null,
'subtotal' => $compraInsumo->getValorUnitario(),
'iva' => $iva,
'total' => $total
]);
return $list;
}
// * CREATE OR UPDATE FUNCTIONS *
/**
* @Route("/addComprobantesCompra", name="addComprobantesCompra")
*/
public function addComprobantesCompra(Request $request, UserInterface $user, DocumentsService $documentsService) {
try {
$data = $request->request->get('comprobante_compras');
//return $this->json($data, 200);
$id = $data['id'];
if ($id != null) :
$pagoCredito = $this->em->getRepository(PagoCredito::class)->findOneBy(['idComprobantesCompra' => $id]);
if ($pagoCredito) :
return $this->json(['response' => false, 'message' => "Lo sentimos, el comprobante ya tiene registros de pagos de un credito."]);
endif;
endif;
$comprobanteCompra = ($id != null) ? $this->em->getRepository(ComprobantesCompra::class)->find($data['id']) : new ComprobantesCompra;
$comprobanteCompra = $this->setDataComprobante($data, $comprobanteCompra, $user);
$message = ($id != null) ? $this->msgUpdate : $this->msgCreate;
$this->em->persist($comprobanteCompra);
if ($data['idTipoComprobanteCompra'] != 4) :
if ($_FILES['comprobante_compras']['error']['comprobante'][0] != 4) :
$this->setComprobantesCompra($comprobanteCompra, $user, $documentsService);
endif;
endif;
if ($data['id'] == "") :
if (isset($data['numeroPagosCredito'])) {
for ($i = 0; $i < $data['numeroPagosCredito'] ; $i++) {
$pagoCredito = new PagoCredito;
$pagoCredito->setIdComprobantesCompra($comprobanteCompra)->setPagado(false);
$pagoCredito = $this->setGenericData($user, $pagoCredito);
$this->em->persist($pagoCredito);
}
}
endif;
$this->em->flush();
return $this->json(['response' => true, 'message' => $message]);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>addComprobantesCompra</i>"]);
}
}
private function setDataComprobante($data, ComprobantesCompra $comprobante, $user) {
$idTipoComprobanteCompra = $this->em->getRepository(TipoComprobanteCompra::class)->find($data['idTipoComprobanteCompra']);
$idPorcentajeIva = $this->em->getRepository(PorcentajeIva::class)->find(isset($data['idPorcentajeIva']) ? $data['idPorcentajeIva'] : 0);
$iva = 0; $porcentajeIVA = 0;
if (isset($data['idPorcentajeIva'])) :
$porcentajeIVA = intval($idPorcentajeIva->getPorcentaje());
$iva = $data['iva'];
endif;
$date = \DateTime::createFromFormat('Y-m-d', $data['fecha']);
if (strtoupper($idTipoComprobanteCompra->getNombre()) == 'SIN DOCUMENTO') { //Secuencial
if ($data['id'] == '') {
$numero = $this->setSecuencial($user);
$comprobante->setNumero($numero);
}
} else {
$comprobante->setNumero($data['numero']);
}
$comprobante
->setFecha($date)
->setPorcentajeIva($porcentajeIVA)
->setValorIvaCero($data['valorIvaCero'])
->setValorDescuento(0)
->setIva($iva)
->setIdProveedores($this->em->getRepository(Proveedores::class)->find($data['idProveedor']))
->setIdMedioPago($this->em->getRepository(MedioPago::class)->find($data['idMedioPago']))
->setObservacion($data['observacion'])
->setIdTipoComprobanteCompra($idTipoComprobanteCompra)
->setIdSubtipoGasto($this->em->getRepository(SubtipoGasto::class)->find($data['idSubtipoGasto']))
->setCredito(false)
->setRegistrado(false)
->setCompraBien(isset($data['compraBien']) ? true : false)
->setNumeroPagosCredito(0);
if (isset($data['valorSinIva'])) {
$comprobante->setValorSinIva($data['valorSinIva']);
} else { $comprobante->setValorSinIva(0); }
if (isset($data['estado'])) {
$comprobante->setPagada($data['estado'] == 'PAGADO' ? true : false);
}
if (isset($data['numeroPagosCredito'])) {
$comprobante
->setCredito(true)
->setNumeroPagosCredito($data['numeroPagosCredito']);
} else {
$comprobante
->setCredito(false);
}
$comprobante = $this->setGenericData($user, $comprobante);
return $comprobante;
}
private function setSecuencial($user) {
$comprobantes = $this->em->getRepository(ComprobantesCompra::class)->findAll();
$count = 0;
if ($comprobantes) {
foreach ($comprobantes as $comp) {
$numero = $comp->getNumero();
if (stristr($numero, '_')) {
$numero = explode('_', $numero);
if ($numero[0] == $user->getIdPersona()->getNumeroIdentificacion()) {
$count++;
}
}
}
}
$count++;
$numero = "{$user->getIdPersona()->getNumeroIdentificacion()}_{$count}";
return $numero;
}
private function setComprobantesCompra($comprobanteCompra, $user, $documentsService) {
$type = $_FILES['comprobante_compras']['type'];
$size = $_FILES['comprobante_compras']['size'];
$tmp_name = $_FILES['comprobante_compras']['tmp_name'];
$name = $_FILES['comprobante_compras']['name'];
$countComprobantes = count($_FILES['comprobante_compras']['name']['comprobante']);
if ($countComprobantes > 0) :
for ($i = 0; $i < $countComprobantes; $i++) {
$comprobante = $documentsService->getEstructureDocument($name['comprobante'][$i], $size['comprobante'][$i], $tmp_name['comprobante'][$i], $type['comprobante'][$i]);
$documentName = $documentsService->flushDocument($comprobante, "COMP_COMRP", 'docs_directory');
$addDocument = $documentsService->addDocument($comprobante, $documentName, "images/documents/$documentName", true, $user, null);
$documentosComprobantesCompra = new DocumentosComprobantesCompra;
$documentosComprobantesCompra
->setIdCargaDocumento($addDocument)
->setIdComprobantesCompra($comprobanteCompra)
;
$documentosComprobantesCompra = $this->setGenericData($user, $documentosComprobantesCompra);
$this->em->persist($documentosComprobantesCompra);
}
endif;
}
/**
* @Route("/setCheckRegistrado", name="setCheckRegistrado")
*/
public function setCheckRegistrado(Request $request) {
try {
$id = $request->request->get('id');
$val = $request->request->get('val');
$comprobantesCompra = $this->em->getRepository(ComprobantesCompra::class)->find($id);
if ($val === 'true') :
$comprobantesCompra->setRegistrado(true);
else:
$comprobantesCompra->setRegistrado(false);
endif;
$this->em->persist($comprobantesCompra);
$this->em->flush();
return $this->json(['response' => true, 'message' => $this->msgUpdate]);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>setCheckRegistrado</i>"]);
}
}
/**
* @Route("/setCheckPagadoCredito", name="setCheckPagadoCredito")
*/
public function setCheckPagadoCredito(Request $request) {
try {
$id = $request->request->get('id');
$val = $request->request->get('val');
$pagoCredito = $this->em->getRepository(PagoCredito::class)->find($id);
if ($val === 'true') :
$pagoCredito->setPagado(true);
else:
$pagoCredito->setPagado(false);
endif;
$this->em->persist($pagoCredito);
$this->em->flush();
return $this->json(['response' => true, 'message' => $this->msgUpdate]);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>setCheckPagadoCredito</i>"]);
}
}
/**
* @Route("/setFechaPagoCredito", name="setFechaPagoCredito")
*/
public function setFechaPagoCredito(Request $request, UserInterface $user) {
try {
$id = $request->request->get('id');
$fecha = \DateTime::createFromFormat('Y-m-d', $request->request->get('fecha'));
$pagoCredito = $this->em->getRepository(PagoCredito::class)->find($id);
$pagoCredito->setFechaPago($fecha);
$pagoCredito = $this->setGenericData($user, $pagoCredito);
$this->em->persist($pagoCredito);
$this->em->flush();
return $this->json(['response' => true, 'message' => $this->msgUpdate]);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>setFechaPagoCredito</i>"]);
}
}
/**
* @Route("/setValorPagoCredito", name="setValorPagoCredito")
*/
public function setValorPagoCredito(Request $request, UserInterface $user) {
try {
$id = $request->request->get('id');
$valor = $request->request->get('valor');
$pagoCredito = $this->em->getRepository(PagoCredito::class)->find($id);
$pagoCredito->setValor($valor);
$pagoCredito = $this->setGenericData($user, $pagoCredito);
$this->em->persist($pagoCredito);
$this->em->flush();
return $this->json(['response' => true, 'message' => $this->msgUpdate]);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>setValorPagoCredito</i>"]);
}
}
private function setGenericData($user = null, $entity) {
$entity->setIdUsuarioModificacion($user != null ? $user->getId() : '1')
->setFechaModificacion(new \DateTime())
->setIpModificacion($_SERVER['REMOTE_ADDR']);
return $entity;
}
// * DELETE FUNCTIONS *
/**
* @Route("/deleteComprobantesCompras", name="deleteComprobantesCompras")
*/
public function deleteComprobantesCompras(Request $request) {
try {
$id = $request->request->get('id');
$comprobantesCompra = $this->em->getRepository(ComprobantesCompra::class)->find($id);
$comprasInsumos = $this->em->getRepository(ComprasInsumos::class)->findOneBy(['idComprobantesCompra' => $id]);
if ($comprasInsumos) :
return $this->json(['response' => false, 'exception' => false], 200);
endif;
$this->em->remove($comprobantesCompra);
$this->em->flush();
return $this->json(['response' => true, 'message' => $this->msgDelete, 'exception' => false], 200);
} catch (Exception $e) {
return $this->json(['response' => false, 'message' => "<b>{$e->getMessage()}</b> error al realizar el registro dentro de la petición <i>deleteComprobantesCompras</i>", 'exception' => true]);
}
}
// * EXPORTS *
/**
* @Route("/getExcelComprobantesCompra", name="getExcelComprobantesCompra")
*/
public function getExcelComprobantesCompra() {
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle("Comprobantes");
$headers = ['id', 'documento', 'ruc', 'nombre', 'valor', 'nro. documento', 'fecha compra', 'iva', 'total', 'credito', 'registrado', 'estado'];
$sheet->fromArray( $headers, NULL, 'A1' );
$lista = $this->cache->get('excelListComprobantesCompras');
$lista = !$lista ? [] : $lista;
if(count($lista) != 0):
$data = array_map(function ($menu) {
return [
$menu['id'],
$menu['idTipoComprobanteCompra']['nombre'],
$menu['idProveedores']['ruc'],
$menu['idProveedores']['nombre'],
round($menu['valor'], 2),
$menu['numero'],
$menu['fecha'],
$menu['iva'],
round($menu['total'], 2),
$menu['credito'] ? 'Sí' : 'No',
$menu['estado'],
$menu['registrado'] ? 'Sí' : 'No'
];
}, $lista);
endif;
$sheet->fromArray($data, null, 'A2');
$writer = new Xlsx($spreadsheet);
$fileName = 'comprobantes.xlsx';
$temp_file = tempnam(sys_get_temp_dir(), $fileName);
$writer->save($temp_file);
return $this->file($temp_file, $fileName, ResponseHeaderBag::DISPOSITION_INLINE);
}
}