This commit is contained in:
57
.dockerignore
Normal file
57
.dockerignore
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Contexto do build e a raiz do repositorio (api/ + frontend/).
|
||||||
|
|
||||||
|
# Credenciais — os .example precisam entrar (o build gera caches com eles).
|
||||||
|
**/.env
|
||||||
|
**/.env.*
|
||||||
|
!api/.env.example
|
||||||
|
api/connections.json
|
||||||
|
!api/connections.json.example
|
||||||
|
api/storage/*.key
|
||||||
|
|
||||||
|
# Reconstruidos dentro da imagem.
|
||||||
|
api/vendor/
|
||||||
|
frontend/node_modules/
|
||||||
|
frontend/dist/
|
||||||
|
|
||||||
|
# Dados de runtime.
|
||||||
|
api/storage/logs/*
|
||||||
|
api/storage/framework/cache/*
|
||||||
|
api/storage/framework/sessions/*
|
||||||
|
api/storage/framework/views/*
|
||||||
|
api/storage/framework/testing/*
|
||||||
|
api/storage/app/public/*
|
||||||
|
api/storage/app/documento/*
|
||||||
|
api/storage/app/intranet/*
|
||||||
|
api/storage/pronto-atendimento/*
|
||||||
|
api/bootstrap/cache/*
|
||||||
|
api/public/storage
|
||||||
|
api/public/hot
|
||||||
|
|
||||||
|
# Nao entram na imagem: deploy antigo (bare metal) e ferramentas de repo.
|
||||||
|
config/
|
||||||
|
scripts/
|
||||||
|
README.md
|
||||||
|
.git
|
||||||
|
.gitea
|
||||||
|
.github
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
api/docker-compose.yml
|
||||||
|
api/webpack.mix.js
|
||||||
|
api/package.json
|
||||||
|
api/package-lock.json
|
||||||
|
api/tests/
|
||||||
|
api/phpunit.xml
|
||||||
|
api/.phpunit.result.cache
|
||||||
|
api/.styleci.yml
|
||||||
|
api/.editorconfig
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
*.log
|
||||||
|
routes.txt
|
||||||
|
TODO*
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
8
.gitea/runner/.env.example
Normal file
8
.gitea/runner/.env.example
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
GITEA_INSTANCE_URL=http://192.168.0.41:3001
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN=
|
||||||
|
|
||||||
|
RUNNER_NAME=conectasus-runner-01
|
||||||
|
RUNNER_LABELS=ubuntu-latest:docker://gitea/runner-images:ubuntu-latest
|
||||||
|
|
||||||
|
ACT_RUNNER_IMAGE=gitea/act_runner:0.6.1
|
||||||
|
TZ=America/Sao_Paulo
|
||||||
106
.gitea/runner/README.md
Normal file
106
.gitea/runner/README.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# Runner do Gitea (act_runner)
|
||||||
|
|
||||||
|
Runner que executa a esteira [`build-api-image.yml`](../workflows/build-api-image.yml).
|
||||||
|
Sobe em um servidor **separado** do Gitea — o Gitea fica em `192.168.0.41:3001`
|
||||||
|
e este compose roda na máquina que vai construir as imagens.
|
||||||
|
|
||||||
|
## Instalação
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Pegue o token de registro no Gitea e cole em `GITEA_RUNNER_REGISTRATION_TOKEN`:
|
||||||
|
|
||||||
|
| Escopo do runner | Onde pegar o token |
|
||||||
|
| --- | --- |
|
||||||
|
| Só o repositório conectasus | Repo › Settings › Actions › Runners › Create new runner |
|
||||||
|
| Toda a organização `rkm` | Org › Settings › Actions › Runners |
|
||||||
|
| Instância inteira | Site Administration › Actions › Runners |
|
||||||
|
|
||||||
|
Depois:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
docker compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
O runner aparece como online em Settings › Actions › Runners do Gitea. O token de
|
||||||
|
registro é usado uma única vez; a credencial permanente fica em `./data/.runner`.
|
||||||
|
|
||||||
|
## O que o compose faz
|
||||||
|
|
||||||
|
| Item | Motivo |
|
||||||
|
| --- | --- |
|
||||||
|
| `/var/run/docker.sock` montado | O `act_runner` usa o daemon do host para criar os containers de job **e** repassa o socket para dentro deles. É isso que faz o `docker build` da esteira funcionar. |
|
||||||
|
| `./data` | Guarda o registro do runner. Apagar essa pasta força novo registro. |
|
||||||
|
| Label `ubuntu-latest:docker://gitea/runner-images:ubuntu-latest` | Casa com o `runs-on: ubuntu-latest` do workflow. Essa imagem (0,57 GB) já traz `docker`, `git`, `node`, `bash` e `curl` — tudo que a esteira usa. A variante `-full` tem 17,6 GB e não é necessária. |
|
||||||
|
|
||||||
|
Como o Gitea está em outro servidor, tudo que aponta para ele é configuração:
|
||||||
|
`GITEA_INSTANCE_URL` e o token vêm do `.env`, nada fixo no compose. Se as
|
||||||
|
variáveis obrigatórias faltarem, o `docker compose up` falha na hora com a
|
||||||
|
mensagem em vez de subir um runner quebrado.
|
||||||
|
|
||||||
|
## Pré-requisitos no servidor do runner
|
||||||
|
|
||||||
|
**1. Alcançar o Gitea.** O runner e os containers de job precisam falar com
|
||||||
|
`192.168.0.41:3001` (API do Actions e registry de imagens):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s http://192.168.0.41:3001/api/v1/version
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Confiar no registry via HTTP.** O registry não tem TLS, e o `docker push` da
|
||||||
|
esteira roda no daemon do host (por causa do socket montado). Então a
|
||||||
|
configuração é do host, não do compose — em `/etc/docker/daemon.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "insecure-registries": ["192.168.0.41:3001"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
Se o arquivo já existir, **acrescente ao array** em vez de sobrescrever. Depois:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl reload docker
|
||||||
|
docker info | grep -A5 'Insecure Registries'
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `reload`, não `restart`. `insecure-registries` é recarregável por SIGHUP, e
|
||||||
|
`restart` derruba todos os containers do host quando `live-restore` está
|
||||||
|
desligado (confira com `docker info --format '{{.LiveRestoreEnabled}}'`).
|
||||||
|
|
||||||
|
Sem isso o push falha com `http: server gave HTTP response to HTTPS client`.
|
||||||
|
|
||||||
|
**3. Espaço em disco.** Cada build gera uma imagem da API com o `vendor/`
|
||||||
|
completo. Convém uma limpeza periódica:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker image prune -af --filter "until=168h"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mudando o runner de máquina
|
||||||
|
|
||||||
|
O compose não tem nada preso à máquina: o Gitea é alcançado por
|
||||||
|
`GITEA_INSTANCE_URL`, que vem do `.env`. Para mover o runner basta subir o
|
||||||
|
compose no servidor novo e registrar de novo.
|
||||||
|
|
||||||
|
Na fase inicial de desenvolvimento é natural rodar na própria máquina de dev.
|
||||||
|
Duas ressalvas quando esse host também roda outros containers:
|
||||||
|
|
||||||
|
- Um `restart` do daemon Docker (necessário se você usar `restart` em vez de
|
||||||
|
`reload` para o `insecure-registries`) derruba tudo que estiver no host.
|
||||||
|
- Os builds competem por disco e CPU com os containers já existentes.
|
||||||
|
|
||||||
|
Ao migrar para o servidor do Gitea, o registro anterior deve ser removido em
|
||||||
|
Settings › Actions › Runners, e a pasta `./data` do host antigo descartada.
|
||||||
|
`GITEA_INSTANCE_URL` pode continuar apontando para o IP — não precisa virar
|
||||||
|
`localhost`.
|
||||||
|
|
||||||
|
## Notas
|
||||||
|
|
||||||
|
- Se o Gitea for acessado por hostname em vez de IP e o servidor do runner não
|
||||||
|
resolver esse nome, acrescente `extra_hosts` ao serviço no compose.
|
||||||
|
- Por padrão o runner executa **um job por vez**. Para paralelismo, monte um
|
||||||
|
`config.yaml` com `runner.capacity` e aponte `CONFIG_FILE` para ele.
|
||||||
|
- O socket do Docker montado dá ao runner controle total sobre o daemon do host.
|
||||||
|
Use um servidor dedicado a CI, não um que rode containers de produção.
|
||||||
22
.gitea/runner/compose.portainer.yml
Normal file
22
.gitea/runner/compose.portainer.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
act-runner:
|
||||||
|
image: ${ACT_RUNNER_IMAGE:-gitea/act_runner:0.6.1}
|
||||||
|
container_name: ${RUNNER_NAME:-conectasus-runner-01}
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
GITEA_INSTANCE_URL: ${GITEA_INSTANCE_URL:?informe a URL do Gitea}
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN: NJtScAqvccbNQJfdFnS8udtLsjSITXJq5bzmi41d
|
||||||
|
GITEA_RUNNER_NAME: ${RUNNER_NAME:-conectasus-runner-01}
|
||||||
|
GITEA_RUNNER_LABELS: ${RUNNER_LABELS:-ubuntu-latest:docker://gitea/runner-images:ubuntu-latest}
|
||||||
|
TZ: ${TZ:-America/Sao_Paulo}
|
||||||
|
volumes:
|
||||||
|
- runner-data:/data
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
runner-data:
|
||||||
21
.gitea/runner/compose.yml
Normal file
21
.gitea/runner/compose.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: gitea-runner
|
||||||
|
|
||||||
|
services:
|
||||||
|
act-runner:
|
||||||
|
image: ${ACT_RUNNER_IMAGE:-gitea/act_runner:0.6.1}
|
||||||
|
container_name: ${RUNNER_NAME:-conectasus-runner-01}
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
GITEA_INSTANCE_URL: ${GITEA_INSTANCE_URL:?defina GITEA_INSTANCE_URL no .env}
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN: ${GITEA_RUNNER_REGISTRATION_TOKEN:?defina GITEA_RUNNER_REGISTRATION_TOKEN no .env}
|
||||||
|
GITEA_RUNNER_NAME: ${RUNNER_NAME:-conectasus-runner-01}
|
||||||
|
GITEA_RUNNER_LABELS: ${RUNNER_LABELS:-ubuntu-latest:docker://gitea/runner-images:ubuntu-latest}
|
||||||
|
TZ: ${TZ:-America/Sao_Paulo}
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
453
.gitea/workflows/build-api-image.yml
Normal file
453
.gitea/workflows/build-api-image.yml
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
name: build-api-image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
# Branch = ambiente. Um merge aceito aqui constroi e implanta no ambiente
|
||||||
|
# correspondente (mapeamento no step de metadados).
|
||||||
|
- develop # -> teste
|
||||||
|
- 'release-*' # -> homologacao
|
||||||
|
- feat_CI_CD_TEST # -> teste (branch de validacao da propria esteira)
|
||||||
|
tags:
|
||||||
|
- '2.*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY_HOST || '192.168.0.41:3001' }}
|
||||||
|
IMAGE_NAME: ${{ vars.API_IMAGE_NAME || 'rkm/conectasus-api' }}
|
||||||
|
BASE_IMAGE: ${{ vars.API_BASE_IMAGE || 'tirkm/v2-application:6' }}
|
||||||
|
# O contexto e a raiz do application: o build precisa enxergar api/ e
|
||||||
|
# frontend/ ao mesmo tempo, entao Dockerfile e docker/ vivem na raiz.
|
||||||
|
CONTEXT_DIR: ${{ vars.CONTEXT_DIR || '.' }}
|
||||||
|
DOCKERFILE: ${{ vars.DOCKERFILE || 'Dockerfile' }}
|
||||||
|
# Subdiretorio da API, usado nas checagens que leem arquivos do repo
|
||||||
|
# (composer.json, migrations) — nao confundir com o contexto do build.
|
||||||
|
API_DIR: ${{ vars.API_DIR || 'api' }}
|
||||||
|
PUSH_LATEST: ${{ vars.PUSH_LATEST || 'true' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Definir metadados do build
|
||||||
|
id: meta
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${GITHUB_REF}" != "${GITHUB_REF#refs/tags/}" ]; then
|
||||||
|
IS_TAG=true
|
||||||
|
else
|
||||||
|
IS_TAG=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION=$(echo "${GITHUB_REF_NAME}" | tr '/' '-')
|
||||||
|
IMAGE="${REGISTRY}/${IMAGE_NAME}"
|
||||||
|
|
||||||
|
# Branch -> ambiente. A tag de release constroi a imagem, mas nao
|
||||||
|
# implanta nem aplica migrations: ambos exigem acao manual.
|
||||||
|
case "${GITHUB_REF_NAME}" in
|
||||||
|
develop|feat_CI_CD_TEST) AMBIENTE=teste ;;
|
||||||
|
release-*) AMBIENTE=homolog ;;
|
||||||
|
*) AMBIENTE="" ;;
|
||||||
|
esac
|
||||||
|
[ "${IS_TAG}" = "true" ] && AMBIENTE=""
|
||||||
|
|
||||||
|
# Uma imagem serve todos os ambientes: a config do frontend e resolvida
|
||||||
|
# em runtime (config.js montado no deploy), nao gravada no bundle.
|
||||||
|
# Toda imagem tambem recebe uma tag pelo commit, para rastreabilidade
|
||||||
|
# e retencao. Tags de release sempre constroem uma imagem nova a
|
||||||
|
# partir do commit marcado: a tag e o marco formal do artefato.
|
||||||
|
SHA_TAG="sha-$(echo "${GITHUB_SHA}" | cut -c1-8)"
|
||||||
|
|
||||||
|
echo "ambiente=${AMBIENTE}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "sha_tag=${SHA_TAG}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "tag_sha=${IMAGE}:${SHA_TAG}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "is_tag=${IS_TAG}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "image=${IMAGE}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "tag_version=${IMAGE}:${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "tag_latest=${IMAGE}:latest" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
echo "Evento : $([ "${IS_TAG}" = "true" ] && echo tag || echo branch)"
|
||||||
|
echo "Versao : ${VERSION}"
|
||||||
|
echo "Imagem : ${IMAGE}:${VERSION}"
|
||||||
|
echo "Base : ${BASE_IMAGE}"
|
||||||
|
|
||||||
|
- name: Conferir versao do composer.json
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ "${{ steps.meta.outputs.is_tag }}" != "true" ]; then
|
||||||
|
echo "Build de branch; comparacao com composer.json nao se aplica."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
DECLARED=$(grep -m1 '"version"' "${API_DIR}/composer.json" \
|
||||||
|
| sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')
|
||||||
|
TAG="${{ steps.meta.outputs.version }}"
|
||||||
|
|
||||||
|
if [ "${DECLARED}" != "${TAG}" ]; then
|
||||||
|
echo "::warning::composer.json declara versao '${DECLARED}' mas a tag e '${TAG}'. Build segue com a tag."
|
||||||
|
else
|
||||||
|
echo "composer.json e tag batem: ${TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Avaliar reversibilidade das migrations
|
||||||
|
id: rollback
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
PREV=$(git describe --tags --abbrev=0 "${GITHUB_REF_NAME}^" 2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ -z "${PREV}" ]; then
|
||||||
|
echo "Nenhuma tag anterior encontrada; analise de rollback ignorada."
|
||||||
|
echo "safe=unknown" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Comparando ${PREV} -> ${GITHUB_REF_NAME}"
|
||||||
|
|
||||||
|
NOVAS=$(git diff --name-only --diff-filter=A "${PREV}" "${GITHUB_REF_NAME}" \
|
||||||
|
-- "${API_DIR}/database/migrations" || true)
|
||||||
|
|
||||||
|
if [ -z "${NOVAS}" ]; then
|
||||||
|
echo "Nenhuma migration nova neste release."
|
||||||
|
echo "safe=true" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Migrations novas:"
|
||||||
|
echo "${NOVAS}" | sed 's/^/ /'
|
||||||
|
|
||||||
|
DESTRUTIVAS=""
|
||||||
|
while IFS= read -r f; do
|
||||||
|
[ -f "${f}" ] || continue
|
||||||
|
UP=$(sed '/function[[:space:]]*down[[:space:]]*(/,$d' "${f}")
|
||||||
|
if echo "${UP}" | grep -qE 'dropColumn|renameColumn|dropIfExists|DROP TABLE|DROP COLUMN'; then
|
||||||
|
DESTRUTIVAS="${DESTRUTIVAS}${f}"$'\n'
|
||||||
|
fi
|
||||||
|
done <<< "${NOVAS}"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "### Reversibilidade"
|
||||||
|
echo ""
|
||||||
|
echo "Comparado com \`${PREV}\`."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
if [ -z "${DESTRUTIVAS}" ]; then
|
||||||
|
echo "Todas as migrations novas sao aditivas."
|
||||||
|
echo "safe=true" >> "$GITHUB_OUTPUT"
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "Migrations novas sao **aditivas**. Rollback da imagem para \`${PREV}\` e seguro mesmo com o schema ja migrado."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "safe=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "${DESTRUTIVAS}" | while IFS= read -r f; do
|
||||||
|
[ -n "${f}" ] && echo "::warning file=${f}::Migration destrutiva no up(): rollback para ${PREV} nao sera seguro apos aplicar."
|
||||||
|
done
|
||||||
|
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "**Atencao: este release contem migrations destrutivas.**"
|
||||||
|
echo ""
|
||||||
|
echo "Depois de aplicar a migration, voltar a imagem para \`${PREV}\` NAO restaura o funcionamento:"
|
||||||
|
echo "o codigo antigo vai referenciar colunas/tabelas que deixaram de existir. Faca backup do banco"
|
||||||
|
echo "antes de migrar, ou planeje a correcao como hotfix para frente."
|
||||||
|
echo ""
|
||||||
|
echo "| Migration |"
|
||||||
|
echo "| --- |"
|
||||||
|
echo "${DESTRUTIVAS}" | while IFS= read -r f; do
|
||||||
|
[ -n "${f}" ] && echo "| \`${f}\` |"
|
||||||
|
done
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
- name: Login no Docker Hub (imagem base)
|
||||||
|
env:
|
||||||
|
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||||
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -z "${DOCKERHUB_TOKEN:-}" ]; then
|
||||||
|
echo "DOCKERHUB_TOKEN nao definido; assumindo imagem base publica ou ja em cache."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "${DOCKERHUB_TOKEN}" | docker login -u "${DOCKERHUB_USER}" --password-stdin
|
||||||
|
|
||||||
|
- name: Login no registry do Gitea
|
||||||
|
env:
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
USER="${REGISTRY_USER:-$ACTOR}"
|
||||||
|
TOKEN="${REGISTRY_TOKEN:-}"
|
||||||
|
|
||||||
|
if [ -z "${TOKEN}" ]; then
|
||||||
|
echo "REGISTRY_TOKEN ausente; usando o GITEA_TOKEN do job."
|
||||||
|
TOKEN="${GITEA_TOKEN}"
|
||||||
|
USER="${ACTOR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${TOKEN}" | docker login "${REGISTRY}" -u "${USER}" --password-stdin
|
||||||
|
|
||||||
|
- name: Build da imagem
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker build \
|
||||||
|
--file "${DOCKERFILE}" \
|
||||||
|
--build-arg BASE_IMAGE="${BASE_IMAGE}" \
|
||||||
|
--build-arg APP_VERSION="${{ steps.meta.outputs.version }}" \
|
||||||
|
--build-arg VCS_REF="${GITHUB_SHA}" \
|
||||||
|
--build-arg BUILD_DATE="${{ steps.meta.outputs.build_date }}" \
|
||||||
|
--build-arg SOURCE_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \
|
||||||
|
--tag "${{ steps.meta.outputs.tag_version }}" \
|
||||||
|
--tag "${{ steps.meta.outputs.tag_sha }}" \
|
||||||
|
"${CONTEXT_DIR}"
|
||||||
|
|
||||||
|
- name: Smoke test da imagem
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
IMG="${{ steps.meta.outputs.tag_version }}"
|
||||||
|
|
||||||
|
echo "--> aplicacao deve bootar com config presente"
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c '
|
||||||
|
set -e
|
||||||
|
cd /var/www/api
|
||||||
|
cp .env.example .env
|
||||||
|
cp connections.json.example connections.json
|
||||||
|
php artisan --version
|
||||||
|
test -f bootstrap/cache/routes-v7.php || test -f bootstrap/cache/routes.php
|
||||||
|
test -f bootstrap/cache/packages.php
|
||||||
|
'
|
||||||
|
|
||||||
|
echo "--> imagem nao pode carregar credenciais"
|
||||||
|
if docker run --rm --entrypoint bash "${IMG}" -c 'test -f /var/www/api/.env || test -f /var/www/api/connections.json'; then
|
||||||
|
echo "::error::.env ou connections.json foram parar dentro da imagem"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "--> entrypoint deve recusar subir sem config"
|
||||||
|
if docker run --rm "${IMG}" true 2>/dev/null; then
|
||||||
|
echo "::error::entrypoint subiu sem .env/connections.json"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "--> frontend deve estar publicado no dist"
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c '
|
||||||
|
set -e
|
||||||
|
test -f /var/www/frontend/dist/index.html
|
||||||
|
test -d /var/www/frontend/dist/js
|
||||||
|
test -d /var/www/frontend/dist/css
|
||||||
|
'
|
||||||
|
|
||||||
|
echo "--> imagem NAO pode ter URL de ambiente gravada no bundle"
|
||||||
|
# O ponto da config em runtime e a imagem ser neutra. Se alguem voltar
|
||||||
|
# a ler process.env.VUE_APP_* num componente, o webpack grava o valor
|
||||||
|
# no bundle e a imagem silenciosamente vira especifica de um ambiente —
|
||||||
|
# o que quebra a promessa de "o que foi homologado e o que vai a prod".
|
||||||
|
# O index.html precisa carregar o config.js antes do bundle.
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c '
|
||||||
|
set -e
|
||||||
|
test -f /var/www/frontend/dist/config.js
|
||||||
|
grep -q "__APP_CONFIG__" /var/www/frontend/dist/config.js
|
||||||
|
grep -q "config.js" /var/www/frontend/dist/index.html
|
||||||
|
'
|
||||||
|
|
||||||
|
echo "--> apache deve servir api na :80 e frontend na :8080"
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c '
|
||||||
|
set -e
|
||||||
|
apache2ctl configtest 2>&1 | grep -q "Syntax OK"
|
||||||
|
apache2ctl -S 2>/dev/null | grep -q "^\*:80 "
|
||||||
|
apache2ctl -S 2>/dev/null | grep -q "^\*:8080 "
|
||||||
|
'
|
||||||
|
|
||||||
|
# As checagens acima usam --entrypoint bash, que nunca executa o CMD.
|
||||||
|
# As de baixo sobem o container de verdade: sao as unicas que pegam
|
||||||
|
# defeito de supervisord/apache que so aparece no boot real.
|
||||||
|
#
|
||||||
|
# O job roda com o docker.sock do host, entao bind mount de arquivo
|
||||||
|
# criado aqui dentro nao chegaria ao daemon (o caminho nao existe no
|
||||||
|
# host). Por isso a config entra via 'docker cp' num container criado
|
||||||
|
# e ainda nao iniciado.
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c 'cat /var/www/api/.env.example' > "${TMP}/.env"
|
||||||
|
docker run --rm --entrypoint bash "${IMG}" -c 'cat /var/www/api/connections.json.example' > "${TMP}/connections.json"
|
||||||
|
sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(head -c 32 /dev/urandom | base64)|" "${TMP}/.env"
|
||||||
|
printf 'window.__APP_CONFIG__ = { ROOT_API: "http://smoke-test", DNS: {}, ENV: "" }\n' > "${TMP}/config.js"
|
||||||
|
chmod 644 "${TMP}/.env" "${TMP}/connections.json" "${TMP}/config.js"
|
||||||
|
|
||||||
|
echo "--> entrypoint deve recusar subir sem a config de runtime do frontend"
|
||||||
|
# Sem o mount, o app subiria apontando para lugar nenhum em vez de
|
||||||
|
# falhar — o silencio e que e perigoso aqui.
|
||||||
|
CID_SEM=$(docker create "${IMG}")
|
||||||
|
docker cp "${TMP}/.env" "${CID_SEM}:/var/www/api/.env"
|
||||||
|
docker cp "${TMP}/connections.json" "${CID_SEM}:/var/www/api/connections.json"
|
||||||
|
docker start "${CID_SEM}" >/dev/null 2>&1 || true
|
||||||
|
sleep 3
|
||||||
|
if [ "$(docker inspect -f '{{.State.Running}}' "${CID_SEM}")" = "true" ]; then
|
||||||
|
echo "::error::container subiu sem /var/www/frontend/config.js montado"
|
||||||
|
docker rm -f "${CID_SEM}" >/dev/null 2>&1 || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
docker rm -f "${CID_SEM}" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
echo "--> container deve subir com config e permanecer de pe"
|
||||||
|
CID=$(docker create "${IMG}")
|
||||||
|
cleanup() { docker rm -f "${CID}" >/dev/null 2>&1 || true; rm -rf "${TMP}"; }
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
docker cp "${TMP}/.env" "${CID}:/var/www/api/.env"
|
||||||
|
docker cp "${TMP}/connections.json" "${CID}:/var/www/api/connections.json"
|
||||||
|
docker cp "${TMP}/config.js" "${CID}:/var/www/frontend/config.js"
|
||||||
|
docker start "${CID}" >/dev/null
|
||||||
|
|
||||||
|
for _ in $(seq 1 15); do
|
||||||
|
docker exec "${CID}" curl -s -o /dev/null http://localhost:8080/ 2>/dev/null && break
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$(docker inspect -f '{{.State.Running}}' "${CID}")" != "true" ]; then
|
||||||
|
echo "::error::container nao permaneceu de pe (exit=$(docker inspect -f '{{.State.ExitCode}}' "${CID}"))"
|
||||||
|
docker logs "${CID}" 2>&1 | tail -20
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CODE_API=$(docker exec "${CID}" curl -s -o /dev/null -w '%{http_code}' http://localhost:80/)
|
||||||
|
CODE_SPA=$(docker exec "${CID}" curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/)
|
||||||
|
CODE_ROTA=$(docker exec "${CID}" curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/rota/interna)
|
||||||
|
|
||||||
|
echo " api :80 -> ${CODE_API} | spa :8080 -> ${CODE_SPA} | spa /rota -> ${CODE_ROTA}"
|
||||||
|
|
||||||
|
# A API nao tem rota "/", entao 404 e resposta valida; o que nao pode e
|
||||||
|
# 000 (sem resposta). Ja o SPA precisa de 200 na raiz e tambem na rota
|
||||||
|
# interna — este segundo cobre o FallbackResource do mode: 'history'.
|
||||||
|
[ "${CODE_API}" != "000" ] || { echo "::error::apache nao respondeu na :80"; exit 1; }
|
||||||
|
[ "${CODE_SPA}" = "200" ] || { echo "::error::frontend nao respondeu 200 na :8080"; exit 1; }
|
||||||
|
[ "${CODE_ROTA}" = "200" ] || { echo "::error::FallbackResource do SPA nao esta ativo"; exit 1; }
|
||||||
|
|
||||||
|
echo "--> config.js servido deve ser o montado, e sem cache"
|
||||||
|
# Fecha o ciclo: nao basta o entrypoint copiar, o Apache precisa servir
|
||||||
|
# o arquivo instalado. E o no-store evita que o browser continue com a
|
||||||
|
# URL do ambiente anterior depois de uma troca.
|
||||||
|
SERVIDO=$(docker exec "${CID}" curl -s http://localhost:8080/config.js)
|
||||||
|
echo "${SERVIDO}" | grep -q 'smoke-test' \
|
||||||
|
|| { echo "::error::config.js servido nao e o montado: ${SERVIDO}"; exit 1; }
|
||||||
|
docker exec "${CID}" curl -sI http://localhost:8080/config.js | grep -qi 'cache-control: *no-store' \
|
||||||
|
|| { echo "::error::config.js servido sem Cache-Control no-store (mod_headers habilitado?)"; exit 1; }
|
||||||
|
|
||||||
|
echo "Smoke test OK"
|
||||||
|
|
||||||
|
- name: Push da imagem
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
docker push "${{ steps.meta.outputs.tag_version }}"
|
||||||
|
|
||||||
|
docker push "${{ steps.meta.outputs.tag_sha }}"
|
||||||
|
|
||||||
|
if [ "${{ steps.meta.outputs.is_tag }}" != "true" ]; then
|
||||||
|
echo "Build de branch: tag 'latest' preservada."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PUSH_LATEST}" = "true" ]; then
|
||||||
|
docker tag "${{ steps.meta.outputs.tag_version }}" "${{ steps.meta.outputs.tag_latest }}"
|
||||||
|
docker push "${{ steps.meta.outputs.tag_latest }}"
|
||||||
|
else
|
||||||
|
echo "PUSH_LATEST=${PUSH_LATEST}: tag 'latest' nao publicada."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Deploy no ambiente da branch
|
||||||
|
# Branch = ambiente: develop -> teste e release-* -> homolog.
|
||||||
|
# Tags e master nao fazem deploy por este workflow.
|
||||||
|
#
|
||||||
|
# Fica aqui, e nao num workflow proprio disparado por push, porque dois
|
||||||
|
# workflows no mesmo evento sao enfileirados em ordem arbitraria — o
|
||||||
|
# deploy poderia rodar antes de a imagem existir. Aqui a ordem e
|
||||||
|
# garantida e a imagem acabou de ser publicada.
|
||||||
|
#
|
||||||
|
# Precede a Limpeza de proposito: ela faz docker logout, e o deploy
|
||||||
|
# ainda precisa do login para o pull.
|
||||||
|
if: ${{ steps.meta.outputs.ambiente != '' && vars.AUTO_DEPLOY != 'false' }}
|
||||||
|
env:
|
||||||
|
AMBIENTE: ${{ steps.meta.outputs.ambiente }}
|
||||||
|
SSH_HOST: ${{ vars.TEST_SSH_HOST || '192.168.0.44' }}
|
||||||
|
SSH_PORT: ${{ vars.TEST_SSH_PORT || '22' }}
|
||||||
|
SSH_USER: ${{ vars.SSH_USER_TEST || secrets.SSH_USER_TEST }}
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY_TEST }}
|
||||||
|
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS_TEST }}
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# O Gitea publica a tag em minusculas; a branch pode ter maiusculas.
|
||||||
|
TAG=$(echo "${{ steps.meta.outputs.version }}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
if [ "${AMBIENTE}" = "teste" ]; then
|
||||||
|
echo "Deploy de teste usa SSH para ${SSH_HOST}:${SSH_PORT}."
|
||||||
|
chmod +x docker/deploy/deploy-over-ssh.sh
|
||||||
|
./docker/deploy/deploy-over-ssh.sh "${AMBIENTE}" "${TAG}"
|
||||||
|
else
|
||||||
|
chmod +x docker/deploy/deploy.sh
|
||||||
|
./docker/deploy/deploy.sh "${AMBIENTE}" "${TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Migrations automaticas do ambiente de teste
|
||||||
|
# Migrations nunca acompanham homolog/prod automaticamente. Em teste,
|
||||||
|
# a lista continua explicita para nao atingir conexoes tecnicas do
|
||||||
|
# connections.json. As duas variables sao opt-in deliberado.
|
||||||
|
if: ${{ steps.meta.outputs.ambiente == 'teste' && vars.AUTO_DEPLOY != 'false' && vars.AUTO_MIGRATE_TEST == 'true' }}
|
||||||
|
env:
|
||||||
|
TAG_VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
MUNICIPIOS: ${{ vars.MIGRATION_CONNECTIONS_TEST }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -z "${MUNICIPIOS:-}" ]; then
|
||||||
|
echo "::error::AUTO_MIGRATE_TEST=true exige a variable MIGRATION_CONNECTIONS_TEST com a lista explicita de municipios."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# O Gitea normaliza a tag de branch para minusculas no registry.
|
||||||
|
TAG=$(echo "${TAG_VERSION}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
chmod +x docker/deploy/migrate.sh
|
||||||
|
./docker/deploy/migrate.sh teste "${TAG}" "${MUNICIPIOS}"
|
||||||
|
|
||||||
|
- name: Resumo
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "### Imagem publicada"
|
||||||
|
echo ""
|
||||||
|
echo "| Campo | Valor |"
|
||||||
|
echo "| --- | --- |"
|
||||||
|
echo "| Versao | \`${{ steps.meta.outputs.version }}\` |"
|
||||||
|
echo "| Imagem | \`${{ steps.meta.outputs.tag_version }}\` |"
|
||||||
|
echo "| Base | \`${BASE_IMAGE}\` |"
|
||||||
|
echo "| Commit | \`${GITHUB_SHA}\` |"
|
||||||
|
echo ""
|
||||||
|
echo "**Uma imagem serve todos os ambientes.** A config do frontend e"
|
||||||
|
echo "resolvida em runtime: monte o \`config.js\` do ambiente em"
|
||||||
|
echo "\`/var/www/frontend/config.js\` (modelo em \`docker/config.js.example\`)."
|
||||||
|
echo "Tags de release constroem a imagem e a publicam no registry."
|
||||||
|
echo "Deploy e migrations de producao continuam sendo passos manuais."
|
||||||
|
echo ""
|
||||||
|
echo "Migrations municipais so executam automaticamente em teste quando"
|
||||||
|
echo "\`AUTO_MIGRATE_TEST=true\` e \`MIGRATION_CONNECTIONS_TEST\` estao definidos."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
- name: Limpeza
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
docker rmi "${{ steps.meta.outputs.tag_version }}" \
|
||||||
|
"${{ steps.meta.outputs.tag_latest }}" \
|
||||||
|
"${{ steps.meta.outputs.tag_sha }}" 2>/dev/null || true
|
||||||
|
docker logout "${REGISTRY}" 2>/dev/null || true
|
||||||
102
.gitea/workflows/deploy.yml
Normal file
102
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
name: deploy
|
||||||
|
|
||||||
|
# Implanta uma imagem ja publicada. Nao constroi nada: a tag de release e o
|
||||||
|
# artefato formal, construido quando ela e criada e escolhido explicitamente
|
||||||
|
# para cada deploy.
|
||||||
|
#
|
||||||
|
# Producao nunca sobe sozinha: exige acionamento manual, com a versao escolhida.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
ambiente:
|
||||||
|
description: 'Ambiente de destino'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- teste
|
||||||
|
- homolog
|
||||||
|
- prod
|
||||||
|
versao:
|
||||||
|
description: 'Tag da imagem (ex.: 2.59.3, feat_ci_cd_test)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY_HOST || '192.168.0.41:3001' }}
|
||||||
|
IMAGE_NAME: ${{ vars.API_IMAGE_NAME || 'rkm/conectasus-api' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Login no registry do Gitea
|
||||||
|
env:
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -z "${REGISTRY_TOKEN:-}" ]; then
|
||||||
|
echo "::error::REGISTRY_TOKEN nao definido. O pull da imagem privada depende dele."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER:-$ACTOR}" --password-stdin
|
||||||
|
|
||||||
|
- name: Confirmar que a imagem existe antes de mexer no ambiente
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
IMG="${REGISTRY}/${IMAGE_NAME}:${{ inputs.versao }}"
|
||||||
|
if ! docker manifest inspect "${IMG}" >/dev/null 2>&1; then
|
||||||
|
echo "::error::${IMG} nao existe no registry. Confira a tag (o Gitea publica em minusculas)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "imagem encontrada: ${IMG}"
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
env:
|
||||||
|
AMBIENTE: ${{ inputs.ambiente }}
|
||||||
|
VERSAO: ${{ inputs.versao }}
|
||||||
|
SSH_HOST: ${{ vars.TEST_SSH_HOST || '192.168.0.44' }}
|
||||||
|
SSH_PORT: ${{ vars.TEST_SSH_PORT || '22' }}
|
||||||
|
SSH_USER: ${{ vars.SSH_USER_TEST || secrets.SSH_USER_TEST }}
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY_TEST }}
|
||||||
|
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS_TEST || secrets.SSH_KNOWN_HOST_TEST }}
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ "${AMBIENTE}" = "teste" ]; then
|
||||||
|
echo "Deploy de teste usa SSH para ${SSH_HOST}:${SSH_PORT}."
|
||||||
|
chmod +x docker/deploy/deploy-over-ssh.sh
|
||||||
|
./docker/deploy/deploy-over-ssh.sh "${AMBIENTE}" "${VERSAO}"
|
||||||
|
else
|
||||||
|
chmod +x docker/deploy/deploy.sh
|
||||||
|
./docker/deploy/deploy.sh "${AMBIENTE}" "${VERSAO}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Resumo
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "### Deploy"
|
||||||
|
echo ""
|
||||||
|
echo "| Campo | Valor |"
|
||||||
|
echo "| --- | --- |"
|
||||||
|
echo "| Ambiente | \`${{ inputs.ambiente }}\` |"
|
||||||
|
echo "| Versao | \`${{ inputs.versao }}\` |"
|
||||||
|
echo "| Acionado por | \`${{ github.actor }}\` |"
|
||||||
|
echo "| Resultado | \`${{ job.status }}\` |"
|
||||||
|
echo ""
|
||||||
|
echo "O deploy so troca a imagem. Migrations continuam sendo passo"
|
||||||
|
echo "separado e deliberado — ver \`docker/README.md\`."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
- name: Limpeza
|
||||||
|
if: always()
|
||||||
|
run: docker logout "${REGISTRY}" 2>/dev/null || true
|
||||||
99
.gitea/workflows/migrate.yml
Normal file
99
.gitea/workflows/migrate.yml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
name: migrate
|
||||||
|
|
||||||
|
# Migrations alteram dados persistentes e nao acompanham o deploy automatico.
|
||||||
|
# Este workflow manual recebe uma imagem ja publicada e uma lista EXPLICITA de
|
||||||
|
# municipios; ele nunca tenta inferir ou migrar todas as conexoes.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
ambiente:
|
||||||
|
description: 'Ambiente de destino'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- teste
|
||||||
|
- homolog
|
||||||
|
- prod
|
||||||
|
versao:
|
||||||
|
description: 'Tag da imagem ja publicada (ex.: 2.59.3)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
municipios:
|
||||||
|
description: 'Conexoes municipais separadas por virgula (ex.: anhembi,aparecida)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
confirmacao:
|
||||||
|
description: 'Digite MIGRAR para confirmar a alteracao dos bancos'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
migrate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY_HOST || '192.168.0.41:3001' }}
|
||||||
|
IMAGE_NAME: ${{ vars.API_IMAGE_NAME || 'rkm/conectasus-api' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Confirmar operacao destrutiva
|
||||||
|
env:
|
||||||
|
CONFIRMACAO: ${{ inputs.confirmacao }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ "${CONFIRMACAO}" != "MIGRAR" ]; then
|
||||||
|
echo "::error::Para executar migrations, informe confirmacao=MIGRAR."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Login no registry do Gitea
|
||||||
|
env:
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REGISTRY_USER: ${{ vars.REGISTRY_USER }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -z "${REGISTRY_TOKEN:-}" ]; then
|
||||||
|
echo "::error::REGISTRY_TOKEN nao definido. A imagem privada nao pode ser usada."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER:-$ACTOR}" --password-stdin
|
||||||
|
|
||||||
|
- name: Aplicar migrations municipais
|
||||||
|
env:
|
||||||
|
AMBIENTE: ${{ inputs.ambiente }}
|
||||||
|
VERSAO: ${{ inputs.versao }}
|
||||||
|
MUNICIPIOS: ${{ inputs.municipios }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
chmod +x docker/deploy/migrate.sh
|
||||||
|
./docker/deploy/migrate.sh \
|
||||||
|
"${AMBIENTE}" \
|
||||||
|
"${VERSAO}" \
|
||||||
|
"${MUNICIPIOS}"
|
||||||
|
|
||||||
|
- name: Resumo
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "### Migrations"
|
||||||
|
echo ""
|
||||||
|
echo "| Campo | Valor |"
|
||||||
|
echo "| --- | --- |"
|
||||||
|
echo "| Ambiente | \`${{ inputs.ambiente }}\` |"
|
||||||
|
echo "| Versao | \`${{ inputs.versao }}\` |"
|
||||||
|
echo "| Municipios | \`${{ inputs.municipios }}\` |"
|
||||||
|
echo "| Acionado por | \`${{ github.actor }}\` |"
|
||||||
|
echo "| Resultado | \`${{ job.status }}\` |"
|
||||||
|
echo ""
|
||||||
|
echo "A execucao para no primeiro municipio com falha. Bancos anteriores"
|
||||||
|
echo "podem ja ter recebido migrations e exigem verificacao antes de repetir."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
|
- name: Limpeza
|
||||||
|
if: always()
|
||||||
|
run: docker logout "${REGISTRY}" 2>/dev/null || true
|
||||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
*.code-workspace
|
||||||
|
.github
|
||||||
|
.exec
|
||||||
|
.github
|
||||||
|
.integracao
|
||||||
|
.qodo
|
||||||
|
.vscode
|
||||||
|
scripts/*.sh
|
||||||
|
vetur.config.js
|
||||||
|
.claude
|
||||||
124
Dockerfile
Normal file
124
Dockerfile
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
ARG BASE_IMAGE=tirkm/v1-automation-ci
|
||||||
|
# Node 10 / npm 6 — o mesmo toolchain com que este projeto (vue 2.6 /
|
||||||
|
# @vue/cli-service 4.5) e construido hoje. Subir de versao aqui e uma mudanca
|
||||||
|
# a parte: muda o bundle gerado, e merece ser validada por si.
|
||||||
|
ARG NODE_IMAGE=node:10-alpine
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Frontend: npm so existe neste stage, e numa imagem dedicada — a base de
|
||||||
|
# runtime nao carrega toolchain de frontend. Para o runtime atravessa apenas o
|
||||||
|
# dist/.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
FROM ${NODE_IMAGE} AS frontend-build
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY frontend/package.json frontend/package-lock.json ./
|
||||||
|
|
||||||
|
RUN npm ci --no-audit --no-fund
|
||||||
|
|
||||||
|
COPY frontend/ ./
|
||||||
|
|
||||||
|
# Nenhum .env entra aqui de proposito. A config do frontend e resolvida em
|
||||||
|
# RUNTIME, via public/config.js -> window.__APP_CONFIG__ (ver src/config.js),
|
||||||
|
# com o arquivo real montado no deploy. E o que mantem uma unica imagem servindo
|
||||||
|
# teste, homolog e producao: o binario homologado e o mesmo que vai para prod.
|
||||||
|
#
|
||||||
|
# Node 10 limita o heap a ~1.5GB por padrao e o webpack deste projeto estoura
|
||||||
|
# esse teto ("JavaScript heap out of memory"). O build so passa com o limite
|
||||||
|
# elevado.
|
||||||
|
RUN NODE_OPTIONS=--max-old-space-size=4096 npm run build
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# API
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
FROM ${BASE_IMAGE} AS build
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY api/composer.json api/composer.lock ./
|
||||||
|
|
||||||
|
RUN composer install \
|
||||||
|
--no-dev \
|
||||||
|
--no-scripts \
|
||||||
|
--no-autoloader \
|
||||||
|
--no-interaction \
|
||||||
|
--prefer-dist \
|
||||||
|
--no-progress
|
||||||
|
|
||||||
|
COPY api/ ./
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
mkdir -p bootstrap/cache storage/framework/cache storage/framework/views storage/framework/sessions storage/logs; \
|
||||||
|
cp .env.example .env; \
|
||||||
|
cp connections.json.example connections.json; \
|
||||||
|
composer dump-autoload --no-dev --optimize --no-interaction; \
|
||||||
|
php artisan key:generate --no-interaction; \
|
||||||
|
php artisan route:cache; \
|
||||||
|
rm -f .env connections.json; \
|
||||||
|
rm -rf tests .git .idea .vscode; \
|
||||||
|
rm -f docker-compose.yml phpunit.xml .styleci.yml .editorconfig \
|
||||||
|
package.json package-lock.json webpack.mix.js .phpunit.result.cache; \
|
||||||
|
find storage/logs -type f -delete
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Runtime
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
FROM ${BASE_IMAGE} AS runtime
|
||||||
|
|
||||||
|
ARG APP_VERSION=dev
|
||||||
|
ARG VCS_REF=unknown
|
||||||
|
ARG BUILD_DATE=unknown
|
||||||
|
ARG SOURCE_URL=http://192.168.0.41:3001/rkm/conectasus
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.title="ConectaSUS V2" \
|
||||||
|
org.opencontainers.image.description="API Laravel + frontend Vue do ConectaSUS V2, encapsulados" \
|
||||||
|
org.opencontainers.image.version="${APP_VERSION}" \
|
||||||
|
org.opencontainers.image.revision="${VCS_REF}" \
|
||||||
|
org.opencontainers.image.created="${BUILD_DATE}" \
|
||||||
|
org.opencontainers.image.source="${SOURCE_URL}" \
|
||||||
|
org.opencontainers.image.vendor="RKM Sistemas"
|
||||||
|
|
||||||
|
ENV APP_VERSION=${APP_VERSION}
|
||||||
|
|
||||||
|
COPY docker/apache/ports.conf /etc/apache2/ports.conf
|
||||||
|
COPY docker/apache/000-default.conf /etc/apache2/sites-enabled/000-default.conf
|
||||||
|
COPY docker/apache/frontend.conf /etc/apache2/sites-enabled/frontend.conf
|
||||||
|
COPY docker/supervisor/conf.d/ /etc/supervisor/conf.d/
|
||||||
|
COPY docker/entrypoint.sh /usr/local/bin/entrypoint
|
||||||
|
|
||||||
|
# O frontend.conf usa 'Header set Cache-Control' no config.js, e mod_headers vem
|
||||||
|
# desabilitado na base :6. A base enxuta ja o habilita, mas manter aqui e de
|
||||||
|
# proposito: a2enmod e idempotente, e assim a imagem funciona sobre qualquer uma
|
||||||
|
# das duas bases em vez de depender de um detalhe interno dela.
|
||||||
|
RUN a2enmod headers
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/entrypoint
|
||||||
|
|
||||||
|
COPY --from=build --chown=www-data:www-data /build /var/www/api
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
mkdir -p /var/www/api/storage/framework/cache \
|
||||||
|
/var/www/api/storage/framework/views \
|
||||||
|
/var/www/api/storage/framework/sessions \
|
||||||
|
/var/www/api/storage/logs \
|
||||||
|
/var/www/api/storage/app/public \
|
||||||
|
/var/www/api/storage/app/documento \
|
||||||
|
/var/www/api/storage/app/intranet \
|
||||||
|
/var/www/api/bootstrap/cache; \
|
||||||
|
chown -R www-data:www-data /var/www/api/storage /var/www/api/bootstrap/cache; \
|
||||||
|
chmod -R ug+rwX /var/www/api/storage /var/www/api/bootstrap/cache
|
||||||
|
|
||||||
|
# Por ultimo de proposito: e a camada que mais muda. Assim uma alteracao so de
|
||||||
|
# frontend nao invalida as camadas pesadas da API (vendor/, caches de boot).
|
||||||
|
COPY --from=frontend-build --chown=www-data:www-data /build/dist /var/www/frontend/dist
|
||||||
|
|
||||||
|
WORKDIR /var/www
|
||||||
|
|
||||||
|
EXPOSE 80 8080 6001
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint"]
|
||||||
|
# -n (nodaemon) e obrigatorio: o supervisord.conf da imagem base nao define
|
||||||
|
# nodaemon=true, entao sem esta flag o supervisord daemoniza, o processo em
|
||||||
|
# primeiro plano encerra e o container sai com exit 0 logo apos subir.
|
||||||
|
CMD ["supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
|
||||||
134
README.md
Normal file
134
README.md
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# Antes de começar
|
||||||
|
- Reestaure os bancos de dados da INTRANET e do SIGTAP. (Esses arquivos podem ser encontrados em [192.168.0.5\backups\DATACENTER\BANCOS])
|
||||||
|
|
||||||
|
# Instalação
|
||||||
|
01 - Clone o repositório no seu ambiente de desenvolvimento:
|
||||||
|
```bash
|
||||||
|
git clone http://192.168.0.41:3001/rkm/conectasus.git .
|
||||||
|
```
|
||||||
|
|
||||||
|
02 - Entre no diretório da api:
|
||||||
|
```bash
|
||||||
|
cd api
|
||||||
|
```
|
||||||
|
|
||||||
|
03 - Copie os arquivos de configuração:
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
cp connections.json.example connections.json
|
||||||
|
```
|
||||||
|
|
||||||
|
04 - Instale as dependências da api utilizando o `composer`:
|
||||||
|
```bash
|
||||||
|
composer install
|
||||||
|
```
|
||||||
|
|
||||||
|
05 - Gere as chaves de configuração:
|
||||||
|
```bash
|
||||||
|
php artisan key:generate
|
||||||
|
php artisan jwt:secret
|
||||||
|
```
|
||||||
|
|
||||||
|
06 - Configure o arquivo `.env`:
|
||||||
|
```bash
|
||||||
|
APP_NAME="ConectaSUS V2"
|
||||||
|
APP_URL=http://[URL_DO_PROJETO]
|
||||||
|
APP_URL_FRONTEND=http://[URL_DO_FRONTEND_DO_PROJETO]
|
||||||
|
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mail.rkmsistemas.com.br
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_USERNAME=socialnet@rkmsistemas.com.br
|
||||||
|
MAIL_PASSWORD=$ocial@2021RKM
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS=socialnet@rkmsistemas.com.br
|
||||||
|
|
||||||
|
PUSHER_APP_ID=1
|
||||||
|
PUSHER_APP_KEY=1
|
||||||
|
PUSHER_APP_SECRET=1
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
# Remover a diretiva do .env.
|
||||||
|
WKHTML_PDF_BINARY=
|
||||||
|
```
|
||||||
|
|
||||||
|
07 - Configure o arquivo `connections.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"intranet": {
|
||||||
|
"driver": "mysql",
|
||||||
|
"host": "[IP_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"port": "[PORTA_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"database": "intranet",
|
||||||
|
"username": "[USUARIO_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"password": "[SENHA_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"collation": "utf8mb4_unicode_ci"
|
||||||
|
},
|
||||||
|
"sigtap": {
|
||||||
|
"driver": "mysql",
|
||||||
|
"host": "[IP_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"port": "[PORTA_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"database": "sigtap",
|
||||||
|
"username": "[USUARIO_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"password": "[SENHA_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"collation": "utf8mb4_unicode_ci"
|
||||||
|
},
|
||||||
|
"[PREFIXO_DO_CLIENTE_AQUI]": {
|
||||||
|
"driver": "mysql",
|
||||||
|
"host": "[IP_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"port": "[PORTA_DO_SERVIDOR_DE_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"database": "[NOME_DO_BANCO_DE_DADOS_DO_CLIENTE_AQUI]",
|
||||||
|
"username": "[USUARIO_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"password": "[SENHA_DO_BANCO_DE_DADOS_AQUI]",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"collation": "utf8mb4_unicode_ci"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
08 - Crie o banco de dados com o nome do cliente `NOME_DO_BANCO_DE_DADOS_DO_CLIENTE_AQUI`.
|
||||||
|
|
||||||
|
09 - Execute as migrations e seeders:
|
||||||
|
```bash
|
||||||
|
php artisan migrate --seed
|
||||||
|
```
|
||||||
|
|
||||||
|
10 - Para criar as configurações iniciais, execute o seeder (Necessário executar apenas na primeira vez após instalação):
|
||||||
|
```bash
|
||||||
|
php artisan db:seed --class=InicialSeeder
|
||||||
|
```
|
||||||
|
|
||||||
|
11 - Inicie o servidor de websocket:
|
||||||
|
```bash
|
||||||
|
php artisan websockets:serve
|
||||||
|
```
|
||||||
|
|
||||||
|
12 - Entre no diretório do frontend:
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
13 - Copie o arquivo de configuração:
|
||||||
|
```bash
|
||||||
|
cp .env.development.local.example .env.development.local
|
||||||
|
```
|
||||||
|
|
||||||
|
14 - Configure o arquivo `.env.development.local`:
|
||||||
|
```bash
|
||||||
|
VUE_APP_ROOT_API=http://[URL_DA_API_DO_PROJETO]
|
||||||
|
VUE_APP_WS_APP_KEY=1
|
||||||
|
VUE_APP_WS_HOST=[IP_DO_SERVIDOR_APACHE]
|
||||||
|
VUE_APP_WS_PORT=[PORTA_DO_WEBSOCKET]
|
||||||
|
```
|
||||||
|
|
||||||
|
15 - Instale as dependências da api utilizando o `npm`:
|
||||||
|
```bash
|
||||||
|
npm ci
|
||||||
|
```
|
||||||
|
|
||||||
|
16 - Acesse a URL do projeto no navegador:
|
||||||
|
```bash
|
||||||
|
http://[URL_DO_FRONTEND_DO_PROJETO]:[PORTA_DO_FRONTEND_DO_PROJETO]/login/[PREFIXO_DO_CLIENTE]
|
||||||
|
```
|
||||||
21
api/.editorconfig
Normal file
21
api/.editorconfig
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.blade.php]
|
||||||
|
insert_final_newline = false
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[TODO*]
|
||||||
|
indent_size = 2
|
||||||
97
api/.env.example
Normal file
97
api/.env.example
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=http://localhost
|
||||||
|
APP_URL_FRONTEND=http://localhost
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
QUEUE_CONNECTION=database
|
||||||
|
QUEUE_NAME=default
|
||||||
|
QUEUE_DB_HOST=localhost
|
||||||
|
QUEUE_DB_PORT=3306
|
||||||
|
QUEUE_DB_USERNAME=root
|
||||||
|
QUEUE_DB_PASSWORD=
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=pusher
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
MEMCACHED_HOST=memcached
|
||||||
|
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailhog
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS=null
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
|
||||||
|
PUSHER_HOST=
|
||||||
|
PUSHER_PORT=
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
|
# Dados para configuração do JWT.
|
||||||
|
JWT_SECRET=
|
||||||
|
JWT_SECRET_EXTERNAL=
|
||||||
|
JWT_TTL=480
|
||||||
|
|
||||||
|
# Dados para configuração do WKHTMLTOPDF para geração de PDF.
|
||||||
|
WKHTML_PDF_BINARY=
|
||||||
|
|
||||||
|
# Dados para acesso à API de assinatura eletrônica.
|
||||||
|
PKI_ENDPOINT_URL=
|
||||||
|
PKI_ACCESS_TOKEN=
|
||||||
|
|
||||||
|
# Dados para acesso à API de integração.
|
||||||
|
INTEGRACAO_CIDADAO_URL=http://localhost
|
||||||
|
INTEGRACAO_CIDADAO_SENHA=rkm2021
|
||||||
|
|
||||||
|
# Dados para acesso ao histórico do ConectaSUS V1.
|
||||||
|
CONECTASUS_V1_URL=
|
||||||
|
CONECTASUS_V1_URL_PEDERNEIRAS=
|
||||||
|
|
||||||
|
# Dados para envio de notificações via Telegram.
|
||||||
|
TELEGRAM_BOT_TOKEN=
|
||||||
|
TELEGRAM_CHAT_ID=
|
||||||
|
|
||||||
|
# Dados para acesso à integrações externas.
|
||||||
|
BNAFAR_HOMOLOGACAO_URL_API_SERVICO=https://servicoshm.saude.gov.br/bnafar
|
||||||
|
BNAFAR_HOMOLOGACAO_URL_API_TOKEN=http://servicoshm.saude.gov.br/jwtauth/auth
|
||||||
|
BNAFAR_PRODUCAO_URL_API_SERVICO=https://servicos.saude.gov.br/bnafar
|
||||||
|
BNAFAR_PRODUCAO_URL_API_TOKEN=https://servicos.saude.gov.br/jwtauth/auth
|
||||||
|
CNS_HOMOLOGACAO_URL_API_SERVICO=https://servicoshm.saude.gov.br/cadsus/v2/PDQSupplierJWT
|
||||||
|
CNS_HOMOLOGACAO_URL_API_TOKEN=https://ehr-auth-hmg.saude.gov.br/api/osb/token
|
||||||
|
CNS_PRODUCAO_URL_API_SERVICO=https://servicos.saude.gov.br/cadsus/v2/PDQSupplierJWT
|
||||||
|
CNS_PRODUCAO_URL_API_TOKEN=https://ehr-auth.saude.gov.br/api/osb/token
|
||||||
|
RIA_HOMOLOGACAO_URL_API_SERVICO=ehr-services-hmg.saude.gov.br/api
|
||||||
|
RIA_HOMOLOGACAO_URL_API_TOKEN=ehr-auth-hmg.saude.gov.br/api/token
|
||||||
|
RIA_PRODUCAO_URL_API_SERVICO=ehr-services.saude.gov.br/api
|
||||||
|
RIA_PRODUCAO_URL_API_TOKEN=ehr-auth.saude.gov.br/api/token
|
||||||
|
RIRA_HOMOLOGACAO_URL_API_SERVICO=https://ehr-services-hmg.saude.gov.br/api
|
||||||
|
RIRA_HOMOLOGACAO_URL_API_TOKEN=https://ehr-auth-hmg.saude.gov.br/api/token
|
||||||
|
RIRA_PRODUCAO_URL_API_SERVICO=https://uf-ehr-services.saude.gov.br/api
|
||||||
|
RIRA_PRODUCAO_URL_API_TOKEN=https://ehr-auth.saude.gov.br/api/token
|
||||||
|
|
||||||
|
RUN_SCHEDULE=
|
||||||
BIN
api/.env.swp
Normal file
BIN
api/.env.swp
Normal file
Binary file not shown.
5
api/.gitattributes
vendored
Normal file
5
api/.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
* text=auto
|
||||||
|
*.css linguist-vendored
|
||||||
|
*.scss linguist-vendored
|
||||||
|
*.js linguist-vendored
|
||||||
|
CHANGELOG.md export-ignore
|
||||||
18
api/.gitignore
vendored
Normal file
18
api/.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/node_modules
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/storage/*.key
|
||||||
|
/storage/logs/mobile
|
||||||
|
/storage/pronto-atendimento/*
|
||||||
|
/vendor
|
||||||
|
.env
|
||||||
|
.env.backup
|
||||||
|
.phpunit.result.cache
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
connections.json
|
||||||
|
routes.txt
|
||||||
|
.idea/
|
||||||
|
TODO*
|
||||||
13
api/.styleci.yml
Normal file
13
api/.styleci.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
php:
|
||||||
|
preset: laravel
|
||||||
|
disabled:
|
||||||
|
- no_unused_imports
|
||||||
|
finder:
|
||||||
|
not-name:
|
||||||
|
- index.php
|
||||||
|
- server.php
|
||||||
|
js:
|
||||||
|
finder:
|
||||||
|
not-name:
|
||||||
|
- webpack.mix.js
|
||||||
|
css: true
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Farmacia;
|
||||||
|
|
||||||
|
use App\Enums\Administracao\Modulo;
|
||||||
|
use App\Models\PainelSenha\Fila;
|
||||||
|
use App\Models\PainelSenha\OpcaoEntrada;
|
||||||
|
use App\Services\Administracao\ModuloService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class LimparFilaAtendimentoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'farmacia:limpar-fila-atendimento';
|
||||||
|
protected $description = 'Comando para limpeza da fila de atendimento no módulo farmácia.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
$this->getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente);
|
||||||
|
|
||||||
|
Fila::where('finalizado', false)
|
||||||
|
->where('evadido', false)
|
||||||
|
->whereIn('opcao_entrada_id', $this->getOpcoesEntrada())
|
||||||
|
->update([
|
||||||
|
'finalizado' => true,
|
||||||
|
'evadido' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::channel('farmacia-fila-atendimento')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
]);
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('farmacia-fila-atendimento')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Farmácia (' . ($cliente) . '):</strong> (Erro ao executar o comando: LimparFilaAtendimentoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('farmacia-fila-atendimento')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Farmácia:</strong> (Erro ao executar o comando: LimparFilaAtendimentoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOpcoesEntrada()
|
||||||
|
{
|
||||||
|
return OpcaoEntrada::where('modulo_id', ModuloService::getId(Modulo::FARMACIA))
|
||||||
|
->pluck('id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Bnafar;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\BnafarService;
|
||||||
|
use App\Services\Integracao\Bnafar\PosicaoEstoqueService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarPosicaoEstoqueCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:bnafar-enviar-posicao-estoque';
|
||||||
|
protected $description = 'Comando para envio de posição de estoque ao BNAFAR.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$ibge = substr($cliente->municipio->ibge, 0, 6);
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = BnafarService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = BnafarService::getToken($parametrizacao->usuario, $parametrizacao->senha);
|
||||||
|
|
||||||
|
if (!is_null($token)) {
|
||||||
|
$token = $token['access_token'];
|
||||||
|
|
||||||
|
PosicaoEstoqueService::store();
|
||||||
|
PosicaoEstoqueService::post($cliente->link, $token, $ibge);
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarPosicaoEstoqueCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarPosicaoEstoqueCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarPosicaoEstoqueCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarPosicaoEstoqueCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR:</strong> (Erro ao executar o comando: EnviarPosicaoEstoqueCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Bnafar;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\Bnafar\SaidaService;
|
||||||
|
use App\Services\Integracao\BnafarService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarSaidaCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:bnafar-enviar-saida';
|
||||||
|
protected $description = 'Comando para envio de saida ao BNAFAR.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$ibge = substr($cliente->municipio->ibge, 0, 6);
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = BnafarService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = BnafarService::getToken($parametrizacao->usuario, $parametrizacao->senha);
|
||||||
|
|
||||||
|
if (!is_null($token)) {
|
||||||
|
$token = $token['access_token'];
|
||||||
|
|
||||||
|
SaidaService::store();
|
||||||
|
SaidaService::post($cliente->link, $token, $ibge);
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarSaidaCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarSaidaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarSaidaCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarSaidaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR:</strong> (Erro ao executar o comando: EnviarSaidaCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Bnafar;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\Bnafar\PosicaoEstoqueService;
|
||||||
|
use App\Services\Integracao\BnafarService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class VerificarPosicaoEstoqueCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:bnafar-verificar-posicao-estoque';
|
||||||
|
protected $description = 'Comando para verificação de posição de estoque enviada ao BNAFAR.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$ibge = substr($cliente->municipio->ibge, 0, 6);
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = BnafarService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = BnafarService::getToken($parametrizacao->usuario, $parametrizacao->senha);
|
||||||
|
|
||||||
|
if (!is_null($token)) {
|
||||||
|
$token = $token['access_token'];
|
||||||
|
|
||||||
|
PosicaoEstoqueService::check($cliente->link, $token, $ibge);
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'VerificarPosicaoEstoqueCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'VerificarPosicaoEstoqueCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: VerificarPosicaoEstoqueCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'VerificarPosicaoEstoqueCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR:</strong> (Erro ao executar o comando: VerificarPosicaoEstoqueCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Bnafar;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\Bnafar\SaidaService;
|
||||||
|
use App\Services\Integracao\BnafarService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class VerificarSaidaCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:bnafar-verificar-saida';
|
||||||
|
protected $description = 'Comando para verificação de saida enviada ao BNAFAR.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$ibge = substr($cliente->municipio->ibge, 0, 6);
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = BnafarService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = BnafarService::getToken($parametrizacao->usuario, $parametrizacao->senha);
|
||||||
|
|
||||||
|
if (!is_null($token)) {
|
||||||
|
$token = $token['access_token'];
|
||||||
|
|
||||||
|
SaidaService::check($cliente->link, $token, $ibge);
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'VerificarSaidaCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'VerificarSaidaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: VerificarSaidaCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-bnafar')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'VerificarSaidaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração BNAFAR:</strong> (Erro ao executar o comando: VerificarSaidaCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Erpsaude;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Integracao\Erpsaude\Atendimento as ErpsaudeAtendimento;
|
||||||
|
use App\Models\Integracao\Erpsaude\Exame as ErpsaudeExame;
|
||||||
|
use App\Models\Integracao\Erpsaude\Medicamento;
|
||||||
|
use App\Models\Integracao\Erpsaude\Paciente as ErpsaudePaciente;
|
||||||
|
use App\Models\Integracao\Erpsaude\Reavaliacao;
|
||||||
|
use App\Models\Integracao\Erpsaude\TipoAlta;
|
||||||
|
use App\Models\Integracao\Erpsaude\TipoAtendimento as ErpsaudeTipoAtendimento;
|
||||||
|
use App\Models\Integracao\Erpsaude\UnidadeAtendimento;
|
||||||
|
use App\Models\Integracao\Erpsaude\UnidadeEncaminhadora;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class BuscarAtendimentosHospitalSantaCasaCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:erpsaude-buscar-atendimentos-hospital-santa-casa';
|
||||||
|
protected $description = 'Comando para buscar os atendimentos realizados no hospital santa casa.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', 'santarita')
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$token = env('ERPSAUDE_ACCESS_TOKEN');
|
||||||
|
$url = env('ERPSAUDE_ENDPOINT_URL') . "DadosPaciente";
|
||||||
|
|
||||||
|
$response = Http::withHeaders([
|
||||||
|
'Authorization' => "Bearer $token"
|
||||||
|
])->get($url);
|
||||||
|
|
||||||
|
$dados = $response->json();
|
||||||
|
|
||||||
|
if (!is_array($dados)) {
|
||||||
|
Log::channel('integracao-erpsaude')->error('A resposta da API não retornou um array válido', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'BuscarAtendimentosHospitalSantaCasaCommand',
|
||||||
|
'dados' => $dados,
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response->successful()) {
|
||||||
|
foreach ($dados as $item) {
|
||||||
|
|
||||||
|
$cpf = isset($item['cpf']) ? substr(preg_replace('/\D/', '', $item['cpf']), 0, 11) : null;
|
||||||
|
$dataNascimento = Carbon::createFromFormat('d/m/Y', $item['dataNascimento'])->format('Y-m-d');
|
||||||
|
$cns = $item['cartaoNacionalSaude'];
|
||||||
|
$nome = $item['paciente'];
|
||||||
|
|
||||||
|
$paciente = null;
|
||||||
|
|
||||||
|
if ($cpf) {
|
||||||
|
$paciente = ErpsaudePaciente::where('cpf', $cpf)
|
||||||
|
->where('nome', $nome)
|
||||||
|
->where('data_nascimento', $dataNascimento)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$paciente) {
|
||||||
|
$paciente = ErpsaudePaciente::where('cns', $cns)
|
||||||
|
->where('nome', $nome)
|
||||||
|
->where('data_nascimento', $dataNascimento)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$paciente) {
|
||||||
|
$paciente = ErpsaudePaciente::create([
|
||||||
|
'nome' => $nome,
|
||||||
|
'cpf' => $cpf,
|
||||||
|
'cns' => $cns,
|
||||||
|
'data_nascimento' => $dataNascimento,
|
||||||
|
'sexo' => $item['sexo'],
|
||||||
|
'cep' => isset($item['cep']) ? preg_replace('/\D/', '', $item['cep']) : null,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$paciente->update([
|
||||||
|
'nome' => $nome,
|
||||||
|
'cpf' => $cpf,
|
||||||
|
'cns' => $cns,
|
||||||
|
'data_nascimento' => $dataNascimento,
|
||||||
|
'sexo' => $item['sexo'],
|
||||||
|
'cep' => isset($item['cep']) ? preg_replace('/\D/', '', $item['cep']) : null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tipoAlta = TipoAlta::where('codigo', $item['codTipoAlta'])->first();
|
||||||
|
$tipoAtendimento = ErpsaudeTipoAtendimento::where('codigo', (int) $item['codTipoAtendimento'])->first();
|
||||||
|
$unidadeEncaminhadora = UnidadeEncaminhadora::where('codigo', (int) $item['codUnEncaminhadora'])->first();
|
||||||
|
$unidadeAtendimento = UnidadeAtendimento::where('codigo', (int) $item['codUnAtendimento'])->first();
|
||||||
|
|
||||||
|
$atendimento = ErpsaudeAtendimento::create([
|
||||||
|
'paciente_id' => $paciente->id,
|
||||||
|
'registro_paciente' => $item['registroPaciente'],
|
||||||
|
'data' => Carbon::createFromFormat('d/m/Y', $item['data'])->format('Y-m-d'),
|
||||||
|
'hora' => $item['hora'],
|
||||||
|
'suspeita_maus_tratos' => $item['suspeitaMausTratos'],
|
||||||
|
'hipotese_diagnostica' => $item['hipoteseDiagnostica'],
|
||||||
|
'cid10' => $item['cid10'],
|
||||||
|
'descricao_procedimento' => $item['descricaoProcedimento'],
|
||||||
|
'descricao_exame_clinico' => $item['descricaoExameClinico'],
|
||||||
|
'conduta_medica' => $item['condutaMedica'],
|
||||||
|
'codigo_conta_prof' => $item['codigoContaProf'],
|
||||||
|
'profissional' => $item['profissional'],
|
||||||
|
'conselho' => $item['conselho'],
|
||||||
|
'uf_conselho' => $item['ufConselho'],
|
||||||
|
'convenio' => $item['convenio'],
|
||||||
|
'registro_ans' => $item['registroAns'],
|
||||||
|
'cod_convenio' => $item['codConvenio'],
|
||||||
|
'nome_setor' => $item['nomeSetor'],
|
||||||
|
'codigo_setor' => $item['codigoSetor'],
|
||||||
|
'cod_tipo_encaminhamento' => $item['codTipoEncaminhamento'],
|
||||||
|
'tipo_atendimento_id' => $tipoAtendimento ? $tipoAtendimento->id : null,
|
||||||
|
'cod_grupo_atendimento' => $item['codGrupoAtendimento'],
|
||||||
|
'unidade_encaminhadora_id' => $unidadeEncaminhadora ? $unidadeEncaminhadora->id : null,
|
||||||
|
'unidade_atendimento_id' => $unidadeAtendimento ? $unidadeAtendimento->id : null,
|
||||||
|
'data_atendimento' => Carbon::createFromFormat('d/m/Y', $item['dataAtendimento'])->format('Y-m-d'),
|
||||||
|
'data_alta' => !empty($item['dataAlta']) && preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $item['dataAlta'])
|
||||||
|
? Carbon::createFromFormat('d/m/Y', $item['dataAlta'])->format('Y-m-d')
|
||||||
|
: null,
|
||||||
|
'horario_atendimento' => $item['horarioAtendimento'],
|
||||||
|
'hora_alta' => isset($item['horaAlta']) && trim($item['horaAlta']) !== '' ? $item['horaAlta'] : null,
|
||||||
|
'tipo_alta_id' => $tipoAlta ? $tipoAlta->id : null,
|
||||||
|
'unidade_atendimento' => $item['unAtendimento'],
|
||||||
|
'cnes_un_atendimento' => $item['cnesUnAtendimento'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!empty($item['reavaliacoes'])) {
|
||||||
|
foreach ($item['reavaliacoes'] as $reavaliacao) {
|
||||||
|
|
||||||
|
Reavaliacao::create([
|
||||||
|
'atendimento_id' => $atendimento->id,
|
||||||
|
'reavaliacao' => $reavaliacao['reavalicao'],
|
||||||
|
'profissional' => $reavaliacao['profissional'],
|
||||||
|
'numero_conselho' => $reavaliacao['numConselho'],
|
||||||
|
'uf_conselho' => $reavaliacao['ufConselho'],
|
||||||
|
'data' => Carbon::createFromFormat('d/m/Y', $reavaliacao['dataReavaliacao'])->format('Y-m-d'),
|
||||||
|
'hora' => $reavaliacao['horaReavaliacao'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['medicamentos'])) {
|
||||||
|
foreach ($item['medicamentos'] as $med) {
|
||||||
|
|
||||||
|
Medicamento::create([
|
||||||
|
'atendimento_id' => $atendimento->id,
|
||||||
|
'medicamento' => $med['medicamento'],
|
||||||
|
'quantidade' => str_replace(',', '.', $med['qtdePresc']),
|
||||||
|
'unidade_medida' => $med['uniMedPresc'],
|
||||||
|
'medicamento_id' => $med['idMedicamento'],
|
||||||
|
'tipo' => $med['tipo'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item['exames'])) {
|
||||||
|
foreach ($item['exames'] as $exame) {
|
||||||
|
|
||||||
|
ErpsaudeExame::create([
|
||||||
|
'atendimento_id' => $atendimento->id,
|
||||||
|
'exame' => $exame['descricao'] ?? '',
|
||||||
|
'tipo' => $exame['tipo'] ?? '',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::channel('integracao-erpsaude')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'BuscarAtendimentosHospitalSantaCasaCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-erpsaude')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'BuscarAtendimentosHospitalSantaCasaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
151
api/app/Console/Commands/Integracao/Esus/EnviarCommand.php
Normal file
151
api/app/Console/Commands/Integracao/Esus/EnviarCommand.php
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Esus;
|
||||||
|
|
||||||
|
use App\Models\Integracao\Esus\Parametrizacao;
|
||||||
|
use App\Services\AtencaoBasica\Exportacao\ExportacaoService;
|
||||||
|
use App\Services\Integracao\EsusService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:esus-enviar';
|
||||||
|
protected $description = 'Comando para envio de fichas ao e-SUS.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
$mesAnoInicial = '072025';
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) use($mesAnoInicial) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente);
|
||||||
|
|
||||||
|
$parametrizacao = Parametrizacao::first();
|
||||||
|
|
||||||
|
if (!($parametrizacao->ativo ?? false)) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parametrizacao->url_instalacao = trim($parametrizacao->url_instalacao, '/');
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
EsusService::getAuthorizationCookie($parametrizacao);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->error('Falha na conexão.', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => 'Exportação não realizada (falha no cookie inicial)',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (ExportacaoService::gerarExportacoes($mesAnoInicial) as $nomeFicha => $fichas) {
|
||||||
|
|
||||||
|
$parametrizacao->cookie = EsusService::getAuthorizationCookie($parametrizacao);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
EsusService::deleteInconsistencias($cliente, $nomeFicha);
|
||||||
|
|
||||||
|
foreach ($fichas as $ficha) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
EsusService::sendFicha($cliente, $parametrizacao, $nomeFicha, $ficha);
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração ESUS (' . $cliente . '):</strong> (Erro ao executar o comando: EnviarCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração ESUS (' . $cliente . '):</strong> (Erro ao executar o comando: EnviarCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração ESUS (' . $cliente . '):</strong> (Erro ao executar o comando: EnviarCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception $error) {
|
||||||
|
|
||||||
|
Log::channel('integracao-esus')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração ESUS:</strong> (Erro ao executar o comando: EnviarCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')
|
||||||
|
->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])
|
||||||
|
))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Integracao\Ria\DocumentoImunologicoRotina;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarDocumentoAlteradoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-documento-alterado';
|
||||||
|
protected $description = 'Comando para envio de documentos alterados ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($cliente, $parametrizacao, $parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getDocumentosAlterados()
|
||||||
|
->each(function($documentoAlterado) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$documentoAlterado->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$documentoAlterado->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$documentoAlterado->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $documentoAlterado, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
if ($response->status() === 201) {
|
||||||
|
$documentoAlterado->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$documentoAlterado->response = $response->json();
|
||||||
|
$documentoAlterado->alterar = false;
|
||||||
|
$documentoAlterado->atualizado = true;
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::update($documentoAlterado->documento_imunologico_rotina_id, $documentoAlterado);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DocumentoImunologicoRotina::where('id', $documentoAlterado->documento_imunologico_rotina_id)->update([
|
||||||
|
'tentou_substituir' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::updateInconsistencias($documentoAlterado->documento_imunologico_rotina_id, $response->json());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarDocumentoAlteradoCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarDocumentoAlteradoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarDocumentoAlteradoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarDocumentoAlteradoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarDocumentoAlteradoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarDocumentoComInconsistenciaCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-documento-com-inconsistencia';
|
||||||
|
protected $description = 'Comando para envio de documentos com inconsistencia ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($cliente, $parametrizacao, $parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getDocumentosComInconsistencia()
|
||||||
|
->each(function($documentoComInconsistencia) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$documentoComInconsistencia->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$documentoComInconsistencia->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$documentoComInconsistencia->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $documentoComInconsistencia, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$documentoComInconsistencia->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$documentoComInconsistencia->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::update($documentoComInconsistencia->documento_imunologico_rotina_id, $documentoComInconsistencia);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarDocumentoComInconsistenciaCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarDocumentoComInconsistenciaCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarDocumentoComInconsistenciaRetroativoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-documento-com-inconsistencia-retroativo';
|
||||||
|
protected $description = 'Comando para envio de documentos com inconsistencia retroativos ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getDocumentosComInconsistenciaRetroativos()
|
||||||
|
->each(function($documentoComInconsistenciaRetroativo) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$documentoComInconsistenciaRetroativo->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$documentoComInconsistenciaRetroativo->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$documentoComInconsistenciaRetroativo->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $documentoComInconsistenciaRetroativo, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$documentoComInconsistenciaRetroativo->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$documentoComInconsistenciaRetroativo->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::update($documentoComInconsistenciaRetroativo->documento_imunologico_rotina_id, $documentoComInconsistenciaRetroativo);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaRetroativoCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarDocumentoComInconsistenciaRetroativoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarDocumentoComInconsistenciaRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarDocumentoComInconsistenciaRetroativoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Integracao\Ria\DocumentoImunologicoRotina;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarExclusaoDocumentoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-exclusao-documento';
|
||||||
|
protected $description = 'Comando para envio de exclusão de documentos ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getDocumentosParaExclusao()
|
||||||
|
->each(function($documento) use ($parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (!app()->environment('production') && !str_contains($documento->identificador_rnds, 'ehr-services-hmg.saude.gov.br')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$documento->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$documento->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$documento->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::destroy($headers, $documento->identificador_rnds);
|
||||||
|
|
||||||
|
if ($response->status() === 204) {
|
||||||
|
DocumentoImunologicoRotina::destroy($documento->id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$documento->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::update($documento->id, $documento);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarExclusaoDocumentoCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarExclusaoDocumentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarExclusaoDocumentoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarExclusaoDocumentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarExclusaoDocumentoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarRegistroAplicacaoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-registro-aplicacao';
|
||||||
|
protected $description = 'Comando para envio de novos registros de aplicação ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getRegistrosAplicacao()
|
||||||
|
->each(function($registroAplicacao) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$registroAplicacao->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$registroAplicacao->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$registroAplicacao->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $registroAplicacao, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$registroAplicacao->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$registroAplicacao->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::store($registroAplicacao);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarRegistroAplicacaoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarRegistroAplicacaoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarRegistroAplicacaoRetroativoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-registro-aplicacao-retroativo';
|
||||||
|
protected $description = 'Comando para envio de registros de aplicação retroativos ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getRegistrosAplicacaoRetroativos()
|
||||||
|
->each(function($registroAplicacaoRetroativo) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$registroAplicacaoRetroativo->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$registroAplicacaoRetroativo->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$registroAplicacaoRetroativo->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $registroAplicacaoRetroativo, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$registroAplicacaoRetroativo->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$registroAplicacaoRetroativo->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::store($registroAplicacaoRetroativo);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoRetroativoCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarRegistroAplicacaoRetroativoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarRegistroAplicacaoRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarRegistroAplicacaoRetroativoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarRegistroAtualizacaoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-registro-atualizacao';
|
||||||
|
protected $description = 'Comando para envio de novos registros de atulaização ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getRegistrosAtualizacao()
|
||||||
|
->each(function($registroAtualizacao) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$registroAtualizacao->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$registroAtualizacao->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$registroAtualizacao->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $registroAtualizacao, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$registroAtualizacao->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$registroAtualizacao->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::store($registroAtualizacao);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoCommand',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarRegistroAtualizacaoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarRegistroAtualizacaoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Ria;
|
||||||
|
|
||||||
|
use App\Enums\Intranet\Sistema;
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\RiaService;
|
||||||
|
use App\Services\Integracao\Ria\DocumentoImunologicoRotinaService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarRegistroAtualizacaoRetroativoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:ria-enviar-registro-atualizacao-retroativo';
|
||||||
|
protected $description = 'Comando para envio de registros de atualização retroativos ao RIA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
$cliente = Cliente::where('link', $cliente)
|
||||||
|
->where('sistema_id', Sistema::CONECTASUS)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente->link);
|
||||||
|
|
||||||
|
$parametrizacao = RiaService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::getRegistrosAtualizacaoRetroativos()
|
||||||
|
->each(function($registroAtualizacaoRetroativo) use ($cliente, $parametrizacao, &$token, $expiresAt) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiaService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$registroAtualizacaoRetroativo->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$registroAtualizacaoRetroativo->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$registroAtualizacaoRetroativo->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiaService::sendDocumentoImunologicoRotina($headers, $registroAtualizacaoRetroativo, $cliente->municipio->estado->uf);
|
||||||
|
|
||||||
|
$registroAtualizacaoRetroativo->identificador_rnds = $response->header('Location') ? $response->header('Location') : null;
|
||||||
|
$registroAtualizacaoRetroativo->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoImunologicoRotinaService::store($registroAtualizacaoRetroativo);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-ria')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente->link,
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoRetroativoCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente->link ?? $cliente,
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA (' . ($cliente->link ?? $cliente) . '):</strong> (Erro ao executar o comando: EnviarRegistroAtualizacaoRetroativoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-ria')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarRegistroAtualizacaoRetroativoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIA:</strong> (Erro ao executar o comando: EnviarRegistroAtualizacaoRetroativoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
107
api/app/Console/Commands/Integracao/Rira/EnviarCommand.php
Normal file
107
api/app/Console/Commands/Integracao/Rira/EnviarCommand.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\Integracao\Rira;
|
||||||
|
|
||||||
|
use App\Models\Intranet\Cliente;
|
||||||
|
use App\Services\Integracao\Rira\DocumentoService;
|
||||||
|
use App\Services\Integracao\RiraService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnviarCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'integracao:rira-enviar';
|
||||||
|
protected $description = 'Comando para envio de solicitações ao RIRA.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
Config::set('database.default', $cliente);
|
||||||
|
|
||||||
|
$clienteModel = Cliente::where('link', $cliente)->where('sistema_id', 1)->firstOrFail();
|
||||||
|
$parametrizacao = RiraService::getParametrizacao();
|
||||||
|
|
||||||
|
if (!is_null($parametrizacao)) {
|
||||||
|
$token = RiraService::getToken($parametrizacao, $parametrizacao->senha);
|
||||||
|
$expiresAt = Carbon::now()->addMilliseconds($token['expires_in'])->subMinutes(2);
|
||||||
|
|
||||||
|
DocumentoService::getSolicitacoes()
|
||||||
|
->each(function($solicitacao) use ($parametrizacao, &$token, $expiresAt, $clienteModel) {
|
||||||
|
if (Carbon::now() >= $expiresAt) {
|
||||||
|
$token = RiraService::getToken($parametrizacao->senha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Authorization' => $parametrizacao->cns_solicitante,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Authorization-Server' => "Bearer " . $token['access_token'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$solicitacao->identificador_solicitante = $parametrizacao->identificador_solicitante;
|
||||||
|
$solicitacao->cns_solicitante = $parametrizacao->cns_solicitante;
|
||||||
|
$solicitacao->data_hora_envio = Carbon::now();
|
||||||
|
|
||||||
|
$response = RiraService::send($clienteModel, $headers, $solicitacao);
|
||||||
|
|
||||||
|
$urlRnds = null;
|
||||||
|
$identificadorRnds = null;
|
||||||
|
|
||||||
|
if (!empty($response->header('Location'))) {
|
||||||
|
$urlRnds = $response->header('Location');
|
||||||
|
$urlRndsExploded = explode('/', $urlRnds);
|
||||||
|
$identificadorRnds = $urlRndsExploded[count($urlRndsExploded) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$solicitacao->url_rnds = $urlRnds;
|
||||||
|
$solicitacao->identificador_rnds = $identificadorRnds;
|
||||||
|
$solicitacao->response = $response->json();
|
||||||
|
|
||||||
|
DocumentoService::save($solicitacao);
|
||||||
|
});
|
||||||
|
|
||||||
|
Log::channel('integracao-rira')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'EnviarCommand'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('integracao-rira')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'EnviarCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Integração RIRA:</strong> (Erro ao executar o comando: EnviarCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')
|
||||||
|
->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])
|
||||||
|
))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\PainelSenha;
|
||||||
|
|
||||||
|
use App\Events\PainelSenha\AvisoEvent;
|
||||||
|
use App\Models\PainelSenha\AvisoAgendamento;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class EnvioAvisoAgendadoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'painel-senha:envio-aviso-agendado';
|
||||||
|
protected $description = 'Comando para enviar os avisos que estão agendados';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
self::getClientes()->each(function($cliente) {
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente);
|
||||||
|
|
||||||
|
if(!Schema::hasTable('painel_senha_aviso')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$agora = Carbon::now();
|
||||||
|
$toleranciaInicio = $agora->copy()->subSeconds(30);
|
||||||
|
$toleranciaFim = $agora->copy()->addSeconds(30);
|
||||||
|
|
||||||
|
$agendamentos = DB::table('painel_senha_aviso_agendamento')
|
||||||
|
->whereDate('data_hora_agendada', $agora->toDateString())
|
||||||
|
->whereBetween('data_hora_agendada', [$toleranciaInicio, $toleranciaFim])
|
||||||
|
->whereNull('data_hora_executada')
|
||||||
|
->where('painel_senha_aviso.is_ativo', true)
|
||||||
|
->join('painel_senha_aviso', 'painel_senha_aviso.id', 'painel_senha_aviso_agendamento.aviso_id')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
if($agendamentos->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$idsAgendamentos = $agendamentos->pluck("id");
|
||||||
|
$idsAvisos = $agendamentos->pluck("aviso_id");
|
||||||
|
|
||||||
|
AvisoAgendamento::whereIn('id', $idsAgendamentos)
|
||||||
|
->update(['data_hora_executada' => $agora]);
|
||||||
|
|
||||||
|
$avisos = DB::table('painel_senha_aviso')
|
||||||
|
->select(
|
||||||
|
'painel_senha_aviso.id',
|
||||||
|
'painel_senha_aviso.mensagem',
|
||||||
|
DB::raw('GROUP_CONCAT(cadastro_unidade.nome_fantasia) as unidades'),
|
||||||
|
DB::raw('GROUP_CONCAT(cadastro_unidade.id) as ids_unidade'),
|
||||||
|
'painel_senha_aviso.is_ativo',
|
||||||
|
)
|
||||||
|
->join('painel_senha_aviso_unidade', 'painel_senha_aviso_unidade.aviso_id', 'painel_senha_aviso.id')
|
||||||
|
->leftJoin('cadastro_unidade', 'cadastro_unidade.id', 'painel_senha_aviso_unidade.unidade_id')
|
||||||
|
->groupBy('painel_senha_aviso.id', 'painel_senha_aviso.mensagem', 'painel_senha_aviso.is_ativo')
|
||||||
|
->whereIn('painel_senha_aviso.id', $idsAvisos)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$avisos->map(function($aviso) {
|
||||||
|
AvisoEvent::dispatch($aviso->id, $aviso);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
Log::info("Não foi possível enviar aviso {$th}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands\PainelSenha;
|
||||||
|
|
||||||
|
use App\Enums\Administracao\Modulo;
|
||||||
|
use App\Models\PainelSenha\Fila;
|
||||||
|
use App\Models\PainelSenha\OpcaoEntrada;
|
||||||
|
use App\Services\Administracao\ModuloService;
|
||||||
|
use App\Services\Telegram\TelegramService;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class LimparFilaAtendimentoCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'painel-senha:limpar-fila-atendimento';
|
||||||
|
protected $description = 'Comando para limpesa da fila de atendimento no módulo painel de senha.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$currentDatabase = Config::get('database.default');
|
||||||
|
|
||||||
|
$this->getClientes()->each(function($cliente) {
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
Config::set('database.default', $cliente);
|
||||||
|
|
||||||
|
Fila::where('finalizado', false)
|
||||||
|
->where('evadido', false)
|
||||||
|
->whereIn('opcao_entrada_id', $this->getOpcoesEntrada())
|
||||||
|
->update([
|
||||||
|
'finalizado' => true,
|
||||||
|
'evadido' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::channel('painel-senha-fila-atendimento')->info('Comando executado com sucesso.', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
]);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
Log::channel('painel-senha-fila-atendimento')->error('Erro ao executar o comando', [
|
||||||
|
'cliente' => $cliente,
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Farmácia (' . ($cliente) . '):</strong> (Erro ao executar o comando: LimparFilaAtendimentoCommand).');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Config::set('database.default', $currentDatabase);
|
||||||
|
} catch (Exception $error) {
|
||||||
|
Log::channel('painel-senha-fila-atendimento')->error('Erro ao executar o comando', [
|
||||||
|
'origem' => 'LimparFilaAtendimentoCommand',
|
||||||
|
'erro' => $error->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (env('APP_ENV') === 'production') {
|
||||||
|
TelegramService::send('<strong>Painel de senha:</strong> (Erro ao executar o comando: LimparFilaAtendimentoCommand).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClientes()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => empty(DB::connection('schema')->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?", [$config['database']])))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOpcoesEntrada()
|
||||||
|
{
|
||||||
|
return OpcaoEntrada::where('modulo_id', ModuloService::getId(Modulo::PAINEL_SENHA))
|
||||||
|
->pluck('id');
|
||||||
|
}
|
||||||
|
}
|
||||||
74
api/app/Console/Commands/PublishCommand.php
Normal file
74
api/app/Console/Commands/PublishCommand.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class PublishCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'publish';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Run migrations and seeders';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->getCustomers()->each(function ($customer, $i) {
|
||||||
|
|
||||||
|
if ($i > 0) {
|
||||||
|
$this->getOutput()->writeln("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getOutput()->writeln("<question>{$customer}</question>");
|
||||||
|
|
||||||
|
$this->call('migrate', ['--database' => $customer, '--force' => true]);
|
||||||
|
$this->call('db:seed', ['--database' => $customer, '--force' => true]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCustomers()
|
||||||
|
{
|
||||||
|
return collect(json_decode(file_get_contents(base_path('connections.json')), true))
|
||||||
|
->filter(fn ($config) => isset($config['database']) && Str::startsWith($config['database'], 'conectasus'))
|
||||||
|
->reject(fn ($config) => !$this->databaseExists($config['database']))
|
||||||
|
->map(fn ($config, $customer) => $customer)
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function databaseExists($databaseName)
|
||||||
|
{
|
||||||
|
return !empty(DB::connection('schema')->select(
|
||||||
|
"SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?",
|
||||||
|
[$databaseName]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
280
api/app/Console/Commands/SeedCommand.php
Normal file
280
api/app/Console/Commands/SeedCommand.php
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Console\ConfirmableTrait;
|
||||||
|
use Illuminate\Database\ConnectionResolverInterface as Resolver;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Filesystem\Filesystem;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
class SeedCommand extends Command
|
||||||
|
{
|
||||||
|
use ConfirmableTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = 'db:seed';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Seed the database with records';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection resolver instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Database\ConnectionResolverInterface
|
||||||
|
*/
|
||||||
|
protected $resolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filesystem instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Filesystem\Filesystem
|
||||||
|
*/
|
||||||
|
protected $files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database seed command instance.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\ConnectionResolverInterface $resolver
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Resolver $resolver)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->resolver = $resolver;
|
||||||
|
$this->files = new Filesystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (! $this->confirmToProceed()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previousConnection = $this->resolver->getDefaultConnection();
|
||||||
|
|
||||||
|
$this->resolver->setDefaultConnection($this->getDatabase());
|
||||||
|
|
||||||
|
Schema::disableForeignKeyConstraints();
|
||||||
|
|
||||||
|
self::getSeedersClasses()->each(function ($class) {
|
||||||
|
Model::unguarded(function () use ($class) {
|
||||||
|
|
||||||
|
$this->getOutput()->writeln("<comment>Seeding:</comment> {$class['file_name']}");
|
||||||
|
|
||||||
|
$startTime = microtime(true);
|
||||||
|
|
||||||
|
$this->getSeeder(class_basename($class['instance']))->__invoke();
|
||||||
|
|
||||||
|
$runTime = number_format((microtime(true) - $startTime) * 1000, 2);
|
||||||
|
|
||||||
|
$this->getOutput()->writeln("<info>Seeded:</info> {$class['file_name']} ({$runTime}ms)");
|
||||||
|
|
||||||
|
DB::connection($this->getDatabase())->table('seeders')->insert(['seeder' => $class['file_name']]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::enableForeignKeyConstraints();
|
||||||
|
|
||||||
|
if ($previousConnection) {
|
||||||
|
$this->resolver->setDefaultConnection($previousConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Database seeding completed successfully.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSeedersClasses()
|
||||||
|
{
|
||||||
|
$ran = DB::connection($this->getDatabase())->table('seeders')->select('seeder')->pluck('seeder')->all();
|
||||||
|
$files = $this->getSeederFiles();
|
||||||
|
|
||||||
|
$this->requireFiles($seeders = $this->pendingSeeders(
|
||||||
|
$files, $ran
|
||||||
|
));
|
||||||
|
|
||||||
|
$classes = collect();
|
||||||
|
|
||||||
|
foreach ($seeders as $file) {
|
||||||
|
|
||||||
|
$fileName = $this->getSeederName($file);
|
||||||
|
|
||||||
|
$classes->push([
|
||||||
|
'file_name' => $fileName,
|
||||||
|
'instance' => $this->resolve($fileName)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the seeder files.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSeederFiles()
|
||||||
|
{
|
||||||
|
return Collection::make(self::getSeederPaths())->flatMap(function ($path) {
|
||||||
|
return Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php');
|
||||||
|
})->filter()->values()->keyBy(function ($file) {
|
||||||
|
return $this->getSeederName($file);
|
||||||
|
})->sortBy(function ($file, $key) {
|
||||||
|
return $key;
|
||||||
|
})->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get seeder path.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getSeederPaths()
|
||||||
|
{
|
||||||
|
$invalidContents = ['.', '..', '.gitkeep', 'base'];
|
||||||
|
$seedersDir = database_path() . '/seeders/';
|
||||||
|
|
||||||
|
return $this->getSeederFilesPaths(
|
||||||
|
$invalidContents,
|
||||||
|
$seedersDir
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSeederFilesPaths($invalidContents, $currentDirectory, $paths = [])
|
||||||
|
{
|
||||||
|
$contents = opendir($currentDirectory);
|
||||||
|
|
||||||
|
while ($content = readdir($contents)) {
|
||||||
|
|
||||||
|
if (!in_array($content, $invalidContents)) {
|
||||||
|
|
||||||
|
$fullPath = $currentDirectory . $content;
|
||||||
|
|
||||||
|
if (is_dir($fullPath)) {
|
||||||
|
|
||||||
|
$paths = $this->getSeederFilesPaths(
|
||||||
|
$invalidContents,
|
||||||
|
$fullPath . '/',
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$paths[] = $fullPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require in all the seeder files in a given path.
|
||||||
|
*
|
||||||
|
* @param array $files
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function requireFiles(array $files)
|
||||||
|
{
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$this->files->requireOnce($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a seeder instance from a file.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function resolve($file)
|
||||||
|
{
|
||||||
|
$fileArr = explode('_', $file);
|
||||||
|
$class = Str::studly(implode('_', array_slice($fileArr, 4))).'_'.implode(array_slice($fileArr, 0, 4));
|
||||||
|
|
||||||
|
return new $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the seeder.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSeederName($path)
|
||||||
|
{
|
||||||
|
return str_replace('.php', '', basename($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the seeder files that have not yet run.
|
||||||
|
*
|
||||||
|
* @param array $files
|
||||||
|
* @param array $ran
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function pendingSeeders($files, $ran)
|
||||||
|
{
|
||||||
|
return Collection::make($files)
|
||||||
|
->reject(function ($file) use ($ran) {
|
||||||
|
return in_array($this->getSeederName($file), $ran);
|
||||||
|
})->values()->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a seeder instance from the container.
|
||||||
|
* @param string $class
|
||||||
|
* @return \Illuminate\Database\Seeder
|
||||||
|
*/
|
||||||
|
protected function getSeeder($class)
|
||||||
|
{
|
||||||
|
return $this->laravel->make($class)
|
||||||
|
->setContainer($this->laravel)
|
||||||
|
->setCommand($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the database connection to use.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getDatabase()
|
||||||
|
{
|
||||||
|
$database = $this->input->getOption('database');
|
||||||
|
|
||||||
|
return $database ?: $this->laravel['config']['database.default'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the console command options.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getOptions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'],
|
||||||
|
['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
119
api/app/Console/Commands/SeedPermissionsCommand.php
Normal file
119
api/app/Console/Commands/SeedPermissionsCommand.php
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Database\Seeders\Base\Funcionalidade;
|
||||||
|
use Database\Seeders\Base\FuncionalidadeSub;
|
||||||
|
use Database\Seeders\Base\Menu;
|
||||||
|
use Database\Seeders\Base\Modulo;
|
||||||
|
use Database\Seeders\Base\Permissao;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Database\ConnectionResolverInterface as Resolver;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
class SeedPermissionsCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The console command name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = 'dev:seed-permissions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Seed the database with permissions records';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection resolver instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Database\ConnectionResolverInterface
|
||||||
|
*/
|
||||||
|
protected $resolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filesystem instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Filesystem\Filesystem
|
||||||
|
*/
|
||||||
|
protected $files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database seed command instance.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\ConnectionResolverInterface $resolver
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Resolver $resolver)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->resolver = $resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$previousConnection = $this->resolver->getDefaultConnection();
|
||||||
|
|
||||||
|
$this->resolver->setDefaultConnection($this->getDatabase());
|
||||||
|
|
||||||
|
collect([
|
||||||
|
Modulo::class,
|
||||||
|
Funcionalidade::class,
|
||||||
|
FuncionalidadeSub::class,
|
||||||
|
Menu::class,
|
||||||
|
Permissao::class,
|
||||||
|
])->each(function ($model) {
|
||||||
|
|
||||||
|
$this->getOutput()->writeln("<comment>Seeding:</comment> {$model}");
|
||||||
|
|
||||||
|
$startTime = microtime(true);
|
||||||
|
|
||||||
|
$model::run();
|
||||||
|
|
||||||
|
$runTime = number_format((microtime(true) - $startTime) * 1000, 2);
|
||||||
|
|
||||||
|
$this->getOutput()->writeln("<info>Seeded:</info> {$model} ({$runTime}ms)");
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($previousConnection) {
|
||||||
|
$this->resolver->setDefaultConnection($previousConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Permissions seeding completed successfully.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the database connection to use.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getDatabase()
|
||||||
|
{
|
||||||
|
$database = $this->input->getOption('database');
|
||||||
|
|
||||||
|
return $database ?: $this->laravel['config']['database.default'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the console command options.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getOptions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to seed'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
211
api/app/Console/Commands/SeederMakeCommand.php
Normal file
211
api/app/Console/Commands/SeederMakeCommand.php
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Filesystem\Filesystem;
|
||||||
|
use Illuminate\Support\Composer;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
class SeederMakeCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The console command signature.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'make:seeder {name : The name of the seeder}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Create a new seeder file';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filesystem instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Filesystem\Filesystem
|
||||||
|
*/
|
||||||
|
protected $files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Composer instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Support\Composer
|
||||||
|
*/
|
||||||
|
protected $composer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new seeder make command instance.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Filesystem\Filesystem $files
|
||||||
|
* @param \Illuminate\Support\Composer $composer
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Filesystem $files, Composer $composer)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->files = $files;
|
||||||
|
$this->composer = $composer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$name = Str::snake(trim($this->input->getArgument('name')));
|
||||||
|
|
||||||
|
$this->writeSeeder($name);
|
||||||
|
|
||||||
|
$this->composer->dumpAutoloads();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the seeder file to disk.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function writeSeeder($name)
|
||||||
|
{
|
||||||
|
$file = $this->create(
|
||||||
|
$name, $this->getSeederPath()
|
||||||
|
);
|
||||||
|
|
||||||
|
$file = pathinfo($file, PATHINFO_FILENAME);
|
||||||
|
|
||||||
|
$this->line("<info>Created Seeder:</info> {$file}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get seeder path.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getSeederPath()
|
||||||
|
{
|
||||||
|
return $this->laravel->databasePath().DIRECTORY_SEPARATOR.'seeders';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new seeder at the given path.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function create($name, $path)
|
||||||
|
{
|
||||||
|
$dateTime = new DateTime();
|
||||||
|
$className = $this->getClassName($dateTime, $name);
|
||||||
|
|
||||||
|
$this->ensureSeederDoesntAlreadyExist($className, $path);
|
||||||
|
|
||||||
|
$stub = $this->getStub();
|
||||||
|
$path = $this->getPath($dateTime, $name, $path);
|
||||||
|
|
||||||
|
$this->files->ensureDirectoryExists(dirname($path));
|
||||||
|
|
||||||
|
$this->files->put(
|
||||||
|
$path, $this->populateStub($className, $stub)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that a seeder with the given name doesn't already exist.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string $seederPath
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
protected function ensureSeederDoesntAlreadyExist($className, $seederPath = null)
|
||||||
|
{
|
||||||
|
if (! empty($seederPath)) {
|
||||||
|
$seederFiles = $this->files->glob($seederPath.'/*.php');
|
||||||
|
|
||||||
|
foreach ($seederFiles as $seederFile) {
|
||||||
|
$this->files->requireOnce($seederFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($className)) {
|
||||||
|
throw new InvalidArgumentException("A {$className} class already exists.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the seeder stub file.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getStub()
|
||||||
|
{
|
||||||
|
$stub = $this->stubPath().'/seeder.stub';
|
||||||
|
|
||||||
|
return $this->files->get($stub);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the place-holders in the seeder stub.
|
||||||
|
*
|
||||||
|
* @param string $className
|
||||||
|
* @param string $stub
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function populateStub($className, $stub)
|
||||||
|
{
|
||||||
|
$stub = str_replace(
|
||||||
|
['DummyClass', '{{ class }}', '{{class}}'],
|
||||||
|
$className, $stub
|
||||||
|
);
|
||||||
|
|
||||||
|
return $stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class name of a seeder name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getClassName($dateTime, $name)
|
||||||
|
{
|
||||||
|
return Str::studly($name).'_'.$dateTime->format('YmdHis');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the full path to the seeder.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getPath($dateTime, $name, $path)
|
||||||
|
{
|
||||||
|
return $path.'/'.$dateTime->format('Y_m_d_His').'_'.$name.'.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path to the stubs.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function stubPath()
|
||||||
|
{
|
||||||
|
return $this->laravel->basePath().'/stubs';
|
||||||
|
}
|
||||||
|
}
|
||||||
152
api/app/Console/Kernel.php
Normal file
152
api/app/Console/Kernel.php
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console;
|
||||||
|
|
||||||
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
|
class Kernel extends ConsoleKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Artisan commands provided by your application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $commands = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the application's command schedule.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function schedule(Schedule $schedule)
|
||||||
|
{
|
||||||
|
if (!config('app.run_schedule')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BNAFAR.
|
||||||
|
$schedule->command('integracao:bnafar-enviar-posicao-estoque')
|
||||||
|
->name('integracao:bnafar-enviar-posicao-estoque')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->daily()
|
||||||
|
->at('22:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:bnafar-enviar-saida')
|
||||||
|
->name('integracao:bnafar-enviar-saida')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->daily()
|
||||||
|
->at('22:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:bnafar-verificar-posicao-estoque')
|
||||||
|
->name('integracao:bnafar-verificar-posicao-estoque')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->daily()
|
||||||
|
->at('02:30');
|
||||||
|
|
||||||
|
$schedule->command('integracao:bnafar-verificar-saida')
|
||||||
|
->name('integracao:bnafar-verificar-saida')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->daily()
|
||||||
|
->at('02:30');
|
||||||
|
|
||||||
|
// Fila de atendimento.
|
||||||
|
$schedule->command('farmacia:limpar-fila-atendimento')
|
||||||
|
->name('farmacia-limpar-fila-atendimento')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('00:25');
|
||||||
|
|
||||||
|
$schedule->command('painel-senha:limpar-fila-atendimento')
|
||||||
|
->name('painel-senha-limpar-fila-atendimento')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('00:30');
|
||||||
|
|
||||||
|
// Avisos do painel de senha
|
||||||
|
$schedule->command('painel-senha:envio-aviso-agendado')->everyMinute();
|
||||||
|
|
||||||
|
// RIA.
|
||||||
|
$schedule->command('integracao:ria-enviar-registro-aplicacao-retroativo')
|
||||||
|
->name('integracao:ria-enviar-registro-aplicacao-retroativo')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->everyTwoHours();
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-registro-atualizacao-retroativo')
|
||||||
|
->name('integracao:ria-enviar-registro-atualizacao-retroativo')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->everyTwoHours();
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-registro-aplicacao')
|
||||||
|
->name('integracao:ria-enviar-registro-aplicacao')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('01:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-registro-atualizacao')
|
||||||
|
->name('integracao:ria-enviar-registro-atualizacao')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('01:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-documento-com-inconsistencia')
|
||||||
|
->name('integracao:ria-enviar-documento-com-inconsistencia')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->weeklyOn(6, '01:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-documento-com-inconsistencia-retroativo')
|
||||||
|
->name('integracao:ria-enviar-documento-com-inconsistencia-retroativo')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->weeklyOn(0, '01:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-documento-alterado')
|
||||||
|
->name('integracao:ria-enviar-documento-alterado')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('04:00');
|
||||||
|
|
||||||
|
$schedule->command('integracao:ria-enviar-exclusao-documento')
|
||||||
|
->name('integracao:ria-enviar-exclusao-documento')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('05:00');
|
||||||
|
|
||||||
|
// RIRA
|
||||||
|
$schedule->command('integracao:rira-enviar')
|
||||||
|
->name('integracao:rira-enviar')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('02:00');
|
||||||
|
|
||||||
|
// ERPSAUDE
|
||||||
|
$schedule->command('integracao:erpsaude-buscar-atendimentos-hospital-santa-casa')
|
||||||
|
->name('integracao:erpsaude-buscar-atendimentos-hospital-santa-casa')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([0,1,2,3,4,5,6])
|
||||||
|
->at('02:30');
|
||||||
|
|
||||||
|
// ESUS
|
||||||
|
$schedule->command('integracao:esus-enviar')
|
||||||
|
->name('integracao:esus-enviar')
|
||||||
|
->withoutOverlapping()
|
||||||
|
->days([1,2,3,4,5])
|
||||||
|
->at('03:00');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the commands for the application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function commands()
|
||||||
|
{
|
||||||
|
$this->load(__DIR__.'/Commands');
|
||||||
|
|
||||||
|
require base_path('routes/console.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
25
api/app/Database/MySqlConnection.php
Normal file
25
api/app/Database/MySqlConnection.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database;
|
||||||
|
|
||||||
|
use App\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\MySqlConnection as BaseMySqlConnection;
|
||||||
|
|
||||||
|
class MySqlConnection extends BaseMySqlConnection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get a schema builder instance for the connection.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Schema\MySqlBuilder
|
||||||
|
*/
|
||||||
|
public function getSchemaBuilder()
|
||||||
|
{
|
||||||
|
$builder = parent::getSchemaBuilder();
|
||||||
|
|
||||||
|
$builder->blueprintResolver(function ($table, $callback) {
|
||||||
|
return new Blueprint($table, $callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
api/app/Database/Schema/Blueprint.php
Normal file
62
api/app/Database/Schema/Blueprint.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Schema;
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint as BaseBlueprint;
|
||||||
|
|
||||||
|
class Blueprint extends BaseBlueprint
|
||||||
|
{
|
||||||
|
private const MAX_INDEX_NAME_LENGTH = 64;
|
||||||
|
private const MAX_FRAGMENT_INDEX_LEGNTH = 4;
|
||||||
|
private const MIN_FRAGMENT_INDEX_LEGNTH = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a default index name for the table.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param array $columns
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function createIndexName($type, array $columns)
|
||||||
|
{
|
||||||
|
$index = $this->getReducedIndexName($type, $columns, self::MAX_FRAGMENT_INDEX_LEGNTH);
|
||||||
|
|
||||||
|
return str_replace(['-', '.'], '_', $index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getReducedIndexName($type, array $columns, int $fragmentLength)
|
||||||
|
{
|
||||||
|
$table = null;
|
||||||
|
|
||||||
|
foreach($columns as $key => $value) {
|
||||||
|
$column = null;
|
||||||
|
|
||||||
|
foreach(explode('_', $value) as $explode) {
|
||||||
|
$column .= substr($explode, 0, $fragmentLength) . '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns[$key] = rtrim($column, '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(explode('_', $this->table) as $explode) {
|
||||||
|
$table .= substr($explode, 0, $fragmentLength) . '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = strtolower($this->prefix.rtrim($table, '_').'_'.implode('_', $columns).'_'.$type);
|
||||||
|
|
||||||
|
if (strlen($index) > self::MAX_INDEX_NAME_LENGTH) {
|
||||||
|
|
||||||
|
$newFragmentLength = $fragmentLength - 1;
|
||||||
|
|
||||||
|
if ($newFragmentLength < self::MIN_FRAGMENT_INDEX_LEGNTH) {
|
||||||
|
|
||||||
|
throw new \Exception("An error has occurred while reducing the length of the index. "
|
||||||
|
. "Please, name it manually.\nThe last try result in: {$index}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getReducedIndexName($type, $columns, $newFragmentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $index;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
api/app/Enums/Administracao/CrudAcao.php
Normal file
11
api/app/Enums/Administracao/CrudAcao.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Administracao;
|
||||||
|
|
||||||
|
class CrudAcao
|
||||||
|
{
|
||||||
|
const CRIAR = 1;
|
||||||
|
const VISUALIZAR = 2;
|
||||||
|
const ATUALIZAR = 3;
|
||||||
|
const EXCLUIR = 4;
|
||||||
|
}
|
||||||
9
api/app/Enums/Administracao/HistoricoAcao.php
Normal file
9
api/app/Enums/Administracao/HistoricoAcao.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Administracao;
|
||||||
|
|
||||||
|
class HistoricoAcao
|
||||||
|
{
|
||||||
|
const CADASTRO = 1;
|
||||||
|
const EXCLUSAO = 2;
|
||||||
|
}
|
||||||
15
api/app/Enums/Administracao/Modulo.php
Normal file
15
api/app/Enums/Administracao/Modulo.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Administracao;
|
||||||
|
|
||||||
|
class Modulo
|
||||||
|
{
|
||||||
|
const AMBULATORIO = 'ambulatorio';
|
||||||
|
const EXAME_LABORATORIAL = 'exame-laboratorial';
|
||||||
|
const EXAME_IMAGEM = 'exame-imagem';
|
||||||
|
const IMUNIZACAO = 'imunizacao';
|
||||||
|
const FARMACIA = 'farmacia';
|
||||||
|
const PAINEL_SENHA = 'painel-senha';
|
||||||
|
const PRONTO_ATENDIMENTO = 'pronto-atendimento';
|
||||||
|
const TRANSPORTE_PACIENTE = 'transporte-paciente';
|
||||||
|
}
|
||||||
9
api/app/Enums/Administracao/NotificacaoTipo.php
Normal file
9
api/app/Enums/Administracao/NotificacaoTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Administracao;
|
||||||
|
|
||||||
|
class NotificacaoTipo
|
||||||
|
{
|
||||||
|
const ATUALIZACAO = 1;
|
||||||
|
const AVISO = 2;
|
||||||
|
}
|
||||||
11
api/app/Enums/Almoxarifado/DocumentoTipo.php
Normal file
11
api/app/Enums/Almoxarifado/DocumentoTipo.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class DocumentoTipo
|
||||||
|
{
|
||||||
|
const NOTA_FISCAL = 1;
|
||||||
|
const OUTRAS = 2;
|
||||||
|
const DOACAO = 3;
|
||||||
|
const DEVOLUCAO = 4;
|
||||||
|
}
|
||||||
13
api/app/Enums/Almoxarifado/EntradaTipo.php
Normal file
13
api/app/Enums/Almoxarifado/EntradaTipo.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class EntradaTipo
|
||||||
|
{
|
||||||
|
const MANUAL = 1;
|
||||||
|
const REQUISICAO = 2;
|
||||||
|
const INVENTARIO = 3;
|
||||||
|
const ESTORNO = 4;
|
||||||
|
const INICIAL = 5;
|
||||||
|
const TRANSFERENCIA = 6;
|
||||||
|
}
|
||||||
10
api/app/Enums/Almoxarifado/MotivoBaixaTipo.php
Normal file
10
api/app/Enums/Almoxarifado/MotivoBaixaTipo.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class MotivoBaixaTipo
|
||||||
|
{
|
||||||
|
const CONSUMO_INTERNO = 1;
|
||||||
|
const QUEBRADO = 2;
|
||||||
|
const VENCIDO = 3;
|
||||||
|
}
|
||||||
14
api/app/Enums/Almoxarifado/RequisicaoRespostaItemMotivo.php
Normal file
14
api/app/Enums/Almoxarifado/RequisicaoRespostaItemMotivo.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class RequisicaoRespostaItemMotivo
|
||||||
|
{
|
||||||
|
const SEM_ESTOQUE = 1;
|
||||||
|
const PEDIDO_EM_EXCESSO = 2;
|
||||||
|
const ENTREGA_PARCIAL = 3;
|
||||||
|
const PENDENTE_DE_ENTREGA = 4;
|
||||||
|
const RECUSADO = 5;
|
||||||
|
const ADEQUACAO_DE_CAIXA = 6;
|
||||||
|
const OUTRO = 7;
|
||||||
|
}
|
||||||
10
api/app/Enums/Almoxarifado/RequisicaoRespostaStatus.php
Normal file
10
api/app/Enums/Almoxarifado/RequisicaoRespostaStatus.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class RequisicaoRespostaStatus
|
||||||
|
{
|
||||||
|
const INICIADA = 1;
|
||||||
|
const ENVIADA = 2;
|
||||||
|
const RECEBIDA = 3;
|
||||||
|
}
|
||||||
10
api/app/Enums/Almoxarifado/RequisicaoStatus.php
Normal file
10
api/app/Enums/Almoxarifado/RequisicaoStatus.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class RequisicaoStatus
|
||||||
|
{
|
||||||
|
const ABERTA = 1;
|
||||||
|
const RESPOSTA_INICIADA = 2;
|
||||||
|
const FINALIZADA = 3;
|
||||||
|
}
|
||||||
8
api/app/Enums/Almoxarifado/ReservaMotivo.php
Normal file
8
api/app/Enums/Almoxarifado/ReservaMotivo.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class ReservaMotivo
|
||||||
|
{
|
||||||
|
const REQUISICAO = 1;
|
||||||
|
}
|
||||||
16
api/app/Enums/Almoxarifado/SaidaTipo.php
Normal file
16
api/app/Enums/Almoxarifado/SaidaTipo.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Almoxarifado;
|
||||||
|
|
||||||
|
class SaidaTipo
|
||||||
|
{
|
||||||
|
const MANUAL = 1;
|
||||||
|
const REQUISICAO = 2;
|
||||||
|
const INVENTARIO = 3;
|
||||||
|
const ESTORNO = 4;
|
||||||
|
const DISPENSACAO_FARMACIA = 5;
|
||||||
|
const BAIXA = 6;
|
||||||
|
const TRANSFERENCIA = 7;
|
||||||
|
const DISPENSACAO_ALMOXARIFADO = 8;
|
||||||
|
const DISPENSACAO_AMBULATORIO = 9;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AcompanhamentoOciMotivoEncerramento
|
||||||
|
{
|
||||||
|
const ABANDONO = 1;
|
||||||
|
const OBITO = 2;
|
||||||
|
const CANCELAMENTO_PELO_AUDITOR = 3;
|
||||||
|
const VENCIDO = 4;
|
||||||
|
const CONCLUIDO = 5;
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/AcompanhamentoOciStatus.php
Normal file
10
api/app/Enums/Ambulatorio/AcompanhamentoOciStatus.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AcompanhamentoOciStatus
|
||||||
|
{
|
||||||
|
const EM_ANDAMENTO = 1;
|
||||||
|
const ENCERRADO_MANUALMENTE = 2;
|
||||||
|
const ENCERRADO_AUTOMATICAMENTE = 3;
|
||||||
|
}
|
||||||
16
api/app/Enums/Ambulatorio/AgendamentoStatus.php
Normal file
16
api/app/Enums/Ambulatorio/AgendamentoStatus.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AgendamentoStatus
|
||||||
|
{
|
||||||
|
const AGENDADO = 1;
|
||||||
|
const REAGENDADO_PELO_PACIENTE = 2;
|
||||||
|
const REAGENDADO_PELO_MEDICO = 3;
|
||||||
|
const CANCELADO_PELO_PACIENTE = 4;
|
||||||
|
const CANCELADO_PELO_MEDICO = 5;
|
||||||
|
const FALTA_DO_PACIENTE = 6;
|
||||||
|
const FALTA_DO_MEDICO = 7;
|
||||||
|
const REALIZADO = 8;
|
||||||
|
const EVADIDO = 9;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/AgendamentoTipo.php
Normal file
9
api/app/Enums/Ambulatorio/AgendamentoTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AgendamentoTipo
|
||||||
|
{
|
||||||
|
const CONSULTA = 1;
|
||||||
|
const RETORNO = 2;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/ArcadaDentaria.php
Normal file
9
api/app/Enums/Ambulatorio/ArcadaDentaria.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ArcadaDentaria
|
||||||
|
{
|
||||||
|
const SUPERIOR = 1;
|
||||||
|
const INFERIOR = 2;
|
||||||
|
}
|
||||||
11
api/app/Enums/Ambulatorio/AtendimentoEspecificoTipo.php
Normal file
11
api/app/Enums/Ambulatorio/AtendimentoEspecificoTipo.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AtendimentoEspecificoTipo
|
||||||
|
{
|
||||||
|
const SAUDE_BUCAL = 1;
|
||||||
|
const PRE_NATAL = 2;
|
||||||
|
const PUERICULTURA = 3;
|
||||||
|
const IDOSO = 4;
|
||||||
|
}
|
||||||
21
api/app/Enums/Ambulatorio/AtendimentoImpressaoTipo.php
Normal file
21
api/app/Enums/Ambulatorio/AtendimentoImpressaoTipo.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AtendimentoImpressaoTipo
|
||||||
|
{
|
||||||
|
const RECEITA_COMUM = 1;
|
||||||
|
const RECEITA_ESPECIAL = 2;
|
||||||
|
const RECEITA_ESPECIAL_AZUL = 3;
|
||||||
|
const RECEITA_ESPECIAL_AMARELA = 4;
|
||||||
|
const RECEITA_NAO_PADRONIZADA_COMUM = 5;
|
||||||
|
const RECEITA_NAO_PADRONIZADA_ESPECIAL = 6;
|
||||||
|
const SERVICO_DE_ANALISES_DIAGNOSTICOS_E_TERAPIA_SOLICITACAO_DE_EXAMES_SADAT = 7;
|
||||||
|
const FICHA_DE_REQUISICAO_DE_SERVICOS_AUXILIARES_DE_DIAGOSE_E_TERAPIA_SADT = 8;
|
||||||
|
const LAUDO_PARA_SOLICITACAO_AUTORIZACAO_DE_PROCEDIMENTO_AMBULATORIAL = 9;
|
||||||
|
const ENCAMINHAMENTO = 10;
|
||||||
|
const ATESTADO_MEDICO = 11;
|
||||||
|
const DECLARACAO_COMPARECIMENTO = 12;
|
||||||
|
const CARTA_MEDICA = 13;
|
||||||
|
const ORIENTACAO = 14;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AtendimentoSoapSolicitacaoExameItemStatus
|
||||||
|
{
|
||||||
|
const SOLICITADO = 1;
|
||||||
|
const AGENDADO = 2;
|
||||||
|
const REALIZADO = 3;
|
||||||
|
const FALTA = 4;
|
||||||
|
const CANCELADO = 5;
|
||||||
|
const REAGENDADO = 6;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/AtendimentoTipo.php
Normal file
9
api/app/Enums/Ambulatorio/AtendimentoTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AtendimentoTipo
|
||||||
|
{
|
||||||
|
const DEMANDA_ESPONTANEA = 1;
|
||||||
|
const PROGRAMADA = 2;
|
||||||
|
}
|
||||||
13
api/app/Enums/Ambulatorio/AtestadoModelo.php
Normal file
13
api/app/Enums/Ambulatorio/AtestadoModelo.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class AtestadoModelo
|
||||||
|
{
|
||||||
|
const PADRAO = 1;
|
||||||
|
const EM_BRANCO = 2;
|
||||||
|
const PERIODO_MANHA = 3;
|
||||||
|
const PERIODO_TARDE = 4;
|
||||||
|
const PERIODO_NOITE = 5;
|
||||||
|
const QUANTIDADE_HORAS = 6;
|
||||||
|
}
|
||||||
63
api/app/Enums/Ambulatorio/CasoSuspeito.php
Normal file
63
api/app/Enums/Ambulatorio/CasoSuspeito.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class CasoSuspeito
|
||||||
|
{
|
||||||
|
const ACIDENTE_DE_TRABALHO_COM_EXPOSICAO_A_MATERIAL_BIOLOGICO = 1;
|
||||||
|
const ACIDENTE_DE_TRABALHO_GRAVE = 2;
|
||||||
|
const ACIDENTES_POR_ANIMAIS_PECONHENTOS = 3;
|
||||||
|
const AIDS_PACIENTES_MAIORES_DE_13_ANOS = 4;
|
||||||
|
const ATENDIMENTO_ANTI_RABICO_HUMANO = 5;
|
||||||
|
const BOTULISMO = 6;
|
||||||
|
const CHIKUNGUNYA = 7;
|
||||||
|
const COQUELUCHE = 8;
|
||||||
|
const COLERA = 9;
|
||||||
|
const DENGUE = 10;
|
||||||
|
const DIFTERIA = 11;
|
||||||
|
const DOENCA_MENINGOCOCICA = 12;
|
||||||
|
const DOENCAS_DE_CHAGAS_AGUDA = 13;
|
||||||
|
const DRT_CANCER_RELACIONADO_AO_TRABALHO = 14;
|
||||||
|
const DRT_DERMATOSES_OCUPACIONAIS = 15;
|
||||||
|
const DRT_LER_DORT = 16;
|
||||||
|
const DRT_PAIR = 17;
|
||||||
|
const DRT_PNEUMOCONIOSES = 18;
|
||||||
|
const DRT_TRANSTORNOS_MENTAIS_RELACIONADOS_AO_TRABALHO = 19;
|
||||||
|
const ESQUISTOSSOMOSE = 20;
|
||||||
|
const FEBRE_AMARELA = 21;
|
||||||
|
const FEBRE_MACULOSA_RICKETTSIOSES = 22;
|
||||||
|
const FEBRE_POR_VIRUS_DO_NILO_OCIDENTAL = 23;
|
||||||
|
const FEBRE_TIFOIDE = 24;
|
||||||
|
const GESTANTE_HIV = 25;
|
||||||
|
const HANSENIASE = 26;
|
||||||
|
const HANTAVIROSE = 27;
|
||||||
|
const HEPATITES_VIRAIS = 28;
|
||||||
|
const INTOXICACAO_EXOGENA = 29;
|
||||||
|
const LEISHMANIOSE_TEGUMENTAR_AMERICANA = 30;
|
||||||
|
const LEISHMANIOSE_VISCERAL = 31;
|
||||||
|
const LEPTOSPIROSE = 32;
|
||||||
|
const MALARIA = 33;
|
||||||
|
const OUTRAS_MENINGITES = 34;
|
||||||
|
const PARALISIA_FLACIDA_AGUDA_POLIOMELITE = 35;
|
||||||
|
const PESTE = 36;
|
||||||
|
const RAIVA_HUMANA = 37;
|
||||||
|
const ROTAVIRUS = 38;
|
||||||
|
const RUBEOLA = 39;
|
||||||
|
const SARAMPO = 40;
|
||||||
|
const SIFILIS_CONGENITA = 41;
|
||||||
|
const SIFILIS_EM_GESTANTE = 42;
|
||||||
|
const SINDROME_DA_RUBEOLA_CONGENITA = 43;
|
||||||
|
const TUBERCULOSE = 44;
|
||||||
|
const TETANO_ACIDENTAL = 45;
|
||||||
|
const TETANO_NEONATAL = 46;
|
||||||
|
const AIDS_PACIENTES_MENORES_QUE_13_ANOS = 47;
|
||||||
|
const BOLETIM_DE_INQUERITO_DE_TRACOMA = 48;
|
||||||
|
const DOENCA_DE_CHAGAS_ADULTA = 49;
|
||||||
|
const ENCEFALITE = 50;
|
||||||
|
const INFLUENZA_HUMANA_POR_NOVO_SUBTIPO_PANDEMICO = 51;
|
||||||
|
const MENINGITE = 52;
|
||||||
|
const SINDROME_HEMOLITICO_UREMICA = 53;
|
||||||
|
const SINDROME_RESPIRATORIA_AGUDA_GRAVE_SRAG_INTERNADA_OU_OBITO_POR_SRAG = 54;
|
||||||
|
const SINDROME_DE_GUILLAIN_BARRE_E_OU_OUTRA_MANIFESTACAO_NEUROLOGICA_ASSOCIADA_COM_ARBOVIRUS = 55;
|
||||||
|
const VIOLENCIA_INTERPESSOAL_AUTOPROVOCADA = 56;
|
||||||
|
}
|
||||||
11
api/app/Enums/Ambulatorio/ClassificacaoRisco.php
Normal file
11
api/app/Enums/Ambulatorio/ClassificacaoRisco.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ClassificacaoRisco
|
||||||
|
{
|
||||||
|
const NAO_AGUDA = 1;
|
||||||
|
const BAIXA = 2;
|
||||||
|
const INTERMEDIARIA = 3;
|
||||||
|
const ALTA = 4;
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/ColetaMaterial.php
Normal file
10
api/app/Enums/Ambulatorio/ColetaMaterial.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ColetaMaterial
|
||||||
|
{
|
||||||
|
const COLETA_DE_PAPANICOLAU = 1;
|
||||||
|
const COLETA_DE_EXAME_LABORATORIAL = 2;
|
||||||
|
const COLETA_DE_TRIAGEM_NEONATAL = 3;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/DemandaTipo.php
Normal file
9
api/app/Enums/Ambulatorio/DemandaTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class DemandaTipo
|
||||||
|
{
|
||||||
|
const AGENDADA = 'agendada';
|
||||||
|
const ESPONTANEA = 'espontanea';
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/Desfecho.php
Normal file
10
api/app/Enums/Ambulatorio/Desfecho.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class Desfecho
|
||||||
|
{
|
||||||
|
const PACIENTE_LIBERADO = 'Paciente liberado';
|
||||||
|
const PACIENTE_ENCAMINHADO = 'Paciente encaminhado';
|
||||||
|
const MANTER_NA_FILA = 'Paciente mantido na fila';
|
||||||
|
}
|
||||||
14
api/app/Enums/Ambulatorio/ExameResultadoTipo.php
Normal file
14
api/app/Enums/Ambulatorio/ExameResultadoTipo.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ExameResultadoTipo
|
||||||
|
{
|
||||||
|
const NORMAL = 1;
|
||||||
|
const ALTERADO = 2;
|
||||||
|
const SUGESTIVO_DE_INFECCAO_CONGENITA = 3;
|
||||||
|
const OUTRAS_ALTERACOES = 4;
|
||||||
|
const INDETERMINADO = 5;
|
||||||
|
const FALHOU = 6;
|
||||||
|
const PASSOU = 7;
|
||||||
|
}
|
||||||
43
api/app/Enums/Ambulatorio/FeridaExsudato.php
Normal file
43
api/app/Enums/Ambulatorio/FeridaExsudato.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
final class FeridaExsudato
|
||||||
|
{
|
||||||
|
public const ESCASSO = 1;
|
||||||
|
public const BAIXO = 2;
|
||||||
|
public const MEDIO = 3;
|
||||||
|
public const ALTO = 4;
|
||||||
|
|
||||||
|
public static function fromDescricao(?string $descricao): ?int
|
||||||
|
{
|
||||||
|
if ($descricao === null) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = self::normalize($descricao);
|
||||||
|
|
||||||
|
$map = [
|
||||||
|
'escasso' => self::ESCASSO,
|
||||||
|
'baixo' => self::BAIXO,
|
||||||
|
'medio' => self::MEDIO,
|
||||||
|
'médio' => self::MEDIO,
|
||||||
|
'alto' => self::ALTO,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$norm] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function normalize(string $text): string
|
||||||
|
{
|
||||||
|
$text = trim(mb_strtolower($text));
|
||||||
|
$text = str_replace(
|
||||||
|
['á','à','ã','â','ä','é','è','ê','ë','í','ì','î','ï','ó','ò','õ','ô','ö','ú','ù','û','ü','ç'],
|
||||||
|
['a','a','a','a','a','e','e','e','e','i','i','i','i','o','o','o','o','o','u','u','u','u','c'],
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
return preg_replace('/\s+/', ' ', $text);
|
||||||
|
}
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/FeridaStatus.php
Normal file
9
api/app/Enums/Ambulatorio/FeridaStatus.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class FeridaStatus
|
||||||
|
{
|
||||||
|
const ATIVO = 0;
|
||||||
|
const CICATRIZADA = 1;
|
||||||
|
}
|
||||||
22
api/app/Enums/Ambulatorio/ImpressaoAssinaturaEletronica.php
Normal file
22
api/app/Enums/Ambulatorio/ImpressaoAssinaturaEletronica.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ImpressaoAssinaturaEletronica
|
||||||
|
{
|
||||||
|
const REGISTRO_DO_ATENDIMENTO_MEDICO = 1;
|
||||||
|
const REGISTRO_DO_ATENDIMENTO_DE_ENFERMAGEM = 2;
|
||||||
|
const RECEITUARIO_MEDICO = 3;
|
||||||
|
const ENCAMINHAMENTOS = 4;
|
||||||
|
const ORIENTACAO = 5;
|
||||||
|
const SOLICITACAO_DE_EXAMES_SADAT = 6;
|
||||||
|
const SOLICITACAO_DE_EXAMES_SADT = 7;
|
||||||
|
const SOLICITACAO_DE_EXAMES_APAC = 8;
|
||||||
|
const SOLICITACAO_DE_EXAMES_CITOPATOLOGICO_DE_COLO_DE_UTERO = 9;
|
||||||
|
const SOLICITACAO_DE_EXAMES_HISTOPATOLOGICO_DE_MAMA = 10;
|
||||||
|
const SOLICITACAO_DE_EXAMES_CITOPATOLOGICO_DE_MAMA = 11;
|
||||||
|
const ATESTADOS_MEDICOS = 12;
|
||||||
|
const DECLARACOES_DE_COMPARECIMENTO = 13;
|
||||||
|
const CARTAS_MEDICAS = 14;
|
||||||
|
const NOTIFICACAO_COMPULSORIA = 15;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/JornadaTipo.php
Normal file
9
api/app/Enums/Ambulatorio/JornadaTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class JornadaTipo
|
||||||
|
{
|
||||||
|
const DINAMICA = 1;
|
||||||
|
const FIXA = 2;
|
||||||
|
}
|
||||||
71
api/app/Enums/Ambulatorio/LocalAnatomico.php
Normal file
71
api/app/Enums/Ambulatorio/LocalAnatomico.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
final class LocalAnatomico
|
||||||
|
{
|
||||||
|
public const CABECA = 1;
|
||||||
|
public const PESCOCO = 2;
|
||||||
|
public const TRONCO_FRENTE = 3;
|
||||||
|
public const TRONCO_COSTAS = 4;
|
||||||
|
public const BRACO = 5;
|
||||||
|
public const MAO_DETALHES = 6;
|
||||||
|
public const PERNA = 7;
|
||||||
|
public const PES_DEDOS = 8;
|
||||||
|
public const PES_REGIOES = 9;
|
||||||
|
public const PES_CALCANHARES = 10;
|
||||||
|
public const PES_VISTA_EXTERNA = 11;
|
||||||
|
public const PARTES_LATERAIS = 12;
|
||||||
|
public const LADO_DIREITO = 13;
|
||||||
|
public const LADO_ESQUERDO = 14;
|
||||||
|
public const PARTES_ESPECIFICAS = 15;
|
||||||
|
public const GLUTEOS_DETALHES = 16;
|
||||||
|
public const GENITALIA = 17;
|
||||||
|
public const NADEGAS = 18;
|
||||||
|
public const OUTROS = 19;
|
||||||
|
|
||||||
|
public static function fromDescricao(?string $descricao): ?int
|
||||||
|
{
|
||||||
|
if ($descricao === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = self::normalize($descricao);
|
||||||
|
|
||||||
|
$map = [
|
||||||
|
'cabeça' => self::CABECA,
|
||||||
|
'pescoço' => self::PESCOCO,
|
||||||
|
'tronco frente' => self::TRONCO_FRENTE,
|
||||||
|
'tronco costas' => self::TRONCO_COSTAS,
|
||||||
|
'braço' => self::BRACO,
|
||||||
|
'mão detalhes' => self::MAO_DETALHES,
|
||||||
|
'perna' => self::PERNA,
|
||||||
|
'pés dedos' => self::PES_DEDOS,
|
||||||
|
'pés regiões' => self::PES_REGIOES,
|
||||||
|
'pés calcanhares' => self::PES_CALCANHARES,
|
||||||
|
'pés vista externa' => self::PES_VISTA_EXTERNA,
|
||||||
|
'partes laterais' => self::PARTES_LATERAIS,
|
||||||
|
'lado direito' => self::LADO_DIREITO,
|
||||||
|
'lado esquerdo' => self::LADO_ESQUERDO,
|
||||||
|
'partes específicas' => self::PARTES_ESPECIFICAS,
|
||||||
|
'glúteos detalhes' => self::GLUTEOS_DETALHES,
|
||||||
|
'genitália' => self::GENITALIA,
|
||||||
|
'nádegas' => self::NADEGAS,
|
||||||
|
'outros' => self::OUTROS,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $map[$norm] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function normalize(string $text): string
|
||||||
|
{
|
||||||
|
$text = trim(mb_strtolower($text));
|
||||||
|
$text = str_replace(
|
||||||
|
['á','à','ã','â','ä','é','è','ê','ë','í','ì','î','ï','ó','ò','õ','ô','ö','ú','ù','û','ü','ç'],
|
||||||
|
['a','a','a','a','a','e','e','e','e','i','i','i','i','o','o','o','o','o','u','u','u','u','c'],
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
return preg_replace('/\s+/', ' ', $text);
|
||||||
|
}
|
||||||
|
}
|
||||||
410
api/app/Enums/Ambulatorio/LocalAnatomicoRegiao.php
Normal file
410
api/app/Enums/Ambulatorio/LocalAnatomicoRegiao.php
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
final class LocalAnatomicoRegiao
|
||||||
|
{
|
||||||
|
private const chaveLocalSafecare = [
|
||||||
|
'head' => 1,
|
||||||
|
'forehead' => 1,
|
||||||
|
'nose' => 1,
|
||||||
|
'chin' => 1,
|
||||||
|
'right_cheek' => 1,
|
||||||
|
'left_cheek' => 1,
|
||||||
|
|
||||||
|
'neck' => 2,
|
||||||
|
|
||||||
|
'right_deltoid' => 3,
|
||||||
|
'left_deltoid' => 3,
|
||||||
|
'right_chest' => 3,
|
||||||
|
'left_chest' => 3,
|
||||||
|
'abdomen' => 3,
|
||||||
|
'right_abdomen' => 3,
|
||||||
|
'left_abdomen' => 3,
|
||||||
|
'sacral' => 3,
|
||||||
|
|
||||||
|
'back_body_right' => 4,
|
||||||
|
'back_body_left' => 4,
|
||||||
|
'trapezius_right' => 4,
|
||||||
|
'trapezius_left' => 4,
|
||||||
|
'glute_right' => 4,
|
||||||
|
'glute_left' => 4,
|
||||||
|
'popliteal_right' => 4,
|
||||||
|
'popliteal_left' => 4,
|
||||||
|
'calf_right' => 4,
|
||||||
|
'calf_left' => 4,
|
||||||
|
|
||||||
|
'right_arm' => 5,
|
||||||
|
'left_arm' => 5,
|
||||||
|
'right_forearm' => 5,
|
||||||
|
'left_forearm' => 5,
|
||||||
|
'right_hand' => 5,
|
||||||
|
'left_hand' => 5,
|
||||||
|
|
||||||
|
'pinky' => 6,
|
||||||
|
'ring' => 6,
|
||||||
|
'middle' => 6,
|
||||||
|
'index' => 6,
|
||||||
|
'thumb' => 6,
|
||||||
|
'palm' => 6,
|
||||||
|
'right_pinky' => 6,
|
||||||
|
'right_ring' => 6,
|
||||||
|
'right_middle' => 6,
|
||||||
|
'right_index' => 6,
|
||||||
|
'right_thumb' => 6,
|
||||||
|
'right_palm' => 6,
|
||||||
|
|
||||||
|
'right_thigh' => 7,
|
||||||
|
'left_thigh' => 7,
|
||||||
|
'right_knee' => 7,
|
||||||
|
'left_knee' => 7,
|
||||||
|
'right_tibial' => 7,
|
||||||
|
'left_tibial' => 7,
|
||||||
|
'right_shin' => 7,
|
||||||
|
'left_shin' => 7,
|
||||||
|
'right_foot' => 7,
|
||||||
|
'left_foot' => 7,
|
||||||
|
|
||||||
|
'big_toe' => 8,
|
||||||
|
'second_toe' => 8,
|
||||||
|
'middle_toe' => 8,
|
||||||
|
'fourth_toe' => 8,
|
||||||
|
'little_toe' => 8,
|
||||||
|
'sole' => 8,
|
||||||
|
'right_big_toe' => 8,
|
||||||
|
'right_second_toe' => 8,
|
||||||
|
'right_middle_toe' => 8,
|
||||||
|
'right_fourth_toe' => 8,
|
||||||
|
'right_little_toe' => 8,
|
||||||
|
'right_sole' => 8,
|
||||||
|
|
||||||
|
'medial_forefoot' => 9,
|
||||||
|
'central_forefoot' => 9,
|
||||||
|
'distal_forefoot' => 9,
|
||||||
|
'plantar_arch' => 9,
|
||||||
|
'central_midfoot' => 9,
|
||||||
|
'distal_midfoot' => 9,
|
||||||
|
'medial_hindfoot' => 9,
|
||||||
|
'central_hindfoot' => 9,
|
||||||
|
'distal_hindfoot' => 9,
|
||||||
|
|
||||||
|
'right_heel' => 10,
|
||||||
|
'left_heel' => 10,
|
||||||
|
'right_achilles_tendon' => 10,
|
||||||
|
'left_achilles_tendon' => 10,
|
||||||
|
|
||||||
|
'right_external_malleolus' => 11,
|
||||||
|
'left_external_malleolus' => 11,
|
||||||
|
'right_external_arch' => 11,
|
||||||
|
'left_external_arch' => 11,
|
||||||
|
'right_external_metatarsal' => 11,
|
||||||
|
'left_external_metatarsal' => 11,
|
||||||
|
|
||||||
|
'side_head' => 12,
|
||||||
|
'side_neck' => 12,
|
||||||
|
'side_abdomen' => 12,
|
||||||
|
'side_sacral' => 12,
|
||||||
|
'side_trochanter1' => 12,
|
||||||
|
'side_trochanter2' => 12,
|
||||||
|
'side_malleolus' => 12,
|
||||||
|
|
||||||
|
'side_right_deltoid' => 13,
|
||||||
|
'side_right_arm' => 13,
|
||||||
|
'side_right_forearm' => 13,
|
||||||
|
'side_right_hand' => 13,
|
||||||
|
'side_right_chest' => 13,
|
||||||
|
'side_right_thigh' => 13,
|
||||||
|
'side_right_shin' => 13,
|
||||||
|
'side_right_foot' => 13,
|
||||||
|
|
||||||
|
'side_left_deltoid' => 14,
|
||||||
|
'side_left_arm' => 14,
|
||||||
|
'side_left_forearm' => 14,
|
||||||
|
'side_left_hand' => 14,
|
||||||
|
'side_left_chest' => 14,
|
||||||
|
'side_left_thigh' => 14,
|
||||||
|
'side_left_shin' => 14,
|
||||||
|
'side_left_foot' => 14,
|
||||||
|
|
||||||
|
'trochanter1' => 15,
|
||||||
|
'trochanter2' => 15,
|
||||||
|
'malleolus' => 15,
|
||||||
|
|
||||||
|
'upper_left' => 16,
|
||||||
|
'upper_right' => 16,
|
||||||
|
'lower_left' => 16,
|
||||||
|
'lower_right' => 16,
|
||||||
|
|
||||||
|
'left_foot_subarea_1' => 17,
|
||||||
|
'left_foot_subarea_2' => 17,
|
||||||
|
'left_foot_subarea_3' => 17,
|
||||||
|
'left_foot_subarea_4' => 17,
|
||||||
|
'left_foot_subarea_5' => 17,
|
||||||
|
'left_foot_subarea_6' => 17,
|
||||||
|
'left_foot_subarea_7' => 17,
|
||||||
|
'left_foot_subarea_8' => 17,
|
||||||
|
'left_foot_subarea_9' => 17,
|
||||||
|
'left_foot_subarea_10' => 17,
|
||||||
|
'left_foot_subarea_11' => 17,
|
||||||
|
'left_foot_subarea_12' => 17,
|
||||||
|
'left_foot_subarea_13' => 17,
|
||||||
|
'left_foot_subarea_14' => 17,
|
||||||
|
'left_foot_subarea_15' => 17,
|
||||||
|
|
||||||
|
'right_foot_subarea_1' => 18,
|
||||||
|
'right_foot_subarea_2' => 18,
|
||||||
|
'right_foot_subarea_3' => 18,
|
||||||
|
'right_foot_subarea_4' => 18,
|
||||||
|
'right_foot_subarea_5' => 18,
|
||||||
|
'right_foot_subarea_6' => 18,
|
||||||
|
'right_foot_subarea_7' => 18,
|
||||||
|
'right_foot_subarea_8' => 18,
|
||||||
|
'right_foot_subarea_9' => 18,
|
||||||
|
'right_foot_subarea_10' => 18,
|
||||||
|
'right_foot_subarea_11' => 18,
|
||||||
|
'right_foot_subarea_12' => 18,
|
||||||
|
'right_foot_subarea_13' => 18,
|
||||||
|
'right_foot_subarea_14' => 18,
|
||||||
|
'right_foot_subarea_15' => 18,
|
||||||
|
];
|
||||||
|
|
||||||
|
private const chaveTraduzida = [
|
||||||
|
|
||||||
|
'cabeca' => 'head',
|
||||||
|
'testa' => 'forehead',
|
||||||
|
'nariz' => 'nose',
|
||||||
|
'queixo' => 'chin',
|
||||||
|
'bochecha direita' => 'right_cheek',
|
||||||
|
'bochecha esquerda' => 'left_cheek',
|
||||||
|
|
||||||
|
'pescoco' => 'neck',
|
||||||
|
|
||||||
|
'deltoide direito' => 'right_deltoid',
|
||||||
|
'deltoide esquerdo' => 'left_deltoid',
|
||||||
|
'peito direito' => 'right_chest',
|
||||||
|
'peito esquerdo' => 'left_chest',
|
||||||
|
'abdomen' => 'abdomen',
|
||||||
|
'abdomen direito' => 'right_abdomen',
|
||||||
|
'abdomen esquerdo' => 'left_abdomen',
|
||||||
|
'sacral' => 'sacral',
|
||||||
|
|
||||||
|
'dorso direito' => 'back_body_right',
|
||||||
|
'dorso esquerdo' => 'back_body_left',
|
||||||
|
'trapezio direito' => 'trapezius_right',
|
||||||
|
'trapezio esquerdo' => 'trapezius_left',
|
||||||
|
'gluteo direito' => 'glute_right',
|
||||||
|
'gluteo esquerdo' => 'glute_left',
|
||||||
|
'poplitea direita' => 'popliteal_right',
|
||||||
|
'poplitea esquerda' => 'popliteal_left',
|
||||||
|
'panturrilha direita' => 'calf_right',
|
||||||
|
'panturrilha esquerda' => 'calf_left',
|
||||||
|
|
||||||
|
'braco direito' => 'right_arm',
|
||||||
|
'braco esquerdo' => 'left_arm',
|
||||||
|
'antebraco direito' => 'right_forearm',
|
||||||
|
'antebraco esquerdo' => 'left_forearm',
|
||||||
|
'mao direita' => 'right_hand',
|
||||||
|
'mao esquerda' => 'left_hand',
|
||||||
|
|
||||||
|
'minimo esquerdo' => 'pinky',
|
||||||
|
'anelar esquerdo' => 'ring',
|
||||||
|
'medio esquerdo' => 'middle',
|
||||||
|
'indicador esquerdo' => 'index',
|
||||||
|
'polegar esquerdo' => 'thumb',
|
||||||
|
'palma esquerda' => 'palm',
|
||||||
|
'minimo direito' => 'right_pinky',
|
||||||
|
'anelar direito' => 'right_ring',
|
||||||
|
'medio direito' => 'right_middle',
|
||||||
|
'indicador direito' => 'right_index',
|
||||||
|
'polegar direito' => 'right_thumb',
|
||||||
|
'palma direita' => 'right_palm',
|
||||||
|
|
||||||
|
'coxa direita' => 'right_thigh',
|
||||||
|
'coxa esquerda' => 'left_thigh',
|
||||||
|
'joelho direito' => 'right_knee',
|
||||||
|
'joelho esquerdo' => 'left_knee',
|
||||||
|
'tibial direita' => 'right_tibial',
|
||||||
|
'tibial esquerda' => 'left_tibial',
|
||||||
|
'canela direita' => 'right_shin',
|
||||||
|
'canela esquerda' => 'left_shin',
|
||||||
|
'pe direito' => 'right_foot',
|
||||||
|
'pe esquerdo' => 'left_foot',
|
||||||
|
|
||||||
|
'dedo 1 esquerdo' => 'big_toe',
|
||||||
|
'dedo 2 esquerdo' => 'second_toe',
|
||||||
|
'terceiro dedo esquerdo' => 'middle_toe',
|
||||||
|
'dedo 4 esquerdo' => 'fourth_toe',
|
||||||
|
'dedo 5 esquerdo' => 'little_toe',
|
||||||
|
'planta do pe esquerda' => 'sole',
|
||||||
|
'dedo 1 direito' => 'right_big_toe',
|
||||||
|
'dedo 2 direito' => 'right_second_toe',
|
||||||
|
'dedo 3 direito' => 'right_middle_toe',
|
||||||
|
'dedo 4 direito' => 'right_fourth_toe',
|
||||||
|
'dedo 5 direito' => 'right_little_toe',
|
||||||
|
'planta do pe direita' => 'right_sole',
|
||||||
|
|
||||||
|
'antepe medial' => 'medial_forefoot',
|
||||||
|
'antepe central' => 'central_forefoot',
|
||||||
|
'antepe distal' => 'distal_forefoot',
|
||||||
|
'arco plantar' => 'plantar_arch',
|
||||||
|
'mediope central' => 'central_midfoot',
|
||||||
|
'mediope distal' => 'distal_midfoot',
|
||||||
|
'retrope medial' => 'medial_hindfoot',
|
||||||
|
'retrope central' => 'central_hindfoot',
|
||||||
|
'retrope distal' => 'distal_hindfoot',
|
||||||
|
|
||||||
|
'calcanhar direito' => 'right_heel',
|
||||||
|
'calcanhar esquerdo' => 'left_heel',
|
||||||
|
'tendao de aquiles direito' => 'right_achilles_tendon',
|
||||||
|
'tendao de aquiles esquerdo' => 'left_achilles_tendon',
|
||||||
|
|
||||||
|
'maleolo externo direito' => 'right_external_malleolus',
|
||||||
|
'maleolo externo esquerdo' => 'left_external_malleolus',
|
||||||
|
'arco externo direito' => 'right_external_arch',
|
||||||
|
'arco externo esquerdo' => 'left_external_arch',
|
||||||
|
'metatarso externo direito' => 'right_external_metatarsal',
|
||||||
|
'metatarso externo esquerdo' => 'left_external_metatarsal',
|
||||||
|
|
||||||
|
'cabeca lateral' => 'side_head',
|
||||||
|
'pescoco lateral' => 'side_neck',
|
||||||
|
'abdomen lateral' => 'side_abdomen',
|
||||||
|
'sacral lateral' => 'side_sacral',
|
||||||
|
'trocanter 1 lateral' => 'side_trochanter1',
|
||||||
|
'trocanter 2 lateral' => 'side_trochanter2',
|
||||||
|
'maleolo lateral' => 'side_malleolus',
|
||||||
|
|
||||||
|
'deltoide direito lateral' => 'side_right_deltoid',
|
||||||
|
'braco direito lateral' => 'side_right_arm',
|
||||||
|
'antebraco direito lateral' => 'side_right_forearm',
|
||||||
|
'mao direita lateral' => 'side_right_hand',
|
||||||
|
'peito direito lateral' => 'side_right_chest',
|
||||||
|
'coxa direita lateral' => 'side_right_thigh',
|
||||||
|
'canela direita lateral' => 'side_right_shin',
|
||||||
|
'pe direito lateral' => 'side_right_foot',
|
||||||
|
|
||||||
|
'deltoide esquerdo lateral' => 'side_left_deltoid',
|
||||||
|
'braco esquerdo lateral' => 'side_left_arm',
|
||||||
|
'antebraco esquerdo lateral' => 'side_left_forearm',
|
||||||
|
'mao esquerda lateral' => 'side_left_hand',
|
||||||
|
'peito esquerdo lateral' => 'side_left_chest',
|
||||||
|
'coxa esquerda lateral' => 'side_left_thigh',
|
||||||
|
'canela esquerda lateral' => 'side_left_shin',
|
||||||
|
'pe esquerdo lateral' => 'side_left_foot',
|
||||||
|
|
||||||
|
'trocanter 1' => 'trochanter1',
|
||||||
|
'trocanter 2' => 'trochanter2',
|
||||||
|
'maleolo' => 'malleolus',
|
||||||
|
|
||||||
|
'superior esquerdo' => 'upper_left',
|
||||||
|
'superior direito' => 'upper_right',
|
||||||
|
'inferior esquerdo' => 'lower_left',
|
||||||
|
'inferior direito' => 'lower_right',
|
||||||
|
|
||||||
|
'subarea 1 do pe esquerdo' => 'left_foot_subarea_1',
|
||||||
|
'subarea 2 do pe esquerdo' => 'left_foot_subarea_2',
|
||||||
|
'subarea 3 do pe esquerdo' => 'left_foot_subarea_3',
|
||||||
|
'subarea 4 do pe esquerdo' => 'left_foot_subarea_4',
|
||||||
|
'subarea 5 do pe esquerdo' => 'left_foot_subarea_5',
|
||||||
|
'subarea 6 do pe esquerdo' => 'left_foot_subarea_6',
|
||||||
|
'subarea 7 do pe esquerdo' => 'left_foot_subarea_7',
|
||||||
|
'subarea 8 do pe esquerdo' => 'left_foot_subarea_8',
|
||||||
|
'subarea 9 do pe esquerdo' => 'left_foot_subarea_9',
|
||||||
|
'subarea 10 do pe esquerdo' => 'left_foot_subarea_10',
|
||||||
|
'subarea 11 do pe esquerdo' => 'left_foot_subarea_11',
|
||||||
|
'subarea 12 do pe esquerdo' => 'left_foot_subarea_12',
|
||||||
|
'subarea 13 do pe esquerdo' => 'left_foot_subarea_13',
|
||||||
|
'subarea 14 do pe esquerdo' => 'left_foot_subarea_14',
|
||||||
|
'subarea 15 do pe esquerdo' => 'left_foot_subarea_15',
|
||||||
|
|
||||||
|
'subarea 1 do pe direito' => 'right_foot_subarea_1',
|
||||||
|
'subarea 2 do pe direito' => 'right_foot_subarea_2',
|
||||||
|
'subarea 3 do pe direito' => 'right_foot_subarea_3',
|
||||||
|
'subarea 4 do pe direito' => 'right_foot_subarea_4',
|
||||||
|
'subarea 5 do pe direito' => 'right_foot_subarea_5',
|
||||||
|
'subarea 6 do pe direito' => 'right_foot_subarea_6',
|
||||||
|
'subarea 7 do pe direito' => 'right_foot_subarea_7',
|
||||||
|
'subarea 8 do pe direito' => 'right_foot_subarea_8',
|
||||||
|
'subarea 9 do pe direito' => 'right_foot_subarea_9',
|
||||||
|
'subarea 10 do pe direito' => 'right_foot_subarea_10',
|
||||||
|
'subarea 11 do pe direito' => 'right_foot_subarea_11',
|
||||||
|
'subarea 12 do pe direito' => 'right_foot_subarea_12',
|
||||||
|
'subarea 13 do pe direito' => 'right_foot_subarea_13',
|
||||||
|
'subarea 14 do pe direito' => 'right_foot_subarea_14',
|
||||||
|
'subarea 15 do pe direito' => 'right_foot_subarea_15',
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function fromKey(?string $key, ?int $localAnatomicoId = null): ?int
|
||||||
|
{
|
||||||
|
if ($key === null) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = self::normalizeKey($key);
|
||||||
|
|
||||||
|
$query = DB::table('cadastro_local_anatomico_regiao')
|
||||||
|
->where('key', $key);
|
||||||
|
|
||||||
|
if ($localAnatomicoId !== null) {
|
||||||
|
|
||||||
|
$query->where('local_anatomico_id', $localAnatomicoId);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$hint = self::chaveLocalSafecare[$key] ?? null;
|
||||||
|
|
||||||
|
if ($hint !== null) {
|
||||||
|
|
||||||
|
$query->where('local_anatomico_id', $hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $query->first(['id']);
|
||||||
|
return $row ? (int) $row->id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromDescricao(?string $descricao, ?int $localAnatomicoId = null): ?int
|
||||||
|
{
|
||||||
|
if ($descricao === null) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = self::normalize($descricao);
|
||||||
|
$key = self::chaveTraduzida[$norm] ?? null;
|
||||||
|
|
||||||
|
if ($key === null) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::fromKey($key, $localAnatomicoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function localAnatomicoIdForKey(string $key): ?int
|
||||||
|
{
|
||||||
|
$key = self::normalizeKey($key);
|
||||||
|
return self::chaveLocalSafecare[$key] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function normalize(string $text): string
|
||||||
|
{
|
||||||
|
$text = trim(mb_strtolower($text));
|
||||||
|
$text = str_replace(
|
||||||
|
['á','à','ã','â','ä','é','è','ê','ë','í','ì','î','ï','ó','ò','õ','ô','ö','ú','ù','û','ü','ç','́','’',"'",'º','ª'],
|
||||||
|
['a','a','a','a','a','e','e','e','e','i','i','i','i','o','o','o','o','o','u','u','u','u','c','','','','',''],
|
||||||
|
$text
|
||||||
|
);
|
||||||
|
|
||||||
|
return preg_replace('/\s+/', ' ', $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function normalizeKey(string $key): string
|
||||||
|
{
|
||||||
|
$key = trim(mb_strtolower($key));
|
||||||
|
$key = preg_replace('/\s+/', '_', $key);
|
||||||
|
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/Origem.php
Normal file
9
api/app/Enums/Ambulatorio/Origem.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class Origem
|
||||||
|
{
|
||||||
|
const AGENDADA = 1;
|
||||||
|
const ESPONTANEA = 2;
|
||||||
|
}
|
||||||
14
api/app/Enums/Ambulatorio/OutroProcedimento.php
Normal file
14
api/app/Enums/Ambulatorio/OutroProcedimento.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class OutroProcedimento
|
||||||
|
{
|
||||||
|
const INALACAO = 1;
|
||||||
|
const RETIRADA_DE_PONTOS = 2;
|
||||||
|
const CURATIVO_SIMPLES = 3;
|
||||||
|
const CURATIVO_GRAU_II_COM_OU_SEM_DEBRIDAMENTO = 4;
|
||||||
|
const PROVA_DO_LACO = 5;
|
||||||
|
const CURATIVO_ESPECIAL = 6;
|
||||||
|
const PREPARACAO_PARA_ECG = 7;
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/PrescricaoFrequenciaDose.php
Normal file
10
api/app/Enums/Ambulatorio/PrescricaoFrequenciaDose.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class PrescricaoFrequenciaDose
|
||||||
|
{
|
||||||
|
const INTERVALO = 'intervalo';
|
||||||
|
const FREQUENCIA = 'frequencia';
|
||||||
|
const TURNO = 'turno';
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/ProblemaCondicaoSituacao.php
Normal file
10
api/app/Enums/Ambulatorio/ProblemaCondicaoSituacao.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ProblemaCondicaoSituacao
|
||||||
|
{
|
||||||
|
const ATIVO = 1;
|
||||||
|
const LATENTE = 2;
|
||||||
|
const RESOLVIDO = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class SaudeBucalDenteProblemaCondicao
|
||||||
|
{
|
||||||
|
const AUSENTE_A = 1;
|
||||||
|
const EXTRAIDO_E = 2;
|
||||||
|
const HIGIDO_H = 3;
|
||||||
|
const HIGIDO_SELADO_HS = 4;
|
||||||
|
const PROTESE_PARCIAL_REMOVIVEL = 5;
|
||||||
|
const PROTESE_TEMPORARIA = 6;
|
||||||
|
const INCLUSO_I = 7;
|
||||||
|
const PROTESE_CORONARIA_UNITARIA = 8;
|
||||||
|
const COROA_CO = 9;
|
||||||
|
const IMPLANTE = 10;
|
||||||
|
const PILAR_P = 11;
|
||||||
|
const NUCLEO_PINO = 12;
|
||||||
|
const RESTO_RADICULAR_RR = 13;
|
||||||
|
const RETRACAO_GENGIVAL_RG = 14;
|
||||||
|
const CALCULO_DENTAL_CD = 15;
|
||||||
|
const EXTRACAO_INDICADA_EI = 16;
|
||||||
|
const SELANTE_INDICADO_SI = 17;
|
||||||
|
const FRATURA_FR = 18;
|
||||||
|
const MANCHA_BRANCA_ATIVA_M = 19;
|
||||||
|
const CARIADO_C = 20;
|
||||||
|
const RESTAURADO_R = 21;
|
||||||
|
const CARIE_DA_RAIZ = 22;
|
||||||
|
const RESTAURADO_COM_CARIE_RC = 23;
|
||||||
|
const RAIZ_RESTAURADA = 24;
|
||||||
|
const NECESSITA_DE_TRATAMENTO_ENDODONTICO = 25;
|
||||||
|
const POSSUI_LESAO_DE_FURCA = 26;
|
||||||
|
const TRATAMENTO_ENDODONTICO_REALIZADO = 27;
|
||||||
|
const LESAO_DE_FURCA_TRATADA = 28;
|
||||||
|
const MANTENEDOR_DE_ESPACO_ME = 29;
|
||||||
|
}
|
||||||
11
api/app/Enums/Ambulatorio/ServicoTipo.php
Normal file
11
api/app/Enums/Ambulatorio/ServicoTipo.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class ServicoTipo
|
||||||
|
{
|
||||||
|
const VACINACAO = 1;
|
||||||
|
const DEMANDA_ESPONTANEA = 2;
|
||||||
|
const DEMANDA_AGENDADA = 3;
|
||||||
|
const POS_CONSULTA = 4;
|
||||||
|
}
|
||||||
9
api/app/Enums/Ambulatorio/SigiloTipo.php
Normal file
9
api/app/Enums/Ambulatorio/SigiloTipo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class SigiloTipo
|
||||||
|
{
|
||||||
|
const SIGILO_ATENDIMENTO = 1;
|
||||||
|
const SIGILO_COMPLETO = 2;
|
||||||
|
}
|
||||||
10
api/app/Enums/Ambulatorio/SituacaoCodigoEsus.php
Normal file
10
api/app/Enums/Ambulatorio/SituacaoCodigoEsus.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class SituacaoCodigoEsus
|
||||||
|
{
|
||||||
|
const ATIVO = 0;
|
||||||
|
const LATENTE = 1;
|
||||||
|
const RESOLVIDO = 2;
|
||||||
|
}
|
||||||
28
api/app/Enums/Ambulatorio/TesteRapido.php
Normal file
28
api/app/Enums/Ambulatorio/TesteRapido.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Ambulatorio;
|
||||||
|
|
||||||
|
class TesteRapido
|
||||||
|
{
|
||||||
|
const GRAVIDEZ = 1;
|
||||||
|
const SIFILIS = 2;
|
||||||
|
const DETECCAO_DE_INFECCAO_PELO_HIV = 3;
|
||||||
|
const DETECCAO_DE_INFECCAO_PELO_HBV = 4;
|
||||||
|
const DETECCAO_DE_HEPATITE_C = 5;
|
||||||
|
const DENGUE_IGG_IGM = 6;
|
||||||
|
const PSA = 7;
|
||||||
|
const DETECCAO_DE_SARS_COVID_2 = 8;
|
||||||
|
const FEBRE_CHIKUNGUNYA_IGM = 9;
|
||||||
|
const VIRUS_ZIKA_IGG_IGM = 10;
|
||||||
|
const SIFILIS_NA_GESTANTE_OU_PAI_PARCEIRO = 11;
|
||||||
|
const DETECCAO_DE_HIV_NA_GESTANTE_OU_PAI_PARCEIRO = 12;
|
||||||
|
const DENGUE_NS1 = 13;
|
||||||
|
const PROTEINURIA = 14;
|
||||||
|
const TESTE_DO_OLHINHO_TRV = 15;
|
||||||
|
const TESTE_RAPIDO_SIFILIS_EM_GESTANTE = 16;
|
||||||
|
const TESTE_RAPIDO_SIFILIS_EM_PARCEIRO_OU_PARCERIA_DE_GESTANTE = 17;
|
||||||
|
const TESTE_RAPIDO_DETECCAO_DE_ANTICORPOS_ANTI_HIV_EM_GESTANTE = 18;
|
||||||
|
const TESTE_RAPIDO_DETECCAO_DE_ANTICORPOS_ANTI_HIV_EM_PARCEIRO_OU_PARCERIA_DE_GESTANTE = 19;
|
||||||
|
const TESTE_RAPIDO_PARA_DETECCAO_DE_HEPATITE_C_POPULACAO_GERAL_EXCETO_GESTANTE_PARCEIRO_OU_PARCERIA = 20;
|
||||||
|
const DETECCAO_DE_INFECCAO_PELO_HBV_POPULACAO_GERAL_EXCETO_GESTANTE_PARCEIRO_OU_PARCERIA = 21;
|
||||||
|
}
|
||||||
13
api/app/Enums/Apac/CaraterAtendimento.php
Normal file
13
api/app/Enums/Apac/CaraterAtendimento.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class CaraterAtendimento
|
||||||
|
{
|
||||||
|
const ELETIVO = 1;
|
||||||
|
const URGENCIA = 2;
|
||||||
|
const ACIDENTE_NO_LOCAL_DE_TRABALHO_OU_A_SERVICO_DA_EMPRESA = 3;
|
||||||
|
const ACIDENTE_NO_TRAJETO_PARA_O_TRABALHO = 4;
|
||||||
|
const OUTROS_TIPOS_DE_ACIDENTE_DE_TRANSITO = 5;
|
||||||
|
const OUTROS_TIPOS_DE_LESOES_E_ENVENENAMENTOS_POR_AGENTES_QUIMICOS_OU_FISICOS = 6;
|
||||||
|
}
|
||||||
11
api/app/Enums/Apac/FonteOrcamentaria.php
Normal file
11
api/app/Enums/Apac/FonteOrcamentaria.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class FonteOrcamentaria
|
||||||
|
{
|
||||||
|
const MOD_1_SERVICO_DE_SAUDE_AES = 1;
|
||||||
|
const MOD_2_EQUIPE_VOLANTES_AES = 2;
|
||||||
|
const CREDITO_FINANC_PARC_VENCIDAS_E_VICENDAS = 3;
|
||||||
|
const CREDITO_FINANCEIRO_TRANSACAO_TRIBUTARIA = 4;
|
||||||
|
}
|
||||||
72
api/app/Enums/Apac/Inconsistencia.php
Normal file
72
api/app/Enums/Apac/Inconsistencia.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class Inconsistencia
|
||||||
|
{
|
||||||
|
const COMPETENCIA_INVALIDA = 1;
|
||||||
|
const NUMERO_DA_APAC_E_OBRIGATORIO = 2;
|
||||||
|
const NUMERO_DA_APAC_INVALIDO = 3;
|
||||||
|
const IBGE_DO_ESTADO_DA_UNIDADE_EXECUTANTE_INVALIDO = 4;
|
||||||
|
const CNES_DA_UNIDADE_EXECUTANTE_E_OBRIGATORIO = 5;
|
||||||
|
const CNES_DA_UNIDADE_EXECUTANTE_INVALIDO = 6;
|
||||||
|
const TIPO_DE_ATENDIMENTO_E_OBRIGATORIO = 7;
|
||||||
|
const NOME_DA_MAE_DO_PACIENTE_E_OBRIGATORIO = 8;
|
||||||
|
const ENDERECO_DO_PACIENTE_E_OBRIGATORIO = 9;
|
||||||
|
const CEP_DO_PACIENTE_INVALIDO = 10;
|
||||||
|
const IBGE_DO_MUNICIPIO_DE_RESIDENCIA_DO_PACIENTE_INVALIDO = 11;
|
||||||
|
const DATA_DE_NASCIMENTO_DO_PACIENTE_E_OBRIGATORIA = 12;
|
||||||
|
const SEXO_DO_PACIENTE_E_OBRIGATORIO = 13;
|
||||||
|
const PROCEDIMENTO_PRINCIPAL_INVALIDO_PARA_A_COMPETENCIA = 14;
|
||||||
|
const PROCEDIMENTO_PRINCIPAL_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 15;
|
||||||
|
const PROCEDIMENTO_PRINCIPAL_INVALIDO_PARA_A_IDADE_DO_PACIENTE = 16;
|
||||||
|
const NOME_DO_PROFISSIONAL_AUTORIZADOR_E_OBRIGATORIO = 17;
|
||||||
|
const CNS_DO_PACIENTE_E_OBRIGATORIO = 18;
|
||||||
|
const CNS_DO_PACIENTE_INVALIDO = 19;
|
||||||
|
const CNS_DO_PROFISSIONAL_RESPONSAVEL_E_OBRIGATORIO = 20;
|
||||||
|
const CNS_DO_PROFISSIONAL_RESPONSAVEL_INVALIDO = 21;
|
||||||
|
const CNS_DO_PROFISSIONAL_AUTORIZADOR_E_OBRIGATORIO = 22;
|
||||||
|
const CNS_DO_PROFISSIONAL_AUTORIZADOR_INVALIDO = 23;
|
||||||
|
const CID_CAUSAS_ASSOCIADAS_INVALIDO_PARA_O_PROCEDIMENTO_PRINCIPAL = 24;
|
||||||
|
const CNES_DA_UNIDADE_SOLICITANTE_INVALIDO = 25;
|
||||||
|
const DATA_DA_AUTORIZACAO_E_OBRIGATORIA = 26;
|
||||||
|
const CODIGO_DO_EMISSOR_E_OBRIGATORIO = 27;
|
||||||
|
const CODIGO_DO_EMISSOR_INVALIDO = 28;
|
||||||
|
const NUMERO_DA_APAC_ANTERIOR_INVALIDO = 29;
|
||||||
|
const RACA_COR_DO_PACIENTE_E_OBRIGATORIO = 30;
|
||||||
|
const ETNIA_INDIGENA_DO_PACIENTE_E_OBRIGATORIA = 31;
|
||||||
|
const PAIS_DE_NASCIMENTO_DO_PACIENTE_E_OBRIGATORIO = 32;
|
||||||
|
const TELEFONE_DO_PACIENTE_INVALIDO = 33;
|
||||||
|
const CNS_DO_PROFISSIONAL_EXECUTANTE_E_OBRIGATORIO = 34;
|
||||||
|
const CNS_DO_PROFISSIONAL_EXECUTANTE_INVALIDO = 35;
|
||||||
|
const CPF_DO_PACIENTE_INVALIDO = 36;
|
||||||
|
const CID_PRINCIPAL_E_OBRIGATORIO = 37;
|
||||||
|
const CID_PRINCIPAL_INVALIDO_PARA_O_PROCEDIMENTO_PRINCIPAL = 38;
|
||||||
|
const CID_SECUNDARIO_INVALIDO_PARA_O_PROCEDIMENTO_PRINCIPAL = 39;
|
||||||
|
const DATA_DE_IDENTIFICACAO_PATOLOGICA_E_OBRIGATORIA = 40;
|
||||||
|
const PROCEDIMENTO_INVALIDO_PARA_A_COMPETENCIA = 41;
|
||||||
|
const PROCEDIMENTO_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 42;
|
||||||
|
const PROCEDIMENTO_INVALIDO_PARA_O_CBO = 43;
|
||||||
|
const PROCEDIMENTO_INVALIDO_PARA_A_IDADE_DO_PACIENTE = 44;
|
||||||
|
const QUANTIDADE_DO_PROCEDIMENTO_INVALIDA = 45;
|
||||||
|
const CNPJ_DE_CESSAO_DE_CREDITO_INVALIDO = 46;
|
||||||
|
const CID_PRINCIPAL_INVALIDO_PARA_O_PROCEDIMENTO = 47;
|
||||||
|
const CID_SECUNDARIO_INVALIDO_PARA_O_PROCEDIMENTO = 48;
|
||||||
|
const CLASSIFICACAO_INVALIDA_PARA_O_PROCEDIMENTO = 49;
|
||||||
|
const CLASSIFICACAO_INVALIDA_PARA_O_SERVICO = 50;
|
||||||
|
const CNES_DA_UNIDADE_PRESTADORA_DE_TERCEIRO_INVALIDO = 51;
|
||||||
|
const CID_CAUSA_ASSOCIADA_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 52;
|
||||||
|
const CID_PRINCIPAL_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 53;
|
||||||
|
const CID_SECUNDARIO_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 54;
|
||||||
|
const CEP_DO_PACIENTE_E_OBRIGATORIO = 55;
|
||||||
|
const NUMERO_DO_ENDERECO_DO_PACIENTE_E_OBRIGATORIO = 56;
|
||||||
|
const PROCEDIMENTO_PRINCIPAL_INVALIDO_PARA_O_CBO = 57;
|
||||||
|
const QUANTIDADE_INVALIDA_PARA_O_PROCEDIMENTO_PRINCIPAL = 58;
|
||||||
|
const CLASSIFICACAO_INVALIDA_PARA_O_PROCEDIMENTO_PRINCIPAL = 59;
|
||||||
|
const CID_PRINCIPAL_DADOS_COMPLEMENTARES_E_OBRIGATORIO = 60;
|
||||||
|
const CID_PRINCIPAL_DADOS_COMPLEMENTARES_INVALIDO_PARA_O_PROCEDIMENTO_PRINCIPAL = 61;
|
||||||
|
const CID_PRINCIPAL_DADOS_COMPLEMENTARES_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 62;
|
||||||
|
const CID_SECUNDARIO_DADOS_COMPLEMENTARES_INVALIDO_PARA_O_PROCEDIMENTO_PRINCIPAL = 63;
|
||||||
|
const CID_SECUNDARIO_DADOS_COMPLEMENTARES_INVALIDO_PARA_O_SEXO_DO_PACIENTE = 64;
|
||||||
|
const CID_PRINCIPAL_E_OBRIGATORIO_PARA_O_PROCEDIMENTO_PRINCIPAL = 65;
|
||||||
|
}
|
||||||
21
api/app/Enums/Apac/Linha.php
Normal file
21
api/app/Enums/Apac/Linha.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class Linha
|
||||||
|
{
|
||||||
|
const CABECALHO = '01';
|
||||||
|
const CORPO = '14';
|
||||||
|
const REGISTRO_PROCEDIMENTO = '13';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_QUIMIOTERAPIA = '07';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_RADIOTERAPIA = '08';
|
||||||
|
const PARTE_VARIAVEL_NEFROLOGIA = '09';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_MEDICAMENTO = '10';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_ACOMPANHAMENTO_POS_CIRURGIA_BARIATRICA = '11';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_ACOMPANHAMENTO_PRE_CIRURGIA_BARIATRICA = '17';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_LAUDO_GERAL = '06';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_LAUDO_PROTESE_MAMA = '12';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_LAUDO_TRATAMENTO_DIALITICO = '18';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_LAUDO_ACOMPANHAMENTO_MULTIPROFISSIONAL_DRC = '19';
|
||||||
|
const PARTE_VARIAVEL_PROCEDIMENTO_LAUDO_CONFECCAO_FISTULA_ARTERIOVENOSA = '20';
|
||||||
|
}
|
||||||
28
api/app/Enums/Apac/MotivoSaidaPermanencia.php
Normal file
28
api/app/Enums/Apac/MotivoSaidaPermanencia.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class MotivoSaidaPermanencia
|
||||||
|
{
|
||||||
|
const ALTA_CURADO = 1;
|
||||||
|
const ALTA_MELHORADO = 2;
|
||||||
|
const ALTA_DA_PUERPERA_E_PERMANENCIA_DO_RECEM_NASCIDO = 3;
|
||||||
|
const ALTA_A_PEDIDO = 4;
|
||||||
|
const ALTA_COM_PREVISAO_DE_RETORNO_PARA_ACOMPANHAMENTO_DO_PACIENTE = 5;
|
||||||
|
const ALTA_POR_EVASAO = 6;
|
||||||
|
const ALTA_DA_PUERPERA_E_RECEM_NASCIDO = 7;
|
||||||
|
const ALTA_POR_OUTROS_MOTIVOS = 8;
|
||||||
|
const POR_CARACTERISTICAS_PROPRIAS_DA_DOENCA = 9;
|
||||||
|
const POR_INTERCORRENCIA = 10;
|
||||||
|
const POR_IMPOSSIBILIDADE_SOCIO_FAMILIAR = 11;
|
||||||
|
const POR_PROCESSO_DE_DOACAO_DE_ORGAOS_TECIDOS_E_CELULAS_DOADOR_VIVO = 12;
|
||||||
|
const POR_PROCESSO_DE_DOACAO_DE_ORGAOS_TECIDOS_E_CELULAS_DOADOR_MORTO = 13;
|
||||||
|
const POR_MUDANCA_DE_PROCEDIMENTO = 14;
|
||||||
|
const POR_REOPERACAO = 15;
|
||||||
|
const OUTROS_MOTIVOS = 16;
|
||||||
|
const TRANSFERIDO_PARA_OUTRO_ESTABELECIMENTO = 17;
|
||||||
|
const COM_DECLARACAO_DE_OBITO_FORNECIDA_PELO_MEDICO_ASSISTENTE = 18;
|
||||||
|
const COM_DECLARACAO_DE_OBITO_FORNECIDA_PELO_INSTITUTO_MEDICO_LEGAL_IML = 19;
|
||||||
|
const COM_DECLARACAO_DE_OBITO_FORNECIDA_PELO_SERVICO_DE_VERIFICACAO_DE_OBITO_SVO = 20;
|
||||||
|
const ENCERRAMENTO_ADMINISTRATIVO = 21;
|
||||||
|
}
|
||||||
12
api/app/Enums/Apac/RacaCor.php
Normal file
12
api/app/Enums/Apac/RacaCor.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class RacaCor
|
||||||
|
{
|
||||||
|
const BRANCA = '01';
|
||||||
|
const PRETA = '02';
|
||||||
|
const PARDA = '03';
|
||||||
|
const AMARELA = '04';
|
||||||
|
const INDIGENA = '05';
|
||||||
|
}
|
||||||
9
api/app/Enums/Apac/Sexo.php
Normal file
9
api/app/Enums/Apac/Sexo.php
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class Sexo
|
||||||
|
{
|
||||||
|
const MASCULINO = 'M';
|
||||||
|
const FEMININO = 'F';
|
||||||
|
}
|
||||||
11
api/app/Enums/Apac/Tipo.php
Normal file
11
api/app/Enums/Apac/Tipo.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class Tipo
|
||||||
|
{
|
||||||
|
const INICIAL = 1;
|
||||||
|
const CONTINUIDADE = 2;
|
||||||
|
const UNICA = 3;
|
||||||
|
const ENCERRAMENTO = 4;
|
||||||
|
}
|
||||||
10
api/app/Enums/Apac/TipoAtendimento.php
Normal file
10
api/app/Enums/Apac/TipoAtendimento.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\Apac;
|
||||||
|
|
||||||
|
class TipoAtendimento
|
||||||
|
{
|
||||||
|
const TRS = 1;
|
||||||
|
const RADIOTERAPIA = 2;
|
||||||
|
const QUIMIOTERAPIA = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoDomiciliar;
|
||||||
|
|
||||||
|
class CondicaoAvaliada
|
||||||
|
{
|
||||||
|
const OXIGENOTERAPIA_DOMICILIAR = 17;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoDomiciliar;
|
||||||
|
|
||||||
|
class CondutaDesfecho
|
||||||
|
{
|
||||||
|
const PERMANENCIA = 1;
|
||||||
|
const ALTA_ADMINISTRATIVA = 2;
|
||||||
|
const ALTA_CLINICA = 3;
|
||||||
|
const OBITO = 4;
|
||||||
|
const ATENCAO_BASICA_AD1 = 5;
|
||||||
|
const SERVICO_DE_URGENCIA_E_EMERGENCIA = 6;
|
||||||
|
const SERVICO_DE_INTERNACAO_HOSPITALAR = 7;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoDomiciliar;
|
||||||
|
|
||||||
|
class Modalidade
|
||||||
|
{
|
||||||
|
const AD_1 = 1;
|
||||||
|
const AD_2 = 2;
|
||||||
|
const AD_3 = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoDomiciliar;
|
||||||
|
|
||||||
|
class PerfilEpidemiologico
|
||||||
|
{
|
||||||
|
const USO_DE_DIETAS_ESPECIAIS = 1;
|
||||||
|
const ENTREGA_DE_MATERIAIS = 2;
|
||||||
|
const ADQUIRIU_INFECCAO_DOMICILIAR = 3;
|
||||||
|
const SISTEMA_NEUROLOGICO = 4;
|
||||||
|
const SISTEMA_RESPIRATORIO = 5;
|
||||||
|
const SISTEMA_ENDOCRINO = 6;
|
||||||
|
const SISTEMA_GENITURINARIO = 7;
|
||||||
|
const USO_DE_ESPESSANTE = 8;
|
||||||
|
const AVALIACAO_DE_PROCESSO = 9;
|
||||||
|
const RESIDENTE_EM_AREA_DE_RISCO = 10;
|
||||||
|
const SISTEMA_CARDIOLOGICO = 11;
|
||||||
|
const SISTEMA_OSTEO_MIO_ARTICULAR = 12;
|
||||||
|
const SISTEMA_TEGUMENTAR = 13;
|
||||||
|
const OUTROS = 14;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoDomiciliar;
|
||||||
|
|
||||||
|
class Procedimento
|
||||||
|
{
|
||||||
|
const ACOMPANHAMENTO_PACIENTE_REABILITACAO_COMUNICACAO = '0301070024';
|
||||||
|
const ANTIBIOTICOTERAPIA_PARENTERAL = '0301050082';
|
||||||
|
const ATENDIMENTO_ACOMPANHAMENTO_PACIENTE_REABILITACAO_DESENVOLVIMENTO_MOTOR = '0301070075';
|
||||||
|
const ATENDIMENTO_FISIOTERAPEUTICO_PACIENTE_TRANSTORNO_RESPIRATORIO_SEM_COMPLICACOES_SISTEMICAS = '0302040021';
|
||||||
|
const ATEMDIMENTO_MEDICO_FINALIDADE_ATESTAR_OBITO = '0301050090';
|
||||||
|
const ATENDIMENTO_ACOMPANHAMENTO_REABILITACAO_MULTIPLAS_DEFICIENCIAS = '0301070067';
|
||||||
|
const CATETERISMO_VESICAL_ALIVIO = '0301100047';
|
||||||
|
const CATETERISMO_VESICAL_DEMORA = '0301100055';
|
||||||
|
const COLETA_MATERIAL_EXAME_LABORATORIAL = '0201020041';
|
||||||
|
const CUIDADOS_ESTOMAS = '0301100063';
|
||||||
|
const CUIDADOS_TRAQUEOSTOMIA = '0301100071';
|
||||||
|
const ENEMA = '0301100098';
|
||||||
|
const OXIGENOTERAPIA = '0301100144';
|
||||||
|
const RETIRADAS_PONTOS_CIRURGIAS_BASICAS = '0301100152';
|
||||||
|
const SONDAGEM_GASTRICA = '0301100179';
|
||||||
|
const TERAPIA_REIDRATACAO_ORAL = '0301100187';
|
||||||
|
const TERAPIA_REIDRATACAO_PARENTERAL = '0301050120';
|
||||||
|
const TERAPIA_FONOAUDIOLOGICA_INDIVIDUAL = '0301070113';
|
||||||
|
const TRATAMENTO_TRAUMATISMO = '0308010019';
|
||||||
|
const TRATAMENTO_REABILITACAO = '0303190019';
|
||||||
|
const TRAQUEOSTOMIA = '0404010377';
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums\AtencaoBasica\AtendimentoIndividual;
|
||||||
|
|
||||||
|
class CondicaoAvaliada
|
||||||
|
{
|
||||||
|
const ASMA = 1;
|
||||||
|
const DESNUTRICAO = 2;
|
||||||
|
const DIABETES = 3;
|
||||||
|
const DPOC = 4;
|
||||||
|
const HIPERTENSAO_ARTERIAL = 5;
|
||||||
|
const OBESIDADE = 6;
|
||||||
|
const PRE_NATAL = 7;
|
||||||
|
const PUERICULTURA = 8;
|
||||||
|
const PUERPERIO_ATE_42_DIAS = 9;
|
||||||
|
const REABILITACAO = 10;
|
||||||
|
const SAUDE_MENTAL = 11;
|
||||||
|
const SAUDE_SEXUAL_E_REPRODUTIVA = 12;
|
||||||
|
const TABAGISMO = 13;
|
||||||
|
const USUARIO_DE_ALCOOL = 14;
|
||||||
|
const USUARIO_DE_OUTRAS_DROGAS = 15;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user