Procurar
Tópicos semelhantes
Últimos assuntos
Criando uma rotina de envio de cotação para fornecedores no RM Nucleus
Página 1 de 1
Criando uma rotina de envio de cotação para fornecedores no RM Nucleus
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
Postado por Walter Chagas Jr. às 9/28/2007 07:55:00 AM 1 comentários
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
Postado por Walter Chagas Jr. às 9/28/2007 07:55:00 AM 1 comentários
Tópicos semelhantes
» Criando uma rotina customizada de autoincremento de ID´s no RM
» Tipo de Movimento no Nucleus não faz retenção de impostos para faturamento no fluxus
» Erro na gravação do movimento em Exportação da Contabilidade (NUCLEUS)
» Tipo de Movimento no Nucleus não faz retenção de impostos para faturamento no fluxus
» Erro na gravação do movimento em Exportação da Contabilidade (NUCLEUS)
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos
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