campo-sirio/ha/ha1300.cpp
luca d4fe079489 Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
hardate varie


git-svn-id: svn://10.65.10.50/branches/R_10_00@21504 c028cbd2-c16b-5b4b-a496-9718f37d4682
2011-01-24 15:39:37 +00:00

619 lines
21 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <reputils.h>
#include "halib.h"
#include "ha1300a.h"
#define UPLOAD_FILE "upload.d"
//funzione di ordinamento del file di upload una volta caricato in memoria
int ordina_upload(const TObject** o1, const TObject** o2)
{
const TString& s1 = *(TString*)*o1;
const TString& s2 = *(TString*)*o2;
if (s1[1] == 'F' && s2[1] == 'F')
{
TToken_string k[2];
for (int i = 0; i < 2; i++)
{
const TString& rec = i == 0 ? s1 : s2;
TToken_string& key = k[i];
if (rec[0] == 'T')
{
key.add(rec.mid(14,2)); //anno
key.add(rec.mid(16,1)); //tipodoc
key.add(rec.mid(5,5)); //numdoc
}
else
{
key.add(rec.mid(14,2)); //anno
key.add(rec.mid(28,1)); //tipodoc
key.add(rec.mid(5,5)); //numdoc
key.add(rec.mid(29,5)); //codart
}
}
return k[0].compare(k[1]);
}
else
{
if (s1[1] == 'F')
return +1;
if (s2[1] == 'F')
return -1;
}
return s1.compare(s2);
}
//------------------------------------------------------------
// Hardy_upload_recordset: serve per l'INPUT
//------------------------------------------------------------
class THardy_upload_recordset : public THardy_recordset
{
protected:
virtual TRecnotype new_rec(const char* trc);
public:
THardy_upload_recordset(const TFilename& filename);
};
/////////////////////////////////////////////////////////////
// Recordset specifici per i dati da trasferire INPUT
/////////////////////////////////////////////////////////////
TRecnotype THardy_upload_recordset::new_rec(const char* trc)
{
if (trc && *trc > ' ')
{
TString rec; rec << trc << "\r\n";
return TText_recordset::new_rec(rec);
}
return -1;
}
//questo invece è il metodo magico che vale per il caricamento da file esterno
THardy_upload_recordset::THardy_upload_recordset(const TFilename& filename)
: THardy_recordset(256)
{
TFilename cazzone;
//as400 con lunghezza 256 e chiave lunga 2 (a partire dall'inizio): è il tipo record
parse_query("AS400(256,2)", cazzone);
//Tipo record SU
//--------------
add_trc_field("SU", "TipoRecord", T_X, 1, 2); //x
add_trc_field("SU", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("SU", AGE_CODAGE, T_N, 6, 3); //x
add_trc_field("SU", "NonUsato", T_X, 9, 6);
add_trc_field("SU", "Targa", T_X, 15, 8);
add_trc_field("SU", "nDDT", T_N, 23, 5);
add_trc_field("SU", "nFATT", T_N, 28, 5);
add_trc_field("SU", "nBOLLA", T_N, 33, 5);
add_trc_field("SU", AGE_RAGSOC, T_X, 38, 30); //x
//Tipo record TF
//--------------
add_trc_field("TF", "TipoRecord", T_X, 1, 2); //x
add_trc_field("TF", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("TF", DOC_NDOC, T_N, 6, 5); //x
add_trc_field("TF", DOC_DATADOC, T_X, 11, 6); //x
add_trc_field("TF", DOC_TIPODOC, T_X, 17, 1); //x
add_trc_field("TF", DOC_CODCF, T_X, 18, 6); //x
add_trc_field("TF", DOC_CODCFFATT, T_X, 24, 6); //x
add_trc_field("TF", "ImponibileLordo", T_Nv2N, 30, 8); // campi seguenti da righe doc
add_trc_field("TF", "ScontoFattura", T_2Nv2N,38, 4);
add_trc_field("TF", "ImponibileDoc", T_Nv2N, 42, 8);
add_trc_field("TF", "TotaleDoc", T_Nv2N, 50, 8);
add_trc_field("TF", "ScontoTotale", T_Nv2N, 58, 8);
add_trc_field("TF", "ImponibileOmaggi", T_Nv2N, 66, 8);
add_trc_field("TF", "ImponibileSost", T_Nv2N, 74, 8);
add_trc_field("TF", "Incasso", T_Nv2N, 82, 8); //forse IMPPAGATO ?
add_trc_field("TF", DOC_CODPAG, T_X, 90, 2); //x
add_trc_field("TF", DOC_DATAPART, T_X, 92, 6); //x
add_trc_field("TF", "Iva1", T_N, 98, 2); //anche questi da righe doc
add_trc_field("TF", "Imponibile1", T_Nv2N, 100,8);
add_trc_field("TF", "Imposta1", T_Nv2N, 108,7);
add_trc_field("TF", "Iva2", T_N, 115,2);
add_trc_field("TF", "Imponibile2", T_Nv2N, 117,8);
add_trc_field("TF", "Imposta2", T_Nv2N, 125,7);
add_trc_field("TF", "Iva3", T_N, 132,2);
add_trc_field("TF", "Imponibile3", T_Nv2N, 134,8);
add_trc_field("TF", "Imposta3", T_Nv2N, 142,7);
add_trc_field("TF", "Iva4", T_N, 149,2);
add_trc_field("TF", "Imponibile4", T_Nv2N, 151,8);
add_trc_field("TF", "Imposta4", T_Nv2N, 159,7);
add_trc_field("TF", "CodcliGiro3", T_X, 166,6);
add_trc_field("TF", "IvaOmag1", T_N, 172,2);
add_trc_field("TF", "ImponibileOmag1", T_Nv2N, 174,6);
add_trc_field("TF", "ImpostaOmag1", T_Nv2N, 180,5);
add_trc_field("TF", "IvaOmag2", T_N, 185,2);
add_trc_field("TF", "ImponibileOmag2", T_Nv2N, 187,6);
add_trc_field("TF", "ImpostaOmag2", T_Nv2N, 193,5);
add_trc_field("TF", "DataEmissione", T_X, 198,6);
add_trc_field("TF", "PagamentoCarta", T_X, 204,1);
//Tipo record RF
//--------------
add_trc_field("RF", "TipoRecord", T_X, 1, 2); //x
add_trc_field("RF", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("RF", RDOC_NDOC, T_N, 6, 5); //x
add_trc_field("RF", DOC_DATADOC, T_X, 11, 6); //x testata
add_trc_field("RF", DOC_CODCF, T_X, 17, 6); //x testata
add_trc_field("RF", DOC_CODCFFATT, T_X, 23, 6); //x testata
add_trc_field("RF", DOC_TIPODOC, T_X, 29, 1); //x testata
add_trc_field("RF", RDOC_CODART, T_X, 30, 5); //x
add_trc_field("RF", "TipoCessione", T_X, 35, 1);
add_trc_field("RF", "Qta[int]", T_N, 36, 5); //x
add_trc_field("RF", "Qta[dec]", T_N, 41, 2); //x
add_trc_field("RF", "Sconto1", T_2Nv2N,43, 4);
add_trc_field("RF", "Sconto2", T_2Nv2N,47, 4);
add_trc_field("RF", "Sconto3", T_2Nv2N,51, 4);
add_trc_field("RF", "ScontoLibero", T_2Nv2N,55, 4);
add_trc_field("RF", RDOC_PREZZO, T_Nv3N, 59, 7); //x forse PREZZOL ?
add_trc_field("RF", "TotaleRiga", T_Nv3N, 66, 8);
add_trc_field("RF", "TotaleSconto", T_Nv3N, 74, 8);
add_trc_field("RF", "AliquotaIva", T_N, 82, 2); //noi abbiamo il codice
add_trc_field("RF", RDOC_UMQTA, T_X, 84, 2); //x
add_trc_field("RF", "PrezzoScontato", T_Nv3N, 86, 7);
add_trc_field("RF", "Fascia", T_X, 93, 1);
add_trc_field("RF", "ScontoFascia", T_2N, 94, 2);
add_trc_field("RF", "NonUsato", T_N, 96, 2);
add_trc_field("RF", "CodcliGiro3", T_X, 98, 6);
add_trc_field("RF", "CodiceLotto", T_X, 104,10); //noi lo leghiamo all'articolo
//Tipo record SI
//--------------
add_trc_field("SI", "TipoRecord", T_X, 1, 2); //x
add_trc_field("SI", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("SI", "CodiceCliente", T_X, 6, 6);
add_trc_field("SI", "NumeroFattura", T_X, 12, 12);
add_trc_field("SI", "DataFattura", T_X, 24, 6);
add_trc_field("SI", "NonUsato", T_N, 30, 9);
add_trc_field("SI", "ImportoIncassato", T_Nv2N, 39, 9);
add_trc_field("SI", "DataIncasso", T_X, 48, 6);
add_trc_field("SI", "Partita", T_X, 54, 15);
add_trc_field("SI", "TipoDocumento", T_X, 69, 1);
add_trc_field("SI", "DataEmissione", T_X, 70, 6);
add_trc_field("SI", "PagamentoCarta", T_X, 76, 1);
//Tipo record BR
//--------------
add_trc_field("BR", "TipoRecord", T_X, 1, 2); //x
add_trc_field("BR", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("BR", "NumeroRiga", T_N, 6, 3);
add_trc_field("BR", "NumeroDoc", T_N, 9, 5);
add_trc_field("BR", "DataMov", T_X, 14, 6);
add_trc_field("BR", "CodiceArticolo", T_X, 20, 5);
add_trc_field("BR", "Qta[int]", T_N, 25, 5);
add_trc_field("BR", "Qta[dec]", T_N, 30, 2);
add_trc_field("BR", "Mittente", T_N, 32, 3);
add_trc_field("BR", "Destinatario", T_N, 35, 3);
add_trc_field("BR", "CausaleMov", T_N, 38, 2);
add_trc_field("BR", "CodiceLotto", T_X, 40, 10);
//Tipo record VC
//--------------
add_trc_field("VC", "TipoRecord", T_X, 1, 2); //x
add_trc_field("VC", "CodiceTerminale", T_N, 3, 3); //x
add_trc_field("VC", CLI_CODCF, T_X, 6, 6); //x
add_trc_field("VC", CLI_RAGSOC, T_X, 12, 34); //x
add_trc_field("VC", CLI_INDCF, T_X, 46, 34); //x
add_trc_field("VC", "Localita", T_X, 80, 20); //x attenzione che potrebbe essere il com_dencom
add_trc_field("VC", CLI_CAPCF, T_X, 100, 5); //x
add_trc_field("VC", "Provincia", T_X, 105, 2); //x da questo e da dencom ricaviamo il codcom
add_trc_field("VC", CLI_PAIV, T_X, 107, 16); //x
add_trc_field("VC", CLI_CODPAG, T_X, 123, 1); //x
add_trc_field("VC", "CodiceListino", T_X, 124, 3);
add_trc_field("VC", "TipoDocumento", T_X, 127, 1);
add_trc_field("VC", CLI_COFI, T_X, 128, 16); //x
TText_recordset::load_file(filename);
}
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////
class TUpload2Campo_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TUpload2Campo_mask();
};
bool TUpload2Campo_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
return true;
}
TUpload2Campo_mask::TUpload2Campo_mask() : TAutomask ("ha1300a")
{
TConfig config(CONFIG_DITTA, "ha");
const TString& path = config.get("InputPath");
set(F_PATH, path);
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TUpload2Campo : public TSkeleton_application
{
TFilename _intput_dir;
bool _can_write;
protected:
void elabora_SU(THardy_upload_recordset& recset, TLog_report& log);
void elabora_BR(THardy_upload_recordset& recset, TLog_report& log);
void elabora_VC(THardy_upload_recordset& recset, TLog_report& log);
void elabora_TF(THardy_upload_recordset& recset, TLog_report& log);
void elabora_SI(THardy_upload_recordset& recset, TLog_report& log);
void elabora(const TMask& mask);
public:
virtual void main_loop();
virtual bool create();
};
void TUpload2Campo::elabora_SU(THardy_upload_recordset& recset, TLog_report& log)
{
const TString& cod_term = recset.get("CodiceTerminale").as_string();
const TString& cod_age = recset.get(AGE_CODAGE).as_string();
const TString& descr_age = recset.get(AGE_RAGSOC).as_string();
TString msg;
msg << "Scartati dati agente " << cod_term << " " << descr_age;
log.log(0, msg);
}
void TUpload2Campo::elabora_BR(THardy_upload_recordset& recset, TLog_report& log)
{
const TString& cod_term = recset.get("CodiceTerminale").as_string();
const long ndoc = recset.get("NumeroDoc").as_int();
TString msg;
msg << "Scartato movimento magazzino. Terminale: " << cod_term << " N.Doc: " << ndoc;
log.log(0, msg);
}
void TUpload2Campo::elabora_VC(THardy_upload_recordset& recset, TLog_report& log)
{
const TString& cod_term = recset.get("CodiceTerminale").as_string();
const TString& codcf = recset.get(CLI_CODCF).as_string();
const TString& ragsoc = recset.get(CLI_RAGSOC).as_string();
TString msg;
msg << "Scartato nuovo cliente. Terminale: " << cod_term << " CodCli: " << codcf << " Ragsoc: " << ragsoc;
log.log(0, msg);
}
void TUpload2Campo::elabora_SI(THardy_upload_recordset& recset, TLog_report& log)
{
}
void TUpload2Campo::elabora_TF(THardy_upload_recordset& recset, TLog_report& log)
{
//1) codice terminale (lungo 3) e codice agente (lungo 5)
TString4 codice_terminale = recset.get("CodiceTerminale").as_string();
codice_terminale.right_just(3, '0');
TString8 codice_agente = codice_terminale;
codice_agente.right_just(5, '0');
const TString& codage = cache().get(LF_AGENTI, codice_agente, AGE_CODAGE);
if (codage != codice_agente)
{
_can_write = false;
TString msg;
msg << "Codice agente " << codice_agente << " da terminale: sconosciuto";
log.log(2, msg);
}
//2) Testata documento
//genera una simpatico documento di cui raccatta la chiave
const TString& str_datadoc = recset.get(DOC_DATADOC).as_string();
int anno = 2000 + atoi(str_datadoc.right(2));
const int mese = atoi(str_datadoc.mid(2,2));
const int giorno = atoi(str_datadoc.left(2));
const char rec_tipodoc = recset.get(DOC_TIPODOC).as_string()[0];
//2a) tipo documento
TString4 tipodoc;
TConfig hardy(CONFIG_DITTA, "ha");
switch (rec_tipodoc)
{
case 'F': tipodoc = hardy.get("InpFatTip"); break;
case 'B': tipodoc = hardy.get("InpBolTip"); break;
case 'V': tipodoc = hardy.get("InpValTip"); break;
case 'O': tipodoc = hardy.get("InpOrdTip"); break;
default:
{
_can_write = false;
TString msg;
msg << "Tipo documento in input " << rec_tipodoc << " sconosciuto";
log.log(2, msg);
}
break;
}
//2b) numerazione documento
//il codnum dipende dal tipo documento del terminale (F,B,O...) e dal codice del terminale
TString4 codnum;
codnum << rec_tipodoc << codice_terminale;
const TString& numerazione = cache().get("%NUM", codnum, "CODTAB");
if (numerazione != codnum)
{
_can_write = false;
TString msg;
msg << "Codice numerazione " << codnum << " sconosciuto";
log.log(2, msg);
}
const long ndoc = recset.get(DOC_NDOC).as_int();
TDocumento doc('D', anno, codnum, ndoc);
doc.put(DOC_TIPODOC, tipodoc);
TDate datadoc(giorno, mese, anno);
doc.put(DOC_DATADOC, datadoc);
doc.put(DOC_TIPOCF, "C");
//2c) cliente
const long codcf = recset.get(DOC_CODCF).as_int();
TToken_string key_clifo;
key_clifo.add("C");
key_clifo.add(codcf);
const long cliente = atol(cache().get(LF_CLIFO, key_clifo, CLI_CODCF));
if (cliente != codcf)
{
_can_write = false;
TString msg;
msg << "Codice cliente " << codcf << " sconosciuto";
log.log(2, msg);
}
doc.put(DOC_CODCF, codcf);
doc.put(DOC_CODCFFATT, recset.get(DOC_CODCFFATT).as_int());
//sconto in fattura, sconto totale, incasso ecc.... che cazzo sono?
//TString8 scontone = recset.get();
doc.put(DOC_CODPAG, recset.get(DOC_CODPAG).as_string());
//data spedizione...datapart o datacons? (solo per ordini)
//al simpatico documento appiccia tutte le righe RF che seguono il record TF..
//..dopo il magico ordinamento iniziale del recordset
//intanto azzera le righe eventualmente già presenti (riscrittura)
doc.destroy_rows();
//3) righe documento
//scansione delle righe documento su record RF
while (recset.move_next())
{
if (recset.get("TipoRecord").as_string() != "RF") //quando non trova un RF significa che le righe della testata sono finite!
{
recset.move_prev(); //allora torna indietro di un record per riposizionarsi sull'ultimo non letto
break;
}
//agginunge una nuova riga (solo merce, per quanto ne sappiamo)
TRiga_documento& rigadoc = doc.new_row("01");
//serie delle put sulla riga documento; ricordiamo che la chiave della riga viene riempita dalla new_row
//3a) articolo
TString8 codart = recset.get(RDOC_CODART).as_string();
codart.trim();
const TRectype& rec_anamag = cache().get(LF_ANAMAG, codart);
const TString& articolo = rec_anamag.get(ANAMAG_CODART);
if (articolo != codart)
{
_can_write = false;
TString msg;
msg << "Codice articolo " << codart << " sconosciuto";
log.log(2, msg);
}
rigadoc.put(RDOC_CODART, codart);
rigadoc.put(RDOC_CODARTMAG, codart);
rigadoc.put(RDOC_CHECKED, "X");
rigadoc.put(RDOC_DESCR, rec_anamag.get(ANAMAG_DESCR));
//3b) umart
const TString& umqta = recset.get(RDOC_UMQTA).as_string();
TLocalisamfile file_umart(LF_UMART);
file_umart.setkey(2);
file_umart.put(UMART_CODART, codart);
file_umart.put(UMART_UM, umqta);
const int err_umart = file_umart.read();
if (err_umart != NOERR)
{
_can_write = false;
TString msg;
msg << "U.m. " << umqta << " dell'articolo " << codart << " sconosciuta";
log.log(2, msg);
}
rigadoc.put(RDOC_UMQTA, umqta);
real qta = recset.get("Qta[int]").as_real();
qta += recset.get("Qta[dec]").as_real() / CENTO;
rigadoc.put(RDOC_QTA, qta);
//panegirico sugli sconti
TString str_sconto;
real sconto[4];
sconto[0] = recset.get("Sconto1").as_real();
sconto[1] = recset.get("Sconto2").as_real();
sconto[2] = recset.get("Sconto3").as_real();
sconto[3] = recset.get("ScontoLibero").as_real();
for (int s = 0; s < 4; s++)
{
if (!sconto[s].is_zero())
str_sconto << (sconto[s] / CENTO) << '+';
}
str_sconto.rtrim(1);
rigadoc.put(RDOC_SCONTO, str_sconto);
real prezzo_lordo = recset.get(RDOC_PREZZO).as_real();
prezzo_lordo /= 1000;
rigadoc.put(RDOC_PREZZO, prezzo_lordo);
//3x) iva
const int aliquota_iva = recset.get("AliquotaIva").as_int();
TString4 codiva;
//il codice lo si trova nella configurazione del modulo Ha (c'è un magico sheet apposito)
TConfig config(CONFIG_DITTA, "ha");
TString curr_name;
for (int j = 0; ; j++)
{
const real curr_aliq_iva = config.get("IVAaliquota", NULL, j);
if (curr_aliq_iva == ZERO)
break;
if (curr_aliq_iva.integer() == aliquota_iva)
{
codiva = config.get("IVAcodice", NULL, j);
break;
}
}
rigadoc.put(RDOC_CODIVA, codiva);
rigadoc.put(RDOC_LIVELLO, recset.get("CodiceLotto").as_string());
}
//incredibilmente arriva in fondo
TString msg;
msg << anno << "-" << codnum << "-" << ndoc << " Terminale: " << codice_terminale << " Cliente: " << codcf;
//se può scrivere...
if (_can_write)
{
int err = doc.write();
if (err == NOERR)
{
msg.insert("Registrato documento: ", 0);
log.log(0, msg);
}
else
{
msg.insert("Impossibile registrare documento: ", 0);
log.log(2, msg);
}
}
else //..sennò avverte e basta
{
msg.insert("Controllato documento: ", 0);
log.log(0, msg);
}
log.log(0, "");
}
void TUpload2Campo::elabora(const TMask& mask)
{
TToken_string tipi_record("SU|TF|RF|SI|BR|VC");
//creazione del filename del file da importare
TFilename src_file = mask.get(F_PATH);
src_file.add(UPLOAD_FILE);
THardy_upload_recordset recset(src_file);
const long items = recset.items();
//ordinamento del file in memoria; sotto ogni TF (testata) mette le sue righe (RF)...MAGIA!!!
recset.sort(ordina_upload);
#ifdef DBG
recset.save_as("c:/temp/hardy/cazzone.txt");
#endif
//creazione progind e log
TProgind pi(items, TR("Acquisizione dati in corso..."), true, true);
TLog_report log("Segnalazioni su acquisizione");
log.kill_duplicates();
log.log(0, "");
//parametro di controllo; solo se resta true fino alla fine il documento viene writato
//solo in caso di elaborazione definitiva può diventare true
_can_write = false;
if (mask.get_bool(F_DEFINITIVO))
_can_write = true;
//giro su tutti i record del terribile recordset per l'acquisizione dei dati
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
if (!pi.addstatus(1))
break;
//acquisizione tipo record da riga corrente del file di input
TString4 tipo_record = recset.rec_type();
tipo_record.trim();
const int pos = tipi_record.get_pos(tipo_record);
//trattazione dei vari tracciati record
switch (pos)
{
case 0: //tipo record: SU (SetUp...ovvero agente)
//elabora_SU(recset, log); //non serve a una cippa!
break;
case 1: //tipo record: TF (Testata Fattura)
elabora_TF(recset, log);
break;
case 2: //tipo record: RF (Riga Fattura)
//elabora_RF(recset, log); //non serve! lo fa l'elaborazione di testata
break;
case 3: //tipo record: SI (incasso documenti)
elabora_SI(recset, log);
break;
case 4: //tipo record: BR (movimenti magazzino)
//elabora_BR(recset, log); //non li importiamo perchè vengono eseguiti alla scrittura dei documenti importati su archivi
break;
case 5: //tipo record: VC (Variazioni Cliente)
//elabora_VC(recset, log); //non serve! gli agenti non possono immettere clienti da terminale!
break;
default: //se il tipo record non esiste nella lista dei tipi record si incazza e lo scrive!
{
TString msg;
msg << "Tipo record non riconosciuto '" << tipo_record << "' alla riga " << (recset.current_row() + 1);
log.log(2, msg);
}
break;
} //switch(pos)..
} //for (bool ok...
log.preview();
}
void TUpload2Campo::main_loop()
{
TUpload2Campo_mask mask;
_intput_dir = mask.get(F_PATH);
while (mask.run() == K_ENTER)
{
elabora(mask);
}
}
bool TUpload2Campo::create()
{
return TSkeleton_application::create();
}
int ha1300(int argc, char* argv[])
{
TUpload2Campo a;
a.run(argc, argv, "Importazione dati da file");
return 0;
}