campo-sirio/ha/ha2100.cpp

358 lines
12 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <recarray.h>
#include <recset.h>
#include <reputils.h>
#include <doc.h>
#include <rdoc.h>
#include "../cg/cglib01.h"
#include "../ve/velib.h"
#include "ha2.h"
#include "ha2100a.h"
const char* const APPNAME = TR("Procedura Esselunga: generazione file Privat");
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////
class THardy_esselunga_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
THardy_esselunga_mask();
virtual ~THardy_esselunga_mask() {};
};
THardy_esselunga_mask::THardy_esselunga_mask() : TAutomask ("ha2100a")
{
}
bool THardy_esselunga_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_DATAINI:
if (e == fe_close || e == fe_modify)
{
//se la data iniziale <20> piena -> l'anno deve essere lo stesso nelle 2 date;
//se invece <20> vuota -> la data iniziale viene presa come la data iniziale dell'esercizio della data finale...
//..ma questo qui non serve e viene rinviato alla query principale del recordset
const TDate datafin = get_date(F_DATAFIN);
TEsercizi_contabili esc;
const int datafin_esc = esc.date2esc(datafin);
TDate dataini = o.get();
if (dataini.ok())
{
const int dataini_esc = esc.date2esc(dataini);
if (datafin_esc != dataini_esc)
return error_box("Le date devono appartenere allo stesso esercizio!");
}
}
break;
default:
break;
}
return true;
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class THardy_esselunga : public TSkeleton_application
{
protected:
void elabora(const TMask& mask);
long genera_recordset(const TMask& mask, TISAM_recordset& recset);
void elabora_documenti(const TMask& mask, TISAM_recordset& recset, TLog_report& log);
void check_date(const TDate& datafine, TDate& dataini);
bool check_cliente(const long codcf);
public:
virtual void main_loop();
virtual bool create();
};
//metodo per ricavare la data iniziale di elaborazione qualora l'utonto non la metta e l'esercizio da usare
void THardy_esselunga::check_date(const TDate& datafine, TDate& dataini)
{
TEsercizi_contabili esc;
TDate datafine_tmp = datafine;
const int esercizio = esc.date2esc(datafine);
esc.code2range(esercizio, dataini, datafine_tmp);
}
//metodo che filtra tutti i documenti in base ai parametri della maschera
long THardy_esselunga::genera_recordset(const TMask& mask, TISAM_recordset& recset)
{
TString query;
query << "USE DOC ";
TString filt_expr;
// aggiungo alla query le condizioni sulle numerazioni selezionare da maschera
TSheet_field& sheet = mask.sfield(F_SHEETDOC);
const long items = sheet.items();
if (items > 0)
{
TString16 codnum;
filt_expr << " SELECT ";
FOR_EACH_SHEET_ROW(sheet, r, row)
{
codnum = row->get(0);
if (codnum.not_empty())
{
filt_expr << "(CODNUM==\"";
filt_expr << codnum << "\") OR";
}
}
filt_expr.rtrim(2);
query << filt_expr;
}
query << "\nFROM DATADOC=#DATAINI PROVV=D ANNO=#ANNO";
query << "\nTO DATADOC=#DATAFIN PROVV=D ANNO=#ANNO";
recset.set(query);
//settaggio delle variabili
const TDate datafin = mask.get_date(F_DATAFIN);
TDate dataini = mask.get_date(F_DATAINI);
//se la data iniziale <20> vuota deve coincidere con l'inizio dell'esercizio della data finale (obbligatoria!)
int esc = datafin.year();
if (!dataini.ok())
check_date(datafin, dataini);
recset.set_var("#ANNO", long(esc));
recset.set_var("#DATAINI", dataini);
recset.set_var("#DATAFIN", datafin);
return recset.items();
}
/*
//metodo che riempie un array con tutti i contratti del cliente passatogli (in base alla tipologia di contratti da elaborare)
int THardy_esselunga::find_contratti_cliente(const long codcf, const TMask& mask, TArray& contratti_cliente)
{
contratti_cliente.destroy();
//deve cercare tutti i contratti del cliente e metterli nell'array
TString query;
query << "USE DOC KEY 4";
query << "\nSELECT ((TIPODOC=#A_TIPODOC)||(TIPODOC=#R_TIPODOC)||(TIPODOC=#P_TIPODOC))";
query << "\nFROM TIPOCF=C CODCF=#CODCF";
query << "\nTO TIPOCF=C CODCF=#CODCF";
TISAM_recordset recset(query);
//settaggio delle variabili
//il codice numerazione lo trova nella configurazione Hardy, e lo deve scegliere in base alla tipologia di contratti che sta esaminando!
TConfig config(CONFIG_DITTA, "ha");
const TString& tip_ant = config.get("CoAntTip");
const TString& tip_rifa = config.get("CoRifaTip");
const TString& tip_post = config.get("CoPostTip");
recset.set_var("#A_TIPODOC", tip_ant);
recset.set_var("#R_TIPODOC", tip_rifa);
recset.set_var("#P_TIPODOC", tip_post);
recset.set_var("#CODCF", codcf);
const long n_contratti = recset.items(); //questo serve solo al sagace programmatore
//aggiunge i contratti all'array: solo quelli in auge nel periodo di calcolo selezionato sulla maschera!
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
//contratti anticipo 'A': datainizio esiste sempre, datafine non esiste (va ad esaurimento)
//contratti posticipo 'P': datainizio esiste sempre, datafine pu<70> non esistere
//contratti rifatturazione 'R': come contratti anticipo
//controlla validit<69> 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);
if (!data_ini_elab.ok())
check_date(data_fine_elab, data_ini_elab);
//quindi la datainizio vale per tutti allo stesso modo (<28> obbligatoria nei contratti)
//se l'elaborazione finisce prima che cominci il contratto -> il contratto non serve a nulla
if (data_ini_contratto > data_fine_elab)
continue;
//la data fine vale invece solo per i contratti 'P' e potrebbe non esserci (contratti senza scadenza)
TDate data_fine_contratto;
//se la data fine contratto non <20> valida (ma <20> presente!) non dobbiamo fare nulla, perch<63> il contratto non va elaborato
data_fine_contratto = recset.get(DOC_DATAFCOMP).as_date();
if (data_fine_contratto.ok())
{
if (data_fine_contratto < data_ini_elab)
continue;
}
//ci tocca istanziarci un contratto_premi
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)
{
if (rdoc->get(RDOC_TIPORIGA) == HARDY_TIPORIGA_SOMMA)
{
rdoc->zero(RCA_2_RESO_CORRENTE);
break;
}
}
}
contratti_cliente.add(curr_contratto);
}
return contratti_cliente.items();
}
bool THardy_esselunga::aggiorna_contratti(const TRiga_documento& rdoc, TContratto_premi& contratto)
{
bool elaborato = false;
const char tipo_contratto = contratto.tipo_contratto();
//parametri della riga fattura
TString80 rdoc_codart = rdoc.get(RDOC_CODART);
rdoc_codart.trim();
const real rdoc_qta = rdoc.get_real(RDOC_QTA);
const TString4 rdoc_umqta = rdoc.get(RDOC_UMQTA);
FOR_EACH_PHYSICAL_RDOC(contratto, rm, rigamerce)
{
const TString& rigamerce_codart = rigamerce->get(RDOC_CODART);
//se trova il codart in una delle righe di contratto...
if (rdoc_codart == rigamerce_codart)
{
const real rigamerce_premio = rigamerce->get_real(RC_1_PREMIO);
//se il premio non <20> nullo procede all'aggiornamento del restituito (solo contratti A/R e righe spese) e del bonus (tutti i contratti e righe merce)
if (rigamerce_premio != ZERO)
{
//normalizzazione della qta
const TString& umqta_tot = rigamerce->get(RDOC_UMQTA); //prende la UM dal contratto che far<61> da riferimento!
TArticolo articolo(rdoc_codart);
const real normalized_rdoc_qta = articolo.convert_to_um(rdoc_qta, umqta_tot, rdoc_umqta, true);
//aggiornamento delle righe di tipo spesa (verigh02) per aggiornare le somme restituite nel caso di contratti di anticipo/rifatturazione
if (tipo_contratto == 'A' || tipo_contratto == 'R')
{
FOR_EACH_PHYSICAL_RDOC(contratto, ra, rigacontratto)
{
//cerca una riga anticipo da evadere sul contratto per aggiornare la somma restituita sull'anticipo
if (rigacontratto->is_spese())
{
//si informa su quale fosse la somma anticipata
const real somma_anticipata = rigacontratto->get_real(RCA_2_ANTICIPATO);
//aggiorna la somma restituita dovuta al contratto (parte da zero per ogni elaborazione di NAC)
real somma_restituita = rigacontratto->get_real(RCA_2_RESO_CORRENTE);
//controlla che il contratto non sia per caso gi<67> stato pareggiato! quindi il reso deve essere < dell'anticipato per procedere
//la somma restituita deve essere incrementata per la qta di merce (caff<66>) che c'<27> sulla riga della fattura in esame...
//..moltiplicata per il premio che c'<27> nella riga di tipo merce del contratto in esame
somma_restituita += normalized_rdoc_qta * rigamerce_premio;
rigacontratto->put(RCA_2_RESO_CORRENTE, somma_restituita);
elaborato = true;
break;
}
} //FOR_EACH_PHYSICAL.. fine casino sulla riga di tipo spese
} //if(tipo_contratto == "A"...
//questo va bene invece per ogni riga merce (verigh01), sia per contratti di tipo A/R che di tipo P
if (rigamerce->is_merce())
{
real somma_bonus = rigamerce->get_real(RC_1_BONUS);
somma_bonus += normalized_rdoc_qta * rigamerce_premio;
rigamerce->put(RC_1_BONUS, somma_bonus);
rigamerce->add(RDOC_QTA, normalized_rdoc_qta); //riscrive sul campo di appoggio del contratto
elaborato = true;
}
} //if(rigamerce_premio != ZERO...
} //if(rdoc_codart...
} //FOR_EACH_PHYSICAL..
return elaborato;
}
*/
void THardy_esselunga::elabora_documenti(const TMask& mask, TISAM_recordset& recset, TLog_report& log)
{
TProgind pi(recset.items(), TR("Elaborazione documenti in corso..."), true, true);
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
if (!pi.addstatus(1))
break;
const long codcf = recset.get(DOC_CODCF).as_int();
// verificare se il cliente appartiene alla dipendenza selezionata e se ha tutti i parametri per poter essere inviato
if (check_cliente(codcf))
{
TDocumento* doc = new TDocumento(recset.cursor()->curr());
// passo tutte le righe del documento all'AS400recordset
FOR_EACH_PHYSICAL_RDOC(*doc, r, rigadoc)
{
} //FOR_EACH...
delete doc;
} // if check_cliente...
} //for (bool ok = recset.move_first()...
//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)
{
}
}
bool THardy_esselunga::check_cliente(const long codcf)
{
return true;
}
void THardy_esselunga::elabora(const TMask& mask)
{
TLog_report log(APPNAME);
log.kill_duplicates();
log.log(0, "");
TISAM_recordset recset("");
const long items = genera_recordset(mask, recset);
if (items == 0)
log.log(1, "Non esistono documenti che soddisfano i parametri selezionati.");
elabora_documenti(mask, recset, log);
log.print_or_preview();
}
void THardy_esselunga::main_loop()
{
THardy_esselunga_mask mask;
while (mask.run() == K_ENTER)
elabora(mask);
}
bool THardy_esselunga::create()
{
open_files(LF_DOC, LF_RIGHEDOC, 0);
return TSkeleton_application::create();
}
int ha2100 (int argc, char* argv[])
{
THardy_esselunga elabapp;
elabapp.run(argc, argv, APPNAME);
return 0;
}