Corretta generazione NAC

git-svn-id: svn://10.65.10.50/branches/R_10_00@22791 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2013-01-30 16:58:06 +00:00
parent 07bb60d62b
commit b2556eb707
3 changed files with 118 additions and 69 deletions

View File

@ -115,8 +115,8 @@ protected:
void elabora_documenti(const TMask& mask, TISAM_recordset& recset, TLog_report& log);
//metodi medio livello
bool aggiorna_contratti(const TRiga_documento& rdoc, TContratto_premi& contratto, TLog_report& log);
bool elabora_contratti(TDocumento& curr_doc, TArray& contratti_cliente, TLog_report& log);
bool aggiorna_contratto(const TRiga_documento& rdoc, TContratto_premi& contratto, TLog_report& log);
bool elabora_contratti(TDocumento& curr_doc, TArray& contratti_cliente, const TDate& data_fine, TLog_report& log);
bool genera_nac(const TMask& mask, TArray& contratti_cliente, TArray& documenti_cliente, TLog_report& log);
//metodi basso livello
@ -231,33 +231,21 @@ long THardy_elab_docs::genera_recordset(const TMask& mask, TISAM_recordset& recs
//se c'è l'agente specificato...
const TString& agente = mask.get(F_CODAGE);
const bool has_007 = agente.full();
if (has_007)
query << "&&(CODAG=#CODAG)";
//ordinamento agente-codcf-numdoc
query << "\nBY ";
if (has_007)
query << DOC_CODAG << " ";
query << DOC_CODCF << " " << DOC_NDOC;
//ordinamento (agente)-codcf-ndoc
query << "\nBY " << DOC_CODCF << " " << DOC_NDOC;
//from-to dipendente da chiave
switch (key)
{
case 2: //chiave per tipocf-codcf-provv-anno-datadoc-codnum
{
query << "\nFROM TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#DADATA";
query << "\nTO TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#ADATA";
}
query << "\nFROM TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#DADATA"
<< "\nTO TIPOCF=C CODCF=#CODCF PROVV=D ANNO=#ANNO DATADOC=#ADATA";
break;
case 3: //chiave per datadoc-provv-anno-codnum
{
query << "\nFROM DATADOC=#DADATA PROVV=D ANNO=#ANNO";
query << "\nTO DATADOC=#ADATA PROVV=D ANNO=#ANNO";
}
query << "\nFROM DATADOC=#DADATA PROVV=D ANNO=#ANNO"
<< "\nTO DATADOC=#ADATA PROVV=D ANNO=#ANNO";
break;
default:
break;
}
@ -269,7 +257,6 @@ long THardy_elab_docs::genera_recordset(const TMask& mask, TISAM_recordset& recs
const TDate adata = mask.get_date(F_ADATA);
TDate dadata = mask.get_date(F_DADATA);
//se la data iniziale è vuota deve coincidere con l'inizio dell'esercizio della data finale (obbligatoria!)
int esc = adata.year();
if (!dadata.ok())
check_date(adata, dadata);
@ -281,7 +268,7 @@ long THardy_elab_docs::genera_recordset(const TMask& mask, TISAM_recordset& recs
recset.set_var("#CODAG", agente);
if (codcf > 0)
recset.set_var("#CODCF", codcf);
recset.set_var("#ANNO", long(esc));
recset.set_var("#ANNO", long(adata.year()));
recset.set_var("#DADATA", dadata);
recset.set_var("#ADATA", adata);
@ -308,10 +295,13 @@ int THardy_elab_docs::find_contratti_cliente(const long codcfatt, const TMask& m
FOR_EACH_ASSOC_OBJECT(cod_num_cont, h, k, o)
{
//deve cercare tutti i contratti del cliente e metterli nell'array
const TString& agente = mask.get(F_CODAGE);
//deve cercare tutti i contratti del cliente e metterli nell'array
TString query;
query << "USE DOC KEY 5";
query << "\nSELECT ((TIPODOC=#A_TIPODOC)||(TIPODOC=#R_TIPODOC)||(TIPODOC=#P_TIPODOC))&&(STR(DOC2=#CODCF))";
if (agente.full()) query << "&&(CODAG=#CODAG)";
query << "\nFROM PROVV=D CODNUM=" << k;
query << "\nTO PROVV=D CODNUM=" << k;
@ -322,6 +312,7 @@ int THardy_elab_docs::find_contratti_cliente(const long codcfatt, const TMask& m
recset.set_var("#P_TIPODOC", tip_post);
recset.set_var("#CODCF", codcfatt);
recset.set_var("#CODAG", agente);
const long n_contratti = recset.items(); //questo serve solo al sagace programmatore
@ -335,8 +326,8 @@ int THardy_elab_docs::find_contratti_cliente(const long codcfatt, const TMask& m
//controlla validità del contratto con le date scelte per l'elaborazione dei documenti
const TDate data_ini_contratto = recset.get(DOC_DATACOMP).as_date();
TDate data_ini_elab = mask.get_date(F_DADATA);
const TDate data_fine_elab = mask.get_date(F_ADATA);
TDate data_ini_elab = mask.get_date(F_DADATA);
if (!data_ini_elab.ok())
check_date(data_fine_elab, data_ini_elab);
@ -359,6 +350,7 @@ int THardy_elab_docs::find_contratti_cliente(const long codcfatt, const TMask& m
TContratto_premi* curr_contratto = new TContratto_premi(recset.cursor()->curr());
//azzeratore del campo con il totale reso per elaborazione, nel caso di contratti Anticipo/Rifatturazione, riga spese
const char tipo_contr = curr_contratto->tipo_contratto();
if (tipo_contr == 'A' || tipo_contr == 'R')
{
FOR_EACH_PHYSICAL_RDOC(*curr_contratto, r, rdoc)
@ -366,18 +358,28 @@ int THardy_elab_docs::find_contratti_cliente(const long codcfatt, const TMask& m
if (rdoc->get(RDOC_TIPORIGA) == HARDY_TIPORIGA_SOMMA)
{
rdoc->zero(RCA_2_RESO_CORRENTE);
const real prezzo = rdoc->prezzo(false, false);
const real resost = rdoc->get(RCA_2_RESO_STORICO);
if (resost >= prezzo) // Contratto esaurito da ignorare
{
delete curr_contratto;
curr_contratto = NULL;
}
break;
}
}
}
contratti_cliente.add(curr_contratto);
if (curr_contratto != NULL) // Ignora contratti chiusi
contratti_cliente.add(curr_contratto);
}
}
return contratti_cliente.items();
}
bool THardy_elab_docs::aggiorna_contratti(const TRiga_documento& rdoc, TContratto_premi& contratto, TLog_report& log)
bool THardy_elab_docs::aggiorna_contratto(const TRiga_documento& rdoc, TContratto_premi& contratto, TLog_report& log)
{
bool elaborato = false;
const char tipo_contratto = contratto.tipo_contratto();
@ -429,7 +431,7 @@ bool THardy_elab_docs::aggiorna_contratti(const TRiga_documento& rdoc, TContratt
elaborato = true;
TString msg;
msg.format("Documento %d/%s %ld - %s: %s %s -> Bonus %s su contratto %d/%s %ld",
msg.format("Doc. %d/%s %ld - %s: %s %s -> Bonus %s Contr. %d/%s %ld",
rdoc.get_int(RDOC_ANNO), (const char*)rdoc.get(RDOC_CODNUM), rdoc.get_long(RDOC_NDOC),
(const char*)rdoc_codart, normalized_rdoc_qta.stringa(4, 0), (const char*)rdoc_umqta, bonus.stringa(7,2),
contratto.get_int(DOC_ANNO), (const char*)contratto.get(DOC_CODNUM), contratto.get_long(DOC_NDOC));
@ -446,17 +448,32 @@ bool THardy_elab_docs::aggiorna_contratti(const TRiga_documento& rdoc, TContratt
//aggiorna, in base al documento in esame curr_doc, le somme restituite nelle righe di tipo verigh02 nei contratti validi..
//..del cliente
bool THardy_elab_docs::elabora_contratti(TDocumento& curr_doc, TArray& contratti_cliente, TLog_report& log)
bool THardy_elab_docs::elabora_contratti(TDocumento& curr_doc, TArray& contratti_cliente, const TDate& data_fine, TLog_report& log)
{
const TDate datadoc = curr_doc.get(DOC_DATADOC);
bool elaborato = false;
FOR_EACH_PHYSICAL_RDOC(curr_doc, r, rdoc) if (rdoc->is_merce()) //giro su tutte le righe merce delle fatture
{
//controlla se il codart della riga esiste in uno dei contratti validi
//controlla se il codart della riga esiste in uno o più contratti validi
for (int i = 0; i < contratti_cliente.items(); i++)
{
TContratto_premi& contratto = (TContratto_premi&)contratti_cliente[i];
elaborato |= aggiorna_contratti(*rdoc, contratto, log);
if (!contratto.data_valida(datadoc))
continue;
// Calcola l'inizio di validità dei documenti in base alla frequenza (14-01-2013)
TDate data_inizio(1, 1, data_fine.year());
switch (contratto.frequenza())
{
case 'S': data_inizio.set_month(data_fine.month() > 6 ? 7 : 1); break;
case 'T': data_inizio.set_month(max(1, data_fine.month()-2)); break;
default: break;
}
// Elabora solo i documenti che ricadano nell'intervallo valido
if (datadoc >= data_inizio && datadoc <= data_fine)
elaborato |= aggiorna_contratto(*rdoc, contratto, log);
} //for(int i..
} //FOR_EACH...
@ -464,8 +481,11 @@ bool THardy_elab_docs::elabora_contratti(TDocumento& curr_doc, TArray& contratti
}
bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente, TArray& /*documenti_cliente*/, TLog_report& log)
bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente, TArray& documenti_cliente, TLog_report& log)
{
if (documenti_cliente.empty())
return false;
//si informa se l'elaborazione è definitiva o meno
const bool definitivo = mask.get_bool(F_DEFINITIVO);
@ -479,7 +499,7 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
//segnaliamo l'elaborazione del contratto sul log
TString log_msg;
log_msg.format("Contratto:%6ld Cliente:%6ld", ndoc, codcf);
log_msg.format(FR("Contratto:%6ld Cliente:%6ld"), ndoc, codcf);
// generazione del documento NAC dal contratto
// -------------------------------------------
@ -518,7 +538,8 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
cod_riga = codspesa;
}
const int anno = mask.get_date(F_ADATA).year();
const TDate datadoc = mask.get(F_DATAELAB);
const int anno = datadoc.year();
//solo in caso di elaborazione definitiva si scrivono NAC di tipo D;
//sennò di tipo P, che sono uccidibili all'inizio di ogni nuova elaborazione
const char provv = definitivo ? 'D' : 'P';
@ -526,7 +547,7 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
TDocumento nac(provv, anno, nac_codnum, 0); //num_doc = 0 perchè viene aggiornato in fase di registrazione
nac.set_tipo(nac_tipo);
nac.put(DOC_STATO, 1);
nac.put(DOC_DATADOC, mask.get(F_DATAELAB));
nac.put(DOC_DATADOC, datadoc);
nac.put(DOC_TIPOCF, 'C');
nac.put(DOC_CODCF, codcf);
nac.put(DOC_CODAG, codage);
@ -543,6 +564,30 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
const TString80 descr_riga_spp = rec_spp.get("S0");
const TString4 codiva = rec_spp.get("S3");
TDate adata = mask.get_date(F_ADATA);
TDate dadata = mask.get_date(F_DADATA);
if (!dadata.ok())
check_date(adata, dadata);
TDate dmin(1, 1, adata.year());
switch (contratto.frequenza())
{
case 'S': dmin.set_month(adata.month() > 6 ? 7 : 1); break;
case 'T': dmin.set_month(max(1, adata.month()-2)); break;
default: break;
}
if (dmin > dadata)
dadata = dmin;
if (!contratto.data_valida(dadata))
dadata = contratto.data_inizio();
if (!contratto.data_valida(adata))
adata = contratto.data_fine();
TString msg_date; msg_date << " " << dadata << " -- " << adata;
//giro sulle righe del contratto, che originano le righe NAC
for (int i = 1; i <= contratto.rows(); i++)
{
@ -564,15 +609,7 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
//panegirico della descrizione
nac_row.put(RDOC_DESCR, descr_riga_spp);
TString msg;
const TDate adata = mask.get_date(F_ADATA);
TDate dadata = mask.get_date(F_DADATA);
if (!dadata.ok())
check_date(adata, dadata);
msg << " " << dadata << " -- " << adata;
nac_row.put(RDOC_DESCEST, msg);
nac_row.put(RDOC_DESCEST, msg_date);
nac_row.put(RDOC_DESCLUNGA, "X");
//importi, qta, umqta
@ -610,15 +647,7 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
//panegirico della descrizione
nac_row.put(RDOC_DESCR, descr_riga_spp);
TString msg;
const TDate adata = mask.get_date(F_ADATA);
TDate dadata = mask.get_date(F_DADATA);
if (!dadata.ok())
check_date(adata, dadata);
msg << " " << dadata << " -- " << adata;
nac_row.put(RDOC_DESCEST, msg);
nac_row.put(RDOC_DESCEST, msg_date);
nac_row.put(RDOC_DESCLUNGA, "X");
//importi, qta
@ -640,9 +669,9 @@ bool THardy_elab_docs::genera_nac(const TMask& mask, TArray& contratti_cliente,
// viene scritta comunque, con provv='D' se elaborazione definitiva
int err = nac.write();
TString wrk_msg;
if (err == NOERR)
{
TString wrk_msg;
wrk_msg.format(" -- Generata NAC: %-4s%-4s%c %7ld", (const char*)nac_codnum, (const char*)nac_tipo, provv, nac.get_long(DOC_NDOC));
log_msg << wrk_msg;
}
@ -715,10 +744,9 @@ void THardy_elab_docs::elabora_documenti(const TMask& mask, TISAM_recordset& fat
if (codcf != old_codcf)
{
//generazione NAC del cliente precedente (una per contratto cliente)
if (old_codcf > 0)
if (old_codcf > 0 && !documenti_cliente.empty())
genera_nac(mask, contratti_cliente, documenti_cliente, log);
CHECK(codcf > old_codcf, "Ordinamento clienti errato!");
//aggiorna old_codcf in modo da poter controllare i contratti solo al cambio codcf
old_codcf = codcf;
@ -730,17 +758,19 @@ void THardy_elab_docs::elabora_documenti(const TMask& mask, TISAM_recordset& fat
if (n_contratti == 0)
{
TString msg;
msg << "Il cliente " << codcf << " non ha un contratto premi valido nel periodo di elaborazione selezionato ma ha fatture.";
msg << "Il cliente " << codcf << " non ha un contratto valido nel periodo selezionato pur avendo fatture.";
log.log_error(msg);
}
}
if (contratti_cliente.items() > 0)
{
const TDate data_fine = mask.get(F_ADATA);
//se ha trovato uno o più contratti validi nel periodo passa alla elaborazione dei documenti del cliente
TDocumento* curr_doc = new TDocumento(fatture.cursor()->curr());
//elabora il documento corrente aggiornando le somme restituite sui contratti validi
if (elabora_contratti(*curr_doc, contratti_cliente, log))
if (elabora_contratti(*curr_doc, contratti_cliente, data_fine, log))
documenti_cliente.add(curr_doc);
else
delete(curr_doc);
@ -748,15 +778,15 @@ void THardy_elab_docs::elabora_documenti(const TMask& mask, TISAM_recordset& fat
} //for (bool ok = recset.move_first()...
//generazione NAC dell'ultimo cliente (una per contratto cliente)
genera_nac(mask, contratti_cliente, documenti_cliente, log);
if (!documenti_cliente.empty())
genera_nac(mask, contratti_cliente, documenti_cliente, log);
//se elaborazione definitiva -> cambia lo stato ai documenti di vendita elaborati, mettendolo uguale..
//..a quello deciso in configurazione
const bool definitivo = mask.get_bool(F_DEFINITIVO);
if (definitivo)
{
TConfig config(CONFIG_DITTA, "ha");
const TString& stato_finale = config.get("StatoFinFatt");
const TString4 stato_finale = ini_get_string(CONFIG_DITTA, "ha", "StatoFinFatt");
FOR_EACH_ARRAY_ITEM(documenti_cliente, r, riga)
{
TDocumento& fattura = *(TDocumento*)riga;
@ -764,11 +794,8 @@ void THardy_elab_docs::elabora_documenti(const TMask& mask, TISAM_recordset& fat
fattura.rewrite();
}
}
}
//metodo di alto livello con i punti principali del programma (come da analisi...)
void THardy_elab_docs::elabora(const TMask& mask)
{
@ -779,7 +806,6 @@ void THardy_elab_docs::elabora(const TMask& mask)
//log report con segnalazioni sui clienti trattati (bene o male)
TLog_report log("Sintesi elaborazione");
log.kill_duplicates();
log.log(0, "");
//2) recordset ordinato codag-codcf-numdoc con tutti i docs che soddisfano i parametri dell'utente
@ -787,9 +813,7 @@ void THardy_elab_docs::elabora(const TMask& mask)
TISAM_recordset recset("");
const long items = genera_recordset(mask, recset);
if (items == 0)
{
log.log(1, "Non esistono documenti di vendita che soddisfino i parametri selezionati!");
}
log.log(1, TR("Non esistono documenti di vendita che soddisfino i parametri selezionati!"));
//3) elaborazione documenti e contratti, generazione NAC, salvataggi
// ---------------------------------------------------------------

View File

@ -32,6 +32,26 @@ char TContratto_premi::tipo_contratto() const
return 'P';
}
char TContratto_premi::frequenza() const
{
char f = get_char(DOC_CATVEN);
if (f < 'A') f = 'A';
return f;
}
bool TContratto_premi::data_valida(const TDate& datadoc) const
{
const TDate i = data_inizio();
if (i.ok() && datadoc < i)
return false;
const TDate f = data_fine();
if (f.ok() && datadoc > f)
return false;
return true;
}
long TContratto_premi::codcf_fatt() const
{
long cod = get_long(DOC_DOC2);

View File

@ -27,12 +27,17 @@
class TContratto_premi : public TDocumento
{
static TString4 _tipo_ant, _tipo_post, _tipo_rifa;
static TString4 _tipo_ant, _tipo_post, _tipo_rifa;
public:
char tipo_contratto() const;
char frequenza() const;
long codcf_fatt() const;
TDate data_inizio() const { return get_date(DOC_DATACOMP); }
TDate data_fine() const { return get_date(DOC_DATAFCOMP); }
bool data_valida(const TDate& datadoc) const;
TContratto_premi(char provv, int anno, const char* codnum, long ndoc);
TContratto_premi(const TRectype& rec_doc);
};