NR_DIASRETIRADA - Dias para próxima retirada após devolução de item locado
Tela: MFA001 - Parâmetros de Faturamento Localização: Parâmetros → Faturamento → aba Locações (
pagLocacaoemUMFA001.dfm:10630) →GroupBox5 ' Parâmetros de Locações '→ campo Dias para Próx. Retirada após Devolução (labelLabel68emUMFA001.dfm:10660-10674,Caption = 'Dias para Próx. Retirada após Devolução',FocusControl = DBEdit1, posicionado emLeft=18, Top=46) Tabela:PARMFATUR.NR_DIASRETIRADATipo: Numérico inteiro (dias) —DOM_INTEGERno DDL (docs/schema/tables/PARMFATUR.sql:152);TIntegerFieldno client (UdmMFA001.pas:202,UdmMFA001.dfm:1506-1510) comAlignment = taCenter; editado viaTDBEdit DBEdit1(UMFA001.dfm:10812-10828). Valor padrão:NULL— oAfterInsertdetabPARMFATURemUdmMFA001.pas:434não atribui default para este campo. O DDL (DOM_INTEGER) também não defineDEFAULT, então o campo nasce vazio. As procedures que o consomem aplicamCOALESCE(P.NR_DIASRETIRADA, 0)para tratar oNULLcomo zero. Validação (MFA001): não háOnValidateparatabPARMFATURNR_DIASRETIRADAemUdmMFA001.pas. Qualquer inteiro é aceito, inclusive0e negativos.
O que o parâmetro faz
NR_DIASRETIRADA é o número de dias de "quarentena" aplicado entre a devolução de um item locado e sua próxima retirada — um período pós-devolução durante o qual o item não deve voltar a ser locado. É usado pelas procedures de saldo de locação (RETORNA_SALDO_LOCACAO e RETORNA_SALDO_LOCACAOTROCA) para:
- Calcular
O_DT_PROXRETIRADA— a data a partir da qual o item voltaria a estar disponível após uma devolução. É sempreDT_DEVOLUCAOMIN + NR_DIASRETIRADA. - Ajustar a janela de contagem de itens retornados — para determinar a disponibilidade de um item em uma nova locação, a procedure precisa considerar retornos ocorridos nos
NR_DIASRETIRADA - 1dias anteriores à data solicitada (itens devolvidos há pouco ainda estão em quarentena e não podem ser contados como "livres").
O objetivo operacional é permitir que a empresa configure um intervalo técnico de manutenção/inspeção entre locações do mesmo item (ex.: pneus de locação que precisam de 2 dias para revisão antes de sair para outro cliente).
Telas impactadas
| Módulo | Código | Papel |
|---|---|---|
| Parâmetros de Faturamento | MFA001 | Produtora — cadastra/edita o valor no campo DBEdit1 (aba Locações). CRUD da PARMFATUR inclui o campo em SELECT/INSERT/UPDATE (UdmMFA001.dfm:211, 2405, 2571, 2801, 3091). |
| Locações | MPD043 | Consumidora direta — em ValidaDisponibilidadeItem (UdmMPD043.pas:3003) lê PARMFATUR.NR_DIASRETIRADA diretamente e passa implicitamente para as procedures ao chamar RETORNA_SALDO_LOCACAO. |
Procedures impactadas
| Procedure | Papel |
|---|---|
RETORNA_SALDO_LOCACAO | Consumidora principal. Lê COALESCE(P.NR_DIASRETIRADA, 0) na linha 147-150. Usa o valor para (a) calcular O_DT_PROXRETIRADA = DATEADD(V_NR_DIASRETIRADA DAY TO V_DT_DEVOLUCAOMIN) (linhas 439 e 445) e (b) definir V_DT_ANTERIORRET = DATEADD(- V_NR_DIASRETIRADA + 1 DAY TO I_DT_INICIAL) (linha 518), usado no laço de contagem de itens em quarentena. |
RETORNA_SALDO_LOCACAOTROCA | Consumidora secundária (variante para troca). Mesma lógica: lê COALESCE(P.NR_DIASRETIRADA, 0) nas linhas 96-99, calcula O_DT_PROXRETIRADA (linhas 340 e 346) e V_DT_ANTERIORRET (linha 401). |
Campos envolvidos
| Campo | Tabela | Papel |
|---|---|---|
NR_DIASRETIRADA | PARMFATUR | Dias de quarentena pós-devolução (este parâmetro). |
DT_RETIRADA | LOCACAO | Data solicitada para retirada na nova locação — é o I_DT_INICIAL passado às procedures. |
DT_DEVOLUCAO | LOCACAO | Data prevista de devolução da locação em análise — é o I_DT_FINAL. |
DT_DEVOLUCAO | LOCACAODEVOL | Data de devolução efetiva do item (locações anteriores). A procedure busca a menor data de devolução no período (V_DT_DEVOLUCAOMIN) e é sobre ela que NR_DIASRETIRADA é somado. |
ST_LOCACAO | LOCACAO | Filtro: IN ('P','T') — locações pendentes / em trânsito. |
ST_LOCADO / ST_TROCADO | LOCACAOITEM | Filtros: ST_LOCADO = 'S', ST_TROCADO = 'N'. |
O_DT_PROXRETIRADA | saída | Data calculada a partir da qual o item pode ser retirado novamente. |
O_ST_DISPRETIRADA | saída | 'S' / 'N' / 'F' — flag de disponibilidade para a data solicitada. |
Comportamento / Regra
Valor = 0 (ou NULL)
| Aspecto | Comportamento |
|---|---|
| Consulta nas procedures | SELECT COALESCE(P.NR_DIASRETIRADA, 0) INTO V_NR_DIASRETIRADA — NULL é tratado como 0. |
O_DT_PROXRETIRADA | DATEADD(0 DAY TO V_DT_DEVOLUCAOMIN) = própria data de devolução. Item fica disponível já no dia em que é devolvido. |
Janela de quarentena (V_DT_ANTERIORRET) | DATEADD(0 + 1 DAY TO I_DT_INICIAL) = I_DT_INICIAL + 1. O laço WHILE (V_DT_AUX <= I_DT_INICIAL) não executa nenhuma iteração (condição I_DT_INICIAL + 1 <= I_DT_INICIAL é falsa) → nenhum dia anterior é considerado em quarentena. |
NR_DIASRETIRADA IS NULL literalmente | No bloco IF((V_NR_DIASRETIRADA IS NOT NULL) AND (O_QT_LIVRE > 0)) (linha 443), como a SELECT usa COALESCE, V_NR_DIASRETIRADA nunca é NULL na prática — o ramo sempre entra se houver saldo livre. |
Resultado esperado: o parâmetro fica inativo. Itens podem ser realocados no mesmo dia da devolução, sem quarentena.
Valor > 0
| Aspecto | Comportamento |
|---|---|
| Leitura | COALESCE(P.NR_DIASRETIRADA, 0) retorna o inteiro configurado. |
O_DT_PROXRETIRADA (saldo livre) | DATEADD(V_NR_DIASRETIRADA DAY TO V_DT_DEVOLUCAOMIN) — acrescenta os dias de quarentena à menor data de devolução encontrada no período. |
O_DT_PROXRETIRADA (sem saldo livre) | DATEADD(COALESCE(V_NR_DIASRETIRADA, 0) DAY TO V_DT_DEVOLUCAOMIN) — mesmo cálculo, indicando a data em que o item poderia estar disponível novamente. |
| Janela retroativa de contagem | V_DT_ANTERIORRET = DATEADD(- V_NR_DIASRETIRADA + 1 DAY TO I_DT_INICIAL). O laço percorre de V_DT_ANTERIORRET até I_DT_INICIAL, somando LI.QT_ITEM das devoluções ocorridas nesses dias. O total V_QT_RET é subtraído do saldo de estoque — itens ainda em "quarentena de retirada" não contam como livres para a data solicitada. |
| Decisão final | Se V_QT_RET <= 0 após a subtração, O_ST_DISPRETIRADA = 'N' (indisponível). |
Simulação passo a passo
Pré-requisitos do cenário:
PARMFATUR.NR_DIASRETIRADA = 2definido em MFA001 → aba Locações.- Item
CD_ITEM = 500com saldo de estoque = 3 unidades na empresa1. - Locações anteriores para o item 500:
- Locação 800 →
DT_RETIRADA = 10/05/2026,DT_DEVOLUCAO = 13/05/2026,QT_ITEM = 2, devolvido emLOCACAODEVOL.DT_DEVOLUCAO = 13/05/2026.
- Locação 800 →
- Operador está tentando criar nova locação do item 500 para
DT_RETIRADA = 14/05/2026,DT_DEVOLUCAO = 16/05/2026,QT_ITEM = 3.
- Em MFA001 → aba Locações → informe
Dias para Próx. Retirada após Devolução = 2. Salve (F6). Valor grava emPARMFATUR.NR_DIASRETIRADA. - Em MPD043, ao incluir o item 500 na nova locação, o sistema executa
ValidaDisponibilidadeItem(UdmMPD043.pas:3003), que chamaRETORNA_SALDO_LOCACAO(500, 1, '14/05/2026', '16/05/2026', 'L', :nova_locacao). - Dentro da procedure:
SELECT COALESCE(NR_DIASRETIRADA, 0) INTO V_NR_DIASRETIRADA→V_NR_DIASRETIRADA = 2(linha147-150).- Calcula
V_DT_DEVOLUCAOMINbuscando a menorLD.DT_DEVOLUCAOdas locações ativas que ainda não devolveram → suponha que encontre13/05/2026. - Como há saldo livre (
O_QT_LIVRE > 0), entra no blocoIF((V_NR_DIASRETIRADA IS NOT NULL) AND (O_QT_LIVRE > 0))(linha443). O_DT_PROXRETIRADA = DATEADD(2 DAY TO 13/05/2026) = 15/05/2026(linha445).- Calcula janela retroativa:
V_DT_ANTERIORRET = DATEADD(-2 + 1 DAY TO 14/05/2026) = 13/05/2026(linha518). - Laço
WHILE (V_DT_AUX <= 14/05/2026)percorrendo13/05e14/05:13/05→ encontra a devolução da Locação 800 (LD.DT_DEVOLUCAO = 13/05/2026comQT_ITEM = 2) →V_QT_RET = 2.14/05→ não há devoluções →V_QT_RETsegue2.
V_QT_RET = V_QT_SALDOESTOQUE - V_QT_RET = 3 - 2 = 1(linha544).V_QT_RET (1) <= 0? Não, então segue sem marcar como indisponível por esse critério. MasO_QT_LIVRE(calculado antes) já refletia saldo real descontando as 2 unidades em quarentena.
- O resultado retornado à MPD043 indica que apenas 1 unidade está efetivamente livre para 14/05/2026 (as 2 unidades devolvidas em 13/05 ainda estão em quarentena). Como o operador pediu 3, o item é marcado como
Indisponívele a mensagem"Produto ... indisponível para a data 14/05/2026. Quantidade Solicitada: 3. Quantidade Disponível: 1."é levantada comoW-0000emUdmMPD043.pas:3055.
Resultado esperado: itens devolvidos menos de NR_DIASRETIRADA dias antes da data de retirada solicitada não contam como disponíveis; a procedure exibe a DT_PROXRETIRADA ajustada (data de devolução + quarentena) para orientar o operador sobre quando o item voltará a estar livre.
Casos de borda
| Cenário | Comportamento |
|---|---|
NR_DIASRETIRADA = 1 | V_DT_ANTERIORRET = DATEADD(0 DAY TO I_DT_INICIAL) = I_DT_INICIAL. O laço executa uma única vez (para a própria data solicitada) → conta apenas devoluções ocorridas no mesmíssimo dia da retirada. |
NR_DIASRETIRADA negativo | O DDL não impede (DOM_INTEGER), e não há validação em MFA001. Resultado matemático: DATEADD(- N DAY TO I_DT_INICIAL) geraria uma data futura em relação a I_DT_INICIAL, fazendo o WHILE não executar (condição inicial já falsa). Configuração incorreta — evitar. |
| Sem locações devolvidas no período | V_DT_DEVOLUCAOMIN resulta da combinação de LOCACAODEVOL e LOCACAO; se não houver devoluções, O_DT_PROXRETIRADA é calculado sobre a data mínima disponível no contexto (ver blocos específicos da procedure). |
O_QT_LIVRE = 0 | Entra no ramo da linha 437-441: O_DT_PROXRETIRADA = DATEADD(COALESCE(V_NR_DIASRETIRADA, 0) DAY TO V_DT_DEVOLUCAOMIN) e O_ST_DISPRETIRADA = 'N'. |
Locação tipo 'V' (venda) | Em RETORNA_SALDO_LOCACAO, o bloco específico de locação-venda (a partir da linha 552) contém lógica extra, mas não reutiliza V_NR_DIASRETIRADA nessa verificação adicional — só na parte comum de cálculo de O_DT_PROXRETIRADA. |
Referências no Código Fonte
Delphi — MFA001 (cadastro do parâmetro)
| Arquivo | Linhas | Papel |
|---|---|---|
source/MFA001/UMFA001.dfm | 10630-10631 | TTabSheet pagLocacao com Caption = 'Locações' |
source/MFA001/UMFA001.dfm | 10638 | TGroupBox GroupBox5 ' Parâmetros de Locações ' (container visual) |
source/MFA001/UMFA001.dfm | 10660-10674 | TLabel Label68 com Caption = 'Dias para Próx. Retirada após Devolução', FocusControl = DBEdit1, Left=18, Top=46 |
source/MFA001/UMFA001.dfm | 10812-10828 | TDBEdit DBEdit1 — DataField = 'NR_DIASRETIRADA', DataSource = dmMFA001.dsPARMFATUR, Left=221, Top=41, Width=66, Height=21 |
source/MFA001/UdmMFA001.pas | 202 | Declaração tabPARMFATURNR_DIASRETIRADA: TIntegerField |
source/MFA001/UdmMFA001.pas | 434 | tabPARMFATURAfterInsert não atribui default para NR_DIASRETIRADA (o campo nasce NULL) |
source/MFA001/UdmMFA001.dfm | 211, 3091 | SelectSQL / RefreshSQL: PARMFATUR.NR_DIASRETIRADA, PARMFATUR.HR_INTERVALORET, ... |
source/MFA001/UdmMFA001.dfm | 1506-1510 | Definição do TIntegerField com FieldName = 'NR_DIASRETIRADA', Alignment = taCenter, Origin = '"PARMFATUR"."NR_DIASRETIRADA"' |
source/MFA001/UdmMFA001.dfm | 2405 | InsertSQL: inclui NR_DIASRETIRADA na cláusula de colunas |
source/MFA001/UdmMFA001.dfm | 2571 | InsertSQL: VALUES (..., :NR_DIASRETIRADA, ...) |
source/MFA001/UdmMFA001.dfm | 2801 | UpdateSQL: NR_DIASRETIRADA = :NR_DIASRETIRADA, |
Delphi — MPD043 (consumidora)
| Arquivo | Linhas | Papel |
|---|---|---|
source/MPD043/UdmMPD043.pas | 3003-3143 | Procedure livre ValidaDisponibilidadeItem — contém a chamada à procedure RETORNA_SALDO_LOCACAO |
source/MPD043/UdmMPD043.pas | 3008 | Declaração Nr_DiasRetirada: Integer |
source/MPD043/UdmMPD043.pas | 3019-3024 | Leitura local do parâmetro: SELECT P.NR_DIASRETIRADA FROM PARMFATUR P WHERE P.CD_EMPRESA = ... → Nr_DiasRetirada := StrToInt(Resultado[0]) (variável é declarada, mas o cálculo efetivo ocorre dentro das procedures chamadas em seguida) |
source/MPD043/UdmMPD043.pas | 3025-3035 | Chamada da procedure RETORNA_SALDO_LOCACAO — o parâmetro é relido internamente pela procedure |
DDL
docs/schema/tables/PARMFATUR.sql:152—NR_DIASRETIRADA DOM_INTEGER,(semNOT NULL, sem default → permiteNULL; consumidores aplicamCOALESCE(..., 0)).
SQL — Procedures
| Arquivo | Linhas | Papel |
|---|---|---|
Scripts/RETORNA_SALDO_LOCACAO.sql | 28 | declare variable V_NR_DIASRETIRADA integer; |
Scripts/RETORNA_SALDO_LOCACAO.sql | 147-150 | Leitura: SELECT COALESCE(P.NR_DIASRETIRADA, 0) FROM PARMFATUR P WHERE P.CD_EMPRESA = :I_CD_EMPRESA INTO V_NR_DIASRETIRADA — comentário documenta: "Parâmetro Dias para Próx Retirada após Devolução [MFA001]" |
Scripts/RETORNA_SALDO_LOCACAO.sql | 439 | Ramo O_QT_LIVRE = 0: O_DT_PROXRETIRADA = DATEADD(COALESCE(V_NR_DIASRETIRADA, 0) DAY TO V_DT_DEVOLUCAOMIN) |
Scripts/RETORNA_SALDO_LOCACAO.sql | 443-445 | Ramo com saldo livre: IF((V_NR_DIASRETIRADA IS NOT NULL) AND (O_QT_LIVRE > 0)) THEN ... O_DT_PROXRETIRADA = DATEADD(V_NR_DIASRETIRADA DAY TO V_DT_DEVOLUCAOMIN) |
Scripts/RETORNA_SALDO_LOCACAO.sql | 518 | Janela retroativa: V_DT_ANTERIORRET = DATEADD(- V_NR_DIASRETIRADA + 1 DAY TO I_DT_INICIAL) — base do laço WHILE que soma devoluções em quarentena (linhas 521-541) |
Scripts/RETORNA_SALDO_LOCACAOTROCA.sql | 28 | declare variable V_NR_DIASRETIRADA integer; |
Scripts/RETORNA_SALDO_LOCACAOTROCA.sql | 96-99 | Leitura: SELECT COALESCE(P.NR_DIASRETIRADA, 0) FROM PARMFATUR P WHERE P.CD_EMPRESA = :I_CD_EMPRESA INTO V_NR_DIASRETIRADA |
Scripts/RETORNA_SALDO_LOCACAOTROCA.sql | 340 | Ramo O_QT_LIVRE = 0: O_DT_PROXRETIRADA = DATEADD(COALESCE(V_NR_DIASRETIRADA, 0) DAY TO V_DT_DEVOLUCAOMIN) |
Scripts/RETORNA_SALDO_LOCACAOTROCA.sql | 344-346 | Ramo com saldo livre: análogo à RETORNA_SALDO_LOCACAO |
Scripts/RETORNA_SALDO_LOCACAOTROCA.sql | 401 | V_DT_ANTERIORRET = DATEADD(- V_NR_DIASRETIRADA + 1 DAY TO I_DT_INICIAL) |