FM SOLUÇÕES - (31) 3761-3490
Seja bem vindo ao Fórum FM Soluções!!

Aqui você poderá postar suas dúvidas, experiências e ainda baixar e postar roteiros e tutoriais não oficiais sobre os módulos da RM Sistemas.

E ainda, conhecer um pouco sobre os nossos produtos e serviços!!!
Buscar
 
 

Resultados por:
 


Rechercher Busca avançada

Últimos assuntos
» Consulta SQL Banco RM
Ter 20 Jun 2017 - 12:48 por paulo.ferreira_rj

» Instalar base DEMO
Sex 2 Jun 2017 - 6:29 por akaytatsu

» Relatorio Rm reports / Holerite salario
Ter 18 Out 2016 - 8:09 por Gárgio

» DEFAULT NO CADASTRO DE FUNCIONARIOS RM LABORE
Sex 7 Out 2016 - 21:51 por mpsbrasilia

» Duvida RM Labore - Calculo Folha de Pagamento
Seg 12 Set 2016 - 15:51 por RIVALDO PAES

» Exportar Imagem do banco de dados SQL SERVER
Qui 28 Jul 2016 - 11:42 por edivan

» Consulta SQL
Qui 10 Set 2015 - 11:32 por evertonerp

» Existe Algum Demo do RM Labore???
Sex 17 Abr 2015 - 11:53 por fmsolucoes

» RM BIBLIOS
Seg 16 Fev 2015 - 7:50 por fmsolucoes

Galeria


Navegação
 Portal
 Índice
 Membros
 Perfil
 FAQ
 Buscar
Parceiros & Clientes FM Soluções

Criando uma rotina de envio de cotação para fornecedores no RM Nucleus

Ir em baixo

Criando uma rotina de envio de cotação para fornecedores no RM Nucleus

Mensagem por fmsolucoes em Qua 6 Jan 2010 - 14:16

O processo de envio de uma cotação para os seus fornecedores via RM Nucleus, é um processo meio que deficiente pois é enviado um documento texto para o mesmo que é preenchido a mão e retornado em um E-mail aonde então o cotador terá que entrar no RM e preencher isto tudo na mão onerando tempo
desnecessário. Se for uma cotação de 10 itens, até que vai, mas se forem aquelas megacotações de 1000 a 2000 itens?

Eu fiz uma rotina que dispensa o método usado pelo RM e o faz diretamente via uma customização direta aonde geramos uma planilha para cada fornecedor, enviamos por E-mail para ele preencher e depois ficamos apenas por conta de importarmos a supra-citada pra dentro do RM. Processo bem mais agil que pode
automatizar cotações de infinitas quantidades de intens.

Os passos a serem adotados serão: Montar a lista dos intens cotados, montar a lista dos fornecesdores destino, montar a planilha a ser preenchida pelo fornecedor e depois importar a planilha e gravar na tabela de cotação.

O primeiro passo a ser adotado é montarmos uma sentença SQL que irá buscar os dados da cotação em questão. Para isto a tabela alvo do Nucleus vai ser a TCITMORCAMENTO aonde estão os itens a serem orçados e seus respectivos fornecedores vinculados.

Para este processo funcionar, seus fornecedores deverão estar todos cadastrados na tabela FCFO e com seus respectivos E-Mails vigentes.

Na Unit do Plugin, iremos adicionar os dois itens do menu da customização:


MenuInfo : array [0..MAXMENU-1] of TPlugMenuInfo =
(
(Caption: '&Enviar orçamentos para fornecedores'; Hint: 'Envia itens orçados
na cotação para os fornecedores cadastrados';
Tag: 999992; Event: nil; Process: false; Bitmap: ''),
(Caption: '&Importar orçamentos cotados'; Hint: 'Importa itens orçados pelos
fornecedores cadastrados para a cotação';
Tag: 999992; Event: nil; Process: false; Bitmap: ''),
(Caption: '-'; Hint: '';
);

No Initialize do plugin, iremos declará-las:

i := 0; MenuInfo[i].Event := mnuEnviaCotacaoOrcadaClick;
inc(i); MenuInfo[i].Event := mnuImportaCotacaoOrcadaClick;
inc(i);

Feito isto, você deverá montar uma tela aonde colocaremos dois
DBLookUpComboBox, um progressbar e dois buttons.

Um DBLookup irá receber a lista de cotações em aberto (Todas diferentes do
flag 7 (Cancelado)). A sentença a ser usada na query, deve ser algo parecido
com:

select I.CODCOMPRADOR, I.CODCOTACAO, I.DATLIMRESPTA, P.EMAIL, P.NOME
from TCCOTACAO as I, PPESSOA as P where I.CODCOMPRADOR = P.CODIGO and I.STSCOTACAO
= 1 and I.CODCOLIGADA = 2

Um dos Buttons é para fechar o form o outro irémos inserir as rotinas de montagem da planilha e envio. Nesta rotina, você precisará primeiro criar uma query que busque a relação de fornecedores da cotação e seus
respectívos itens a serem orçados. Lembrando pela ordem que o registro mestre será o fornecedor, e os filhos serão seus itens. Sendo assim, a sentença SQL para listar os fornecedores será a seguinte:

select DISTINCT F.CODCFO, F.NOME, F.EMAIL from TCITMORCAMENTO AS C,
FCFO AS F WHERE F.CODCFO = C.CODCFO AND F.CODCOLIGADA = :CODCOLIGADA AND C.CODCOTACAO
= :CODCOTACAO and F.EMAIL is not null

A lista dos itens destinadas a cada fornecedor, será constituída da seguinte
sentença SQL:

select C.CODCFO,P.CODIGOPRD, P.DESCRICAO, C.CODUND, SUM(I.QUANTIDADE)
QUANTIDADE from TCITMORCAMENTO as C left outer join TPRD as P on P.IDPRD = C.IDPRD,
TMOV as M, TITMMOV as I Where C.CODCFO = :CODCFO AND C.CODCOTACAO = :CODCOTACAO
AND M.IDMOV = C.IDMOV

AND I.IDMOV = M.IDMOV
AND I.IDPRD = C.IDPRD
AND M.STATUS <> 'C'
GROUP BY C.CODCFO,P.CODIGOPRD, P.DESCRICAO, C.CODUND
ORDER BY P.DESCRICAO

Os códigos de status das cotações são:

1 - Composição (Ainda não foi enviado o orçamento para o fornecedor)
2 - Aguardando Resposta dos fornecedores
3 - Ordem de compra Parcialmente gerada
4 - Não usado
5 - Em negociação
6 - Composição
7 - Cancelada

Bom. De posse então dos dados para prepararmos a planilha, você monta uma rotina de escrita em uma planilha excel e mande salvá-la em disco (A Web tá cheia de exemplos de como gravar dados em uma planilha excel). Então criariamos uma rotina que iriia lendo fornecedor por fornecedor, gera a planilha, envia para o destinatrio e, em seguida, apaga a planilha do disco


FOR i := 0 TO DadosFornecedor.Count - 1 DO
BEGIN
DadosFornecedor.items[i];
IF CreateCotacaoSheet(DadosFornecedor,i,Cotacao,DadosItemCotacao, sNameFile) THEN
BEGIN


IF DadosFornecedor.Items[i].EMailUsuario <> '' THEN
BEGIN
SendSMTPMail(PChar(Cotacao.Operador), PChar(Cotacao.EMailOperador), PChar(DadosFornecedor.Items[i].Nome), PChar(DadosFornecedor.Items[i].EMailUsuario),NIL,NIL,pChar('PEDIDO DE ORÇAMENTO Nº ' + Cotacao.CodCotacao + '-' + DadosFornecedor.Items[i].CodFornecedor),PChar(BodyMessage),[PChar(sNameFile)]);
DeleteFile(sNameFile);
END
ELSE
MessageDlg('Fornecedor ' + DadosFornecedor.Items[i].Nome + ' Não possui conta de E-Mail. A planilha será salva no disco!', mtWarning, [mbOk], 0);
END;
END;
MessageDlg('Processo de envio de orçamentos para os fornecedores processado com sucesso!', mtInformation, [mbOk], 0);
SetStatusCotacao(Cotacao.CodCotacao,2);
FreeAndNil(DadosFornecedor);
FreeAndNil(DadosItemCotacao);
//
END;

Note você que esta rotina somente apaga a planilha do disco, se o fornecedor
tiver E-mail. Caso não o tenha ele não apaga pois você pode pegar esta
planilha, imprimir e enviar ela por Fax pro cara.

Depois disto, você deverá mudar o status da cotação para "Aguardando resposta
dos fornecedores". Para isto, você cria uma rotina usando a seguinte sentença
SQL:

UPDATE TCCOTACAO SET STSCOTACAO = :STSCOTACAO WHERE CODCOTACAO = :CODCOTACAO

Para mudar o status para "Aguardando resposta dos fornecedores" use o código 2
no parametro CODCOTACAO

Importando os dados.

Quanto a questão da importação desta planilha, é mais simples ainda.
Geralmente eu salvo a planilha como Texto separado por tabulações e uso a
rotina abaixo para importar os dados para o RM:


procedure TfImpOrcamento.btnImportClick(Sender: TObject);
var
fi : textfile;
BackupName, line, CodCotacao, CodPrd, ValFrete, CodCfo, ValPrazoEntrega,ValPrazoValidade,
NumeroParcelas, ValLimiteResposta, CondicoesPagto, CodCpg, FreteCIFouFob,
Preco, Unitario, IPI, Desconto, ValorDescontado, ValorFinal,
Quantidade, Total, ValTrb, ValCotacao, ValICMS: String;
LimiteResposta, DataEmissao: TDateTime;
Frete, ICMS: Extended;
i, k: integer;
done, decimal : boolean;
iCount, PrazoEntrega, PrazoValidade: integer;
Orcamento : TOrcamento;
DadosOrcamento : TDadosOrcamento;
Item : TItem;
DadosItem : TDadosItem;
begin
if eFileName.Text = '' then
begin
MessageDlg('Você deverá selecionar um arquivo para proceder com a importação', mtError, [mbOk], 0);
eFileName.Setfocus;
Exit;
end
else if IsFileInUse(eFileName.text) then
begin
MessageDlg('Erro ao abrir o arquivo ' + ExtractFileName(eFileName.text)
+ '. O arquivo está sendo usadado por outro processo', mtError, [mbOk], 0);
eFileName.Setfocus;
exit;
end;
try
//
assignfile(fi, eFileName.text);
{$i-} Reset(fi); {$i+}
//
pBar.Max := 40;
//
if ioresult <> 0 then
begin
MessageDlg('Erro ao abrir arquivo ' +
eFileName.text, mtInformation, [mbOk], 0);
exit;
end;
done := False;
//
if not eof(fi) then
begin
//
DadosOrcamento := TDadosOrcamento.Create;
DadosItem := TDadosItem.Create;
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1,10)=
'Fornecedor');
pBar.StepIt;
line := copy(line, 12, length(line));
line := RetiraCaracteres(#$09, line);
CodCfo := copy(Line,1,6);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1,19)= 'Pedido de Orçamento');
pBar.StepIt;
line := copy(line, 21, length(line));
CodCotacao := LTrim(RetiraPalavra(line, #$09));
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 14)= 'Data Lim. Resp');
pBar.StepIt;
line := copy(line, 16, length(line));
ValLimiteResposta := RetiraCaracteres(#$09, line);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 22)= 'Condições de Pagamento');
pBar.StepIt;
line := copy(line, 24, length(line));
CondicoesPagto := RetiraPalavra(line, #$09);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 18)= 'Número de parcelas');
pBar.StepIt;
line := copy(line, 20, length(line));
line := RetiraPalavra(line, #$09);
NumeroParcelas := SomenteDigitos(line,2);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 16)= 'Prazo de entrega');
pBar.StepIt;
line := copy(line, 18, length(line));
ValPrazoEntrega := RetiraPalavra(line, #$09);
ValPrazoEntrega := SomenteDigitos(ValPrazoEntrega,2);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 21)= 'Alíquota ICMS Inclusa');
pBar.StepIt;
line := copy(line, 23, length(line));
line := RetiraPalavra(line, #$09);
ValICMS := SomenteDigitos(line,2);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 21)= 'Validade do Orçamento');
pBar.StepIt;
line := copy(line, 23, length(line));
ValPrazoValidade := RetiraPalavra(line, #$09);
ValPrazoValidade := SomenteDigitos(ValPrazoValidade,2);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 14)= 'Valor do Frete');
pBar.StepIt;
line := copy(line, 16, length(line));
ValFrete := RetiraPalavra(line, #$09);
//
repeat
if not eof(fi) then
readln(fi, line);
until eof(fi) or (copy(line, 1, 13)= 'Tipo de Frete');
pBar.StepIt;
line := copy(line, 15, length(line));
FreteCIFouFob := RetiraPalavra(line, #$09);
//
if not DadosOrcamento.Locate(CodCfo)
then
begin
Orcamento := DadosOrcamento.Add;
//
Orcamento.CodCfo := CodCfo;
Orcamento.CodCotacao := CodCotacao;
Orcamento.CondicoesPagto := CondicoesPagto;
Orcamento.FreteCIFouFob := FreteCIFouFob;
Orcamento.PrazoEntrega := PrazoEntrega;
Orcamento.PrazoValidade := PrazoValidade;
Orcamento.NumeroParcelas := StrToInt(NumeroParcelas);
try
LimiteResposta := StrToDate(ValLimiteResposta);
Orcamento.LimiteResposta := LimiteResposta;
except
end;
Orcamento.DataEmissao := DataEmissao;
try
ICMS := StrToFloat(ValICMS);
Orcamento.ICMS := ICMS;
except
end;
try
Frete := StrToFloat(ValFrete);
Orcamento.Frete := Frete;
except
end;
end;
//
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
readln(fi, line);
//
while not Eof(fi) do
begin
readln(fi, line);
CodPrd := '';
i := 1;
k := 0;
//
while (i <= length(line))
and (line[i] <> #$09) do
begin
CodPrd := CodPrd + line[i];
inc(i);
end;
inc(i);
if Copy(CodPrd,1,11) = 'Observações' then
Break;
if CodPrd <> '' then
begin
//
Unitario := '';
Quantidade := '';
IPI := '';
Desconto := '';
ValorDescontado := '';
ValorFinal := '';
decimal := false;
k := 0;
//
while (i <= length(line)) and (line[i] <> #$09) do
inc(i);
inc(i);
while (i <= length(line)) and (line[i] <> #$09) do
begin
case line[i] of
'0'..'9':
begin
inc(k);
if not decimal or (k <= 4) then
Quantidade := Quantidade + line[i];
end;
',':
begin
Quantidade := Quantidade + ',';
decimal := true;
k := 0;
end;
end;
inc(i);
end;
try
StrToFloat(Quantidade);
except
Quantidade := '0';
end;
inc(i);
while (i <=
length(line)) and (line[i] <> #$09) do
inc(i);
inc(i);
while (i <= length(line)) and (line[i] <> #$09) do
begin
case line[i] of
'0'..'9':
begin
inc(k);
if not decimal or (k <= 4) then
Unitario := Unitario + line[i];
end;
',':
begin
Unitario := Unitario + ',';
decimal := true;
k := 0;
end;
end;
inc(i);
end;
try
StrToFloat(Unitario);
except
Unitario := '0';
end;
inc(i);
while (i <= length(line)) and (line[i] <> #$09) do
begin
IPI := IPI + line[i];
inc(i);
end;
try
StrToFloat(IPI);
except
IPI := '0';
end;
inc(i);
while (i <= length(line)) and (line[i] <> #$09) do
begin
case
line[i] of
'0'..'9':
begin
inc(k);
if not decimal or (k <= 4) then
Desconto := Desconto + line[i];
end;
',':
begin
Desconto := Desconto + ',';
decimal := true;
k := 0;
end;
end;
inc(i);
end;
try
StrToFloat(Desconto);
except
Desconto := '0';
end;
inc(i);
while (i <=length(line)) and (line[i] <> #$09) do
begin
ValorDescontado := ValorDescontado + line[i];
inc(i);
end;
try
StrToFloat(ValorDescontado);
except
ValorDescontado := '0';
end;
inc(i);
while (i <=length(line)) and (line[i] <> #$09) do
begin
ValorFinal := ValorFinal + line[i];
inc(i);
end;
try
StrToFloat(ValorFinal);
except
ValorFinal := '0';
end;
inc(i);
//
Item := DadosItem.Add;
Item.CodCfo := CodCfo;
Item.CodPrd := CodPrd;
if Unitario <> '0'
then
Item.Status := 0
else
Item.Status := 1;
Item.Unitario := StrToFloat(Unitario);
Item.Quantidade := StrToFloat(Quantidade);
Item.IPI := StrTofloat(IPI);
Item.Desconto := StrToFloat(Desconto);
Item.ValorDescontado := StrToFloat(ValorDescontado);
Item.Valortotal := StrToFloat(ValorFinal);
//
end;
end;
//
try
qryGravaCotacao.ParamByName('VALPRAZOENTREGA').AsInteger := Orcamento.PrazoEntrega;
qryGravaCotacao.ParamByName('DATENTREGA').AsDateTime := Date;
qryGravaCotacao.ParamByName('CODCPG').AsString := BuscaPrazoPagamento(Orcamento.CondicoesPagto, Orcamento.NumeroParcelas);
qryGravaCotacao.ParamByName('VALFRETE').AsFloat := Orcamento.Frete;
qryGravaCotacao.ParamByName('FRETECIFOUFOB').AsInteger := BuscaTipoFrete(Orcamento.FreteCIFouFob);
qryGravaCotacao.ParamByName('VALTRB').AsFloat := Orcamento.ICMS;
qryGravaCotacao.ParamByName('CODCOTACAO').AsString := Orcamento.CodCotacao;
qryGravaCotacao.ParamByName('CODCOLIGADA').AsInteger := CorporeRM.Coligada;
qryGravaCotacao.ParamByName('CODCFO').AsString := Orcamento.CodCfo;
qryGravaCotacao.ExecSQL;
try
for k := 0 to DadosItem.Count-1 do
begin

DadosItem.Items[k];
if
(DadosItem.Items[k].CodCfo = Orcamento.CodCfo) then
begin
try
CodCpg := BuscaPrazoPagamento(Orcamento.CondicoesPagto, Orcamento.NumeroParcelas);
qryGravaItemCotacao.ParamByName('IDPRD').AsInteger := BuscaIDProduto(DadosItem.Items[k].CodPrd);
qryGravaItemCotacao.ParamByName('CODCFO').AsString := DadosItem.Items[k].CodCfo;
qryGravaItemCotacao.ParamByName('VALCOTACAO').AsFloat := DadosItem.Items[k].Unitario;
qryGravaItemCotacao.ParamByName('VALNEGOCIADO').AsFloat := DadosItem.Items[k].Unitario;
qryGravaItemCotacao.ParamByName('VALTRB').AsFloat := DadosItem.Items[k].IPI;
qryGravaItemCotacao.ParamByName('DESCONTO').AsFloat := DadosItem.Items[k].ValorDescontado;
qryGravaItemCotacao.ParamByName('PERCDESCONTO').AsFloat := DadosItem.Items[k].Desconto;
qryGravaItemCotacao.ParamByName('VALTOTCOTACAONEG').AsFloat := 0;
qryGravaItemCotacao.ParamByName('CODCOTACAO').AsString := Orcamento.CodCotacao;
qryGravaItemCotacao.ParamByName('CODCOLIGADA').AsInteger := CorporeRM.Coligada;
qryGravaItemCotacao.ParamByName('STSITEM').AsInteger := DadosItem.Items[k].Status;
//
qryGravaItemCotacao.ParamByName('CFOVENCEDOR').AsFloat := DadosItem.Items[k].Quantidade;
qryGravaItemCotacao.ParamByName('VALTOTCOTACAO').AsFloat := 0; //
(DadosItem.Items[k].Unitario * DadosItem.Items[k].Quantidade);
qryGravaItemCotacao.ParamByName('CODCPGNEGOCIADA').AsString := CodCpg;
qryGravaItemCotacao.ParamByName('CODCPG').AsString := CodCpg;
qryGravaItemCotacao.ExecSQL;
except
MessageDlg('Erro ao tentar gravar o item "' + IntToStr(K) + '" desta
Cotação: '+ Exception(exceptobject).message, mtError, [mbOk], 0);
end;
end
end;
except
MessageDlg('Erro ao tentar gravar os dados nesta Cotação: '+ Exception(exceptobject).message, mtError, [mbOk], 0);
end;
except
MessageDlg('Erro ao tentar ler os dados para esta Cotação: '+ Exception(exceptobject).message, mtError, [mbOk], 0);
end;
//
end;
finally
MessageDlg('Importação realizada com sucesso!', mtInformation, [mbOk], 0);
CloseFile(fi);
SetStatusCotacao(Orcamento.CodCotacao,5);
//
BackupName := ExtractFileName(eFileName.text);
BackupName := ChangeFileExt(BackupName, '.old');
if not RenameFile(eFileName.text, BackupName) then
raise Exception.Create('Não foi possível renomear o arquivo já importado!');
//
end;
end;



Feita a rotina para lermos os dados da planilha, vamos atualizar os itens da
cotação. Para isto iremos mexer em duas tabelas: TCORCAMENTO e TCITMORCAMENTO.

Você deve usar a seguinte sentença SQL para gravar os dados na TCORCAMENTO:

update TCORCAMENTO SET VALPRAZOENTREGA = :VALPRAZOENTREGA, DATENTREGA = :DATENTREGA, CODCPG = :CODCPG, VALFRETE = :VALFRETE, FRETECIFOUFOB = :FRETECIFOUFOB, VALTRB = :VALTRB where CODCOTACAO = :CODCOTACAO and CODCOLIGADA = :CODCOLIGADA and CODCFO = :CODCFO

E, para gravar na TCITMORCAMENTO:

update TCITMORCAMENTO set VALCOTACAO = :VALCOTACAO,VALNEGOCIADO = :VALNEGOCIADO, VALTRB = :VALTRB,DESCONTO = :DESCONTO, PERCDESCONTO = :PERCDESCONTO, VALTOTCOTACAONEG =:VALTOTCOTACAONEG, CODMOEDA = 'R$', CODCPG = :CODCPG, CODCPGNEGOCIADA = :CODCPGNEGOCIADA, STSITEM = 0, VALTOTCOTACAO = :VALTOTCOTACAO where CODCOTACAO = :CODCOTACAO and CODCOLIGADA = :CODCOLIGADA and CODCFO = :CODCFO and IDPRD = :IDPRD

Atente para o campo STSITEM da Tabela. Você pode gravar o valor 0 para ele ser atualizado na cotação ou então usar uma regra conforme o que você importar na planilha.

0 = Cotado
1 = Não fornece
2 = Não cotou
4 = Desqualificado

Depois você deve usar aquela mesma rotina de mudança de status da cotação e muda para o status 5 (Em negociação). E pronto!


É isso aí. Peixe mais bem pescado que este não vão encontrar em lugar algum Smile

Postado por Walter Chagas Jr. às 9/28/2007 07:55:00 AM 1 comentários
avatar
fmsolucoes
Admin

Mensagens : 292
Pontos : 613
Data de inscrição : 17/07/2009
Idade : 40
Localização : Conselheiro Lafaiete

Ver perfil do usuário http://www.fmsolucoeserp.com.br

Voltar ao Topo Ir em baixo

Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum