This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\WebService\Almoxarifado\Cliente;
|
||||
|
||||
use App\Enums\Almoxarifado\SaidaTipo;
|
||||
use App\Exceptions\WebService\Almoxarifado\Cliente\Saida\InvalidSearchPeriodException;
|
||||
use App\Models\WebService\Almoxarifado\Cliente\Unidade;
|
||||
use App\Services\Service;
|
||||
use App\Utils\DataUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class SaidaService extends Service
|
||||
{
|
||||
public const LIMITE_DIAS_PERIODO_BUSCA = 31;
|
||||
|
||||
public static function index($request)
|
||||
{
|
||||
self::validateIndex($request);
|
||||
|
||||
$unidadeAlmoxarifado = Unidade::find($request->unidade_almoxarifado_id);
|
||||
$unidadeRequisitante = is_null($request->unidade_id) ? null : Unidade::find($request->unidade_id);
|
||||
|
||||
$dataInicial = Carbon::create($request->data_inicial)->startOfDay();
|
||||
$dataFinal = Carbon::create($request->data_final)->endOfDay();
|
||||
|
||||
$saidas = DB::table('almoxarifado_saida_item_entrada_item AS saida_item_entrada_item')
|
||||
->join(
|
||||
'almoxarifado_entrada_item AS entrada_item',
|
||||
'entrada_item.id',
|
||||
'saida_item_entrada_item.entrada_item_id'
|
||||
)
|
||||
->join(
|
||||
'almoxarifado_saida_item AS saida_item',
|
||||
'saida_item.id',
|
||||
'saida_item_entrada_item.saida_item_id'
|
||||
)
|
||||
->join(
|
||||
'almoxarifado_saida AS saida',
|
||||
'saida.id',
|
||||
'saida_item.saida_id'
|
||||
)
|
||||
->join(
|
||||
'web_service_almoxarifado_cliente_material AS cliente_material',
|
||||
'cliente_material.conectasus_material_id',
|
||||
'saida_item.material_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'almoxarifado_saida_requisicao AS saida_requisicao',
|
||||
'saida_requisicao.saida_id',
|
||||
'saida.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'almoxarifado_saida_transferencia AS saida_transferencia',
|
||||
'saida_transferencia.saida_id',
|
||||
'saida.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'almoxarifado_requisicao_resposta AS requisicao_resposta',
|
||||
'requisicao_resposta.saida_id',
|
||||
'saida.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'almoxarifado_requisicao AS requisicao',
|
||||
'requisicao.id',
|
||||
'requisicao_resposta.requisicao_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'web_service_almoxarifado_cliente_unidade AS cliente_unidade_requisitante',
|
||||
'cliente_unidade_requisitante.conectasus_centro_custo_id',
|
||||
DB::raw("COALESCE(
|
||||
saida_requisicao.centro_custo_id,
|
||||
saida_transferencia.centro_custo_id,
|
||||
requisicao.created_centro_custo_id
|
||||
)")
|
||||
)
|
||||
->where('saida.finalizada', true)
|
||||
->where('saida.centro_custo_id', $unidadeAlmoxarifado->conectasus_centro_custo_id)
|
||||
->whereBetween('saida.created_at', [$dataInicial, $dataFinal])
|
||||
->where('saida.tipo_id', '<>', SaidaTipo::ESTORNO)
|
||||
->when($unidadeRequisitante->conectasus_centro_custo_id ?? null, fn ($q, $id) => $q->where(fn ($q) => $q
|
||||
->where('saida_requisicao.centro_custo_id', $id)
|
||||
->orWhere('saida_transferencia.centro_custo_id', $id)
|
||||
->orWhere('requisicao.created_centro_custo_id', $id)
|
||||
))
|
||||
->when(DataUtil::isStringBoolean($request->query('is_estornada')), fn ($q) => $q
|
||||
->when(DataUtil::isStringTrue($request->query('is_estornada')),
|
||||
fn ($q) => $q->whereNotNull('saida_item.estornado_em'),
|
||||
fn ($q) => $q->whereNull('saida_item.estornado_em')
|
||||
)
|
||||
)
|
||||
->select([
|
||||
DB::raw("CAST(saida.created_at AS DATE) AS data"),
|
||||
DB::raw("CAST(saida_item.estornado_em AS DATE) AS data_estorno"),
|
||||
'cliente_unidade_requisitante.id AS unidade_id',
|
||||
'cliente_material.id AS material_id',
|
||||
'entrada_item.lote',
|
||||
'entrada_item.validade_lote',
|
||||
DB::raw('IF(saida_item.estornado_em IS NULL, 0, 1) AS is_estornada'),
|
||||
DB::raw("SUM(saida_item_entrada_item.quantidade_saida) AS quantidade"),
|
||||
])
|
||||
->orderBy('saida.created_at')
|
||||
->orderBy('saida_item.estornado_em')
|
||||
->groupBy([
|
||||
DB::raw("CAST(saida.created_at AS DATE)"),
|
||||
DB::raw("CAST(saida_item.estornado_em AS DATE)"),
|
||||
'cliente_unidade_requisitante.id',
|
||||
'cliente_material.id',
|
||||
'entrada_item.lote',
|
||||
'entrada_item.validade_lote',
|
||||
DB::raw('IF(saida_item.estornado_em IS NULL, 0, 1)'),
|
||||
])
|
||||
->get();
|
||||
|
||||
return tap($saidas)->each(function ($saida) {
|
||||
|
||||
$saida->is_estornada = (bool) $saida->is_estornada;
|
||||
$saida->quantidade = (int) $saida->quantidade;
|
||||
});
|
||||
}
|
||||
|
||||
private static function validateIndex($request)
|
||||
{
|
||||
$request->validate([
|
||||
'data_inicial' => [
|
||||
'required',
|
||||
'date_format:Y-m-d',
|
||||
'before_or_equal:data_final',
|
||||
],
|
||||
'data_final' => [
|
||||
'required',
|
||||
'date_format:Y-m-d',
|
||||
'after_or_equal:data_inicial',
|
||||
],
|
||||
'unidade_almoxarifado_id' => [
|
||||
'bail',
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Unidade::class, 'id'),
|
||||
function ($attribute, $value, $fail) {
|
||||
|
||||
if (!Unidade::find($value)->is_almoxarifado) {
|
||||
|
||||
$fail("O campo {$attribute} não é um almoxarifado.");
|
||||
}
|
||||
},
|
||||
function ($attribute, $value, $fail) {
|
||||
|
||||
if (is_null(Unidade::find($value)->conectasus_centro_custo_id)) {
|
||||
|
||||
$fail("O campo {$attribute} não está vinculado com um centro de custo do ConectaSUS.");
|
||||
}
|
||||
},
|
||||
],
|
||||
'unidade_id' => [
|
||||
'bail',
|
||||
'integer',
|
||||
Rule::exists(Unidade::class, 'id'),
|
||||
function ($attribute, $value, $fail) {
|
||||
|
||||
if (is_null(Unidade::find($value)->conectasus_centro_custo_id)) {
|
||||
|
||||
$fail("O campo {$attribute} não está vinculado com um centro de custo do ConectaSUS.");
|
||||
}
|
||||
},
|
||||
],
|
||||
'is_estornada' => [
|
||||
'string',
|
||||
Rule::in('true', 'false'),
|
||||
]
|
||||
]);
|
||||
|
||||
$dataInicial = Carbon::create($request->data_inicial);
|
||||
$dataFinal = Carbon::create($request->data_final);
|
||||
|
||||
if ($dataInicial->diff($dataFinal)->days > self::LIMITE_DIAS_PERIODO_BUSCA) {
|
||||
|
||||
throw new InvalidSearchPeriodException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user