Utilizar controle de numeração de um campo com a SX5

Preciso realizar um controle de numeração de lote na abertura de uma ordem de produção. O campo de lote é personalizado e eu preciso de uma numeração automática para ele quando a ordem de produção for de um tipo especifico. O que seria o ideal? Não posso ativar o controle de numeração do license server pq esse campo só pode ter essa numeração automática em condições especificas. Eu criar uma tabela genérica e controlar a numeração por lá com o GetSX5 e PutSX5 daria certo? Alguém já implementou algo similar?

1 curtida

Bruno nesses casos eu uso um fonte customizado para controlar a numeração, e utilizo mesmo a função GetSxeNum() para isso. Então na customização decido qual numeração utilizar conforme a situação.

Com o controle de numeração do license eu conseguiria definir quando o numero vai incrementar? Acredito que é uma abordagem mais segura mesmo, principalmente em casos de multiplos usuarios fazendo a inclusão simultânea

Bruno, é uma rotina padrão ou customizada?
Essa rotina está em MVC?
Se for padrão, qual o nome da rotina?

Já utilizei o ponto de entrada CRIASXE para ajustar numeração.

#Include “protheus.ch”
#Include “TopConn.CH”

User Function CRIASXE()
Local cNum := NIL
Local aArea := getarea()

Local cAlias    := paramixb[1]
Local cCpoSx8   := paramixb[2]
// Local cAliasSx8 := paramixb[3]
Local nOrdSX8   := paramixb[4]

Local aUsa      := &(SuperGetMV("MV_YNUMVAL",.F.,"{{}}"))       //Tabelas para Numeracao
Local nPos      := ASCAN(aUsa, { |x| UPPER(x[1]) == cAlias })   //Posicao da Tabela no Parametro
Local cIndex    := IndexKey(nOrdSX8)                            //Indice
Local cCpoFil
Local nTamCpo   := 0

//Verificar se existe tabela no parametro
IF nPos > 0 .and. !Empty(cIndex)
    //Campo de Filial
    cCpoFil := STRTOkARR(cIndex,"+")[1] 
    //Identifica tamanho do codigo
    nTamCpo := aUsa[nPos][2]

    //Prepara Query
    cQuery := " SELECT IsNull(Rtrim(MAX(" +cCpoSx8+ ")),'" + STRZERO(0,nTamCpo) + "') COD FROM " + RetSqlName(cAlias)
    cQuery += " (NOLOCK) WHERE " +cCpoSx8+ " < 'A'  AND D_E_L_E_T_=' ' "

    IF !Empty(xFilial(cAlias))
        cQuery += " AND " +cCpoFil+ "='" +xFilial(cAlias)+ "'"
    EndIF
    TcQuery cQuery New Alias T99
    cNum := Soma1(StrZero(Val(T99->COD),nTamCpo))
    T99->(DbCloseArea())
EndIF
RestArea(aArea)

Return cNum

É um campo personalizado dentro de uma rotina padrão. É a rotina padrão de abertura de ordens de produção do modulo 10 do protheus.

Utilizar qualquer controle que não seja a numeração automática, você tem maiores chances de criar um conflito de numeração, porém fica a seu critério.

Acredito, que o cenário ideal, é você ter um ponto de entrada antes e depois da gravação.

Você faria algo mais ou menos da seguinte forma:

  • Editaria o when do campo, para conforme suas condições, para que o campo não fique editável, visto que você vai gerar a numeração.
  • Caso seja um campo obrigatório, preencher com algum valor fixo, apenas para a validação de campos obrigatórios
  • No ponto de entrada antes da gravação, você geraria uma numeração automática, conforme as suas condições específicas e adicionaria o valor ao campo
  • Após a gravação, você confirmaria essa numeração automática, por isso o ideal é ter dois pontos de entrada, assim você só confirma caso a gravação tenha dado certo

Outra possível solução:

  • Criar um gatilho, que conforme suas condições, dispare a numeração automática pro campo
  • Novamente, o ideal é trabalhar com o when, para evitar que o usuário altere a numeração
  • Utilizar algum ponto de entrada da rotina para confirmar a numeração automática, o ideal, é confirmar somente após o commit, tendo assim a certeza que a numeração foi utilizada
  • Nesse cenário, você tem um porém, o usuário cancelar, você precisaria de alguma forma, via PE provavelmente, dar o rollback da numeração.

É uma situação atípica, normalmente um campo tem numeração automática independente de qualquer condição, portanto é necessário avaliar as possibilidades.
O que fica ainda mais complexo, é que você depende de pontos de entrada da rotina.

Achei uma documentação que concentra diversos pontos de entrada dessa rotina:
https://tdn.totvs.com.br/pages/viewpage.action?pageId=272168144

E tem mais esse aqui que não consta na lista:
https://tdn.totvs.com.br/pages/viewpage.action?pageId=285661676

1 curtida

É realmente um caso bem atípico, tenho que gerar um lote automático se o tipo de ordem de produção for um especifico. Ajudou demais dadinel, muito obrigado!