0) { $protocoloId = Protocolo::create([ 'servico_tipo_id' => BnafarServicoTipo::SAIDA, 'operacao_tipo_id' => BnafarOperacaoTipo::OPERACAO_INCLUSAO_REGISTRO, ])->id; } foreach ($saidas as $saida) { $saidaId = DB::table('integracao_bnafar_saida') ->where('almoxarifado_saida_id', $saida->almoxarifado_saida_id) ->whereRaw(' ( SELECT COUNT(*) FROM integracao_bnafar_saida_item WHERE integracao_bnafar_saida_item.saida_id = integracao_bnafar_saida.id ) < ' . self::ITENS_POR_SAIDA . ' ') ->first()->id ?? null; if (is_null($saidaId)) { $protocoloId = DB::table('integracao_bnafar_protocolo') ->where('id', $protocoloId) ->whereRaw(' ( SELECT COUNT(*) FROM integracao_bnafar_saida WHERE integracao_bnafar_saida.protocolo_id = integracao_bnafar_protocolo.id ) < ' . self::SAIDAS_POR_PROTOCOLO . ' ') ->first()->id ?? null; if (is_null($protocoloId)) { $protocoloId = Protocolo::create([ 'servico_tipo_id' => BnafarServicoTipo::SAIDA, 'operacao_tipo_id' => BnafarOperacaoTipo::OPERACAO_INCLUSAO_REGISTRO, ])->id; } $saidaId = Saida::create([ 'protocolo_id' => $protocoloId, 'saida_tipo_id' => self::getSaidaTipo($saida->saida_tipo_id), 'almoxarifado_saida_id' => $saida->almoxarifado_saida_id, 'centro_custo_id' => $saida->centro_custo_id, 'data_saida' => $saida->data_saida, 'centro_custo_destino_id' => $saida->centro_custo_destino_id, ])->id; } SaidaItem::create([ 'saida_id' => $saidaId, 'almoxarifado_saida_item_id' => $saida->almoxarifado_saida_item_id, 'material_id' => $saida->material_id, 'fabricante_id' => $saida->fabricante_id, 'integracao_bnafar_medicamento_id' => $saida->integracao_bnafar_medicamento_id, 'lote' => $saida->lote, 'data_validade' => $saida->data_validade, 'quantidade' => $saida->quantidade, 'valor_unitario' => $saida->valor_unitario, ]); } } public static function post($cliente, $token, $ibge) { $protocolos = self::getSaidas(); foreach ($protocolos as $protocolo) { try { $response = BnafarService::post(['action' => 'saida-lote', 'token' => $token, 'ibge' => $ibge], $protocolo['saidas']); if (isset($response['protocolo'])) { Protocolo::where('id', $protocolo['id'])->update([ 'processamento_status_id' => $response['situacao'], 'protocolo' => $response['protocolo'], 'data_protocolo' => $response['dataProtocolo'], ]); } else { Protocolo::where('id', $protocolo['id'])->update(['processamento_status_id' => BnafarProcessamentoStatus::ERRO_INTERNO_SERVIDOR]); ProtocoloResposta::create([ 'protocolo_id' => $protocolo['id'], 'resposta' => json_encode($response->json()), ]); } } catch (Exception $error) { Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [ 'cliente' => $cliente, 'origem' => 'PosicaoEstoqueService', 'erro' => $error->getMessage(), ]); if (env('APP_ENV') === 'production') { TelegramService::send('Integração BNAFAR (' . $cliente . '): (Erro ao executar o comando: EnviarPosicaoEstoqueCommand).'); } continue; } } } public static function check($cliente, $token, $ibge) { Protocolo::whereNull('protocolo')->delete(); $protocolos = self::getProtocolos(); foreach ($protocolos as $protocolo) { try { $response = BnafarService::getDetalheProcessamento($token, $ibge, $protocolo->protocolo); if (isset($response['protocolo'])) { Protocolo::where('id', $protocolo->id)->update(['processamento_status_id' => $response['protocolo']['situacao']]); } $resposta = BnafarService::getInconsistencias($token, $ibge, $protocolo->protocolo); if (!is_null($resposta)) { ProtocoloResposta::create([ 'protocolo_id' => $protocolo->id, 'resposta' => $resposta, ]); self::salvarInconsistenciasItens($resposta); } else { ProtocoloResposta::where('protocolo_id', $protocolo->id)->delete(); } if (isset($response['itensProcessados'])) { foreach ($response['itensProcessados'] as $itemProcessado) { Saida::where('id', $itemProcessado['codigoOrigem'])->update([ 'codigo_registro' => isset($itemProcessado['codigoBnafar']) && $itemProcessado['codigoBnafar'] > 0 ? $itemProcessado['codigoBnafar'] : null, 'processado_sucesso' => $itemProcessado['sucesso'], ]); } } } catch (Exception $error) { Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [ 'cliente' => $cliente, 'origem' => 'PosicaoEstoqueService', 'erro' => $error->getMessage(), ]); if (env('APP_ENV') === 'production') { TelegramService::send('Integração BNAFAR (' . $cliente . '): (Erro ao executar o comando: EnviarPosicaoEstoqueCommand).'); } continue; } } } private static function salvarInconsistenciasItens($resposta) { collect(json_decode($resposta, true)) ->pluck('inconsistencias') ->filter() ->flatten(1) ->groupBy('codigoOrigem') ->each(function ($inconsistencias, $codigoOrigem) { $mensagem = $inconsistencias ->pluck('mensagem') ->map(fn ($mensagem) => BnafarService::formatarMensagem($mensagem)) ->filter() ->unique() ->implode(' '); SaidaItem::where('id', $codigoOrigem)->update(['mensagem' => $mensagem]); }); } private static function getSaidas() { return DB::table('integracao_bnafar_protocolo') ->select('id') ->where('servico_tipo_id', BnafarServicoTipo::SAIDA) ->whereNull('integracao_bnafar_protocolo.processamento_status_id') ->get() ->map(function($protocolo) { $saidas = DB::table('integracao_bnafar_saida') ->select([ 'cadastro_unidade.cnes AS cnes', 'cadastro_setor.id AS setor_tipo_id', 'integracao_bnafar_saida.id AS codigo_origem', DB::raw("DATE_FORMAT(integracao_bnafar_saida.data_saida, '%Y-%m-%d') AS data_saida"), 'cadastro_unidade_destino.cnes AS estabelecimento_destino', 'integracao_bnafar_saida_tipo.codigo AS tipo_saida', ]) ->join('cadastro_centro_custo', 'cadastro_centro_custo.id', 'integracao_bnafar_saida.centro_custo_id') ->join('cadastro_setor', 'cadastro_setor.id', 'cadastro_centro_custo.setor_id') ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_centro_custo.infraestrutura_id') ->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id') ->join('cadastro_centro_custo AS cadastro_centro_custo_destino', 'cadastro_centro_custo_destino.id', 'integracao_bnafar_saida.centro_custo_destino_id') ->join('cadastro_infraestrutura AS cadastro_infraestrutura_destino', 'cadastro_infraestrutura_destino.id', 'cadastro_centro_custo_destino.infraestrutura_id') ->join('cadastro_unidade AS cadastro_unidade_destino', 'cadastro_unidade_destino.id', 'cadastro_infraestrutura_destino.unidade_id') ->join('integracao_bnafar_saida_tipo', 'integracao_bnafar_saida_tipo.id', 'integracao_bnafar_saida.saida_tipo_id') ->where('integracao_bnafar_saida.protocolo_id', $protocolo->id) ->where('cadastro_unidade_destino.cnes', '!=', null) ->where(function($query) { $query ->whereNull('integracao_bnafar_saida.processado_sucesso') ->orWhere('integracao_bnafar_saida.processado_sucesso', false); }) ->get() ->map(function($saida) { $itens = DB::table('integracao_bnafar_saida_item') ->select([ 'integracao_bnafar_saida_item.id AS codigo_origem', 'cadastro_material_bnafar.codigo AS numero', 'cadastro_material_bnafar.tipo AS tipo_produto', 'integracao_bnafar_saida_item.lote', DB::raw("DATE_FORMAT(integracao_bnafar_saida_item.data_validade, '%Y-%m-%d') AS data_validade"), 'cadastro_fabricante.tipo_id AS tipo_fabricante', 'cadastro_fabricante.cnpj AS cnpj_fabricante', 'cadastro_fabricante.nome AS nome_fabricante', 'integracao_bnafar_medicamento.codigo AS integracao_bnafar_medicamento_codigo', 'integracao_bnafar_saida_item.quantidade', 'integracao_bnafar_saida_item.valor_unitario', ]) ->join('cadastro_material', 'cadastro_material.id', 'integracao_bnafar_saida_item.material_id') ->join('cadastro_material_bnafar', 'cadastro_material_bnafar.id', 'cadastro_material.material_bnafar_id') ->join('cadastro_fabricante', 'cadastro_fabricante.id', 'integracao_bnafar_saida_item.fabricante_id') ->leftJoin('integracao_bnafar_medicamento', 'integracao_bnafar_medicamento.id', 'integracao_bnafar_saida_item.integracao_bnafar_medicamento_id') ->where('integracao_bnafar_saida_item.saida_id', $saida->codigo_origem) ->get() ->map(function($item) { return [ 'codigoOrigem' => $item->codigo_origem, 'numero' => $item->numero, 'terminologia' => $item->integracao_bnafar_medicamento_codigo ? 'OBM' : 'CATMAT', 'codigoAmpp' => $item->integracao_bnafar_medicamento_codigo, 'tipoProduto' => $item->tipo_produto, 'lote' => $item->lote, 'dataValidade' => $item->data_validade, 'cnpjFabricante' => $item->tipo_fabricante === FabricanteTipo::NACIONAL ? $item->cnpj_fabricante : null, 'nomeFabricanteInternacional' => $item->tipo_fabricante === FabricanteTipo::INTERNACIONAL ? $item->nome_fabricante : null, 'quantidade' => $item->quantidade, 'valorUnitario' => $item->valor_unitario, ]; }) ->toArray(); return [ 'estabelecimento' => [ 'cnes' => $saida->cnes, 'tipo' => BnafarService::getEstabelecimentoTipo($saida->setor_tipo_id), ], 'caracterizacao' => [ 'codigoOrigem' => $saida->codigo_origem, 'dataSaida' => $saida->data_saida, 'estabelecimentoDestino' => $saida->estabelecimento_destino, 'tipoSaida' => $saida->tipo_saida, ], 'itens' => $itens, ]; }) ->toArray(); return [ 'id' => $protocolo->id, 'saidas' => $saidas, ]; }) ->toArray(); } private static function getProtocolos() { return DB::table('integracao_bnafar_protocolo') ->select([ 'id', 'protocolo', ]) ->where('servico_tipo_id', BnafarServicoTipo::SAIDA) ->where('processamento_status_id', '!=', BnafarProcessamentoStatus::PROCESSAMENTO_FINALIZADO_SEM_INCONSISTENCIA) ->whereNotNull('processamento_status_id') ->get(); } private static function getAlmoxarifadoSaidas() { return DB::table('almoxarifado_saida_item') ->select([ 'almoxarifado_saida.tipo_id AS saida_tipo_id', 'almoxarifado_saida.id AS almoxarifado_saida_id', 'almoxarifado_saida.centro_custo_id', DB::raw("DATE_FORMAT(almoxarifado_saida.created_at, '%Y-%m-%d') AS data_saida"), 'almoxarifado_saida_item.id AS almoxarifado_saida_item_id', 'almoxarifado_saida_item.material_id', 'almoxarifado_entrada_item.fabricante_id', 'almoxarifado_entrada_item.integracao_bnafar_medicamento_id', 'almoxarifado_entrada_item.lote AS lote', DB::raw("DATE_FORMAT(almoxarifado_entrada_item.validade_lote, '%Y-%m-%d') AS data_validade"), 'almoxarifado_saida_item_entrada_item.quantidade_saida AS quantidade', 'almoxarifado_entrada_item.valor_unitario', DB::raw(" ( CASE almoxarifado_saida.tipo_id WHEN " . SaidaTipo::MANUAL . " THEN ( select centro_custo_id from almoxarifado_saida_requisicao where almoxarifado_saida_requisicao.saida_id = almoxarifado_saida.id ) WHEN " . SaidaTipo::REQUISICAO . " THEN ( select almoxarifado_requisicao.created_centro_custo_id from almoxarifado_requisicao_resposta_item inner join almoxarifado_requisicao_item on almoxarifado_requisicao_item.id = almoxarifado_requisicao_resposta_item.requisicao_item_id inner join almoxarifado_requisicao on almoxarifado_requisicao.id = almoxarifado_requisicao_item.requisicao_id where almoxarifado_requisicao_resposta_item.saida_item_id = almoxarifado_saida_item.id ) WHEN " . SaidaTipo::INVENTARIO . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::ESTORNO . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::BAIXA . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::TRANSFERENCIA . " THEN ( select almoxarifado_saida_transferencia.centro_custo_id from almoxarifado_saida_transferencia where almoxarifado_saida_transferencia.saida_id = almoxarifado_saida.id ) END ) AS centro_custo_destino_id ") ]) ->join('almoxarifado_saida', 'almoxarifado_saida.id', 'almoxarifado_saida_item.saida_id') ->join('almoxarifado_saida_item_entrada_item', 'almoxarifado_saida_item_entrada_item.saida_item_id', 'almoxarifado_saida_item.id') ->join('almoxarifado_entrada_item', 'almoxarifado_entrada_item.id', 'almoxarifado_saida_item_entrada_item.entrada_item_id') ->where('almoxarifado_saida.finalizada', true) ->where('almoxarifado_saida.tipo_id', '<>', SaidaTipo::DISPENSACAO_FARMACIA) ->whereRaw("CAST(almoxarifado_saida.created_at AS DATE) >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)") ->whereNotNull('almoxarifado_entrada_item.fabricante_id') ->whereNotNull('almoxarifado_entrada_item.lote') ->where(DB::raw('ROUND(almoxarifado_entrada_item.valor_unitario, 2)'), '>', 0) ->whereRaw(" ( CASE almoxarifado_saida.tipo_id WHEN " . SaidaTipo::MANUAL . " THEN ( select centro_custo_id from almoxarifado_saida_requisicao where almoxarifado_saida_requisicao.saida_id = almoxarifado_saida.id ) WHEN " . SaidaTipo::REQUISICAO . " THEN ( select almoxarifado_requisicao.created_centro_custo_id from almoxarifado_requisicao_resposta_item inner join almoxarifado_requisicao_item on almoxarifado_requisicao_item.id = almoxarifado_requisicao_resposta_item.requisicao_item_id inner join almoxarifado_requisicao on almoxarifado_requisicao.id = almoxarifado_requisicao_item.requisicao_id where almoxarifado_requisicao_resposta_item.saida_item_id = almoxarifado_saida_item.id ) WHEN " . SaidaTipo::INVENTARIO . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::ESTORNO . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::BAIXA . " THEN almoxarifado_saida.centro_custo_id WHEN " . SaidaTipo::TRANSFERENCIA . " THEN ( select almoxarifado_saida_transferencia.centro_custo_id from almoxarifado_saida_transferencia where almoxarifado_saida_transferencia.saida_id = almoxarifado_saida.id ) END ) IS NOT NULL ") ->whereExists(fn ($q) => $q ->select(DB::raw(1)) ->from('cadastro_material') ->join('cadastro_material_bnafar', 'cadastro_material_bnafar.id', 'cadastro_material.material_bnafar_id') ->whereColumn('cadastro_material.id', 'almoxarifado_saida_item.material_id') ) ->whereNotExists(function ($query) { $query->select(DB::raw(1)) ->from('integracao_bnafar_saida') ->whereColumn('integracao_bnafar_saida.almoxarifado_saida_id', 'almoxarifado_saida.id'); }) ->get(); } private static function getSaidaTipo($saidaTipoId) { $saidaTipo = null; if ($saidaTipoId === SaidaTipo::INVENTARIO) { $saidaTipo = BnafarSaidaTipo::SAIDA_POR_AJUSTE_ESTOQUE; } else if ($saidaTipoId === SaidaTipo::ESTORNO) { $saidaTipo = BnafarSaidaTipo::DEVOLUCAO_DE_ENTRADA_PRODUTO; } else if ($saidaTipoId === SaidaTipo::BAIXA) { $saidaTipo = BnafarSaidaTipo::SAIDA_POR_PERDA; } else if ($saidaTipoId === SaidaTipo::MANUAL || $saidaTipoId === SaidaTipo::REQUISICAO || $saidaTipoId === SaidaTipo::TRANSFERENCIA) { $saidaTipo = BnafarSaidaTipo::SAIDA_POR_TRANSFERENCIA_REMANEJAMENTO; } return $saidaTipo; } }