campo-sirio/ve/ve1200.cpp
luca faf072a109 Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :calcolo del fido in corso d'opera


git-svn-id: svn://10.65.10.50/trunk@17600 c028cbd2-c16b-5b4b-a496-9718f37d4682
2008-11-12 11:25:59 +00:00

702 lines
20 KiB
C++
Executable File
Raw Blame History

#include <applicat.h>
#include <automask.h>
#include <form.h>
#include <printer.h>
#include <progind.h>
#include <recarray.h>
#include <tabutil.h>
#include "velib04.h"
#include "ve1200a.h"
#include <doc.h>
///////////////////////////////////////////////////////////
// TScoperto_msk
///////////////////////////////////////////////////////////
class TScoperto_msk : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
bool fill_sheet();
public:
TScoperto_msk();
};
bool TScoperto_msk::on_field_event(TOperable_field& f, TField_event e, long jolly)
{
switch (f.dlg())
{
case F_CONSORD:
if (e == fe_modify)
fill_sheet();
break;
case F_BOLLE:
if (e == se_query_add || e == se_query_del)
return FALSE;
if (e == fe_close)
{
TSheet_field& s = sfield(F_BOLLE);
FOR_EACH_SHEET_ROW(s, r, row)
{
if (*row->get(0) == 'X')
return TRUE;
}
return error_box("Selezionare almeno una numerazione");
}
break;
case 100:
if (e == fe_button)
{
TMask& m = f.mask(); // Sheet mask
m.set(F_SELECTED, m.get_bool(F_SELECTED) ? "" : "X");
if (!m.is_open())
sfield(F_BOLLE).force_update();
}
break;
default:
break;
}
return TRUE;
}
bool TScoperto_msk::fill_sheet()
{
TSheet_field& sheet = sfield(F_BOLLE);
sheet.destroy();
const TTipo_elaborazione tipo_elab_bolle = get_bool(F_CONSORD) ? _consegna_ordini : _fatturazione_bolle;
const TTipo_elaborazione tipo_elab_fatt = _contabilizzazione;
TWait_cursor hourglass;
TTable num("%NUM");
for (int err = num.first(); err == NOERR; err = num.next()) if (num.get_int("I1") == 1) // bolle
{
TToken_string tipi(50, ',');
const TCodice_numerazione codnum(num.curr());
for (int t = codnum.ntipi_doc()-1; t >= 0; t--)
{
const TString4 td = codnum.tipo_doc(t);
const TTipo_documento& tpd = cached_tipodoc(td);
TFilename prof; tpd.profile_name(prof);
TConfig ini(prof, "MAIN");
if (ini.get("TIPOCF") == "F")
tipi.add(td);
}
if (tipi.not_empty())
{
TTable eld("%ELD");
TToken_string fatture(50, ',');
TString8 stato_bolla, stato_fatt;
for (int err = eld.first(); err == NOERR; err = eld.next())
{
const TTipo_elaborazione te = (TTipo_elaborazione)eld.get_int("I0");
if (te == tipo_elab_bolle)
{
TElaborazione_esterna elab(eld.curr()); // Una vale l'altra :-)
TString8 ti;
for (int i = 0; ; i++)
{
ti = elab.tipo_iniziale(i); // Tipo iniziale
if (ti.empty())
break;
if (tipi.get_pos(ti) >= 0)
{
if (stato_bolla.empty())
stato_bolla << elab.stato_iniziale(i);
const TString8 codfatt = elab.codice_numerazione_finale();
if (fatture.get_pos(codfatt) < 0) // Non e' gi<67> presente in lista
{
const TRectype& numfatt = cache().get("%NUM", codfatt);
if (numfatt.get_int("I1") == 2) // Fattura vera!
fatture.add(codfatt);
}
}
}
}
if (te == tipo_elab_fatt && stato_fatt.empty())
{
TElaborazione_esterna elab(eld.curr()); // Una vale l'altra :-)
const TString8 codfatt = elab.codice_numerazione_finale();
bool is_fatt = fatture.get_pos(codfatt) >= 0;
if (!is_fatt)
{
const TRectype& numfatt = cache().get("%NUM", codfatt);
is_fatt = numfatt.get_int("I1") == 2;
}
if (is_fatt)
stato_fatt << elab.stato_finale_doc_iniziale();
}
}
if (fatture.not_empty())
{
TToken_string& row = sheet.row(-1);
row = " ";
row.add(codnum.codice());
row.add(codnum.descrizione());
row.add(tipi);
row.add(stato_bolla); // Stato bolle non fatturate
row.add(fatture);
row.add(stato_fatt); // Stato fatture contabilizzate
}
}
}
sheet.force_update();
return sheet.items() > 0;
}
TScoperto_msk::TScoperto_msk() : TAutomask("ve1200a")
{
if (!fill_sheet())
{
set(F_CONSORD, "X");
fill_sheet();
}
}
///////////////////////////////////////////////////////////
// TScoperto_form
///////////////////////////////////////////////////////////
class TScoperto_form : public TForm
{
TDate _data_rif;
bool _work_on_residual;
char _stato_bolle;
char _stato_fatture;
private:
static TScoperto_form* _curr_form;
static void header_handler(TPrinter& p);
protected:
virtual bool validate(TForm_item& f, TToken_string& msg);
const TRectype& head_of(const TRectype& row) const;
public:
void print_header();
int print_bolla(const TRectype& doc, TArray* fatt);
void print_total();
TScoperto_form(const TDate& dr, bool wor, char sb, char sf);
virtual ~TScoperto_form();
};
TScoperto_form* TScoperto_form::_curr_form = NULL;
bool TScoperto_form::validate(TForm_item& f, TToken_string& msg)
{
if (msg == "_CLIFO")
{
const TRectype& r = cursor()->curr(LF_DOC);
TToken_string key;
key.add(r.get(DOC_TIPOCF));
key.add(r.get(DOC_CODCF));
const TRectype& rec = cache().get(LF_CLIFO, key);
key = rec.get("RAGSOC");
if (key.len() > 30 && key[29] == ' ')
{
const TString nome = key.mid(30);
key.cut(30); key.rtrim();
key << ' ' << nome;
}
f.set(key);
return TRUE;
}
if (msg == "_DESCART")
{
const TRectype& r = cursor()->curr(LF_RIGHEDOC);
TToken_string key;
key.add(r.get(RDOC_CODARTMAG));
const TRectype& rec = cache().get(LF_ANAMAG, key);
f.set(rec.get("DESCR"));
return TRUE;
}
return TForm::validate(f, msg);
}
void TScoperto_form::print_header()
{
TPrint_section& head = section('H');
head.find_field(H_DATARIF).set(_data_rif.string());
set_header(1, FALSE);
set_header(1, TRUE);
}
const TRectype& TScoperto_form::head_of(const TRectype& row) const
{
TToken_string key;
key.add(row.get(RDOC_PROVV));
key.add(row.get(RDOC_ANNO));
key.add(row.get(RDOC_CODNUM));
key.add(row.get(RDOC_NDOC));
return cache().get(LF_DOC, key);
}
int TScoperto_form::print_bolla(const TRectype& dochead, TArray* fatt)
{
TDocumento& doc =(TDocumento& )cursor()->curr(LF_DOC);
doc.read(dochead);
TPrint_section& body = section('B', odd_page);
TString_array note;
bool testata_stampata = FALSE;
for (int r = 1; r <= doc.physical_rows(); r++)
{
TRiga_documento& riga = doc[r];
if (riga.is_merce())
{
real quant, valore;
TString16 docrif, datarif, codnum, ndoc, postilla;
if (_work_on_residual)
{
// Cerco le righe di fattura generate da questa riga di bolla
if (fatt != NULL)
{
real qtafatt; // Quantit<69> fatturata
int fatture = 0;
TToken_string key_bol, key_fat;
key_bol = riga.get(RDOC_PROVV);
key_bol.add(riga.get(RDOC_ANNO));
key_bol.add(riga.get(RDOC_CODNUM));
key_bol.add(riga.get(RDOC_NDOC));
key_bol.add(riga.get(RDOC_IDRIGA));
for (int r = fatt->last(); r >= 0; r--)
{
const TRectype& rfatt = (const TRectype&)(*fatt)[r];
const TRectype& fatt_head = head_of(rfatt);
const TDate data_fatt = fatt_head.get_date(DOC_DATADOC);
const char stato_fatt = fatt_head.get_char(DOC_STATO);
if (stato_fatt < _stato_fatture || data_fatt > _data_rif)
{
key_fat = rfatt.get(RDOC_DAPROVV);
key_fat.add(rfatt.get(RDOC_DAANNO));
key_fat.add(rfatt.get(RDOC_DACODNUM));
key_fat.add(rfatt.get(RDOC_DANDOC));
key_fat.add(rfatt.get(RDOC_DAIDRIGA));
if (key_fat == key_bol)
{
qtafatt += rfatt.get_real(RDOC_QTA);
fatture++;
if (docrif.empty())
{
docrif = fatt_head.get(DOC_NUMDOCRIF);
datarif = fatt_head.get(DOC_DATADOCRIF);
codnum = fatt_head.get(DOC_CODNUM);
ndoc = fatt_head.get(DOC_NDOC);
}
else
{
TToken_string n(50, ',');
n = fatt_head.get(DOC_NUMDOCRIF);
if (n != docrif) // Non annotare il documento principale!
{
TToken_string* nota = (TToken_string*)note.objptr(r);
if (nota == NULL)
{
nota = new TToken_string;
note.add(nota, r);
postilla.format("(%d)", note.items());
}
n.add(fatt_head.get(DOC_DATADOCRIF));
n.add(fatt_head.get(DOC_CODNUM));
n.add(fatt_head.get(DOC_NDOC));
if (nota->get_pos(n) < 0) // Non annotare due volte lo stesso documento!
nota->add(n);
}
}
}
}
}
if (!qtafatt.is_zero())
{
// Calcolo nuova quantita evasa sulla riga della bolla
// Se la riga <20> completamente evasa da una sola fattura devo azzerara la quantit<69> evasa
// altrimenti devo scalare da questa la quantit<69> specificata sulla fattura
real qtaevasa;
if (fatture > 1 || !riga.get_bool(RDOC_RIGAEVASA))
{
qtaevasa = riga.get_real(riga.field_qtaevasa());
qtaevasa -= qtafatt;
}
riga.put(riga.field_qtaevasa(), qtaevasa);
riga.put(RDOC_RIGAEVASA, ""); // La riga non pu<70> essere evasa completamente
}
}
quant = riga.qtaresidua();
valore = riga.valore(false, false, AUTO_DECIMALS);
}
else
{
if (fatt != NULL)
{
TToken_string key_bol, key_fat;
key_bol = riga.get(RDOC_PROVV);
key_bol.add(riga.get(RDOC_ANNO));
key_bol.add(riga.get(RDOC_CODNUM));
key_bol.add(riga.get(RDOC_NDOC));
key_bol.add(riga.get(RDOC_IDRIGA));
for (int r = fatt->last(); r >= 0; r--)
{
const TRectype& rfatt = (const TRectype&)(*fatt)[r];
const TRectype& fatt_head = head_of(rfatt);
const TDate data_fatt = fatt_head.get_date(DOC_DATADOC);
const char stato_fatt = fatt_head.get_char(DOC_STATO);
if (stato_fatt < _stato_fatture || data_fatt > _data_rif)
{
key_fat = rfatt.get(RDOC_DAPROVV);
key_fat.add(rfatt.get(RDOC_DAANNO));
key_fat.add(rfatt.get(RDOC_DACODNUM));
key_fat.add(rfatt.get(RDOC_DANDOC));
key_fat.add(rfatt.get(RDOC_DAIDRIGA));
if (key_fat == key_bol)
{
if (docrif.empty())
{
docrif = fatt_head.get(DOC_NUMDOCRIF);
datarif = fatt_head.get(DOC_DATADOCRIF);
codnum = fatt_head.get(DOC_CODNUM);
ndoc = fatt_head.get(DOC_NDOC);
break; // Non ne dovrebbero esistere altre
}
}
}
}
}
quant = riga.quantita();
valore = riga.valore(true, false, AUTO_DECIMALS);
}
if (valore > ZERO) // Devo stampare la riga
{
if (!testata_stampata) // Controllo se devo stampare la testata relativa
{
set_body(1, FALSE); // Inizializza BODY FIRST
set_body(1, TRUE); // Stampa testata bolla
testata_stampata = TRUE;
}
cursor()->curr(LF_RIGHEDOC) = riga;
body.find_field(R_QUANT).set(quant.string());
body.find_field(R_VALORE).set(valore.string());
body.find_field(R_DOCRIF).set(docrif);
body.find_field(R_DATARIF).set(datarif);
body.find_field(R_CODNUM_FAT).set(codnum);
body.find_field(R_NDOC_FAT).set(ndoc);
body.find_field(R_NOTA).set(postilla);
set_body(3, FALSE); // Inizializza BODY ODD
set_body(3, TRUE); // Stampa riga bolla
}
}
}
if (testata_stampata)
{
set_body(2, FALSE); // Inizializza BODY EVEN
set_body(2, TRUE); // Stampa totale bolla
if (note.items() > 0)
{
TPrinter& pr = printer();
TPrintrow prow;
pr.print(prow);
int progr = 0;
FOR_EACH_ARRAY_ROW(note, n, nota)
{
TString r;
r.format("@b(%d) ATTENZIONE!@r ", ++progr);
r << "La riga della bolla ha generato righe di merce anche sulle seguenti fatture: ";
prow.reset();
prow.put(r);
pr.print(prow);
FOR_EACH_TOKEN((*nota), tok)
{
TToken_string t(tok, ',');
prow.reset();
prow.put("Fattura di riferimento: "); prow.put(t.get(0));
prow.put(" "); prow.put(t.get());
prow.put(" Fattura: "); prow.put(t.get());
prow.put(" "); prow.put(t.get());
pr.print(prow);
}
}
}
}
return testata_stampata ? 1 : 0;
}
void TScoperto_form::print_total()
{
set_body(0, FALSE); // Inizializza BODY LAST
set_body(0, TRUE); // Stampa totale generale
printer().formfeed();
}
void TScoperto_form::header_handler(TPrinter&)
{
_curr_form->print_header();
}
TScoperto_form::TScoperto_form(const TDate& dr, bool wor, char sb, char sf)
: TForm("ve1200a"), _data_rif(dr), _work_on_residual(wor), _stato_bolle(sb), _stato_fatture(sf)
{
TCursor* cur = cursor();
TDocumento *doc = new TDocumento; // Don't delete!
cur->file(LF_DOC).set_curr(doc);
cur->file(LF_RIGHEDOC).set_curr(new TRiga_documento(doc));// Don't delete!
_curr_form = this;
printer().setheaderhandler(header_handler); // Setta handler testata
}
TScoperto_form::~TScoperto_form()
{
_curr_form = NULL;
}
///////////////////////////////////////////////////////////
// TLista_bolle
///////////////////////////////////////////////////////////
class TLista_bolle : public TObject
{
TAssoc_array _bolle;
TToken_string _key;
protected:
const TString& key(const TRectype& rec);
public:
void add_riga_fatt(const TRectype& rdoc_fatt);
TArray* find_bolla(const TRectype& doc_bolla);
void destroy() { _bolle.destroy(); }
};
const TString& TLista_bolle::key(const TRectype& rec)
{
if (rec.num() == LF_RIGHEDOC)
{
_key = rec.get(RDOC_DAPROVV);
_key.add(rec.get(RDOC_DAANNO));
_key.add(rec.get(RDOC_DACODNUM));
_key.add(rec.get(RDOC_DANDOC));
}
else
{
_key = rec.get(DOC_PROVV);
_key.add(rec.get(DOC_ANNO));
_key.add(rec.get(DOC_CODNUM));
_key.add(rec.get(DOC_NDOC));
}
return _key;
}
void TLista_bolle::add_riga_fatt(const TRectype& riga_fatt)
{
const TString& k = key(riga_fatt);
TArray* fatture = (TArray*)_bolle.objptr(k);
if (fatture == NULL)
{
fatture = new TArray;
_bolle.add(k, fatture);
}
fatture->add(riga_fatt);
}
TArray* TLista_bolle::find_bolla(const TRectype& doc_bolla)
{
const TString& k = key(doc_bolla);
return (TArray*)_bolle.objptr(k);
}
///////////////////////////////////////////////////////////
// TScoperto_app
///////////////////////////////////////////////////////////
class TScoperto_app : public TSkeleton_application
{
TLista_bolle _bolle_fatturate;
protected:
virtual void main_loop();
public:
bool trova_bolle_fatturate_dal(TString_array& bolle, TString_array& fatture, char stato_fatt, const TDate& datarif);
void print_bolle(TString_array& bolle, char stato_bolle, char stato_fatture, const TDate& datarif, bool work_on_res);
};
bool TScoperto_app::trova_bolle_fatturate_dal(TString_array& bolle, TString_array& fatture, char stato_fatt, const TDate& datarif)
{
const int codes = esercizi().date2esc(datarif);
const TDate inies = esercizi()[codes].inizio();
TRelation rel(LF_DOC);
TRectype& curr = rel.curr();
TString str;
str << "Ricerca bolle fatturate dopo il " << datarif;
_bolle_fatturate.destroy();
curr.put(DOC_DATADOC, inies);
if (fatture.items() == 1) // Ottimizziamo un po' il filtro, se c'<27> una sola fattura
{
curr.put(DOC_PROVV, "D");
curr.put(DOC_ANNO, inies.year());
curr.put(DOC_CODNUM, fatture.row(0));
}
TCursor cur(&rel, "", 3, &curr);
const long items = cur.items();
cur.freeze();
TProgind pi(items, str, TRUE, TRUE);
TRecord_array righe(LF_RIGHEDOC, RDOC_NRIGA);
for (cur = 0; cur.pos() < items; ++cur)
{
pi.addstatus(1);
if (pi.iscancelled())
return FALSE;
const TString& codnumfat = curr.get(DOC_CODNUM);
if (fatture.find(codnumfat) >= 0) // E' proprio una fattura!
{
const TDate data = curr.get_date(DOC_DATADOC);
const char stato = curr.get_char(DOC_STATO);
// Devo considerare le fatture dopo la datarif
// oppure quelle non ancora contabilizzate prima della datarif
if (data > datarif || stato < stato_fatt)
{
TRectype* chiave = new TRectype(LF_RIGHEDOC);
chiave->put(RDOC_PROVV, curr.get(DOC_PROVV));
chiave->put(RDOC_ANNO, curr.get(DOC_ANNO));
chiave->put(RDOC_CODNUM, curr.get(DOC_CODNUM));
chiave->put(RDOC_NDOC, curr.get(DOC_NDOC));
righe.read(chiave);
for (int r = righe.rows(); r > 0; r--)
{
const TRectype& riga = righe.row(r);
const TString& codnumbol = riga.get(RDOC_DACODNUM);
if (codnumbol.not_empty() && bolle.find(codnumbol) >= 0) // Riga generata da fattura!
_bolle_fatturate.add_riga_fatt(riga);
}
}
}
}
return TRUE;
}
void TScoperto_app::print_bolle(TString_array& bolle, char stato_bolle, char stato_fatture, const TDate& datarif, bool work_on_res)
{
const int codes = esercizi().date2esc(datarif);
const TDate inies = esercizi()[codes].inizio();
TRelation rel(LF_DOC);
TRectype& curr = rel.curr();
curr.put(DOC_DATADOC, inies);
TRectype recfin = curr;
recfin.put(DOC_DATADOC, datarif);
// Elenco di tutte le bolle comprese tra inizio esercizio e datarif
TString filter;
for (int i = 0; i < bolle.items(); i++)
{
if (i > 0) filter << "||";
filter << "(" << DOC_CODNUM << "==\"" << bolle.row(i) << "\")";
}
TCursor cur(&rel, filter, 3, &curr, &recfin);
const long items = cur.items();
if (items > 0)
{
cur.freeze();
TScoperto_form form(datarif, work_on_res, stato_bolle, stato_fatture);
printer().open();
long printed = 0;
for (cur = 0L; cur.pos() < items; ++cur)
{
if (printer().frozen())
break;
const char stato = curr.get_char(DOC_STATO);
if (stato == stato_bolle) // Bolla da fatturare
{
printed += form.print_bolla(curr, NULL);
}
else
{
TArray* fatt = _bolle_fatturate.find_bolla(curr);
if (fatt != NULL) // Bolla fatturata
printed += form.print_bolla(curr, fatt);
}
}
if (printed > 0)
form.print_total();
printer().close();
}
}
void TScoperto_app::main_loop()
{
open_files(LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_CLIFO, LF_CFVEN, 0);
TScoperto_msk msk;
while (msk.run() != K_QUIT)
{
const TDate datarif = msk.get_date(F_DATA);
const bool work_on_res = msk.get_bool(F_CONSORD);
TSheet_field& s = msk.sfield(F_BOLLE);
char stato_bolle = ' ', stato_fatt = ' ';
// Costruisco la lista delle bolle e delle fatture da leggere
TString_array bolle, fatture;
FOR_EACH_SHEET_ROW(s, r, row) if (*row->get(0) == 'X')
{
bolle.add(row->get(F_CODNUM-FIRST_FIELD));
if (stato_bolle <= ' ')
stato_bolle = row->get(F_STATOBOLL-FIRST_FIELD)[0];
TToken_string f(row->get(F_FATTURE-FIRST_FIELD), ',');
FOR_EACH_TOKEN(f, t)
{
if (fatture.find(t) < 0)
fatture.add(t);
}
if (stato_fatt <= ' ')
stato_fatt = row->get(F_STATOFATT-FIRST_FIELD)[0];
}
bool ok = trova_bolle_fatturate_dal(bolle, fatture, stato_fatt, datarif);
if (ok)
print_bolle(bolle, stato_bolle, stato_fatt, datarif, work_on_res);
}
}
int ve1200(int argc, char* argv[])
{
TScoperto_app a;
a.run(argc, argv, TR("Scoperto da fattura"));
return (0);
}