campo-sirio/ve/velib04a.cpp
alex 145ecbff09 Patch level : 10.0 418
Files correlati     : ve0.exe ve6.ex
Ricompilazione Demo : [ ]
Commento

Bugs 0001356 :  Elaborazione differita per fatturazione di prova

Ho inserito una nuova numerazione documenti F09 "fatturazione di prova" con il
check di "numerazione provvisoria" un tipo documento "fatturazione di prova" F09
ho inserito una elaborazione differita che lascia le bolle B01 allo stato 2 ma crea un F09
quando vado a vedere le fatture F09 sono definitive e non provvisorie.
Allego la parte tabellare


git-svn-id: svn://10.65.10.50/trunk@19313 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-09-21 13:06:50 +00:00

586 lines
16 KiB
C++
Executable File

#include "velib04.h"
#include <dongle.h>
#include <modaut.h>
///////////////////////////////////////////////////////////
// TFatturazione bolle
///////////////////////////////////////////////////////////
TFatturazione_bolle::TFatturazione_bolle(const char* cod)
: TElaborazione(cod)
{
TConfig c(CONFIG_DITTA, "ve");
TString16 name; name.format("AGGFLD(%s)", cod);
_lista_campi = c.get(name);
}
void TFatturazione_bolle::tipi_validi(TToken_string& tipi) const
{
tipi.cut(0);
TString4 t;
for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++)
{
t = tipo_iniziale(i);
if (t.not_empty())
tipi.add(t);
}
CHECK(!tipi.empty_items(), "Nessun tipo documento valido");
}
void TFatturazione_bolle::stati_validi(TToken_string& stati) const
{
stati.cut(0);
for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++)
{
const char s = stato_iniziale(i);
if (s != '\0')
stati.add(s);
}
CHECK(!stati.empty_items(), "Nessuno stato documento valido");
}
void TFatturazione_bolle::campi_raggruppamento_righe(TToken_string& campi_riga) const
{
const bool ragg_rig = raggruppa_righe();
if (ragg_rig)
{
campi_riga = "CODART|UMQTA"; // Uguali sempre
// Uguali se commesse attive
if (dongle().active(CAAUT) || dongle().active(CMAUT))
{
campi_riga.add(RDOC_CODCMS);
campi_riga.add(RDOC_FASCMS);
campi_riga.add(RDOC_CODCOSTO);
}
// Uguali opzionalmente
if (riga_uguale(0)) campi_riga.add("CODMAG");
if (riga_uguale(1)) campi_riga.add("CODIVA");
if (riga_uguale(2)) campi_riga.add("PREZZO|SCONTO");
}
}
void TFatturazione_bolle::campi_raggruppamento(TToken_string& campi) const
{
campi = "TIPOCF|CODCF|CODVAL|CODLIN"; // Uguali sempre
// Uguali opzionalmente
const char* cond[] = { "CAMBIO", "SCONTO", "TIPODOC", "CODNUM",
"CODPAG", "CODABIA|CODCABA", "CODLIST", "CODAG|CODAGVIS",
"CODSPMEZZO", "CODPORTO", "CAUSTRASP", "CODVETT1|CODVETT2|CODVETT3",
"CODINDSP", "CODCMS",
NULL };
for (int u = 0; cond[u]; u++)
if (doc_uguale(u)) campi.add(cond[u]);
}
bool TFatturazione_bolle::doc_raggruppabili(const TDocumento& doc_in, const TDocumento& doc_out, TToken_string& campi) const
{
if (doc_in.ha_riga_esenzione() != doc_out.ha_riga_esenzione())
return false;
return doc_in.raggruppabile(doc_out, campi);
}
void TFatturazione_bolle::create_row(TDocumento& doc_out, const TRiga_documento& rin)
{
TRiga_documento& rout = doc_out.new_row(); // ... crea una riga nuova e
doc_out.copy_data(rout, rin); // copiaci tutti i campi della riga sorgente.
rout.set_original_rdoc_key(rin); // memorizza il codice della riga originale
if (usa_data_consegna())
{
rout.zero(RDOC_QTAEVASA);
rout.zero(RDOC_RIGAEVASA);
}
if (kill_descrizione_estesa()) // Cancello eventualmente la descrizione estesa
{
rout.zero(RDOC_DESCLUNGA);
rout.zero(RDOC_DESCEST);
}
if (prezzo_da_ordine()) // Se devo copiare il prezzo originale all'ordine
{
const TRectype* row_ord = rin.find_original_rdoc();
if (row_ord != NULL)
{
const real ord_price = row_ord->get_real(RDOC_PREZZO);
const TString& ord_scont = row_ord->get(RDOC_SCONTO);
rout.put(RDOC_PREZZO, ord_price);
rout.put(RDOC_SCONTO, ord_scont);
}
}
}
void TFatturazione_bolle::elabora_riga(TRiga_documento& r, TDocumento& doc_out, bool usa_dcons, bool ragg_rig, bool ignora_desc,
TToken_string & campi_riga, const TDate & dcons, const TDate & ddoc)
{
TRiga_documento rin(r);
const bool rindesc = rin.sola_descrizione(); // La riga di input e' descrittiva
if (ignora_desc && rindesc)
return;
if (rin.is_attrezzatura() || rin.is_risorsa())
{
const TSpesa_prest & risatt = rin.spesa();
const TString codprest(risatt.revenue());
if ( codprest.full())
{
const TSpesa_prest prest(codprest, RIGA_PRESTAZIONI);
rin.put(RDOC_TIPORIGA, "06");
rin.put(RDOC_CODART, prest.codice());
rin.put(RDOC_DESCR, prest.descrizione());
rin.put(RDOC_UMQTA, prest.um());
rin.put(RDOC_PREZZO, prest.prezzo());
rin.put(RDOC_CODIVA, prest.cod_iva());
}
}
if (usa_dcons)
{
TDate data_cons = rin.get(RDOC_DATACONS);
if (!data_cons.ok())
data_cons = dcons;
if (ddoc < data_cons || rin.get_bool(RDOC_RIGAEVASA))
return;
const real q = rin.get(RDOC_QTA);
r.put(RDOC_QTAEVASA, q);
r.put(RDOC_RIGAEVASA, true);
}
bool elaborata = false;
// Raggruppo le righe se e' settato il flag di raggruppamento e
// se la riga non contiene solo una descrizione
if (ragg_rig && !rindesc) // Se devo raggruppare le righe ...
{
const int last = doc_out.physical_rows();
for (int o = 1; o <= last; o++) // ... cerca una riga compatibile
{
TRiga_documento& rout = doc_out[o];
if (rout.sola_descrizione()) // Ignora le righe descrittive
continue;
if (da_raggruppare(rin) && rin.raggruppabile(rout, campi_riga)) // Se esiste una riga compatibile ...
{
add_rows(rout, rin);
elaborata = true; // Ricorda di averla gia' elaborata
break;
}
}
}
if (!elaborata) // Se la riga non e' stata gia' sommata ...
create_row(doc_out, rin);
}
bool TFatturazione_bolle::raggruppa(TDocumento& doc_in, TDocumento& doc_out)
{
#ifdef DBG
const TString4 tipodoc = doc_in.tipo().codice();
int i;
for (i = 0; i < TElaborazione::_max_tipi_doc_elab; i++)
{
if (tipodoc == tipo_iniziale(i))
break;
}
if (i >= TElaborazione::_max_tipi_doc_elab)
{
NFCHECK("Tipo documento non valido: '%s'", (const char*)tipodoc);
return true;
}
#endif
const TDate dcons = doc_in.get_date(DOC_DATACONS);
const TDate ddoc = doc_out.get_date(DOC_DATADOC);
const bool usa_dcons = usa_data_consegna();
const int doc_out_rows = doc_out.physical_rows();
if (usa_dcons)
{
bool da_elaborare = FALSE;
for (int r = 1; !da_elaborare && r <= doc_in.physical_rows(); r++)
{
const TRiga_documento* rin = &doc_in[r];
TDate data_cons = rin->get_date(RDOC_DATACONS);
if (!data_cons.ok())
data_cons = dcons;
da_elaborare = ddoc >= data_cons && !rin->get_bool(RDOC_RIGAEVASA);
}
if (!da_elaborare)
return FALSE;
}
//***vecchio posto cambio stato
if (gestione_riferimenti())
{
if (change_clifo())
{
const int indsped = doc_in.get_int(DOC_CODINDSP);
if (indsped > 0)
{
const char t = doc_in.get_char(DOC_TIPOCFFATT);
const long codcf = doc_in.get_long(DOC_CODCFFATT);
TString16 kis; kis << t << '|' << codcf << '|' << indsped;
const TString& dest = cache().get(LF_INDSP, kis, IND_RAGSOC);
if (dest.full()) // crea una riga descrizione nuova per indirizzo di spedizione valido
{
TRiga_documento& rout = doc_out.new_row();
rout.forza_sola_descrizione();
rout.put(RDOC_DESCR, dest);
}
}
}
// Determina ed eventualmente crea la riga di riferimento
const bool rif_testa = riferimenti_in_testa();
const bool rif_packed = pack_rif();
const int riga_rif = rif_testa ? 1 : doc_out.physical_rows()+1;
if (riga_rif > doc_out.physical_rows())
{
TRiga_documento& rout = doc_out.new_row();
rout.forza_sola_descrizione();
}
TRiga_documento& rout = doc_out[riga_rif];
// Costruisce la stringa di riferimento
TString riferimento;
if (!rif_testa || !rif_packed || doc_out_rows == 0)
{
doc_in.riferimento(riferimento);
if (riferimento.empty())
riferimento = doc_in.tipo().descrizione();
if (riferimento.full())
riferimento << ' ';
}
if (usa_doc_rif() && doc_in.get(DOC_NUMDOCRIF).not_empty())
{
riferimento << "n. " << doc_in.get(DOC_NUMDOCRIF);
if (rif_packed)
riferimento << ' ' << doc_in.get_date(DOC_DATADOCRIF).string(brief);
else
riferimento << " del " << doc_in.get(DOC_DATADOCRIF);
}
else
{
riferimento << " n. " << doc_in.numero();
if (rif_packed)
riferimento << ' ' << doc_in.data().string(brief);
else
riferimento << " del " << doc_in.data().string();
}
// Setta la descrizione se vuota
if (rif_packed)
{
TString memo(1024);
memo = rout.get(RDOC_DESCR);
if (rout.get_bool(RDOC_DESCLUNGA))
memo << rout.get(RDOC_DESCEST);
if (memo.full())
memo << " - ";
memo << riferimento;
if (memo.len() < rout.length(RDOC_DESCR))
rout.put(RDOC_DESCR, memo);
else
{
rout.put(RDOC_DESCR, memo.left(rout.length(RDOC_DESCR)));
rout.put(RDOC_DESCEST, memo.mid(rout.length(RDOC_DESCR)));
rout.put(RDOC_DESCLUNGA, "X");
}
}
else
{
if (rout.get(RDOC_DESCR).empty())
rout.put(RDOC_DESCR, riferimento);
else
{
// Altrimenti aggiungi il riferimento al memo
TString memo(1024);
memo = rout.get(RDOC_DESCEST);
if (memo.empty())
{
TString80 rif(rout.get(RDOC_DESCR));
rif << '\n';
rout.put(RDOC_DESCR, rif);
rout.put(RDOC_DESCLUNGA, "X");
}
else
memo << '\n';
memo << riferimento;
rout.put(RDOC_DESCEST, memo);
}
}
}
const bool ignora_desc = ignora_descrizioni();
TToken_string campi_riga(80);
campi_raggruppamento_righe(campi_riga);
const bool ragg_rig = campi_riga.full();
for (int r = 1; r <= doc_in.physical_rows(); r++)
elabora_riga(doc_in[r], doc_out, usa_dcons, ragg_rig, ignora_desc, campi_riga, dcons, ddoc);
//cambio stato documento
bool cambia_stato_doc_in = true;
if (usa_dcons)
{
for (int r = 1; r <= doc_in.physical_rows(); r++)
{
const TRiga_documento & rin = doc_in[r];
if (!rin.sola_descrizione() && !rin.get_bool(RDOC_RIGAEVASA))
{
cambia_stato_doc_in = false;
break;
}
}
}
if (cambia_stato_doc_in)
{
const char stato_finale_in = get_char("S4");
doc_in.stato(stato_finale_in);
}
const char stato_finale_out = get_char("S9");
doc_out.stato(stato_finale_out);
if (usa_dcons)
doc_in.rewrite();
return TRUE;
}
bool TFatturazione_bolle::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
const TDate& data_elab, bool interattivo)
{
TWait_cursor hourglass;
TToken_string campi_doc(128); // Lista di campi che devono essere uguali
TBit_array closed;
campi_raggruppamento(campi_doc);
pre_process_input(doc_in);
for (int id = 0; id < doc_in.items(); id++)
{
TDocumento& campione = doc_in[id];
const char orig_t = campione.get_char(DOC_TIPOCF);
const long orig_cod = campione.get_long(DOC_CODCF);
if (change_clifo())
{
const char t = campione.get_char(DOC_TIPOCFFATT);
const long codcf = campione.get_long(DOC_CODCFFATT);
if (t > ' ')
{
campione.put(DOC_TIPOCF, t);
if (interattivo)
doc_out[0].put(DOC_TIPOCF, t);
}
if (codcf > 0L)
{
campione.put(DOC_CODCF, codcf);
if (interattivo)
doc_out[0].put(DOC_CODCF, codcf);
}
}
if (_lista_campi.full())
{
TToken_string s("", '=');
for (s = _lista_campi.get(0); s.full(); s = _lista_campi.get())
{
TString16 oname(s.get());
TString16 iname(s.get());
if (oname == RDOC_CODIVA)
{
const int rows = campione.physical_rows();
const TString8 codesiva = campione.codesiva();
for (int i = 1; i <= rows; i++)
{
TRiga_documento& rdoc = campione[i];
if (codesiva.full())
rdoc.put(RDOC_CODIVA, codesiva);
else
{
if (rdoc.is_articolo())
{
const TArticolo_giacenza & art = rdoc.articolo();
const TString8 codiva = art.get(ANAMAG_CODIVA);
if (codiva.full())
rdoc.put(RDOC_CODIVA, codiva);
}
else
if (rdoc.is_spese() || rdoc.is_prestazione())
{
const TSpesa_prest & s = rdoc.spesa();
const TString8 codiva = s.cod_iva();
if (codiva.full())
rdoc.put(RDOC_CODIVA, codiva);
}
}
}
}
else
{
if (iname.blank())
iname = oname;
if (iname.starts_with("17."))
campione.put(oname, campione.clifor().vendite().get(iname.mid(3)));
else
if (iname.starts_with("CFVEN."))
campione.put(oname, campione.clifor().vendite().get(iname.mid(6)));
else
campione.put(oname, campione.clifor().get(iname));
}
}
}
campione.set_riga_esenzione();
const int tot = doc_out.items();
int od = tot;
if (interattivo)
{
od = 0;
const char tipo = campione.get_char(DOC_TIPOCF);
const long codice = campione.get_long(DOC_CODCF);
TDocumento & out = doc_out[od];
if (tipo != out.get_char(DOC_TIPOCF) ||
codice != out.get_long(DOC_CODCF))
return error_box("Documenti incompatibili: cliente/fornitore diverso");
const TString4 codnum(out.get(DOC_CODNUM));
if (cached_numerazione(codnum).num_provv())
out.put(DOC_PROVV, 'P');
}
else
{
if (doc_raggruppabile(campione)) // Se il documento ha il flag di raggruppabilita' ...
{
for (od = 0; od < tot; od++) // ... cerca un documento compatibile.
{
if (!closed[od])
{
const int in_rows = campione.rows();
const int out_rows = doc_out[od].rows();
if (in_rows + out_rows > 990)
closed.set(od);
else
{
if (doc_raggruppabili(campione, doc_out[od], campi_doc))
break;
}
}
}
}
}
if (od >= tot) // Se non ho trovato un documento compatibile ...
{ // ... creane uno nuovo (certamente compatibile)
const int anno = data_elab.year();
const TString4 codnum(campione.get(DOC_CODNUM));
const TString4 tipo_out(get("S8")); // Tipo del documento di output
char provv = 'D';
if (cached_numerazione(codice_numerazione_finale()).num_provv())
provv = 'P';
TDocumento* new_doc = new TDocumento(provv, anno, codnum, -1);
// Attenzione! Il cambio del tipo documento provocherebbe il reset delle variabili
// Per cui lo scrivo temporaneamente nel tipo del documento d'ingresso
// TRecfield td(campione, DOC_TIPODOC); // Uso il TRecfield per scavalcare tutti gli automatismi
// const TString16 old_tipo_in = td; // Salvo il vecchio tipo
// td = tipo_out; // Setto il nuovo
TDocumento::copy_data(new_doc->head(), campione.head()); // Copio la testata
// td = old_tipo_in; // Ripristino il vecchio
new_doc->put(DOC_DATADOC, data_elab);
// Aggiungilo alla lista dei documenti in uscita
od = doc_out.add(new_doc);
}
if (change_clifo())
{
campione.put(DOC_TIPOCF, orig_t);
campione.put(DOC_CODCF, orig_cod);
}
if (!raggruppa(campione, doc_out[od]) && doc_out[od].physical_rows() == 0)
doc_out.destroy(od);
else
doc_out[od].set_riga_esenzione();
campione.flush_rows();
}
post_process_input(doc_in);
const int tot = doc_out.items();
const TString4 codnum(codice_numerazione_finale());
for (int i = 0; i < tot; i++) // Forza tipo e numerazione documento.
{
TDocumento & d = doc_out[i];
d.put(DOC_CODNUM, codnum);
TToken_string key; key.add(d.get(DOC_TIPOCF)); key.add(d.get(DOC_CODCF));
const TRectype & cfven = cache().get(LF_CFVEN, key);
const TString4 tipo_cli(cfven.get(CFV_TIPODOCFAT));
const TString & tipo_out = get_tipo_out(d); // Tipo del documento di output
TRecfield td(d, DOC_TIPODOC); // Uso il TRecfield per scavalcare tutti gli automatismi
td = tipo_cli.empty() ? tipo_out : tipo_cli;
const TString& sconto = d.get(DOC_SCONTOPERC);
d.put(DOC_SCONTOPERC, sconto);
if (change_clifo())
{
const TString8 tipodoc(d.tipo().codice());
TDocumento_mask m(tipodoc);
if (reload_prices())
{
const int rows = d.physical_rows();
for (int i = 1; i <= rows;i++)
d[i].zero(RDOC_CHECKED);
}
m.doc() = d;
m.doc2mask(true, true);
m.mask2doc();
d = m.doc();
}
}
post_process_output(doc_out);
return tot > 0;
}