Files correlati : lv2.exe Ricompilazione Demo : [ ] Commento Se richiedo i riferimenti in testata ora viene aggiunto il contenuto del campo note della prima bolla del mese se compilato Modificato il calcolo del valore convenzionale per articolo nella fatturazione, ora fa una sola riga di conguaglio per tutti gli articoli che hanno questo forfait git-svn-id: svn://10.65.10.50/trunk@20452 c028cbd2-c16b-5b4b-a496-9718f37d4682
2072 lines
72 KiB
C++
Executable File
2072 lines
72 KiB
C++
Executable File
#include <progind.h>
|
||
#include <config.h>
|
||
#include <dongle.h>
|
||
#include <modaut.h>
|
||
#include <utility.h>
|
||
|
||
#include "lvlib.h"
|
||
#include "lv2500a.h"
|
||
|
||
#include "../pr/agenti.h"
|
||
#include "../pr/percprov.h"
|
||
#include "clifo.h"
|
||
#include "cfven.h"
|
||
#include "lvcondv.h"
|
||
#include "lvrcondv.h"
|
||
#include "doc.h"
|
||
#include "rdoc.h"
|
||
|
||
#include "../db/dblib.h"
|
||
#include "../mg/mglib.h"
|
||
#include "../ve/ve6200.h"
|
||
#include "../ve/ve6200a.h"
|
||
|
||
class TFatturazione_lavanderie;
|
||
|
||
////////////////////////////////////////
|
||
//// classe TFatturazione_msk ////
|
||
////////////////////////////////////////
|
||
|
||
class TFatturazione_msk: public TAutomask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly){return true;}
|
||
public:
|
||
TFatturazione_msk();
|
||
};
|
||
|
||
////////////////////////////////////////
|
||
//// TFatturazione_lavanderie app ////
|
||
////////////////////////////////////////
|
||
|
||
//Classe TFatturazione_lavanderie_app
|
||
class TFatturazione_lav_app: public TSkeleton_application
|
||
{
|
||
TFatturazione_msk* _msk;
|
||
|
||
protected:
|
||
virtual void main_loop();
|
||
|
||
void genera_bolle_nolo(TAssoc_array& cliela, TFatturazione_lavanderie& elab, int& numdocgen);
|
||
bool controlli_preliminari();
|
||
};
|
||
|
||
TFatturazione_lav_app & app() { return (TFatturazione_lav_app &) main_app();}
|
||
|
||
////////////////////////////////////////
|
||
//// TCalc_02_data ////
|
||
////////////////////////////////////////
|
||
|
||
//Classe TCalc_02_data
|
||
class TCalc_02_data : public TObject
|
||
{
|
||
TString _key;
|
||
TGeneric_distrib _distr;
|
||
TGeneric_distrib _distr_rit;
|
||
TAssoc_array _bol_rows;
|
||
|
||
virtual TObject* dup() const;
|
||
void copy(const TCalc_02_data & d);
|
||
|
||
public:
|
||
TCalc_02_data & operator = (const TCalc_02_data & d) { copy(d); return *this; }
|
||
const TString & key() const { return _key; }
|
||
TGeneric_distrib & distr() { return _distr; }
|
||
TGeneric_distrib & distr_rit() { return _distr_rit; }
|
||
TAssoc_array & bol_rows() { return _bol_rows; }
|
||
|
||
TCalc_02_data(const char * key) : _key(key) {}
|
||
TCalc_02_data(const TCalc_02_data & d) {copy(d);}
|
||
};
|
||
|
||
void TCalc_02_data::copy(const TCalc_02_data & d)
|
||
{
|
||
_key = d._key;
|
||
_distr = d._distr;
|
||
_bol_rows = d._bol_rows;
|
||
}
|
||
|
||
TObject* TCalc_02_data::dup() const
|
||
{
|
||
TCalc_02_data* o = new TCalc_02_data(*this);
|
||
return o;
|
||
}
|
||
|
||
|
||
////////////////////////////////////////
|
||
//// TFatturazione_lavanderie ////
|
||
////////////////////////////////////////
|
||
|
||
//Classe TFatturazione_lavanderie
|
||
class TFatturazione_lavanderie:public TFatturazione_bolle
|
||
{
|
||
TDate _data_elab;
|
||
TToken_string _campi_raggruppamento;
|
||
TAssoc_array _output_rows_02;
|
||
TAssoc_array _doc_grouped;
|
||
bool _prova;
|
||
|
||
protected:
|
||
virtual void add_rows(TRiga_documento & rout, TRiga_documento & rin);
|
||
virtual void create_row(TDocumento& doc_out, const TRiga_documento & rin);
|
||
virtual void pre_process_input(TLista_documenti& doc_in);
|
||
virtual void post_process_input(TLista_documenti& doc_in) {}
|
||
virtual void post_process(TLista_documenti& doc_out, TLista_documenti& doc_in);
|
||
virtual bool da_raggruppare(const TRiga_documento & rin);
|
||
virtual bool doc_raggruppabili(const TDocumento& doc_in, const TDocumento& doc_out, TToken_string& campi) const ;
|
||
virtual bool doc_raggruppabile(const TDocumento & doc) const { return true; }
|
||
virtual void campi_raggruppamento_righe(TToken_string& campi_riga) const;
|
||
virtual bool gestione_riferimenti() const { return true; }
|
||
virtual bool riferimenti_in_testa() const { return true; }
|
||
virtual TRiga_documento& find_or_create_row(TDocumento& doc_out, const TRiga_documento & rin,const char lavtype);
|
||
void aggiorna_fattura(TDocumento & doc, int codcont);
|
||
bool fatt_02() const { return !_prova &&lv_is_02_active(); }
|
||
void add_doc_to_list(const TString & key, const TDocumento & doc);
|
||
real get_percprovv(const TRiga_documento & row, char tipoprovv, const TString & codpr, bool first, const TRectype & age) const;
|
||
|
||
public:
|
||
int write_fatt_ragg();
|
||
void set_perc_provv(TRiga_documento & row, bool prima = true);
|
||
virtual bool elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo = false);
|
||
|
||
TFatturazione_lavanderie(const char* cod, bool prova = false);
|
||
~TFatturazione_lavanderie() {}
|
||
};
|
||
|
||
TFatturazione_lavanderie::TFatturazione_lavanderie(const char* cod, bool prova)
|
||
: TFatturazione_bolle(cod), _prova(prova)
|
||
{
|
||
}
|
||
|
||
//DOC_RAGGRUPPABILI: metodo che restituisce true se i documenti sono raggruppabili sulla base dei campi
|
||
//contenuti nella stringa campi
|
||
bool TFatturazione_lavanderie::doc_raggruppabili(const TDocumento& doc_in, const TDocumento& doc_out, TToken_string& campi) const
|
||
{
|
||
if (doc_in.ha_riga_esenzione() != doc_out.ha_riga_esenzione())
|
||
return false;
|
||
bool ok = true;
|
||
TString campo;
|
||
|
||
//scorro tutti i campi contenuti nella TToken_string
|
||
//se sto controllando i campi CODABI e CODCAB, allora il controllo
|
||
//deve essere numerico e non tra stringhe
|
||
for (const char* c = campi.get(0); c && ok; c = campi.get())
|
||
{
|
||
if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0)
|
||
{
|
||
long cod = doc_in.get_long(c);
|
||
ok &= (cod == doc_out.get_long(c));
|
||
}
|
||
else
|
||
{
|
||
campo = doc_in.get(c);
|
||
ok &= campo == doc_out.get(c);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
//DA_RAGGRUPPARE: per adesso segnaposto: resituisce sempre false
|
||
bool TFatturazione_lavanderie::da_raggruppare(const TRiga_documento & rin)
|
||
{
|
||
/* const long clifo = rin.doc().get_long(DOC_CODCF);
|
||
const int indsped = rin.doc().get_int(DOC_CODINDSP);
|
||
TLaundry_contract contr(clifo, indsped, _data_elab);
|
||
const TString80 codart = rin.get(RDOC_CODART);
|
||
const TRectype & rcont = contr.row(codart);
|
||
const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
|
||
|
||
// return tipoforf > 1; // Test originale
|
||
if (tipoforf > 1)
|
||
return true;
|
||
|
||
// Da qui in poi e' sottinteso tipoforf == 1
|
||
if (ini_get_int(CONFIG_DITTA, "lv", "TipoPr") == 1)
|
||
return false;
|
||
|
||
// Test GUY
|
||
const TString8 causale = rin.get(RDOC_CODAGG1);
|
||
const TCausale_lavand cau = cache().get("&CAU", causale);
|
||
if (cau.get_bool("B1"))
|
||
{
|
||
const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2"));
|
||
if (con.sgn(s_dottm)) // Causale di incremento sotazione temporanea
|
||
return true;
|
||
}
|
||
|
||
if (cau.get_bool("B4")) // Causale di rotto
|
||
return true; */
|
||
|
||
return false;
|
||
}
|
||
|
||
void TFatturazione_lavanderie::pre_process_input(TLista_documenti& doc_in)
|
||
{
|
||
for (int id = 0; id < doc_in.items(); id++)
|
||
{
|
||
TDocumento& doc = doc_in[id];
|
||
const int rows = doc.physical_rows();
|
||
|
||
for (int i = 1; i <= rows; i++)
|
||
{
|
||
TRiga_documento & row = doc[i];
|
||
TString str_real = row.get(RDOC_QTAREALE);
|
||
|
||
if (str_real.full())
|
||
{
|
||
real qta_real(decode(str_real));
|
||
|
||
row.put(RDOC_QTA, qta_real);
|
||
row.zero(RDOC_QTAREALE);
|
||
}
|
||
str_real = row.get(RDOC_QTARITREALE);
|
||
|
||
if (str_real.full())
|
||
{
|
||
real qta_real(decode(str_real));
|
||
|
||
row.put(RDOC_QTAGG1, qta_real);
|
||
row.zero(RDOC_QTARITREALE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TFatturazione_lavanderie::aggiorna_fattura(TDocumento & doc, int codcont)
|
||
{
|
||
const int nrows = doc.physical_rows();
|
||
const long codcf = doc.get_long(DOC_CODCF);
|
||
|
||
TString str;
|
||
str << "USE LVRCONDV\n"
|
||
<< "FROM CODCF=" << codcf << " CODCONT=" << codcont << "\n"
|
||
<< "TO CODCF=" << codcf << " CODCONT=" << codcont;
|
||
|
||
TISAM_recordset rcont(str);
|
||
|
||
for(bool ok = rcont.move_first(); ok; ok = rcont.move_next())
|
||
{
|
||
TRectype& riga = rcont.cursor()->curr();
|
||
int forfait = riga.get_int(LVRCONDV_TIPOFORF);
|
||
const TString & codart = riga.get(LVRCONDV_CODART);
|
||
bool to_add = forfait != 0;
|
||
|
||
|
||
for (int i = 1; to_add && i <= nrows ; i++)
|
||
{
|
||
TRiga_documento& rout = doc[i];
|
||
const TString80 codart_contr = rout.get(RDOC_CODART);
|
||
|
||
if (codart == codart_contr)
|
||
to_add = false;
|
||
}
|
||
if (to_add)
|
||
{
|
||
TRiga_documento& rdoc = doc.new_row("21");
|
||
|
||
rdoc.put(RDOC_CODART, codart);
|
||
rdoc.put(RDOC_CODARTMAG, riga.get(LVRCONDV_CODART));
|
||
rdoc.put(RDOC_DESCR, cached_article(codart).get(ANAMAG_DESCR));
|
||
rdoc.put(RDOC_CHECKED, true);
|
||
rdoc.put(RDOC_QTA, 0);
|
||
rdoc.put(RDOC_QTAGG1, 0);
|
||
rdoc.put(RDOC_UMQTA, riga.get(LVRCONDV_UM));
|
||
|
||
TToken_string key;
|
||
key.add('C');
|
||
key.add(codcf);
|
||
TString8 codiva = cache().get(LF_CFVEN, key, CFV_ASSFIS);
|
||
if (codiva.blank())
|
||
codiva = cache().get(LF_ANAMAG, riga.get(LVRCONDV_CODART), ANAMAG_CODIVA);
|
||
|
||
rdoc.put(RDOC_CODIVA, codiva);
|
||
rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"));
|
||
set_perc_provv(rdoc);
|
||
set_perc_provv(rdoc, false);
|
||
}
|
||
}
|
||
}
|
||
|
||
void TFatturazione_lavanderie::add_doc_to_list(const TString & key, const TDocumento & doc)
|
||
{
|
||
TDocumento * doc_cli = (TDocumento *) _doc_grouped.objptr(key);
|
||
|
||
if (doc_cli == NULL)
|
||
_doc_grouped.add(key, doc);
|
||
else
|
||
{
|
||
const int nrows = doc.physical_rows();
|
||
|
||
for (int r = 1; r <=nrows; r++)
|
||
{
|
||
const TRiga_documento & row = doc[r];
|
||
TRiga_documento & new_row = doc_cli->new_row(row.get(RDOC_TIPORIGA));
|
||
|
||
doc_cli->copy_data(new_row, row);
|
||
}
|
||
}
|
||
}
|
||
real TFatturazione_lavanderie::get_percprovv(const TRiga_documento & row, char tipoprovv, const TString & codpr, bool first, const TRectype & age) const
|
||
{
|
||
real val = ZERO;
|
||
const TDocumento & doc = row.doc();
|
||
const TRectype & anamag = cache().get(LF_ANAMAG, row.get(RDOC_CODARTMAG));
|
||
|
||
switch (tipoprovv)
|
||
{
|
||
case 'A':
|
||
val = age.get_real(AGE_PERCPROVV);
|
||
break;
|
||
case 'M':
|
||
val = anamag.get_real(ANAMAG_PERCPROVV);
|
||
break;
|
||
case 'C':
|
||
val = doc.clifor().vendite().get_real(first ? CFV_PERCPROVV : CFV_PERCPROVV1);
|
||
break;
|
||
case 'V':
|
||
{
|
||
const TString16 catven = doc.get(DOC_CATVEN);
|
||
if (catven.not_empty())
|
||
val = real(cache().get("CVE", catven, "R0"));
|
||
}
|
||
break;
|
||
case 'O':
|
||
// val = _rcondv.get_real("PERCPROVV");
|
||
break;
|
||
case '1':
|
||
case '2':
|
||
case '3':
|
||
case '4':
|
||
{
|
||
const TString16 ord = cache().get("APR", codpr, "S3");
|
||
|
||
int len = ord.len();
|
||
TString key;
|
||
TString80 campo;
|
||
|
||
for (int i = 0; i < len; i++)
|
||
{
|
||
switch (ord[i])
|
||
{
|
||
case 'C':
|
||
campo = doc.clifor().get(CLI_CODCF);
|
||
campo.lpad(doc.clifor().length(CLI_CODCF));
|
||
break;
|
||
case 'V':
|
||
campo = doc.get(DOC_CATVEN);
|
||
campo.rpad(doc.length(DOC_CATVEN));
|
||
break;
|
||
case 'A':
|
||
campo = doc.get(DOC_CODAG);
|
||
campo.rpad(doc.length(DOC_CODAG));
|
||
break;
|
||
case 'P':
|
||
campo = doc.get(DOC_CODPAG);
|
||
campo.rpad(doc.length(DOC_CODPAG));
|
||
break;
|
||
case 'S':
|
||
campo = doc.clifor().vendite().get(CFV_CODSCC);
|
||
campo.rpad(doc.clifor().length(CFV_CODSCC));
|
||
break;
|
||
case 'Z':
|
||
campo = doc.get(DOC_ZONA);
|
||
campo.rpad(doc.length(DOC_ZONA));
|
||
break;
|
||
case 'M':
|
||
campo = row.get( RDOC_CODARTMAG );
|
||
campo.rpad(row.length(RDOC_CODARTMAG));
|
||
break;
|
||
case 'E':
|
||
campo = anamag.get(ANAMAG_GRMERC);
|
||
campo.rpad(anamag.length(ANAMAG_GRMERC));
|
||
campo.cut(3);
|
||
break;
|
||
case 'R':
|
||
campo = anamag.get(ANAMAG_GRMERC);
|
||
campo.rpad(anamag.length(ANAMAG_GRMERC));
|
||
break;
|
||
case 'F':
|
||
campo = anamag.get(ANAMAG_RAGGFIS);
|
||
campo.rpad(anamag.length(ANAMAG_RAGGFIS));
|
||
break;
|
||
default:
|
||
campo.cut(0);
|
||
break;
|
||
|
||
}
|
||
key << campo;
|
||
}
|
||
|
||
TLocalisamfile perc(LF_PERCPROV);
|
||
|
||
perc.put(PER_CODPR, codpr);
|
||
perc.put(PER_KEYORD, key);
|
||
if (perc.read() == NOERR)
|
||
val= perc.get_real(PER_PERCPROVV);
|
||
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return val;
|
||
}
|
||
|
||
void TFatturazione_lavanderie::set_perc_provv(TRiga_documento & row, bool prima)
|
||
{
|
||
const TString & codage = row.doc().get(prima ? DOC_CODAG : DOC_CODAGVIS);
|
||
|
||
if (codage.full())
|
||
{
|
||
const TRectype & age = cache().get(LF_AGENTI, codage);
|
||
|
||
if (!age.empty())
|
||
{
|
||
TString16 seqric(age.get(AGE_SEQRIC));
|
||
real percprovv;
|
||
|
||
if (seqric[0] == '-')
|
||
seqric = ini_get_string(CONFIG_DITTA, "ve", "AGETIPOPERC");
|
||
|
||
int len = seqric.len();
|
||
int i;
|
||
|
||
for (i = 0; percprovv.is_zero() && seqric[i] != '\0' && seqric[i] != '-'; i++)
|
||
{
|
||
TString16 codric;
|
||
if (isdigit(seqric[i]))
|
||
codric = age.get(format("CODRICPR%d", i+1));
|
||
percprovv = get_percprovv(row, seqric[i], codric, prima, age);
|
||
}
|
||
real percalt;
|
||
seqric = age.get(AGE_SEQALT);
|
||
for (i = 0; percalt.is_zero() && seqric[i] != '\0' && seqric[i] != '-'; i++)
|
||
{
|
||
TString16 codric;
|
||
if (isdigit(seqric[i]))
|
||
codric = age.get(format("CODALTPR%d", i+1));
|
||
percalt = get_percprovv(row, seqric[i], codric, prima, age);
|
||
}
|
||
percprovv += percalt;
|
||
row.put(prima ? RDOC_PERCPROV : RDOC_PERCPROV1, percprovv);
|
||
}
|
||
}
|
||
}
|
||
|
||
int TFatturazione_lavanderie::write_fatt_ragg()
|
||
{
|
||
int items = _doc_grouped.items();
|
||
TString_array kl;
|
||
|
||
_doc_grouped.get_keys(kl);
|
||
kl.sort();
|
||
FOR_EACH_ARRAY_ROW(kl, r, key)
|
||
{
|
||
TDocumento * d = (TDocumento *)_doc_grouped.objptr(*key);
|
||
|
||
if (d != NULL)
|
||
d->write();
|
||
}
|
||
_doc_grouped.destroy();
|
||
return items;
|
||
}
|
||
|
||
//POST_PROCESS: metodo che elabora i documenti di output dopo che si sono svolte
|
||
//le operazioni di base sugli stessi, in modo da raggruppare le righe raggruppabili
|
||
//e/o eliminare quelle inutili e/o aggiungere quelle per il ciclaggio su 2 linee
|
||
void TFatturazione_lavanderie::post_process(TLista_documenti& doc_out, TLista_documenti& doc_in)
|
||
{
|
||
bool use_indsp = ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED");
|
||
//scorro tutti i documenti di output generati precedentemente
|
||
|
||
for (int id = 0; id < doc_out.items(); id++)
|
||
{
|
||
//instanzio il documento e recupero le variabili di interesse per recuperare
|
||
//il contratto del cliente in questione
|
||
TDocumento& doc = doc_out[id];
|
||
const long clifo = doc.get_long(DOC_CODCF);
|
||
|
||
const int indsped = doc.get_int(DOC_CODINDSP);
|
||
TLaundry_contract contr(clifo,indsped,_data_elab);
|
||
//flag per il calcolo sul valore convenzionale e sul fisso per dotazione iniziale
|
||
bool valconvcli = false;
|
||
bool fixdotin = false;
|
||
bool elcons = contr.get_bool(LVCONDV_ELCONS);
|
||
bool rifbol = contr.get_bool(LVCONDV_RIFBOL);
|
||
bool riftest = ini_get_bool(CONFIG_DITTA, "lv", "RifTest");
|
||
bool liqdiff = doc.clifor().get_int(CLI_ALLEG) == 7 && doc.clifor().vendite().get_bool(CFV_FATTSOSP);
|
||
real consvconv;
|
||
real impvconv;
|
||
TAssoc_array nolo_computed;
|
||
|
||
if (liqdiff)
|
||
doc.put(DOC_LIQDIFF, "X");
|
||
else
|
||
doc.zero(DOC_LIQDIFF);
|
||
if (doc.physical_rows() > 0 && doc[1].is_descrizione())
|
||
{
|
||
if (elcons)
|
||
{
|
||
TRiga_documento& rout = doc[1];
|
||
rout.put(RDOC_DESCR, "COME DA ELENCO CONSEGNE");
|
||
rout.put(RDOC_DESCLUNGA, false);
|
||
rout.put(RDOC_DESCEST, "");
|
||
}
|
||
else
|
||
if (!rifbol)
|
||
doc.destroy_row(1, true);
|
||
}
|
||
|
||
//se devo mettere i riferimenti della bolla in testata, prendo la descrizione della prima riga
|
||
//e la metto sulla testata del documento, poi cancello la prima riga del documento
|
||
if (rifbol && riftest)
|
||
{
|
||
TRiga_documento& rout = doc[1];
|
||
TString descr = rout.get(RDOC_DESCR);
|
||
descr << ' ' << rout.get(RDOC_DESCEST);
|
||
descr.ltrim(21);
|
||
//sostituisco la stringa " - n. " e la sostituisco con la stringa " - " su tutta la stringa descrizione
|
||
int pos = descr.find(" - n. ");
|
||
while (pos > 0)
|
||
{
|
||
descr.overwrite(" - ", pos, 7);
|
||
pos = descr.find(" - n. ", pos + 1);
|
||
}
|
||
descr.strip_double_spaces();
|
||
|
||
const TString original_notes = doc.get(DOC_NOTE);
|
||
|
||
if (original_notes.full())
|
||
descr << '\n' << original_notes;
|
||
doc.put(DOC_NOTE, descr);
|
||
doc.destroy_row(1, true);
|
||
}
|
||
if (doc.physical_rows() > 0)
|
||
doc.sort_rows("LVTYPE|" RDOC_CODART);
|
||
|
||
const bool ragart = contr.get_bool(LVCONDV_RAGART); // leggo il flag di testata raggruppa su unico articolo
|
||
const int tipocan = contr.get_int(LVCONDV_TIPOCAN); // leggo il tipo canone
|
||
const real redditivita = contr.get_real(LVCONDV_REDDI);
|
||
|
||
|
||
if (ragart)
|
||
{
|
||
real totmerc;
|
||
const int rows = doc.physical_rows();
|
||
|
||
for (int i=1; i <= rows; i++) //calcolo totale merce
|
||
{
|
||
const TRiga_documento& riga = doc[i];
|
||
if (riga.is_merce())
|
||
totmerc += riga.importo(true,false);
|
||
}
|
||
|
||
const int rigamerce = doc[1].is_descrizione() ? 2 : 1;
|
||
|
||
for (int i=rigamerce; i <= rows; i++)
|
||
doc.destroy_row(i);
|
||
|
||
TRiga_documento& riga = doc.new_row("01");
|
||
|
||
const TString80 codartcfg = ini_get_string(CONFIG_DITTA, "lv", "Codartcafix");
|
||
const TString80 descart = cache().get(LF_ANAMAG, codartcfg, ANAMAG_DESCR);
|
||
|
||
// istanzio una token string e poi una cache per estrarre l'unit<69> di misura dell articolo in configurazione da UMART
|
||
TToken_string key;
|
||
key.add(codartcfg);
|
||
key.add(1);
|
||
const TRectype& umart = cache().get(LF_UMART,key);
|
||
const TString4 umcodart = umart.get(UMART_UM);
|
||
|
||
/* estraggo il codice IVA istanziando in primis una cache su CFVEN per analizzare il codice esenzione iva
|
||
del cliente in questione. Se <20> >0 imposto il codiva a tale valore, altrimenti se <20> uguale a 0 istanzio
|
||
un altra cache su ANAMAG e imposto il codiva uguale al codice iva dell articolo in questione */
|
||
key = doc.get(DOC_TIPOCF);
|
||
key.add(clifo);
|
||
const TRectype& cfven = cache().get(LF_CFVEN,key);
|
||
TString8 codiva = cfven.get(CFV_ASSFIS);
|
||
|
||
if (codiva.blank())
|
||
{
|
||
const TRectype& anamag = cache().get(LF_ANAMAG,codartcfg);
|
||
codiva = anamag.get(ANAMAG_CODIVA);
|
||
}
|
||
|
||
riga.put(RDOC_QTA,UNO);
|
||
riga.put(RDOC_UMQTA,umcodart);
|
||
riga.put(RDOC_PREZZO,totmerc);
|
||
riga.put(RDOC_CODART,codartcfg);
|
||
riga.put(RDOC_DESCR,descart);
|
||
riga.put(RDOC_CODIVA,codiva);
|
||
set_perc_provv(riga);
|
||
set_perc_provv(riga, false);
|
||
|
||
break;
|
||
}
|
||
else // se non <20> selezionato raggrupa su unico articolo controllo il tipo canone se <20> impostato a importo fisso
|
||
if (tipocan == 1) //se <20> selezionato tipo canone = importo fisso
|
||
{
|
||
// estraggo il canone fisso e l'articolo in configurazione
|
||
const real canfis=contr.get_real(LVCONDV_IMPFIX);
|
||
const TString80 codartcfg = ini_get_string(CONFIG_DITTA, "lv", "Codartfix");
|
||
const TString80 descart = cache().get(LF_ANAMAG, codartcfg, ANAMAG_DESCR);
|
||
|
||
// istanzio una token string e poi una cache per estrarre l'unit<69> di misura dell articolo in configurazione da UMART
|
||
TToken_string key;
|
||
key.add(codartcfg);
|
||
key.add(1);
|
||
const TRectype& umart = cache().get(LF_UMART,key);
|
||
const TString4 umcodart = umart.get(UMART_UM);
|
||
|
||
/* estraggo il codice IVA istanziando in primis una cache su CFVEN per analizzare il codice esenzione iva
|
||
del cliente in questione. Se <20> >0 imposto il codiva a tale valore, altrimenti se <20> uguale a 0 istanzio
|
||
un altra cache su ANAMAG e imposto il codiva uguale al codice iva dell articolo in questione */
|
||
key = doc.get(DOC_TIPOCF);
|
||
key.add(clifo);
|
||
const TRectype& cfven = cache().get(LF_CFVEN,key);
|
||
TString8 codiva = cfven.get(CFV_ASSFIS);
|
||
|
||
if (codiva.blank())
|
||
{
|
||
const TRectype& anamag = cache().get(LF_ANAMAG,codartcfg);
|
||
codiva = anamag.get(ANAMAG_CODIVA);
|
||
}
|
||
|
||
const int rigamerce = doc.physical_rows() > 0 && doc[1].is_descrizione()?2:1;
|
||
TRiga_documento& fixrow=doc.insert_row(rigamerce, "01"); // creo una nuova riga in cima al documento e imposto i valori appena estratti
|
||
|
||
fixrow.put(RDOC_QTA,UNO);
|
||
fixrow.put(RDOC_UMQTA,umcodart);
|
||
fixrow.put(RDOC_PREZZO,canfis);
|
||
fixrow.put(RDOC_CODART,codartcfg);
|
||
fixrow.put(RDOC_DESCR,descart);
|
||
fixrow.put(RDOC_CODIVA,codiva);
|
||
|
||
int tipocanfix = contr.get_int(LVCONDV_CANFIX);
|
||
|
||
const int rows = doc.physical_rows();
|
||
|
||
switch (tipocanfix)
|
||
{
|
||
case 0:
|
||
for (int k = rigamerce+1; k <= rows; k++)
|
||
doc.destroy_row(k);
|
||
break;
|
||
case 1:
|
||
for (int k = rigamerce+1; k <= rows; k++)
|
||
{
|
||
TRiga_documento& rout = doc[k];
|
||
rout.zero(RDOC_PREZZO);
|
||
}
|
||
break;
|
||
case 2:
|
||
for (int k = rigamerce+1; k <= rows; k++)
|
||
{
|
||
TRiga_documento& rout = doc[k];
|
||
rout.zero(RDOC_PREZZO);
|
||
rout.zero(RDOC_QTA);
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
break;
|
||
}
|
||
else // se il tipo canone <20> impostato a nessuno o % sul valore convenzionale per cliente vado in ambedue i casi ad eseguire il ciclo che analizza i tipi forfait
|
||
{
|
||
if (!contr.get_bool(LVCONDV_FORFNOCONS))
|
||
aggiorna_fattura(doc, contr.get_int(LVCONDV_CODCONT));
|
||
//per ogni documento, scorro tutte le sue righe
|
||
for (int i = 1; i <= doc.physical_rows() ; i++)
|
||
{
|
||
TRiga_documento& rout = doc[i];
|
||
|
||
const TString80 codart = rout.get(RDOC_CODART);
|
||
//leggo dalla riga del contratto di questo articolo il tipo dotazione e
|
||
//la scelta per la % sul val.conv su articolo <A> o cliente <C>
|
||
const TRectype& rcont = contr.row(codart);
|
||
const TString4 tipodot = rcont.get(LVRCONDV_NOLCIC);
|
||
const TString4 artcli = rcont.get(LVRCONDV_VCARTCLI);
|
||
real dot;
|
||
const int annoes = _data_elab.year();
|
||
|
||
//instanzio il TArticolo_lavanderia
|
||
//cerco la giacenza per articolo dell'articolo esaminato
|
||
TArticolo_lavanderie& artlav = cached_article_laundry(codart, 'C', clifo, use_indsp ? indsped : 0);
|
||
//estraggo il record corrispondente su LF_CLIFOGIAC
|
||
const TRecmag_lavanderie& reclav = artlav.find_rec(annoes);
|
||
//se lo trovo e se il tipo dotazione <20> iniziale 'I', allora leggo la dotazione iniziale
|
||
//dalle giacenze articolo per cliente, altrimenti leggo la dotazione odierna
|
||
if (tipodot == "I")
|
||
dot = reclav.get_real("DOTIN");
|
||
else
|
||
dot = reclav.get_real("DOTOD");
|
||
|
||
//leggo dalla riga contratto il tipo forfait
|
||
const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
|
||
|
||
switch (tipoforf)
|
||
{
|
||
case 0: //forfait = NESSUNO
|
||
{
|
||
//gestione fatturazione a kg
|
||
const bool fatkg = rcont.get_bool(LVRCONDV_FATTKG);
|
||
//se devo fatturare a kg
|
||
if(fatkg)
|
||
{
|
||
const TString4 umkg = ini_get_string(CONFIG_DITTA, "lv", "UmKg");
|
||
const TString4 umri = rout.get(RDOC_UMQTA);
|
||
|
||
//se la riga <20> gi<67> espressa in kg non devo fare niente, altrimenti:
|
||
if(umri != umkg)
|
||
{
|
||
//leggo e controllo l'unit<69> di misura del peso
|
||
const TString4 ump = artlav.get(ANAMAG_UMP);
|
||
if(ump.empty())
|
||
{
|
||
warning_box(TR("Manca l'unit<69> di misura del peso"));
|
||
break;
|
||
}
|
||
|
||
//leggo e controllo il peso dell'articolo
|
||
const real peso = artlav.get_real(ANAMAG_PESO);
|
||
if(peso == ZERO)
|
||
{
|
||
warning_box(TR("Manca il peso"));
|
||
break;
|
||
}
|
||
|
||
//leggo l'unit<69> di misura dell'articolo e la quantit<69> convertita all'unit<69> di misura dell'articolo
|
||
const TString4 umart = artlav.um()[1].get(UMART_UM);
|
||
const real qta = artlav.convert_to_um(rout.get_real(RDOC_QTA), umart, umri, false);
|
||
|
||
//se l'articolo non <20> espresso in kg, allora:
|
||
if(umart != umkg)
|
||
{
|
||
//preparo una cache sulla tabella delle unit<69> di misura
|
||
const TRectype& unita = cache().get("%UMS", ump);
|
||
real fatconv = UNO;
|
||
|
||
if (ump != umkg)
|
||
{
|
||
//leggo e controllo se esiste l'unit<69> di misura di riferimento
|
||
const TString4 umrif = unita.get("S7");
|
||
if(umrif.empty())
|
||
{
|
||
warning_box(TR("Manca l'unit<69> di misura di riferimento"));
|
||
break;
|
||
}
|
||
if(umrif != umkg)
|
||
{
|
||
warning_box(TR("L'unit<69> di misura di riferimento non <20> quella dei Kg"));
|
||
break;
|
||
}
|
||
|
||
//leggo e controllo il fattore di conversione
|
||
fatconv = unita.get_real("R10");
|
||
if(fatconv == ZERO)
|
||
{
|
||
warning_box(TR("Manca il fattore di conversione"));
|
||
break;
|
||
}
|
||
}
|
||
|
||
//se tutti i controlli sono andati a buon fine, converto la quantit<69> e la scrivo sulla riga documento
|
||
const real qtaconv = qta * fatconv * peso;
|
||
rout.put(RDOC_UMQTA, umkg);
|
||
rout.put(RDOC_QTA, qtaconv);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 1: //forfait = A VALORE FISSO
|
||
{
|
||
rout.put(RDOC_QTA, UNO); //qta fissa a UNO
|
||
rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_IMPFISART)); //prezzo letto dalla riga contratto
|
||
// gestione in base codice per valore fisso ??? tolta la scelta dell'articolo o del cliente
|
||
}
|
||
break;
|
||
case 2: //forfait = NOLO
|
||
{
|
||
//aggiungo una riga tipo merce, che contiene tutti i dati della riga del documento
|
||
//di partenza, poi costruisco la descrizione in base alla periodicit<69> di fatturazione,
|
||
//metto la qta uguale alla dotazione che ho appena letto
|
||
//e prendo il prezzo nolo dalla riga contratto
|
||
if (dot != ZERO && nolo_computed.objptr(codart) == NULL)
|
||
{
|
||
TRiga_documento& nolorow = doc.insert_row(++i, "01");
|
||
nolo_computed.add(codart, codart);
|
||
doc.copy_data(nolorow, rout);
|
||
const TString descrart = rout.get(RDOC_DESCR);
|
||
|
||
TString80 descr("Nolo");
|
||
const int contrper = contr.get_int(LVCONDV_PERFAT);
|
||
|
||
switch (contrper)
|
||
{
|
||
case 0: descr << " per il giorno "; break;
|
||
case 1: descr << " per la settimana "; break;
|
||
case 2: descr << " per la quindicina "; break;
|
||
case 3: descr << " per il mese "; break;
|
||
default: break;
|
||
}
|
||
descr << descrart;
|
||
|
||
int split_pos = descr.find('\n');
|
||
const int descr_len = nolorow.length(RDOC_DESCR);
|
||
if (split_pos < 0 && descr.len() > descr_len)
|
||
split_pos = descr_len;
|
||
if (split_pos > descr_len)
|
||
split_pos = descr_len;
|
||
if (split_pos > 0)
|
||
{
|
||
nolorow.put(RDOC_DESCR, descr.left(split_pos));
|
||
const TString& dest = descr.mid(split_pos);
|
||
nolorow.put(RDOC_DESCLUNGA, "X");
|
||
nolorow.put(RDOC_DESCEST, dest);
|
||
}
|
||
else
|
||
{
|
||
nolorow.put(RDOC_DESCR, descr);
|
||
nolorow.zero(RDOC_DESCLUNGA);
|
||
nolorow.zero(RDOC_DESCEST);
|
||
}
|
||
|
||
nolorow.put(RDOC_QTA, dot);
|
||
nolorow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZNOL));
|
||
}
|
||
}
|
||
break;
|
||
case 3: //forfait = CICLAGGIO
|
||
{
|
||
//leggo la quantit<69> consegnata e calcolo consumo e ciclaggio secondo le formule
|
||
//CONSUMO = QTA * PREZZO(dalla riga documento)
|
||
//CLICLAGGIO = DOT * PREZZO(dalla riga contratto) * MINIMO CICLAGGIO
|
||
const real qta = rout.get_real(RDOC_QTA);
|
||
const real consumo = qta * rout.get_real(RDOC_PREZZO);
|
||
const real ciclaggio = dot * rcont.get_real(LVRCONDV_PREZZO) * rcont.get_real(LVRCONDV_MINCIC);
|
||
//se il consumo <20> minore del ciclaggio, allora
|
||
if (consumo < ciclaggio)
|
||
{
|
||
//leggo il flag del tipo ciclaggio
|
||
const bool cicl2rig = contr.get_bool(LVCONDV_CICLAGGIO);
|
||
//calcolo il valore cicl secondo la formula CICL = MINIMO CICLAGGIO * DOT
|
||
const real cicl = rcont.get_real(LVRCONDV_MINCIC) * dot;
|
||
//se il ciclaggio <20> su due linee, allora aggiungo una riga merce, per pareggiare il minimo ciclaggio
|
||
//che ha come quantit<69> la differenza tra la quantit<69> di minimo cilcaggio
|
||
//e la quantit<69> effettivamente consegnata e come prezzo il prezzo preso dalla riga contratto;
|
||
//altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
|
||
if (cicl2rig)
|
||
{
|
||
TRiga_documento& congrow = doc.insert_row(++i, "01");
|
||
doc.copy_data(congrow,rout);
|
||
congrow.put(RDOC_DESCR,"Pareggio minimo ciclaggio");
|
||
congrow.put(RDOC_QTA, cicl - qta);
|
||
congrow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO));
|
||
}
|
||
else
|
||
{
|
||
rout.put(RDOC_QTA, cicl);
|
||
rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO));
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 4: //forfait = % SUL VALORE CONVENZIONALE
|
||
{
|
||
//leggo dalla riga contratto la % sul val.conv su articolo <A> o cliente <C>
|
||
const char tipovalconv = rcont.get_char(LVRCONDV_VCARTCLI);
|
||
//se la percentuale sul valore convenzionale <20> sull'articolo, allora:
|
||
if (tipovalconv == 'A')
|
||
{
|
||
//leggo la quantit<69> consegnata e calcolo consumo e importo convenzionale secondo le formule
|
||
//CONSUMO = QTA * PREZZO(dalla riga documento)
|
||
//IMPCONV = DOT * PREZZO(dalla riga contratto) * PERCENTUALE DI FORFAIT CLIENTE
|
||
const real qta = rout.get_real(RDOC_QTA);
|
||
const real consumo = qta * rout.get_real(RDOC_PREZZO);
|
||
const real impconv = dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL) / 100;
|
||
|
||
impvconv += impconv;
|
||
consvconv += consumo;
|
||
}
|
||
else
|
||
{
|
||
//se la percentuale sul valore convenzionale <20> sul cliente, allora se il flag valconvcli <20> false
|
||
if (!valconvcli)
|
||
{
|
||
//pongo valconvcli a true in modo da non tornare pi<70> in questo if
|
||
valconvcli = true;
|
||
//instanzio i due real che andranno a contenere l'importo covenzionale totale e il consumo totale
|
||
real impconvtot;
|
||
real consumotot;
|
||
TAssoc_array arts;
|
||
|
||
|
||
//scorro tutte le righe documento dalla riga in esame fino alla fine
|
||
for (int j = i; j < doc.physical_rows(); j++)
|
||
{
|
||
//instanzio la riga documento e sommo ai totali gli importi solo se
|
||
//la percentuale sul valore convenzionale <20> sul cliente
|
||
TRiga_documento& riga = doc[j];
|
||
const TString80 codart = riga.get(RDOC_CODART);
|
||
const TRectype & rcont = contr.row(codart);
|
||
const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
|
||
char lavtype = riga.get_char("LVTYPE");
|
||
if (tipvalconvcli == 'C' && lavtype != 'D')
|
||
{
|
||
if (arts.objptr(codart) == NULL)
|
||
{
|
||
const TString4 tipodot = rcont.get(LVRCONDV_NOLCIC);
|
||
TArticolo_lavanderie& art = cached_article_laundry(codart, 'C', clifo, use_indsp ? indsped : 0);
|
||
//estraggo il record corrispondente su LF_CLIFOGIAC
|
||
const TRecmag_lavanderie& rec = art.find_rec(annoes);
|
||
//se lo trovo e se il tipo dotazione <20> iniziale 'I', allora leggo la dotazione iniziale
|
||
//dalle giacenze articolo per cliente, altrimenti leggo la dotazione odierna
|
||
if (tipodot == "I")
|
||
dot = rec.get_real("DOTIN");
|
||
else
|
||
dot = rec.get_real("DOTOD");
|
||
const real impconv = dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL) / CENTO;
|
||
impconvtot += impconv;
|
||
arts.add(codart, codart);
|
||
}
|
||
consumotot += riga.get_real(RDOC_QTA) * riga.get_real(RDOC_PREZZO);
|
||
}
|
||
}
|
||
//se il consumo <20> minore del ciclaggio, allora
|
||
if (consumotot < impconvtot)
|
||
{
|
||
const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO);
|
||
const TString80 codartcon = ini_get_string(CONFIG_DITTA, "lv", "Codartcofix");
|
||
|
||
//se il ciclaggio <20> su due linee, allora aggiungo una riga merce, che contiene
|
||
//il conguaglio al valore convenzionale, che ha come quantit<69> la costante UNO
|
||
//e come prezzo la differenza tra l'importo convenzionale totale e il consumo totale;
|
||
//altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
|
||
//e elimino tutte le righe che vanno a comporre il totale in modo che rimanga una riga sola
|
||
//per mostrare l'importo del conguaglio al valore convenzionale
|
||
if (cicl2rig)
|
||
{
|
||
i++;
|
||
TRiga_documento& congrow=doc.new_row("01");
|
||
doc.copy_data(congrow, rout);
|
||
congrow.put(RDOC_CODART, codartcon);
|
||
congrow.put(RDOC_CHECKED, "X");
|
||
congrow.put(RDOC_CODARTMAG, codartcon);
|
||
congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
|
||
congrow.put(RDOC_QTA, UNO);
|
||
congrow.put(RDOC_PREZZO, impconvtot - consumotot);
|
||
set_perc_provv(congrow);
|
||
set_perc_provv(congrow, false);
|
||
}
|
||
else
|
||
{
|
||
rout.put(RDOC_CODART, codartcon);
|
||
rout.put(RDOC_CHECKED, "X");
|
||
rout.put(RDOC_CODARTMAG, codartcon);
|
||
rout.put(RDOC_DESCR, "Valore convenzionale");
|
||
rout.put(RDOC_QTA, UNO);
|
||
rout.put(RDOC_PREZZO, impconvtot);
|
||
|
||
for (int k = doc.physical_rows(); k > i; k--)
|
||
{
|
||
TRiga_documento& delrow = doc[k];
|
||
const TString80 codart = delrow.get(RDOC_CODART);
|
||
const TRectype& rcont = contr.row(codart);
|
||
const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
|
||
char lavtype = delrow.get_char("LVTYPE");
|
||
if (tipvalconvcli == 'C' && lavtype != 'D')
|
||
doc.destroy_row(k, true);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 5: //forfait = FISSO SU DOTAZIONE INIZIALE
|
||
{
|
||
rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_IMPFISART));
|
||
const real dotin = reclav.get_real("DOTIN");
|
||
|
||
rout.put(RDOC_QTA, dotin);
|
||
|
||
if (rout.get(RDOC_DESCR).blank())
|
||
{
|
||
const TString & descr = cached_article(codart).get(RDOC_DESCR);
|
||
|
||
rout.put(RDOC_DESCR, descr);
|
||
}
|
||
|
||
const TString80 codartorig=rout.get(RDOC_CODART);
|
||
|
||
for (int h = doc.physical_rows(); h > i; h--)
|
||
{
|
||
TRiga_documento& delrow = doc[h];
|
||
const TString80 codart=delrow.get(RDOC_CODART);
|
||
if ( codartorig == codart)
|
||
doc.destroy_row(h, true);
|
||
}
|
||
}
|
||
break;
|
||
default: break;
|
||
}
|
||
}
|
||
|
||
//se il consumo <20> minore del ciclaggio, allora
|
||
if (impvconv - consvconv > ZERO)
|
||
{
|
||
const bool cicl2rig = contr.get_bool(LVCONDV_CICLAGGIO);
|
||
const int rows = doc.physical_rows();
|
||
|
||
//se il ciclaggio <20> su due linee, allora aggiungo una riga merce, che contiene
|
||
//il conguaglio al valore convenzionale, che ha come quantit<69> la costante UNO
|
||
//e come prezzo la differenza tra l'importo convenzionale e il consumo;
|
||
//altimenti correggo quantit<69> e prezzo direttamente sulla riga documento che sto analizzando
|
||
TRiga_documento& congrow = doc.new_row("01");
|
||
const TString80 codartcon = ini_get_string(CONFIG_DITTA, "lv", "Codartcofix");
|
||
|
||
congrow.put(RDOC_CODART, codartcon);
|
||
congrow.put(RDOC_CHECKED, "X");
|
||
congrow.put(RDOC_CODARTMAG, codartcon);
|
||
congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
|
||
congrow.put(RDOC_QTA, UNO);
|
||
|
||
TString8 codiva = doc.clifor().vendite().get(CFV_ASSFIS);
|
||
|
||
if (codiva.blank())
|
||
codiva = cache().get(LF_ANAMAG, codartcon, ANAMAG_CODIVA);
|
||
|
||
congrow.put(RDOC_CODIVA, codiva);
|
||
|
||
if (cicl2rig)
|
||
congrow.put(RDOC_PREZZO, impvconv - consvconv);
|
||
else
|
||
{
|
||
congrow.put(RDOC_PREZZO, impvconv);
|
||
for (int k = rows - 1; k >= 1; k--)
|
||
{
|
||
TRiga_documento& delrow = doc[k];
|
||
const TString80 codart = delrow.get(RDOC_CODART);
|
||
const TRectype& rcont = contr.row(codart);
|
||
const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
|
||
char lavtype = delrow.get_char("LVTYPE");
|
||
if (tipoforf == 4 && lavtype != 'D')
|
||
doc.destroy_row(k, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
if (redditivita > ZERO && fatt_02() && !ragart && tipocan != 1)
|
||
{
|
||
const real totdoc = doc.totale_doc();
|
||
const real provvigione1 = doc.provvigione();
|
||
const real provvigione2 = doc.provvigione(false);
|
||
|
||
doc.put(RDOC_TOTREALE, encode(totdoc.string()));
|
||
doc.put(RDOC_PROVV1REALE, encode(provvigione1.string()));
|
||
doc.put(RDOC_PROVV2REALE, encode(provvigione2.string()));
|
||
|
||
for(int j = doc.physical_rows(); j > 0; j--)
|
||
{
|
||
TRiga_documento& rdoc = doc[j];
|
||
const TString80 codart = rdoc.get(RDOC_CODARTMAG);
|
||
const TRectype& rcont = contr.row(codart);
|
||
const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
|
||
long ppconf = cached_article(codart).get_long(ANAMAG_PPCONF);
|
||
const real real_qta = rdoc.get(RDOC_QTA);
|
||
|
||
if (rcont.get_int(LVRCONDV_CALCCONS) != 1 || ppconf == 0)
|
||
ppconf = 1;
|
||
|
||
const char lvtype = rdoc.get_char("LVTYPE");
|
||
bool row_has_02 = (tipoforf == 0) && (real_qta / ppconf > UNO) && (lvtype == 'C');
|
||
|
||
// 0 forfait = NESSUN FORFAIT SI
|
||
// 1 forfait = A VALORE FISSO NO
|
||
// 2 forfait = NOLO NO
|
||
// 3 forfait = CICLAGGIO NO
|
||
// 4 forfait = % SUL VALORE CONVENZIONALE NO
|
||
// 5 forfait = FISSO SU DOTAZIONE INIZIALE NO
|
||
|
||
if (row_has_02)
|
||
{
|
||
const TString key = format("%04d%04d", doc.get_int("FATID"), rdoc.get_int(RDOC_IDRIGA));
|
||
real new_qta = real_qta;
|
||
TCalc_02_data * data = (TCalc_02_data *) _output_rows_02.objptr(key);
|
||
|
||
rdoc.put(RDOC_QTAREALE, encode(real_qta.string()));
|
||
|
||
if (data != NULL)
|
||
{
|
||
new_qta /= ppconf;
|
||
|
||
real test = new_qta;
|
||
|
||
test.ceil();
|
||
|
||
if (test * ppconf != real_qta)
|
||
{
|
||
warning_box(FR("L'articolo %s per il cliente %ld ha una quantit<69> %s\nnon coincidente coi pacchi. Controllare le bolle"),
|
||
(const char *)codart, doc.get_long(DOC_CODCF), real_qta.string());
|
||
ppconf = 1;
|
||
}
|
||
new_qta *= (CENTO - redditivita) / CENTO;
|
||
new_qta.round();
|
||
data->distr() = new_qta;
|
||
new_qta *= ppconf;
|
||
rdoc.put(RDOC_QTA, new_qta);
|
||
|
||
real new_qta_rit = rdoc.get_real("TOTRIT");
|
||
new_qta_rit *= (CENTO - redditivita) / CENTO;
|
||
new_qta_rit.round();
|
||
data->distr_rit() = new_qta_rit;
|
||
|
||
TAssoc_array & bol_rows = data->bol_rows();
|
||
|
||
FOR_EACH_ASSOC_OBJECT(bol_rows, obj, wkey, item)
|
||
{
|
||
TToken_string bolkey(wkey);
|
||
const long ndoc = bolkey.get_long(3);
|
||
const long id = bolkey.get_long(4);
|
||
|
||
for (int i = 0; i < doc_in.items(); i++)
|
||
{
|
||
TDocumento& doc = doc_in[i];
|
||
|
||
if (doc.get_long(DOC_NDOC) == ndoc)
|
||
{
|
||
TRiga_documento * bolrow = (TRiga_documento *) doc.get_row_id(id);
|
||
|
||
if (bolrow != NULL)
|
||
{
|
||
const TString8 causale = bolrow->get(RDOC_CODAGG1);
|
||
const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
|
||
if (cau.is_rotto())
|
||
break;
|
||
bool fatturo_ritirato = cau.is_ritiro();
|
||
bool fatturo_consegnato = cau.is_consegna();
|
||
|
||
if (fatturo_ritirato)
|
||
{
|
||
const TCausale_magazzino& rit = cau.causale_ritiro();
|
||
|
||
fatturo_ritirato = rit.sgn(s_consmese) != 0;
|
||
}
|
||
if (fatturo_consegnato)
|
||
{
|
||
const TCausale_magazzino& con = cau.causale_consegna();
|
||
|
||
fatturo_consegnato = con.sgn(s_consmese) != 0;
|
||
}
|
||
|
||
TString str_real = bolrow->get(RDOC_QTA);
|
||
real qta = real(str_real) / ppconf;
|
||
|
||
qta.round();
|
||
if (str_real.full())
|
||
bolrow->put(RDOC_QTAREALE, encode(str_real));
|
||
str_real = bolrow->get(RDOC_QTAGG1);
|
||
|
||
real qtarit = real(str_real);
|
||
|
||
data->distr_rit().add(qtarit);
|
||
if (str_real.full())
|
||
bolrow->put(RDOC_QTARITREALE, encode(str_real));
|
||
if (fatturo_ritirato && !fatturo_consegnato) // ! fatturo il ritirato o fatturo il consegnato
|
||
{
|
||
qtarit = real(str_real) / ppconf;
|
||
qtarit.round();
|
||
data->distr().add(qtarit);
|
||
}
|
||
else
|
||
data->distr().add(qta);
|
||
}
|
||
else
|
||
message_box("Riga_bolla smarrita %d - %s - %ld - id = %ld", bolkey.get_int(1), bolkey.get(0), bolkey.get(3), bolkey.get(4));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
FOR_EACH_ASSOC_OBJECT(bol_rows, obj1, wkey1, item1)
|
||
{
|
||
TToken_string bolkey(wkey);
|
||
const long ndoc = bolkey.get_long(3);
|
||
const long id = bolkey.get_long(4);
|
||
|
||
for (int i = 0; i < doc_in.items(); i++)
|
||
{
|
||
TDocumento& doc = doc_in[i];
|
||
|
||
if (doc.get_long(DOC_NDOC) == ndoc)
|
||
{
|
||
TRiga_documento * bolrow = (TRiga_documento *) doc.get_row_id(id);
|
||
|
||
if (bolrow != NULL)
|
||
{
|
||
const TString8 causale = bolrow->get(RDOC_CODAGG1);
|
||
const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
|
||
if (cau.is_rotto())
|
||
break;
|
||
bool fatturo_ritirato = cau.is_ritiro();
|
||
bool fatturo_consegnato = cau.is_consegna();
|
||
|
||
if (fatturo_ritirato)
|
||
{
|
||
const TCausale_magazzino& rit = cau.causale_ritiro();
|
||
|
||
fatturo_ritirato = rit.sgn(s_consmese) != 0;
|
||
}
|
||
if (fatturo_consegnato)
|
||
{
|
||
const TCausale_magazzino& con = cau.causale_consegna();
|
||
|
||
fatturo_consegnato = con.sgn(s_consmese) != 0;
|
||
}
|
||
|
||
const real qta = data->distr().get() * ppconf;
|
||
const real qtarit = data->distr_rit().get();
|
||
|
||
bolrow->put(RDOC_QTAGG1, qtarit);
|
||
if ((!fatturo_ritirato) || (fatturo_consegnato)) // ! fatturo il ritirato o fatturo il consegnato
|
||
bolrow->put(RDOC_QTA, qta);
|
||
else
|
||
int c = 1; // placeholder
|
||
}
|
||
else
|
||
message_box("Riga_bolla smarrita %d - %s - %ld - id = %ld", bolkey.get_int(1), bolkey.get(0), bolkey.get(3), bolkey.get(4));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for(int h = doc.physical_rows(); h > 0; h--)
|
||
{
|
||
TRiga_documento& rdoc = doc[h];
|
||
if (rdoc.get(RDOC_DESCR).empty() || ((rdoc.imponibile() == ZERO && rdoc.get_real(RDOC_QTA) == ZERO)))
|
||
doc.destroy_row(h, true);
|
||
}
|
||
}
|
||
for (int id = doc_out.items() - 1; id >= 0 ; id--)
|
||
{
|
||
TDocumento& doc = doc_out[id];
|
||
const int rows = doc.physical_rows();
|
||
bool to_delete = true;
|
||
|
||
for (int i = rows; to_delete && i > 0; i--)
|
||
{
|
||
const TRiga_documento& riga = doc[i];
|
||
|
||
if (!riga.is_descrizione())
|
||
to_delete = (riga.imponibile() == ZERO && riga.get_real(RDOC_QTA) == ZERO);
|
||
}
|
||
if (to_delete || doc.totale_doc() == ZERO)
|
||
doc_out.destroy(id);
|
||
}
|
||
for (int id = doc_out.items() - 1; id >= 0 ; id--)
|
||
{
|
||
TDocumento& doc = doc_out[id];
|
||
const TString4 tipocf = doc.get(DOC_TIPOCF);
|
||
const int act_cli = doc.get_long(DOC_CODCF);
|
||
TToken_string key(tipocf);
|
||
|
||
key.add(act_cli);
|
||
|
||
const TRectype & reccli = cache().get(LF_CLIFO, key);
|
||
const long new_cli = reccli.get_long(CLI_CODCFFATT);
|
||
|
||
if (new_cli > 0L)
|
||
{
|
||
doc.put(DOC_CODCF, new_cli);
|
||
key = tipocf;
|
||
key.add(new_cli);
|
||
const TRectype & new_reccliven = cache().get(LF_CFVEN, key);
|
||
TLaundry_contract contr(new_cli, doc.get_long(DOC_CODINDSP), _data_elab);
|
||
|
||
doc.put(DOC_CODINDSP, new_reccliven.get(CFV_CODINDDOC));
|
||
|
||
TString descr;
|
||
TRiga_documento & r = doc.insert_row(1, "05");
|
||
|
||
r.put(RDOC_DESCR, "Consegne effettuate presso\n");
|
||
descr << act_cli << " " << reccli.get(CLI_RAGSOC);
|
||
r.put(RDOC_DESCLUNGA, "X");
|
||
r.put(RDOC_DESCEST, descr);
|
||
if (contr.get_bool(LVCONDV_RAGGCGRUP))
|
||
{
|
||
add_doc_to_list(key, doc);
|
||
doc_out.destroy(id);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//ADD_ROWS: per adesso un segnaposto
|
||
void TFatturazione_lavanderie::add_rows(TRiga_documento & rout, TRiga_documento & rin)
|
||
{
|
||
/*const TString8 causale = rin.get(RDOC_CODAGG1);
|
||
const TRectype& cau = cache().get("&CAU", causale);
|
||
const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1"));
|
||
const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2")); //movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale
|
||
|
||
const long clifo = rin.doc().get_long(DOC_CODCF);
|
||
const int indsped = rin.doc().get_int(DOC_CODINDSP);
|
||
TLaundry_contract contr(clifo, indsped, _data_elab);
|
||
|
||
if (cau.get_bool("B4") && contr.get_int(LVCONDV_ADDCAPROT)) // Guardo se <20> una causale di rotto e se <20> abilitato nella testata del contratto la fatturazione dei rotti
|
||
{
|
||
const real qta = rit.sgn(s_consmese) * rin.get_real(RDOC_QTA);
|
||
rout.put(RDOC_PREZZO,contr.get_int(LVCONDV_PREZROT));
|
||
rout.add(RDOC_QTA, qta);
|
||
}
|
||
else
|
||
{
|
||
if (cau.get_bool("B0"))
|
||
{
|
||
const real qta = rit.sgn(s_consmese) * rin.get_real(RDOC_QTA);
|
||
rout.add(RDOC_QTA, qta);
|
||
|
||
}
|
||
if (cau.get_bool("B1"))
|
||
{
|
||
const real qta = con.sgn(s_consmese) * rin.get_real(RDOC_QTA);
|
||
rout.add(RDOC_QTA, qta);
|
||
}
|
||
} */
|
||
}
|
||
|
||
//CAMPI_RAGGRUPPAMENTO_RIGHE: ridefinisco il metodo campi_raggruppamento_righe della TFatturazione_bolle
|
||
void TFatturazione_lavanderie::campi_raggruppamento_righe(TToken_string& campi_riga) const
|
||
{
|
||
campi_riga = RDOC_CODART"|"RDOC_UMQTA; // Uguali sempre
|
||
const bool ragg_rig = raggruppa_righe();
|
||
if (ragg_rig)
|
||
{
|
||
// Uguali se commesse attive
|
||
if (dongle().active(CAAUT) || dongle().active(CMAUT))
|
||
{
|
||
campi_riga.add(RDOC_CODCMS);
|
||
campi_riga.add(RDOC_FASCMS);
|
||
campi_riga.add(RDOC_CODCOSTO);
|
||
}
|
||
// Uguali opzionalmente
|
||
if (riga_uguale(0)) campi_riga.add(RDOC_CODMAG);
|
||
if (riga_uguale(1)) campi_riga.add(RDOC_CODIVA);
|
||
if (riga_uguale(2))
|
||
{
|
||
const int tipoprezzo = ini_get_int(CONFIG_DITTA, "lv", "TipoPr");
|
||
if(tipoprezzo == 0)
|
||
campi_riga.add(RDOC_SCONTO);
|
||
else
|
||
campi_riga.add(RDOC_PREZZO"|"RDOC_SCONTO);
|
||
}
|
||
}
|
||
}
|
||
|
||
//FIND_OR_CREATE_ROW: questo metodo cerca tra tutte le righe documento della fattura prodotta
|
||
//una eventuale riga lavanderia raggruppabile; se la trova restituiace quella riga, altrimenti
|
||
//ne crea una nuova
|
||
TRiga_documento& TFatturazione_lavanderie::find_or_create_row(TDocumento& doc_out, const TRiga_documento& rin, const char lavtype)
|
||
{
|
||
int r;
|
||
|
||
//scorro le righe documetno
|
||
for (r = doc_out.physical_rows(); r > 0; r--)
|
||
{
|
||
//se trovo una riga raggruppabile e di lavanderia, allora interrompo il ciclo
|
||
if (doc_out[r].raggruppabile(rin, _campi_raggruppamento) && (doc_out[r].get_char("LVTYPE") == lavtype))
|
||
break;
|
||
}
|
||
|
||
//se non ho trovato la riga, ne creo una nuova
|
||
if (r <= 0)
|
||
{
|
||
TRiga_documento& row = doc_out.new_row("01");
|
||
doc_out.copy_data(row, rin);
|
||
row.put(RDOC_TIPORIGA, "01");
|
||
set_perc_provv(row);
|
||
set_perc_provv(row, false);
|
||
|
||
|
||
const TRectype& anamag = cache().get(LF_ANAMAG, rin.get(RDOC_CODART));
|
||
row.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA));
|
||
|
||
row.zero(RDOC_CODAGG1);
|
||
row.zero(RDOC_QTA);
|
||
row.zero(RDOC_QTAGG1);
|
||
row.zero(RDOC_CODMAGC);
|
||
row.put("LVTYPE", lavtype);
|
||
r = row.get_int(RDOC_NRIGA);
|
||
}
|
||
if (fatt_02())
|
||
{
|
||
doc_out.set_row_ids();
|
||
const TString key = format("%04d%04d", doc_out.get_int("FATID"), doc_out[r].get_int(RDOC_IDRIGA));
|
||
TCalc_02_data * data = (TCalc_02_data *) _output_rows_02.objptr(key);
|
||
|
||
if (data == NULL)
|
||
{
|
||
data = new TCalc_02_data(key);
|
||
_output_rows_02.add(key, data);
|
||
}
|
||
TString bolkey = rin.get_rdoc_key();
|
||
data->bol_rows().add(bolkey, bolkey);
|
||
}
|
||
return doc_out[r];
|
||
}
|
||
|
||
//CREATE_ROW: metodo che crea fisicamente la riga sul documento di uscita partendo dal documento di ingresso (bolla)
|
||
void TFatturazione_lavanderie::create_row(TDocumento& doc_out, const TRiga_documento & rin)
|
||
{
|
||
//leggo la causale della riga del documento di ingresso
|
||
const TString8 causale = rin.get(RDOC_CODAGG1);
|
||
const TCausale_lavanderie & cau = cached_causale_lavanderie(causale);
|
||
|
||
//recupero i dati cliente dalla testata del documento e instanzio il contratto
|
||
const long clifo = rin.doc().get_long(DOC_CODCF);
|
||
const int indsped = rin.doc().get_int(DOC_CODINDSP);
|
||
TLaundry_contract contr(clifo, indsped, _data_elab);
|
||
|
||
//leggo dal documento i valori che vanno riportati sulla fattura e recupero la riga contratto
|
||
//di quell'articolo
|
||
const TString80 codart = rin.get(RDOC_CODARTMAG); // non <20> gestito il caso di un articolo fuori contratto
|
||
const real qta = rin.get_real(RDOC_QTA);
|
||
const real qta1 = rin.get_real(RDOC_QTAGG1);
|
||
const TRectype& rcont = contr.row(codart);
|
||
|
||
//leggo dalla configurazione da dove va preso il prezzo
|
||
const int tipoprezzo = ini_get_int(CONFIG_DITTA, "lv", "TipoPr");
|
||
real prezzo;
|
||
//se tipoprezzo == 0 (prezzo da contratto), allora cerco il prezzo sul contratto; se l'articolo
|
||
//non esiste sul contratto, allora cerco il suo prezzo sull'anagrafica di magazzino.
|
||
//Se tipoprezzo == 1 (prezzo da bolla), allora leggo il prezzo sulla riga della bolla
|
||
if (tipoprezzo == 0)
|
||
{
|
||
if (!rcont.empty())
|
||
prezzo = rcont.get_real(LVRCONDV_PREZZO);
|
||
}
|
||
else
|
||
prezzo = rin.get_real(RDOC_PREZZO);
|
||
|
||
//se <20> una causale di rotto e se <20> abilitato nella testata del contratto la fatturazione dei rotti
|
||
//e se sto ritirando una quantit<69> di merce diversa da zero, allora:
|
||
|
||
if (cau.is_rotto() && contr.get_bool(LVCONDV_ADDCAPROT) && !qta1.is_zero())
|
||
{
|
||
//se passo le condizioni iniziali cerco eventualmente una riga che possa essere raggruppata con quella
|
||
//che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> da ritirare
|
||
//al prezzo segnato in contratto
|
||
TRiga_documento& rd = find_or_create_row(doc_out, rin ,'D');
|
||
|
||
rd.put(RDOC_DESCLUNGA, "X");
|
||
rd.put(RDOC_DESCEST, "\nper addebito biancheria");
|
||
rd.add(RDOC_QTA, qta1);
|
||
rd.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZDAN));
|
||
}
|
||
|
||
//se <20> una causale di ritirato e se sto ritirando una quantit<69> di merce diversa da zero, allora:
|
||
if (cau.is_ritiro() && !qta1.is_zero())
|
||
{
|
||
//leggo la casuale di magazzino associata al ritiro e il suo segno sul consegnato mese
|
||
const TCausale_magazzino& rit = cau.causale_ritiro();
|
||
const real sgnrit = rit.sgn(s_consmese);
|
||
|
||
//se movimenta il consegnato mese, cerco eventualmente una riga che possa essere raggruppata con quella
|
||
//che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto ritirando moltiplicata
|
||
//per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
|
||
if (!sgnrit.is_zero())
|
||
{
|
||
TRiga_documento& rr = find_or_create_row(doc_out, rin, 'C');
|
||
rr.add(RDOC_QTA, sgnrit * qta1);
|
||
rr.put(RDOC_PREZZO, prezzo);
|
||
rr.add("TOTRIT", qta1);
|
||
}
|
||
}
|
||
|
||
//se <20> una causale di consegnato e se sto consegnando una quantit<69> di merce diversa da zero, allora:
|
||
if (cau.is_consegna() && !qta.is_zero())
|
||
{
|
||
//leggo la casuale di magazzino associata al ritiro e i suoi segni sul consegnato mese,
|
||
//sulla dotazione temporanea e sulla dotazione iniziale
|
||
const TCausale_magazzino& con = cau.causale_consegna();
|
||
const real sgntmp=con.sgn(s_dottm);
|
||
const real sgndotin=con.sgn(s_dotin);
|
||
const real sgncons=con.sgn(s_consmese);
|
||
|
||
//se movimenta la dotazione temporanea e <20> previsto l'addebito dotazione temporanea con prezzo diverso,
|
||
//cerco eventualmente una riga che possa essere raggruppata con quella che sto guardando adesso,
|
||
//altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
|
||
//per il suo segno al prezzo scritto sul contratto per la dotazine temporanea
|
||
if (!sgntmp.is_zero() && contr.get_bool(LVCONDV_DOTTMPPRZD))
|
||
{
|
||
TRiga_documento& rt = find_or_create_row(doc_out, rin, 'T');
|
||
rt.add(RDOC_QTA, sgntmp * qta);
|
||
rt.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PRZDTTMP));
|
||
}
|
||
|
||
//se movimenta la dotazione iniziale, cerco eventualmente una riga che possa essere raggruppata con quella
|
||
//che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
|
||
//per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
|
||
if (!sgndotin.is_zero() && !sgncons.is_zero())
|
||
{
|
||
TRiga_documento& rc = find_or_create_row(doc_out, rin, 'C');
|
||
rc.add(RDOC_QTA, sgndotin * qta);
|
||
rc.put(RDOC_PREZZO, prezzo);
|
||
}
|
||
else
|
||
{
|
||
//se movimenta il consegnato mese, cerco eventualmente una riga che possa essere raggruppata con quella
|
||
//che sto guardando adesso, altrimenti la creo; in ogni caso aggiungo la quantit<69> che sto consegnando moltiplicata
|
||
//per il suo segno al prezzo ricavato sopra o da contratto (o da magazzino), o da bolla
|
||
if (!sgncons.is_zero())
|
||
{
|
||
TRiga_documento& rc = find_or_create_row(doc_out, rin, 'C');
|
||
rc.add(RDOC_QTA, sgncons * qta);
|
||
rc.put(RDOC_PREZZO, prezzo);
|
||
rc.add("TOTRIT", qta1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//ELABORA: metodo che esegue alcune operazioni prliminari, quali settare la data elaborazione e trovare i campi
|
||
//in base ai quali <20> possibile raggruppare le righe documetno, e poi chiama l'elaborazione standard per la fatturazione
|
||
bool TFatturazione_lavanderie::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
_data_elab = data_elab;
|
||
campi_raggruppamento_righe(_campi_raggruppamento);
|
||
_output_rows_02.destroy();
|
||
return TFatturazione_bolle::elabora(doc_in, doc_out, data_elab, interattivo);
|
||
}
|
||
|
||
/////////////////////////////////
|
||
//// TFatturazione_msk ////
|
||
/////////////////////////////////
|
||
|
||
TFatturazione_msk::TFatturazione_msk():TAutomask("lv2500a")
|
||
{
|
||
//imposto il periodo di fatturazione dal primo del mese precedente all'ultimo del mese precedente
|
||
//se la data odierna <20> inferiore al 10 del mese corrente
|
||
//altrimenti la imposto dal primo del mese corrente alla data odierna
|
||
TDate data(TODAY);
|
||
if (data.day() <= 10)
|
||
{
|
||
data.addmonth(-1);
|
||
data.set_day(1);
|
||
set(F_DADATA, data);
|
||
data.set_end_month();
|
||
set(F_ADATA, data);
|
||
}
|
||
else
|
||
{
|
||
set(F_ADATA, data);
|
||
data.set_day(1);
|
||
set(F_DADATA, data);
|
||
}
|
||
|
||
if (main_app().argc() > 2)
|
||
{
|
||
TString16 tpela = main_app().argv(2);
|
||
tpela = tpela.mid(4);
|
||
TString8 codela = ini_get_string(CONFIG_DITTA, "lv", tpela);
|
||
set(F_COD_ELAB, codela);
|
||
field(F_COD_ELAB).check();
|
||
disable(F_COD_ELAB);
|
||
disable(F_DESC_ELAB);
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////
|
||
//// TFatturazione_lav_app ////
|
||
/////////////////////////////////////
|
||
|
||
//GENERA_BOLLE_NOLO: metodo che genera le fatture di solo nolo per quei clienti a cui non <20> stato consegnato niente
|
||
void TFatturazione_lav_app::genera_bolle_nolo(TAssoc_array& cliela, TFatturazione_lavanderie& elab, int& numdocgen)
|
||
{
|
||
TString4 codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
|
||
TString4 tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
|
||
char stato = cache().get("%TIP", tipodoc, "S2").mid(1,1)[0];
|
||
|
||
//preparo la query sui contratti
|
||
TString str;
|
||
str << "USE LVCONDV";
|
||
|
||
if (_msk->get_long(F_DACODCF) > 0)
|
||
str << "\nFROM CODCF=" << _msk->get_long(F_DACODCF);
|
||
|
||
if (_msk->get_long(F_ACODCF) > 0)
|
||
str << "\nTO CODCF=" << _msk->get_long(F_ACODCF);
|
||
|
||
TISAM_recordset contr(str);
|
||
|
||
TLista_documenti doc_in;
|
||
TLista_documenti doc_out;
|
||
|
||
TProgind pi(contr.items(), "Fatturazione", true, true);
|
||
|
||
for(bool ok = contr.move_first(); ok; ok = contr.move_next())
|
||
{
|
||
pi.set_text(TR("Elaborazione Nolo"));
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
|
||
//scarto i contratti scaduti
|
||
if (contr.get(LVCONDV_DATASC).as_date().ok())
|
||
if (_msk->get_date(F_DADATA) <= contr.get(LVCONDV_DATAIN).as_date() || _msk->get_date(F_ADATA) >= contr.get(LVCONDV_DATASC).as_date())
|
||
continue;
|
||
|
||
//scarto tutti quelli che non sono in periodo di fatturazione corretto
|
||
if (contr.get(LVCONDV_PERFAT).as_int() > _msk->get_int(F_PERFAT))
|
||
continue;
|
||
|
||
// scarto i clienti sospesi
|
||
if (contr.get(LVCONDV_FATTSOSP).as_bool())
|
||
continue;
|
||
|
||
if(cliela.is_key(contr.get(LVCONDV_CODCF).as_string()))
|
||
continue;
|
||
|
||
TDocumento *pdoc= new TDocumento('D', _msk->get_date(F_DATAFAT).year(), codnum, 0);
|
||
|
||
doc_in.add(pdoc);
|
||
TDocumento& doc = *pdoc;
|
||
|
||
doc.put(DOC_TIPODOC, tipodoc);
|
||
doc.put(DOC_STATO, stato);
|
||
doc.put(DOC_TIPOCF, 'C');
|
||
|
||
TLaundry_contract contratto(contr.cursor()->curr());
|
||
|
||
const long codcf = contratto.get_long(LVCONDV_CODCF);
|
||
const int codcont = contratto.get_int(LVCONDV_CODCONT);
|
||
const bool fattnocons = !contratto.get_bool(LVCONDV_FORFNOCONS);
|
||
|
||
doc.put(DOC_CODCF, codcf);
|
||
TToken_string key("C");
|
||
key.add(codcf);
|
||
|
||
const TRectype& clifo = cache().get(LF_CLIFO, key);
|
||
const TString4 codpag = clifo.get(CLI_CODPAG);
|
||
const long codabi = clifo.get_long(CLI_CODABI);
|
||
const long codcab = clifo.get_long(CLI_CODCAB);
|
||
const TString80 iban = clifo.get(CLI_IBAN);
|
||
|
||
//recupero i dati di interesse dal file CFVEN
|
||
const TRectype& cfven = cache().get(LF_CFVEN, key);
|
||
const long codabipr = cfven.get_long(CFV_CODABIPR);
|
||
const long codcabpr = cfven.get_long(CFV_CODCABPR);
|
||
const bool ragdoc = cfven.get_bool(CFV_RAGGDOC);
|
||
const TString8 codag1 = cfven.get(CFV_CODAG1);
|
||
const TString4 codmez = cfven.get(CFV_CODSPMEZZO);
|
||
const TString4 codporto = cfven.get(CFV_CODPORTO);
|
||
const TString4 codnote1 = cfven.get(CFV_CODNOTESP1);
|
||
const TString4 codnote2 = cfven.get(CFV_CODNOTESP2);
|
||
const TString4 codnote = cfven.get(CFV_CODNOTE);
|
||
const TString8 codvet1 = cfven.get(CFV_CODVETT1);
|
||
const TString8 codvet2 = cfven.get(CFV_CODVETT2);
|
||
const TString8 codvet3 = cfven.get(CFV_CODVETT3);
|
||
const real speseinc = cfven.get_real(CFV_PERCSPINC);
|
||
const TString4 catven = cfven.get(CFV_CATVEN);
|
||
const bool addbolli = cfven.get_bool(CFV_ADDBOLLI);
|
||
const TString8 codlist = cfven.get(CFV_CODLIST);
|
||
const TString4 codzona = cfven.get(CFV_CODZONA);
|
||
|
||
//gestione sconto
|
||
TString sconto;
|
||
|
||
const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0];
|
||
switch(tpgest)
|
||
{
|
||
case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente
|
||
case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti
|
||
case 'A': //Gestione archivio sconti
|
||
{
|
||
TConfig ditta(CONFIG_DITTA, "ve");
|
||
|
||
TLocalisamfile sconti(LF_SCONTI);
|
||
sconti.put("TIPO", "I");
|
||
|
||
if(ditta.get_bool("SCOKEY", "ve", 1))
|
||
sconti.put("CODCAT", cfven.get(CFV_CATVEN));
|
||
|
||
TString16 cod;
|
||
if(ditta.get_bool("SCOKEY", "ve", 2))
|
||
cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC));
|
||
else
|
||
cod = " ";
|
||
|
||
if(ditta.get_bool("SCOKEY", "ve", 3))
|
||
{
|
||
TString8 tmp;
|
||
tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA));
|
||
cod << tmp;
|
||
}
|
||
else
|
||
cod << " ";
|
||
|
||
if(ditta.get_bool("SCOKEY", "ve", 4))
|
||
cod << clifo.get(CLI_CODPAG);
|
||
|
||
sconti.put("CODART", cod);
|
||
|
||
if (sconti.read() == NOERR)
|
||
sconto = sconti.get("SCONTO");
|
||
}
|
||
case 'N': //sconto non gestito
|
||
default: break;
|
||
}
|
||
|
||
doc.put(DOC_CODPAG, codpag);
|
||
doc.put(DOC_CODABIA, codabi);
|
||
doc.put(DOC_CODCABA, codcab);
|
||
doc.put(DOC_IBAN, iban);
|
||
doc.put(DOC_CODABIP, codabipr);
|
||
doc.put(DOC_CODCABP, codcabpr);
|
||
doc.put(DOC_CODAGVIS, codag1);
|
||
doc.put(DOC_CODSPMEZZO, codmez);
|
||
doc.put(DOC_ZONA, codzona);
|
||
doc.put(DOC_CODPORTO, codporto);
|
||
doc.put(DOC_CODNOTESP1, codnote1);
|
||
doc.put(DOC_CODNOTESP2, codnote2);
|
||
doc.put(DOC_CODNOTE, codnote);
|
||
doc.put(DOC_CODVETT1, codvet1);
|
||
doc.put(DOC_CODVETT2, codvet2);
|
||
doc.put(DOC_CODVETT3, codvet3);
|
||
doc.put(DOC_CATVEN, catven);
|
||
doc.put(DOC_CODLIST, codlist);
|
||
doc.put(DOC_PERCSPINC, speseinc);
|
||
doc.put(DOC_ADDBOLLI, addbolli);
|
||
doc.put(DOC_SCONTOPERC, sconto);
|
||
|
||
TString str;
|
||
str << "USE LVRCONDV\n"
|
||
<< "FROM CODCF=" << codcf << " CODCONT=" << codcont << "\n"
|
||
<< "TO CODCF=" << codcf << " CODCONT=" << codcont;
|
||
|
||
TISAM_recordset rcont(str);
|
||
|
||
for(bool ok = rcont.move_first(); ok; ok = rcont.move_next())
|
||
{
|
||
TRectype& riga = rcont.cursor()->curr();
|
||
const int tipoforf = riga.get_int(LVRCONDV_TIPOFORF);
|
||
|
||
if (tipoforf > 0 &&
|
||
((tipoforf == 2) ||
|
||
(tipoforf != 2 && fattnocons)))
|
||
{
|
||
TRiga_documento& rdoc = doc.new_row("21");
|
||
|
||
rdoc.put(RDOC_CODART, riga.get(LVRCONDV_CODART));
|
||
rdoc.put(RDOC_CODARTMAG, riga.get(LVRCONDV_CODART));
|
||
rdoc.put(RDOC_QTA, UNO);
|
||
rdoc.put(RDOC_QTAGG1, UNO);
|
||
rdoc.put(RDOC_PREZZO, riga.get_real(LVRCONDV_PREZNOL));
|
||
rdoc.put(RDOC_CHECKED, true);
|
||
rdoc.put(RDOC_UMQTA, riga.get(LVRCONDV_UM));
|
||
|
||
TToken_string key;
|
||
key.add('C');
|
||
key.add(codcf);
|
||
TString8 codiva = cache().get(LF_CFVEN, key, CFV_ASSFIS);
|
||
if (codiva.blank())
|
||
codiva = cache().get(LF_ANAMAG, riga.get(LVRCONDV_CODART), ANAMAG_CODIVA);
|
||
|
||
rdoc.put(RDOC_CODIVA, codiva);
|
||
|
||
rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"));
|
||
elab.set_perc_provv(rdoc);
|
||
elab.set_perc_provv(rdoc, false);
|
||
}
|
||
}
|
||
|
||
if (ini_get_bool(CONFIG_DITTA, "lv", "RifTest"))
|
||
elab.put("B15", true); //forzo la descrizione abbreviata
|
||
|
||
if (doc.physical_rows() > 0)
|
||
{
|
||
elab.elabora(doc_in, doc_out, _msk->get_date(F_DATAFAT));
|
||
int err = doc_out.write();
|
||
numdocgen += doc_out.items();
|
||
}
|
||
|
||
doc_out.destroy(-1);
|
||
|
||
doc_in.destroy(-1);
|
||
}
|
||
}
|
||
|
||
//CONTROLLI PRELIMINARI: metodo che si preoccupa di ferivicare la presenza in configurazione di tutti
|
||
//i dati necessari alla fatturazione
|
||
bool TFatturazione_lav_app::controlli_preliminari()
|
||
{
|
||
bool corretto = true;
|
||
|
||
//controllo se il tipo documento <20> configurato
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "NUM_FAT").empty() || ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_FAT").empty())
|
||
{
|
||
warning_box(TR("Il Tipo documento fattura non <20> configurato correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
//controllo se le causali di dafault sono configurate
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV").empty())
|
||
{
|
||
warning_box(TR("La causale di default non <20> configurata correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "CAULVRITDT").empty())
|
||
{
|
||
warning_box(TR("La causale di default non <20> configurata correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
//controllo se l'articolo per il canone fisso <20> configurato
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "Codartfix").empty())
|
||
{
|
||
warning_box(TR("L'articolo per canone fisso non <20> configurato correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
//controllo se l'articolo per il raggruppamento <20> configurato
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "Codartcafix").empty())
|
||
{
|
||
warning_box(TR("L'articolo per il raggruppamento non <20> configurato correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
//controllo se l'articolo per il raggruppamento <20> configurato
|
||
if (ini_get_string(CONFIG_DITTA, "lv", "Codartcofix").empty())
|
||
{
|
||
warning_box(TR("L'articolo per il valore convenzionale non <20> configurato correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
//controllo se l'unit<69> di misura per la fatturazioni a Kg <20> settata
|
||
if(ini_get_string(CONFIG_DITTA, "lv", "UmKg").empty())
|
||
{
|
||
warning_box(TR("L'unit<69> di misura per la fatturazione a Kg non <20> configurata correttamente"));
|
||
corretto = false;
|
||
}
|
||
|
||
return corretto;
|
||
}
|
||
|
||
void TFatturazione_lav_app::main_loop()
|
||
{
|
||
bool prova = false;
|
||
|
||
if (main_app().argc() > 2)
|
||
{
|
||
TString16 tpela = main_app().argv(2);
|
||
tpela = tpela.mid(4);
|
||
prova = (tpela == "FatPro");
|
||
}
|
||
|
||
//instanzio la maschera
|
||
_msk = new TFatturazione_msk();
|
||
if (lv_is_02_active())
|
||
_msk->field(F_COD_ELAB).set_prompt("@BTipo Fatturazione ");
|
||
|
||
|
||
//instanzio i localisamfile che mi servono
|
||
TLocalisamfile doc(LF_DOC);
|
||
TLocalisamfile rdoc(LF_RIGHEDOC);
|
||
|
||
while (_msk->run()!= K_QUIT)
|
||
{
|
||
if (!controlli_preliminari())
|
||
{
|
||
TString str;
|
||
str << "Prima di poter eseguire la fatturazione <20> necessario correggre tutti gli errori segnalati. "
|
||
<< "Si prega di controllare i dati di configurazione";
|
||
warning_box(str);
|
||
return;
|
||
}
|
||
|
||
//leggo i dati di primo interesse
|
||
const TString4 mskzona = _msk->get(F_CODZONA);
|
||
const TString4 mskcat = _msk->get(F_CODCATC);
|
||
//preparo le date estremi (dal - al) della query e l'anno dell'esercizio
|
||
TDate al = _msk->get_date(F_ADATA);
|
||
//se la data "al" non <20> corretta, la pongo uguale alla data fattura
|
||
if (!al.ok())
|
||
al = _msk->get_date(F_DATAFAT);
|
||
|
||
const long year = al.year();
|
||
|
||
TDate dal = _msk->get_date(F_DADATA);
|
||
//se la data "dal" non <20> corretta, la pongo uguale a 1/1/annoes
|
||
if (!dal.ok())
|
||
{
|
||
dal.set_day(1);
|
||
dal.set_month(1);
|
||
dal.set_year(year);
|
||
}
|
||
|
||
//instanzio una TFatturaziome_lavanderie
|
||
TFatturazione_lavanderie elab(_msk->get(F_COD_ELAB), prova);
|
||
//preparo le variabili di interesse
|
||
TLista_documenti docsin;
|
||
TLista_documenti docsout;
|
||
long lastcli = 0;
|
||
const int period = _msk->get_int(F_PERFAT);
|
||
const TDate datafat = _msk->get_date(F_DATAFAT);
|
||
long indsped;
|
||
|
||
//preparo la query
|
||
TString query;
|
||
//&&(BETWEEN(DATADOC,#DADATA,#ADATA))&&(STATO==\"2\")&&(TIPODOC==\"B01\")
|
||
query << "USE DOC KEY 3 SELECT (TIPOCF==\"C\")&&"
|
||
<< "(BETWEEN(CODCF," << _msk->get_long(F_DACODCF) << ',' << _msk->get_long(F_ACODCF) << "))\n"
|
||
<< "BY TIPOCF CODCF DATADOC\n"
|
||
<< "FROM DATADOC=" << dal << " PROVV=D ANNO=" << year << "\n"
|
||
<< "TO DATADOC=" << al << " PROVV=D ANNO=" << year << "\n";
|
||
// query << "USE DOC KEY 2 SELECT BETWEEN(DATADOC,#DADATA,#ADATA)&&STATO==\"2\")&&(TIPODOC==\"B01\")\n"
|
||
// << "FROM " << "TIPOCF=C PROVV=D ANNO=#ANNO DATADOC=#DADATA \n"
|
||
// << "TO " << "TIPOCF=C PROVV=D ANNO=#ANNO DATADOC=#ADATA \n";
|
||
|
||
//instanzio il recordset
|
||
TISAM_recordset recset(query);
|
||
TProgind pi(recset.items(), "Fatturazione", true, true);
|
||
long last_clifo = 0;
|
||
int numdocgen = 0;
|
||
|
||
//TAssoc_array dei clienti per cui ho generato dei documenti
|
||
TAssoc_array cliela;
|
||
//scorro tutti documenti che la query mi restiuisce
|
||
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
||
{
|
||
//leggo il codcf
|
||
const long clifo = recset.get(DOC_CODCF).as_int();
|
||
if (clifo != last_clifo)
|
||
{
|
||
TString80 str;
|
||
str << TR("Elaborazione Cliente ") << clifo;
|
||
pi.set_text(str);
|
||
last_clifo=clifo;
|
||
}
|
||
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
|
||
//se non <20> l'ultimo cliente, allora:
|
||
if (clifo != lastcli)
|
||
{
|
||
//se effettivamente devo elaborare delle bolle per questo cliente, allora:
|
||
if (docsin.items()!= 0)
|
||
{
|
||
//elaboro tutti i documenti, li salvo nei file di Campo e svuoto le TList_file
|
||
elab.put("B15", 'X');
|
||
elab.elabora(docsin, docsout, datafat);
|
||
const int items = docsout.items();
|
||
if (items > 0)
|
||
{
|
||
docsout.write();
|
||
numdocgen += items;
|
||
TString tmp;
|
||
tmp << lastcli;
|
||
cliela.add(tmp, tmp);
|
||
}
|
||
|
||
docsout.destroy(-1);
|
||
docsin.rewrite();
|
||
docsin.destroy(-1);
|
||
}
|
||
lastcli = clifo;
|
||
}
|
||
|
||
//preparo la chiave e recupero da CFVEN i dati di quel cliente
|
||
TToken_string key;
|
||
key.add('C');
|
||
key.add(clifo);
|
||
const TRectype& clienti = cache().get(LF_CFVEN,key);
|
||
|
||
//se il documento che sto analizzando <20> corretto, allora:
|
||
bool cliok = elab.is_document_ok(recset.cursor()->curr());
|
||
if (cliok)
|
||
{
|
||
//se il codice di zona <20> pieno, allora:
|
||
if (mskzona.full())
|
||
{
|
||
//leggo il codice di zona standard di quel cliente e lo confronto con quello della mascera (V o F)
|
||
const TString& codzona = clienti.get(CFV_CODZONA);
|
||
cliok = (codzona == mskzona);
|
||
}
|
||
|
||
//se il codice categoria economica <20> pieno e ho passato il test sul codice di zona, allora:
|
||
if (cliok && mskcat.full())
|
||
{
|
||
//leggo il codice categoria economica standard di quel cliente e lo confronto con quello della mascera (V o F)
|
||
const TString& codcat = clienti.get(CFV_CODCATC);
|
||
cliok = (codcat == mskcat);
|
||
}
|
||
}
|
||
|
||
//se ho passato tutti e due i test, allora:
|
||
if (cliok)
|
||
{
|
||
//cerco sul contratto qual'<27> il periodo di fatturazione di quel cliente
|
||
indsped = recset.get(DOC_CODINDSP).as_int();
|
||
TLaundry_contract contr(clifo, indsped, datafat);
|
||
const int contrper = contr.get_int(LVCONDV_PERFAT);
|
||
|
||
//se il cliente non <20> sospeso e se si <20> nel periodo di fatturazione giusto, aggiungo il documento alla
|
||
//lista dei documetni da elaborare
|
||
if (!contr.get_bool(LVCONDV_FATTSOSP) && contrper <= period)
|
||
docsin.add(new TDocumento(recset.cursor()->curr()));
|
||
}
|
||
}
|
||
|
||
//se ho dei documenti in lista li elaboro e poi svuoto le TList_file
|
||
if (docsin.items() != 0)
|
||
{
|
||
if (ini_get_bool(CONFIG_DITTA, "lv", "RifTest"))
|
||
elab.put("B15", true); //forzo la descrizione abbreviata
|
||
elab.elabora(docsin, docsout, datafat);
|
||
|
||
const int items = docsout.items();
|
||
if (items > 0)
|
||
{
|
||
docsout.write();
|
||
numdocgen += items;
|
||
TString tmp;
|
||
tmp << lastcli;
|
||
cliela.add(tmp, tmp);
|
||
}
|
||
docsout.destroy(-1);
|
||
docsin.rewrite();
|
||
docsin.destroy(-1);
|
||
}
|
||
|
||
genera_bolle_nolo(cliela, elab, numdocgen);
|
||
numdocgen += elab.write_fatt_ragg();
|
||
|
||
TString str;
|
||
|
||
if (numdocgen > 1 || numdocgen == 0)
|
||
str << "Sono state generate " << numdocgen << " fatture";
|
||
else
|
||
str << "E' stata generata " << numdocgen << " fattura";
|
||
|
||
message_box(str);
|
||
message_box(TR("Elaborazione terminata"));
|
||
}
|
||
}
|
||
|
||
int lv2500(int argc, char *argv[])
|
||
{
|
||
TFatturazione_lav_app a;
|
||
a.run (argc, argv, "Fatturazione lavanderie");
|
||
return TRUE;
|
||
}
|