<?php
namespace App\Repository;
use App\Entity\Articulo;
use App\Helper\DateHelper;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\User\UserInterface;
class ArticuloRepository extends ServiceEntityRepository implements AutoCompletableInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Articulo::class);
}
public function getByPage($text, $offset = 0, $perPage = 100, $filtros = []) {
$qb = $this->createQueryBuilder('a')
->where('a.deletedAt is null')
->orderBy("REPLACE(a.descripcion, '** ', '')");
if ($text) {
$words = preg_split('/\s+/', trim($text));
$andByField = [];
foreach (['descripcion', 'codigo', 'codigotwo'] as $field) {
$andX = $qb->expr()->andX();
foreach ($words as $index => $word) {
$paramName = "{$field}_word_{$index}";
$andX->add($qb->expr()->like("a.$field", ":$paramName"));
$qb->setParameter($paramName, '%' . $word . '%');
}
$andByField[] = $andX;
}
$orX = $qb->expr()->orX();
foreach ($andByField as $condition) {
$orX->add($condition);
}
$qb->andWhere($orX);
}
if ($filtros["talle"] ?? false) {
$qb->andWhere('a.talle = :talle')
->setParameter('talle',$filtros['talle']);
}
if ($filtros["color"] ?? false) {
$qb->andWhere('a.color = :color')
->setParameter('color',$filtros['color']);
}
if ($filtros["genero"] ?? false) {
$qb->andWhere('a.genero = :genero')
->setParameter('genero',$filtros['genero']);
}
$qb->setFirstResult($offset)
->setMaxResults($perPage);
return $qb->getQuery()->getResult();
}
public function getByPagedeleted($text, $offset = 0, $perPage = 100) {
$qb = $this->createQueryBuilder('a')
->where('a.deletedAt IS NOT NULL')
->orderBy('a.id');
if ($text)
$qb ->where("a.descripcion LIKE :text")
->orWhere("a.codigo LIKE :text")
->setParameter('text', '%'.$text.'%');
$qb->setFirstResult($offset)
->setMaxResults($perPage);
return $qb->getQuery()->getResult();
}
public function getCountdeleted($text) {
$qb = $this->createQueryBuilder('a')
->select("Count(a) as count")
->where('a.deletedAt is not null');
if ($text)
$qb ->where("a.descripcion LIKE :text")
->andWhere('a.deletedAt is null')
->setParameter('text', '%'.$text.'%');
return $qb->getQuery()->getResult()[0]["count"];
}
public function getByPage2($text, $offset = 0, $perPage = 100) {
$qb = $this->createQueryBuilder('a')
->where('a.deletedAt is null')
->orderBy('a.id');
if(is_numeric($text)){
$codigo = $text;
$qb = $this->createQueryBuilder('a2')
->select('a2.descripcion')
->where('a2.codigo LIKE :codigo')
->andWhere('a2.deletedAt is null')
->setParameter('codigo', $codigo);
$descripcion = $qb->getQuery()->getResult();
$qb = $this->createQueryBuilder('m')
->where('m.descripcion= :descripcion')
->setParameter('descripcion', $descripcion);
}
else if ($text)
$qb ->where("a.descripcion LIKE :text")
->andWhere('a.deletedAt is null')
->setParameter('text', '%'.$text.'%');
$qb->setFirstResult($offset)
->setMaxResults($perPage);
return $qb->getQuery()->getResult();
}
public function getCount($text) {
$qb = $this->createQueryBuilder('a')
->select("Count(a) as count")
->where('a.deletedAt is null');
if ($text)
$qb ->where("a.descripcion LIKE :text")
->andWhere('a.deletedAt is null')
->setParameter('text', '%'.$text.'%');
return $qb->getQuery()->getResult()[0]["count"];
}
public function getCount2($text) {
$qb = $this->createQueryBuilder('a')
->select("Count(a) as count")
->where('a.deletedAt is null');
if(is_numeric($text)){
$codigo = $text;
$qb
->select('a.descripcion')
->where('a.codigo LIKE :codigo')
->setParameter('codigo', $codigo);
$descripcion = $qb->getQuery()->getResult();
$qb = $this->createQueryBuilder('m')
->select("Count(m) as count")
->where('m.descripcion LIKE :descripcion')
->setParameter('descripcion', $descripcion);
}
else if ($text){
$qb ->where("a.descripcion LIKE :text")
->setParameter('text', '%'.$text.'%');
}
return $qb->getQuery()->getResult()[0]["count"];
}
/**
* Consulta para autocomplete
*
* @param string $searchField
* @param string $text
* @return array
*/
public function autocompleteQuery(string $searchField, string $text, $user = null): array
{
//, :marcaproducto_label ,ma.nombre
$qb = $this->createQueryBuilder('a')
->select('CONCAT(a.'.$searchField.', :categoria_label ,ca.nombre, :marcaProducto_label ,ma.nombre) as label, a.id as id')
// ->leftJoin('a.talle', 't')
// ->leftJoin('a.color', 'c')
->leftJoin('a.categoria', 'ca')
->leftJoin('a.marca_producto', 'ma')
->where('a.deletedAt is NULL')
->andWhere('a.'.$searchField.' like :text')
->setParameter('text', '%'.$text.'%')
->setParameter('categoria_label', ' categoria: ')
->setParameter('marcaProducto_label', ' marca: ')
->setMaxResults(50)
->orderBy('a.'.$searchField);
return $qb->getQuery()->getResult();
}
public function buscar($buscarData,$count,$articulos){
$palabras = explode(' ', $buscarData['palabra']);
$qb = $this->createQueryBuilder('a');
if($count){
$qb->select('Count(a) as count');
}
$qb->where('a.descripcion LIKE :descripcion')
->setParameter('descripcion', ' ');
for ($i=0; $i < count($palabras) ; $i++) {
$qb->orWhere('a.descripcion LIKE :descripcion'.$i)
->setParameter('descripcion'.$i,'%'.$palabras[$i].'%');
}
if($buscarData['codigo']){
$qb->andWhere('a.codigo LIKE :codigo')
->setParameter('codigo','%'.$buscarData['codigo'].'%');
}
if($buscarData['palabra']){
$qb->andWhere('a.descripcion LIKE :descripcion')
->setParameter('descripcion','%'.$buscarData['palabra'].'%');
}
// if($buscarData['rubro']){
// $qb->andWhere('a.rubro = :rubro')
// ->setParameter('rubro',$buscarData['rubro']);
// }
if($buscarData['categoria']){
$qb->andWhere('a.categoria = :categoria')
->setParameter('categoria',$buscarData['categoria']);
}
if($buscarData['grupo']){
$qb->andWhere('a.grupo = :grupo')
->setParameter('grupo',$buscarData['grupo']);
}
// if($buscarData['disciplina']){
// $qb->andWhere('a.disciplina = :disciplina')
// ->setParameter('disciplina',$buscarData['disciplina']);
// }
if($buscarData['marca']){
$qb->andWhere('a.marca_producto = :marca')
->setParameter('marca',$buscarData['marca']);
}
if($buscarData['proveedor']){
$qb->andWhere('a.proveedor = :proveedor')
->setParameter('proveedor',$buscarData['proveedor']);
}
// if($buscarData['talle']){
// $qb->andWhere('a.talle = :talle')
// ->setParameter('talle',$buscarData['talle']);
// }
// if($buscarData['color']){
// $qb->andWhere('a.color = :color')
// ->setParameter('color',$buscarData['color']);
// }
// if($buscarData['genero']){
// $qb->andWhere('a.genero = :genero')
// ->setParameter('genero',$buscarData['genero']);
// }
$qb->andWhere('a.deletedAt is NULL');
if($articulos){
$qb->andWhere('a.id NOT IN (:articulos)')
->setParameter('articulos',explode(',',$articulos));
}
if($count){
return $qb->getQuery()->getResult()[0]["count"];
}
if(!$articulos){
$qb->setFirstResult($buscarData['offset'])
->setMaxResults($buscarData['length']);
}
return $qb->getQuery()->getResult();
}
public function buscar2($buscarData,$count,$articulos) {
$palabras = explode(' ', $buscarData['palabra']);
$qb = $this->createQueryBuilder('a');
if($count){
$qb->select('Count(a) as count');
}
$qb->where('a.descripcion LIKE :descripcion')
->setParameter('descripcion', ' ');
for ($i=0; $i < count($palabras) ; $i++) {
$qb->orWhere('a.descripcion LIKE :descripcion'.$i)
->setParameter('descripcion'.$i,'%'.$palabras[$i].'%');
}
if($buscarData['palabra']){
$qb->andWhere('a.descripcion LIKE :descripcion')
->setParameter('descripcion','%'.$buscarData['palabra'].'%');
}
// if($buscarData['rubro']){
// $qb->andWhere('a.rubro = :rubro')
// ->setParameter('rubro',$buscarData['rubro']);
// }
if($buscarData['categoria']){
$qb->andWhere('a.categoria = :categoria')
->setParameter('categoria',$buscarData['categoria']);
}
if($buscarData['grupo']){
$qb->andWhere('a.grupo = :grupo')
->setParameter('grupo',$buscarData['grupo']);
}
if($buscarData['disciplina']){
$qb->andWhere('a.disciplina = :disciplina')
->setParameter('disciplina',$buscarData['disciplina']);
}
if($buscarData['marca']){
$qb->andWhere('a.marca_producto = :marca')
->setParameter('marca',$buscarData['marca']);
}
if($buscarData['proveedor']){
$qb->andWhere('a.proveedor = :proveedor')
->setParameter('proveedor',$buscarData['proveedor']);
}
if($articulos){
$qb->andWhere('a.id NOT IN (:articulos)')
->setParameter('articulos',explode(',',$articulos));
}
if($count){
return $qb->getQuery()->getResult()[0]["count"];
}
if(!$articulos){
$qb->setFirstResult($buscarData['offset'])
->setMaxResults($buscarData['length']);
}
return $qb->getQuery()->getResult();
}
public function totalesPorProducto($fechaStr, $filtros = []) {
$qb = $this->createQueryBuilder('AR');
$qb ->leftJoin('AR.factulineas', 'FL')
->leftJoin('FL.factura', 'FAC')
// ->leftJoin('AR.rubro', 'RB')
->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
// ->leftJoin('AR.talle', 'TA')
->where('FAC.fechaOperacion >= :start AND FAC.fechaOperacion <= :end')
->andWhere('AR.categoria != 49');
$qb ->select( 'AR.id AS ID, FAC.fechaOperacion AS FECHA, GR.descripcion AS GRUPO, '.
'CAT.nombre AS CATEGORIA, MP.nombre as MARCA, CONCAT(\' \', AR.codigo) as CODIGO, AR.descripcion as DESCRIPCION, '.
'AR.precio AS PRECIO_1, FL.precio AS PRECIO_2, SUM( FL.cantidad) AS CANTIDAD, '.
'SUM(FL.importe) AS TOTAL, '.'SUM(AR.costo * FL.cantidad) AS COSTO, '.'(SUM(FL.importe) - SUM(AR.costo * FL.cantidad) ) AS GANANCIA, '
.'( SUM(FL.importe) - SUM(AR.costo * FL.cantidad) ) / SUM(AR.costo * FL.cantidad) AS PORCENTAJE');
$range = DateHelper::STRING_DATE_TO_RANGE($fechaStr);
$qb = $this->addWhereFiltroProducto($qb, $filtros, [
'start' => $range["start"],
'end' => $range["end"]
]);
$qb->groupBy("AR.id, FAC.fechaOperacion");
$qb ->orderBy("FECHA", "DESC")
// ->orderBy("RUBRO", "ASC")
->addOrderBy("GRUPO", "ASC")
->addOrderBy("CATEGORIA", "ASC")
->addOrderBy("MARCA", "ASC")
->addOrderBy("DESCRIPCION", "ASC");
return $qb->getQuery()->getResult();
}
public function totalesVentaPorMarca($fechaStr, $filtros = [], $global = false) {
$qb = $this->createQueryBuilder('AR');
$qb ->leftJoin('AR.factulineas', 'FL')
->leftJoin('FL.factura', 'FAC')
// ->leftJoin('AR.rubro', 'RB')
->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
// ->leftJoin('AR.talle', 'TA')
->where('FAC.fechaOperacion >= :start AND FAC.fechaOperacion <= :end')
->andWhere('AR.categoria != 49');
if (!$global) {
$qb ->select( 'MP.nombre as MARCA, SUM( FL.cantidad) AS CANTIDAD, SUM(FL.importe) AS TOTAL');
$qb->groupBy("MARCA");
$qb ->orderBy("MARCA", "DESC");
} else {
$qb ->select( 'SUM( FL.cantidad) AS CANTIDAD, SUM(FL.importe) AS TOTAL');
}
$range = DateHelper::STRING_DATE_TO_RANGE($fechaStr);
$qb = $this->addWhereFiltroProducto($qb, $filtros, [
'start' => $range["start"],
'end' => $range["end"]
]);
return $qb->getQuery()->getResult();
}
public function productoStock($filtros = [], $stock) {
$qb = $this->createQueryBuilder('AR');
$qb ->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
->where('1 = 1')
->andWhere('AR.deletedAt IS NULL');
if($stock)
$qb->andWhere('AR.stock<=0');
$qb ->select( "
GR.descripcion AS GRUPO,
CAT.nombre AS CATEGORIA,
MP.nombre as MARCA,
AR.descripcion as DESCRIPCION,
AR.codigo as CODIGO,
SUM(AR.stock) AS stocks,
SUM(AR.stock * AR.costo) AS VAL_COSTO,
SUM(AR.stock * AR.precio) AS VAL_VENTA"
);
$qb = $this->addWhereFiltroProducto($qb, $filtros);
$qb->groupBy("DESCRIPCION");
//$qb->groupBy("AR.id");
$qb ->addOrderBy("DESCRIPCION", "ASC");
/*orderBy("RUBRO", "ASC")
->addOrderBy("GRUPO", "ASC")
->addOrderBy("CATEGORIA", "ASC")
->addOrderBy("MARCA", "ASC")*/
return $qb->getQuery()->getResult();
}
/**
* Obtiene productos solo con stock (sin información de precios/costos)
* @param array $filtros
* @return array
*/
public function productoStockSoloConStock($filtros = []) {
$qb = $this->createQueryBuilder('AR');
$qb->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
->leftJoin('AR.proveedor', 'PRO')
->where('1 = 1')
->andWhere('AR.deletedAt IS NULL')
->andWhere('AR.stock > 0'); // Solo productos con stock
$qb->select("
GR.descripcion AS GRUPO,
CAT.nombre AS CATEGORIA,
MP.nombre as MARCA,
PRO.nombre as PROVEEDOR,
AR.descripcion as DESCRIPCION,
AR.codigo as CODIGO,
SUM(AR.stock) AS stocks
");
$qb = $this->addWhereFiltroProducto($qb, $filtros);
$qb->groupBy("DESCRIPCION")
->addOrderBy("DESCRIPCION", "ASC");
return $qb->getQuery()->getResult();
}
public function productoTalles($filtros = []) {
$qb = $this->createQueryBuilder('AR');
$qb ->leftJoin('AR.rubro', 'RB')
->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
->leftJoin('AR.talle', 'TA')
->leftJoin('AR.color', 'CO')
->where('1 = 1');
$qb ->select( "TA.id AS ID, TA.talle AS VALUE, SUM(AR.stock) AS STOCK");
$qb = $this->addWhereFiltroProducto($qb, $filtros);
$qb->groupBy("ID");
$qb ->addOrderBy("VALUE", "ASC");
return $qb->getQuery()->getResult();
}
// public function ExtraColumnsXLS($filtros = []){
// $qb = $this->createQueryBuilder('AR');
//
// $qb ->leftJoin('AR.talle', 'TA')->where('1 = 1');
//
// $qb ->select( 'GROUP_CONCAT(DISTINCT TA.talle) AS TALLES');
//
// $qb = $this->addWhereFiltroProducto($qb, $filtros);
//
// $qb->groupBy("TA.talle");
//
// $qb ->orderBy("TALLES", "ASC");
//
// return $qb->getQuery()->getResult();
// }
private function addWhereFiltroProducto(QueryBuilder $qb, $filtros, $parameters = []) {
// if (key_exists("rubros", $filtros)) {
//
// $qb ->andWhere('AR.rubro in (:rubros)');
// $parameters["rubros"] = is_array($filtros["rubros"]) ? :explode(",", $filtros["rubros"]);
// }
if (key_exists("grupos", $filtros)) {
$qb ->andWhere('AR.grupo in (:grupos)');
$parameters["grupos"] = is_array($filtros["grupos"]) ? $filtros["grupos"] : explode(",", $filtros["grupos"]);
}
if (key_exists("categorias", $filtros)) {
$qb ->andWhere('AR.categoria in (:categorias)');
$parameters["categorias"] = is_array($filtros["categorias"]) ? $filtros["categorias"] : explode(",", $filtros["categorias"]);
}
if (key_exists("marcas", $filtros)) {
$qb ->andWhere('AR.marca_producto in (:marcas)');
$parameters["marcas"] = is_array($filtros["marcas"]) ? $filtros["marcas"] : explode(",", $filtros["marcas"]);
}
// if (key_exists("disciplinas", $filtros)) {
//
// $qb ->andWhere('AR.disciplina in (:disciplinas)');
// $parameters["disciplinas"] = is_array($filtros["disciplinas"]) ? :explode(",", $filtros["disciplinas"]);
// }
// if (key_exists("generos", $filtros)) {
//
// $qb ->andWhere('AR.genero in (:generos)');
// $parameters["generos"] = is_array($filtros["generos"]) ? :explode(",", $filtros["generos"]);
// }
if (key_exists("proveedores", $filtros) && $filtros["proveedores"]) {
$qb ->andWhere('AR.proveedor in (:proveedores)');
$parameters["proveedores"] = is_array($filtros["proveedores"]) ? $filtros["proveedores"] : explode(",", $filtros["proveedores"]);
}
$qb->setParameters($parameters);
return $qb;
}
public function getSyncList($date, $activo = true) {
$qb = $this->createQueryBuilder('u')
->leftJoin('u.grupo', 'g') // Realiza el LEFT JOIN con la tabla grupo
->where('u.cantidadImagenes > 0')
->andWhere('g.web_ignored != 1'); // Añade la condición para web_ignored
if ($activo) {
$qb->andWhere('u.deletedAt IS NULL');
} else {
$qb->andWhere('u.deletedAt IS NOT NULL');
}
if ($date) {
$qb->andWhere('u.updatedAt IS NULL OR u.updatedAt >= :updatedDate')
->setParameter('updatedDate', $date);
}
$qb->orderBy('u.updatedAt', 'DESC');
return $qb->getQuery()->getResult();
}
public function listadePrecios($filtros = [] )
{
$qb = $this->createQueryBuilder('AR');
$qb->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
->where('1 = 1')
->andWhere('AR.categoria != 49')
->andWhere('AR.deletedAt is null');
$qb = $this->addWhereFiltroProducto($qb, $filtros);
return $qb->getQuery()->getResult();
}
public function StockMinimo($filtros = [] )
{
$qb = $this->createQueryBuilder('AR');
$qb->leftJoin('AR.grupo', 'GR')
->leftJoin('AR.categoria', 'CAT')
->leftJoin('AR.marca_producto', 'MP')
->where('1 = 1')
->andWhere('AR.deletedAt is null')
->andWhere('AR.categoria != 49')
->andWhere('AR.stock <= AR.stockMinimo');
$qb = $this->addWhereFiltroProducto($qb, $filtros);
return $qb->getQuery()->getResult();
}
public function ActualizoPrecios($codigo)
{
$codigo = strtoupper(trim($codigo));
$qb = $this->createQueryBuilder('a');
$qb->where('UPPER(a.codigotwo) = :codigo')
->orWhere('UPPER(a.codigo) = :codigo')
->setParameter('codigo', $codigo);
return $qb->getQuery()->getOneOrNullResult();
}
}