diff --git a/ha/ha0200a.uml b/ha/ha0200a.uml index 766788ff6..4efb4fd22 100755 --- a/ha/ha0200a.uml +++ b/ha/ha0200a.uml @@ -533,42 +533,42 @@ END STRING F_E_PIVA_HARDY 12 BEGIN - PROMPT 2 4 "Partita IVA Hardy " + PROMPT 2 4 "Partita IVA Hardy " HELP "Partita IVA Hardy" FIELD Esselunga_PIvaHardy END STRING F_E_PIVA_ESSELUNGA 12 BEGIN - PROMPT 2 5 "Partita IVA Esselunga " + PROMPT 2 5 "Partita IVA Esselunga " HELP "Partita IVA Esselunga" FIELD Esselunga_PIvaEsselunga END NUMBER F_E_COD_HARDY 6 BEGIN - PROMPT 2 6 "Cod. fornitore " + PROMPT 2 6 "Cod. fornitore Hardy " HELP "Codice fornitore Hardy presso Esselunga" FIELD Esselunga_CodHardy END NUMBER F_E_COD_ESSELUNGA 6 BEGIN - PROMPT 2 6 "Cod. cliente " - HELP "Codice cliente Esselunga" + PROMPT 2 7 "Cod. cliente Esselunga " + HELP "Codice cliente Esselunga presso Hardy" FIELD Esselunga_CodEsselunga END STRING F_E_TIPOEMISSIONE 2 BEGIN - PROMPT 2 7 "Tipo Emissione" + PROMPT 2 8 "Tipo Emissione " HELP "Tipo emissione" FIELD Esselunga_TipoEmissione END DATE F_E_DATACONF BEGIN - PROMPT 2 8 "Data di configurazione " + PROMPT 2 9 "Data di configurazione " HELP "Data di configurazione " FIELD Esselunga_DatConf END diff --git a/ha/ha2.cpp b/ha/ha2.cpp new file mode 100755 index 000000000..86cca20cd --- /dev/null +++ b/ha/ha2.cpp @@ -0,0 +1,22 @@ +#include +#include + +#include "ha2.h" + +#define usage "Error - usage : %s -{0|1}" + +int main(int argc,char** argv) +{ + int rt = -1 ; + const int r = (argc > 1) ? atoi(&argv[1][1]) : -1; + + switch (r) + { + case 0: + rt = ha2100(argc, argv) ; break; //gestione file privat + break; + default: + error_box(usage, argv[0]) ; break; + } + return rt; +} diff --git a/ha/ha2.h b/ha/ha2.h new file mode 100755 index 000000000..1380a7edc --- /dev/null +++ b/ha/ha2.h @@ -0,0 +1 @@ +int ha2100(int argc, char* argv[]); diff --git a/ha/ha2100.cpp b/ha/ha2100.cpp new file mode 100755 index 000000000..91d36c056 --- /dev/null +++ b/ha/ha2100.cpp @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#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 è piena -> l'anno deve essere lo stesso nelle 2 date; + //se invece è 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 è 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ò non esistere + //contratti rifatturazione 'R': come contratti anticipo + + //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); + if (!data_ini_elab.ok()) + check_date(data_fine_elab, data_ini_elab); + + //quindi la datainizio vale per tutti allo stesso modo (è 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 è valida (ma è presente!) non dobbiamo fare nulla, perchè 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 è 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à 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à stato pareggiato! quindi il reso deve essere < dell'anticipato per procedere + + //la somma restituita deve essere incrementata per la qta di merce (caffè) che c'è sulla riga della fattura in esame... + //..moltiplicata per il premio che c'è 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; +} \ No newline at end of file diff --git a/ha/ha2100a.h b/ha/ha2100a.h new file mode 100755 index 000000000..027e1f63a --- /dev/null +++ b/ha/ha2100a.h @@ -0,0 +1,10 @@ +#define F_CODDITTA 201 +#define F_RAGSOC 202 +#define F_DATAINI 203 +#define F_DATAFIN 204 +#define F_DIPENDENZA 205 +#define F_DEFINITIVO 206 +#define F_SHEETDOC 207 +// campi dello sheet +#define F_S_CODNUM 101 +#define F_S_DESNUM 102 diff --git a/ha/ha2100a.uml b/ha/ha2100a.uml new file mode 100755 index 000000000..825aed417 --- /dev/null +++ b/ha/ha2100a.uml @@ -0,0 +1,134 @@ +#include "ha2100a.h" + +TOOLBAR "" 0 -5 0 4 + +STRING 30 70 50 + BEGIN + FLAGS "G" + PROMPT 10 -5 "Profilo " + PSELECT +END + +BUTTON DLG_OK 10 2 +BEGIN + PROMPT -12 -11 "" +END + +BUTTON DLG_QUIT 10 2 +BEGIN + PROMPT -22 -11 "" +END + +ENDPAGE + +PAGE "Procedura Esselunga Privat" -1 -1 78 18 + +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 0 "@bDitta" +END + +NUMBER F_CODDITTA 5 +BEGIN + PROMPT 2 1 "Codice " + FLAGS "GDF" + USE LF_NDITTE + INPUT CODDITTA F_CODDITTA + OUTPUT F_RAGSOC RAGSOC + CHECKTYPE REQUIRED +END + +STRING F_RAGSOC 50 +BEGIN + PROMPT 17 1 "Rag.Soc. " + FLAGS "D" +END + +GROUPBOX DLG_NULL 78 5 +BEGIN + PROMPT 1 3 "@bParametri" +END + +DATE F_DATAINI +BEGIN + PROMPT 2 4 "Documenti dal " + HELP "Data di inizio per trasferimento documenti" + CHECKTYPE REQUIRED + WARNING "Data dal non valida" + FLAGS "A" +END + +DATE F_DATAFIN +BEGIN + PROMPT 30 4 "al " + HELP "Data di fine per trasferimento documenti" + CHECKTYPE REQUIRED + VALIDATE DATE_CMP_FUNC >= F_DATAINI + WARNING "Data di fine scadenza non valida" +END + +LISTBOX F_DIPENDENZA 10 +BEGIN + PROMPT 2 5 "Dipendenza " + ITEM "D|Milano" + ITEM "U|Firenze" +END + +BOOLEAN F_DEFINITIVO +BEGIN + PROMPT 2 6 "Trasferimento definitivo" +END + +SPREADSHEET F_SHEETDOC 78 10 +BEGIN + PROMPT 1 8 "Scelta documenti" + ITEM "Cod. num." + ITEM "Descrizione num.@50" +END + +ENDPAGE +ENDMASK + +PAGE "Scelta documenti" -1 -1 75 10 + +STRING F_S_CODNUM 4 +BEGIN + PROMPT 2 1 "Cod. num. " + FLAGS "U" + USE %NUM + INPUT CODTAB F_S_CODNUM + DISPLAY "Cod. Num." CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_S_CODNUM CODTAB + OUTPUT F_S_DESNUM S0 + CHECKTYPE REQUIRED +END + +STRING F_S_DESNUM 50 +BEGIN + PROMPT 20 1 "" + HELP "Descrizione numerazione" + USE %NUM KEY 2 + INPUT S0 F_S_DESNUM + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice" CODTAB + COPY OUTPUT F_S_CODNUM +END + +BUTTON DLG_OK 9 2 +BEGIN + PROMPT -13 -1 "" +END + +BUTTON DLG_DELREC 9 2 +BEGIN + PROMPT -23 -1 "" +END + +BUTTON DLG_CANCEL 9 2 +BEGIN + PROMPT -33 -1 "" +END + +ENDPAGE +ENDMASK