| ♥ 0 | Boa tarde! Existe alguma forma de recalcular as margens de vendas, quando é atualizado ou inserido um documento de compra/entrada, que altera o preço de custo de um dado artigo? Ou seja, o documento de venda é emitido e só posteriormente o fornecedor envia o documento de compra que afeta o custo e a margem dessa fatura lançada. Ou então é lançado um documento de entrada (composição, por exemplo) que só vai alterar o preço de custo do artigo. Existe alguma forma de recalcular essa margem de venda, sem ter que desbloquear e voltar a gravar a fatura ou faturas respectivas? Isso pode ser feito de forma nativa ou é necessário desenvolvimento? Desde já obrigado.
Marcado como spam |
| Resposta privada Vou escrever como resposta nova pois os comentários não permitem formatação. O desenvolvimento que tenho não serve para isso mas pode sempre criar uma rotina que corre quando é gravado um documento de entrada, e que vai a todas os documentos de vendas relevantes entre a data do documento de compra que está a gravar e ao dia de hoje e os actualiza sem alterações. Não tenho a certeza se o Primavera corre o processo todo de actualização se não houver diferença entre o documento já gravado e a nova versão, mas é uma questão de experimentar. Duas coisas a ter em conta. Primeiro, se for criar um documento de entrada com muito tempo pra trás, o Primavera pode ficar ali um tempo a procurar nas linhas de vendas, e a actualizar os documentos. Por fim, se o método Actualiza não funcionar, terá de ir dar mais um passo e fazer as contas "à mão" e actualizar os campos de margens das linhas manualmente, por documento. Abaixo deixo código que pega no DocCompra que está a ser gravado, pega nos seus artigos e procura-os em todos os DocVenda dos (tipos escolhidos previamente) entre a data do DocCompra e a de agora. Quaisquer DocVenda que tenham pelo menos um desses artigos são Actualizados. public override void DepoisDeGravar(string Filial, string Tipo, string Serie, int NumDoc, ExtensibilityEventArgs e)
{
// Para evitar ter de recompilar o código quando se quiser alterar quaisos documentos de venda que a rotina deve actualizar,
// utiliza-se uma Tabela de Utilizador que pode ser alterada dentro do Primavera.
List<string> listaTipoDocsVenda = BSO.ConsultaDataTable("SELECT * FROM TDU_TipoDocVendaActualizarMargens")
.AsEnumerable()
.Select(linha => linha.Field<string>(0))
.ToList();
// Formatação das strings para ficarem no formato que o SQL precisa
string tipoDocsVendaSQL = PreparaStringParaSQLIn(listaTipoDocsVenda);
// Igual mas para os artigos do documento compra que acabou de ser gravado.
List<string> listaArtigos = DocumentoCompra.Linhas
.Select(a => a.Artigo)
.Distinct()
.ToList();
string artigosSQL = PreparaStringParaSQLIn(listaArtigos);
// Não filtra por série. Depende apenas da data do documento de compra como data inicial da procura.
List<VndBEDocumentoVenda> listaDocsVenda = BSO.Vendas.Documentos.ListaDocumentos(
new StdBE100.StdBEFiltroListagem
{
FiltroWhere = $@"
CabecDoc.DataDoc > {DocumentoCompra.DataDoc}
AND CabecDoc.TipoDoc IN ({tipoDocsVendaSQL})
AND EXISTS (
SELECT 1
FROM LinhasDoc
WHERE LinhasDoc.IdCabecDoc = CabecDoc.Id
AND LinhasDoc.Artigo IN ({artigosSQL})
)"
});
// Metemos os documentos numa colecção do Primavera e actualizamos.
// Se isto não funcionar pode usar o foreach para actualizar um a um com
// BSO.Vendas.Documentos.Actualiza(doc);
VndBEDocumentosVenda docsVenda = new VndBEDocumentosVenda();
foreach (var doc in listaDocsVenda)
{
docsVenda.Insere(doc);
};
string avisos = String.Empty;
BSO.Vendas.Documentos.ActualizaLote(docsVenda, ref avisos);
if (avisos.Length > 0)
{
PSO.MensagensDialogos.MostraAviso("Os documentos abaixo não foram actualizados."
, StdBETipos.IconId.PRI_Exclama,
avisos);
}
base.DepoisDeGravar(Filial, Tipo, Serie, NumDoc, e);
}
private string PreparaStringParaSQLIn(List<string> listaStrings)
{
return string.Join(",", listaStrings.Select(v => $"'{v.Replace("'", "''")}'"));
}
Marcado como spam Comentários Se isto ajudou, por favor marque como respondida e dê um upvote aqui na resposta! :) | |
| Resposta privada Olá Sérgio, O seu processo parece pouco ortodoxo. Se faz e finaliza uma fatura, não pode/deve depois voltar atrás e corrigi-la só porque o fornecedor ajustou os preços dele. Como é que justifica isso a um cliente que já aceitou a fatura? Com uma nota de débito? O único caso em que isso me faz sentido, é se guardar a fatura como rascunho e depois vá editar e finalizar. No entanto, não conheço a realidade da sua empresa. Quanto ao que o Primavera permite fazer: não existe um recalculo automático das margens com base num valor fixo da margem de lucro. Por exemplo, se comprar a um fornecedor o Artigo A a 20€ hoje, e a 30€ amanhã, o Primavera não tem forma de ajustar o preço de venda de modo a manter uma margem de lucro escolhida pelo utilizador. Para isso é preciso um desenvolvimento que necessitará de um CDU nos Artigos especificamente para Margem de Lucro. Tenho já código feito para esse fim, se quiser posso enviar. Marcado como spam Comentários Olá!
Talvez eu não tenha exposto da melhor forma, a minha questão. Até porque a aplicação não permite alterar um documento de venda (financeiro) já gravados. O que eu me refiro é uma coisa que a aplicação já faz, mas não o faz de maneira generalizada. Ou seja, por exemplo , imaginando que emito uma fatura com o produto X e gravo a fatura com a data de hoje. Se posteriormente for consultar as estatísticas de vendas tenho uma determinada margem e percentagem de margem. Se entretanto lançar uma composição de um artigo (COM que dá saída de 3 componentes e entrada de Produto X com influência no custo), para a data de ontem, por exemplo, isso vai afetar a minha margem, no entanto, nas estatísticas ou explorador de vendas não fica refletida.
Mas se voltar à fatura emitida e somente desbloquear o documento, sem qualquer alteração e apenas gravar, as margens são atualizadas e já refletidas nas estatísticas de vendas. Eu apenas pretendia uma opção, que me fizesse um acerto das margens, sem ter que estar a desbloquear os documentos de venda e gravar individualmente.
Mas creio que de base não há uma opção que faça esse recálculo das margens, por isso talvez tenha que recorrer por exemplo a uma situação de desenvolvimento como me está a sugerir. Talvez seja interessante essa sugestão que me está a dar. Pode-me esclarecer mais um bocadinho, por favor? Já tem algum .dll com esse desenvolvimento? Obrigado pela atenção e feedback. |