<?php
declare(strict_types=1);
namespace App\Admin;
use App\Entity\ServicoPropostaComercial;
use Doctrine\ORM\QueryBuilder;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
final class ServicoBoletimMedicaoAdmin extends AbstractAdmin
{
protected $datagridValues = [
'_page' => 1,
'_sort_order' => 'DESC',
'_sort_by' => 'id',
'_per_page' => 50
];
protected $maxPerPage = 50;
protected $perPageOptions = [25, 50, 100, 200];
protected function configureRoutes(RouteCollection $collection)
{
$collection->add('editableList');
$collection->add('updateQuantidade', $this->getRouterIdParameter().'/update-quantidade');
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
$datagridMapper
->add('id')
->add('boletim.numero', null, ['label' => 'Número BM'])
->add('proposta.numero', null, ['label' => 'Número Proposta'])
->add('quantidade')
;
}
protected function configureListFields(ListMapper $listMapper): void
{
$listMapper
->add('boletim.numero', null, ['label' => 'Número BM'])
->add('proposta.numero', null, ['label' => 'Nº Proposta'])
->add('servico.servico.titulo', null, ['label' => 'Título do Serviço'])
->add('servico.valor', null, ['label' => 'Valor'])
->add('quantidade', null, ['editable' => true])
->add('_action', null, [
'actions' => [
'show' => [],
'edit' => [],
],
]);
}
protected function configureFormFields(FormMapper $formMapper): void
{
$formMapper
->add('servico', null, ['label'=>'Serviço','disabled' => true])
->add('quantidade', MoneyType::class, [
'label' => 'Quantidade do Serviço',
'currency' => 'BRL',
'grouping' => true,
'required' => false,
'help'=>'* Este valor será usado somente nesse boletim.',
'attr' => ['class' => 'notusesimbolvaluefloat maskMoney'],
])
;
}
protected function configureShowFields(ShowMapper $showMapper): void
{
$showMapper
->add('id')
->add('quantidade')
;
}
/**
* Otimização de query para evitar N+1 queries
*/
protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
$query = parent::configureQuery($query);
$rootAlias = current($query->getRootAliases());
$query
->leftJoin($rootAlias . '.boletim', 'bm')
->leftJoin($rootAlias . '.proposta', 'prop')
->leftJoin($rootAlias . '.servico', 'spc')
->leftJoin('spc.servico', 's')
->addSelect('bm, prop, spc, s');
return $query;
}
public function updateQuantidadeAction(Request $request)
{
$id = $request->get($this->admin->getIdParameter());
$object = $this->admin->getObject($id);
if (!$object) {
return new JsonResponse(['success' => false, 'message' => 'Objeto não encontrado'], 404);
}
try {
$quantidade = $request->request->get('quantidade');
$valor = $request->request->get('valor');
$servicoId = $request->request->get('servicoId');
if ($quantidade === null) {
return new JsonResponse(['success' => false, 'message' => 'Quantidade não fornecida'], 400);
}
// Atualizar quantidade do ServicoBoletimMedicao
$object->setQuantidade((float) $quantidade);
// Se o valor foi fornecido, atualizar o valor no ServicoPropostaComercial
if ($valor !== null && $servicoId) {
$em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
$servicoPropostaComercial = $em->getRepository(ServicoPropostaComercial::class)->find($servicoId);
if ($servicoPropostaComercial) {
$servicoPropostaComercial->setValor((float) $valor);
}
}
$this->admin->update($object);
return new JsonResponse([
'success' => true,
'message' => 'Dados atualizados com sucesso',
'quantidade' => $object->getQuantidade(),
'valor' => $valor
]);
} catch (\Exception $e) {
return new JsonResponse([
'success' => false,
'message' => 'Erro ao atualizar: ' . $e->getMessage()
], 500);
}
}
}