{RESOLVIDO}Código Inicial (especial) Automatico

Prezados, Sou um iniciante no scriptcase e estou com um problema.
Tenho um sistema de vendas e preciso de um campo especial para receber o código de venda.
São muitos Vendedores em tempo real (talvez milhares) e no cadastro do vendedor(CadVend) criei 2 campos DataVenda (date()) e CountVenda(Interger).

Acontece que o código da venda tem este formato “201801-1”(AnoMês-contador).

Como tem vendedores espertos que utilizam membros da família para aumentar a área de venda. colocam estes membros para vender também com o seu login.

Nesse caso Preciso Bloquear o Registro (Lock Transacional) desse vendedor para fazer o seguinte:

1º Inicia Transação

2º - Verificar a data com o campo DataVenda, Se For a Mesma data Pega o valor do campo Datavenda (guarda numa variável), Pega o valor do campo CountVenda e acrescenta + 1 (guardando numa variável), Se for uma data Posterior Pega a data corrente (guarda numa variável), Pega a Variável do Campo CountVenda e seta para 1.

3º - Concatena os resultados das 2 variáveis (Data e contador) para deixar no formato: “201801-1”(AnoMês-contador)

4º - Atualiza os campos DataVenda e CountVenda do cadastro do vendedor

5º - Termina transação

6º - Retorna resultado do 3º passo para o campo CodVenda do cadastro de vendas.

Pensei em fazer isso no evento no evento “After insert”

Já consegui fazer funcionar numa procedure dentro do mysql mas não consigo fazer retornar o valor do 3º passo para o formulario de cadastro PHP

Alguém poderia me ajudar? sou dba mas não manjo ainda dos paranauê de php + scriptcase ainda.

Segue Abaixo Procedure MYSQL

CREATE PROCEDURE Iserver.Gera_CodProd(OUT V_CodProd CHAR(13))
DETERMINISTIC
SQL SECURITY INVOKER
COMMENT ‘Gera Código de Produção a Partir da Tabela de Configuração geral’
BEGIN
DECLARE V_CodProd VARCHAR(13);
DECLARE V_CountProd decimal(5,0);
DECLARE V_Data_CodProd DATE;
START TRANSACTION;
SELECT tab_Config_Geral.Config_Data_CodProd INTO @V_Data_CodProd FROM tab_Config_Geral FOR UPDATE;
SELECT tab_Config_Geral.Config_CodProd INTO @V_CountProd FROM tab_Config_Geral;
IF @V_Data_CodProd = CURDATE() THEN
SET @V_CountProd = @V_CountProd + 1;
ELSE
SET @V_CountProd = 1;
END IF;
UPDATE tab_Config_Geral SET Config_Data_CodProd = CURDATE(), Config_CodProd = @V_CountProd;
SET @V_CodProd = CONCAT_WS(’-’, CAST(DATE_FORMAT(CURDATE(),’%Y%m’) AS CHAR),CAST(@V_CountProd AS CHAR));
COMMIT;
#SET V_CodProd = CONCAT_WS(’-’, CAST(DATE_FORMAT(CURDATE(),’%Y%m’) AS CHAR),CAST(V_CountProd AS CHAR));
END

Você pode criar o sistema de senhas no Scriptcase com ‘proteção de usuário’ logado, ai só uma pessoa vai conseguir usar aquele usuário e senha no momento.

https://suporte.scriptcase.com.br/pt-br/article/547-modulo-de-seguranca

Ja havia feito isso inicialmente, mas meu contratante me orientou a desfazer pois de qualquer forma ele sai lucrando com esta pratica…
Dai o meu problema…não posso impedir a pratica e tenho que lidar com essa inconsistencia.

Said everything was fully simplification is not as difficult as you think.

O Código de venda deve estar como Chave Primária ou Chave Única no SC.

Criar a Função no seu formulário, entre em Programação > Métodos PHP:

NOVO, nome = Gerar_CodigoVenda:

Esse exemplo usei o MySQL:

/* Macro sc_lookup */

$_Ano_Venda=date(“Y”);
$_Mes_Venda=date(“m”);

$sql ="
SELECT
CodigoVendedorID,
DATE_FORMAT(DataVenda, “%Y-%m”) AS Ano_Mes,
COUNT(*) AS QTDE
FROM
vendas
WHERE
CodigoVendedorID={CodigoVendedorID} AND YEAR(DataVenda)=$_Ano_Venda
AND MONTH(DataVenda)=$_Mes_Venda
GROUP BY
CodigoVendedorID,
DATE_FORMAT(DataVenda, “%Y-%m”)
";

sc_lookup(chk_venda, $sql);

/* Erro no lookup /
if (FALSE === {chk_venda}) {
sc_error_message(“Ocorreu um erro no acesso ao banco de dados.
”);
}
elseif (empty({chk_venda})) { /
EOF */

{CodigoVendaID}=$_Ano_Venda.$_Mes_Venda.'-1';

}
else {

/* Inclua aqui sua rotina de processamento */

{CodigoVendaID}=$_Ano_Venda.$_Mes_Venda.'-'.({chk_venda[0][2]}+1);

}


Ai no OnLoad use:
if (empty({CodigoVendaID})) {
Gerar_CodigoVenda();
}

No OnBeforeInsert:
Gerar_CodigoVenda();

Jailton,

Muitíssimo Obrigado pela sua ajuda !!!
Vou testar sua orientação e Retorno aqui para seu acompanhamento.

Só uma dúvida.
Não sei se entendi direito…
No caso de 2 ou mais pessoas estiverem entrando com o mesmo login ao mesmo tempo, as 2 não receberiam o Mesmo Código de venda inicial?
O código só mudaria quando uma das duas efetivamente terminasse o cadastro. Correto?

Isso, a principio enquanto eles não terminassem o cadastro na tela estaria o mesmo código, mas assim, que fosse clicando o incluir,
ele já pegaria o código mais atual e já gravaria corretamente na tabela, sem repetir.

Jailton,

Mais uma vez, obrigado pela sua presteza em me ajudar.
Após analisar seu código, fiz algumas alterações que funcionaram aqui (pelo menos até agora. rsrsrs).
Com essas alterações eu garanto o ACID do processo.

Não tenho como agradacer. Qualquer coisa que eu puder ajudar é só chamar.

Segue o código, espero que sirva para vc em algum dos seus projetos.

$_Vdata =date(‘Ymd’);
$_VCount =0;
/* Seleciona Registros da Tabela Controler /
$sql ="
SELECT
tab_Config_Controler.Controler_data,
tab_Config_Controler.Controler_count
FROM tab_Config_Controler
WHERE tab_Config_Controler.Config_cnpj_cpf = ‘21740536000113’
AND tab_Config_Controler.Controler_tab = ‘tab_Prod_cadastro’
AND tab_Config_Controler.Controler_data = $_Vdata FOR UPDATE
";
sc_begin_trans(); /
Inicia Transação /
sc_lookup(chk_venda, $sql); /
Executa Lookup Bloqueando registro */

/* Erro no lookup /
if (FALSE === {chk_venda}) { /
Erro no lookup /
sc_error_message(“Ocorreu um erro no acesso ao banco de dados.
”);
}
elseif (empty({chk_venda})) { /
Não encontrou registro no lookup /
$_VCount =1;
}
else {
$_VCount =({chk_venda[0][1]}+1);
}
/
Executa Update da Tabela Controler /
$sql1 ="
UPDATE tab_Config_Controler
SET Controler_data = ‘$_Vdata’,
Controler_count = ‘$_VCount’
WHERE tab_Config_Controler.Config_cnpj_cpf = ‘21740536000113’
AND tab_Config_Controler.Controler_tab = ‘tab_Prod_cadastro’
";
{Prod_cadastro_cod}=$_Vdata.’-’.$_VCount; /
Retorna Valor Para o campo do formulario /
sc_exec_sql ($sql1); /
Executa Update na Tabela /
sc_commit_trans (); /
Efetiva a Transação */