Patch level : 10.0 patch 300

Files correlati     : lv2.exe
Ricompilazione Demo : [ ]
Commento            :
Commentato tutto il prgramma

0001316: Lancio fatturazione per codice Zona
Descrizione: Ho lanciato la fatturazione per codice zona
dopo aver modificato le anagrafiche clienti suddividendo
i clienti che avevano bolle su 3 tipi di zona

01,02 e vuoto

la fatturazione lanciata per la zona 01 mi ha fatturato comunque tutti


git-svn-id: svn://10.65.10.50/trunk@18869 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
luca83 2009-05-13 13:53:31 +00:00
parent f4d2eee18b
commit ae9cab503a

View File

@ -9,20 +9,19 @@
#include "lvrcondv.h" #include "lvrcondv.h"
#include "rdoc.h" #include "rdoc.h"
#include "../ve/ve6200.h" #include "../ve/ve6200.h"
#include "../ve/ve6200a.h" #include "../ve/ve6200a.h"
/////////////////////////////////////////////////////////// ////////////////////////////////////////
// TFatturazione_lavanderie //// TFatturazione_lavanderie ////
/////////////////////////////////////////////////////////// ////////////////////////////////////////
//Classe TFatturazione_lavanderie
class TFatturazione_lavanderie:public TFatturazione_bolle class TFatturazione_lavanderie:public TFatturazione_bolle
{ {
TDate _data_elab; TDate _data_elab;
TToken_string _campi_raggruppamento; TToken_string _campi_raggruppamento;
protected: protected:
virtual void add_rows(TRiga_documento & rout, TRiga_documento & rin); virtual void add_rows(TRiga_documento & rout, TRiga_documento & rin);
virtual void create_row(TDocumento& doc_out, const TRiga_documento & rin); virtual void create_row(TDocumento& doc_out, const TRiga_documento & rin);
@ -51,6 +50,8 @@ TFatturazione_lavanderie::TFatturazione_lavanderie(const char* cod)
{ {
} }
//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 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()) if (doc_in.ha_riga_esenzione() != doc_out.ha_riga_esenzione())
@ -58,7 +59,10 @@ bool TFatturazione_lavanderie::doc_raggruppabili(const TDocumento& doc_in, const
bool ok = true; bool ok = true;
TString campo; TString campo;
for (const char* c = campi.get(0); c && ok; c = campi.get()) //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) if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0)
{ {
@ -74,6 +78,7 @@ bool TFatturazione_lavanderie::doc_raggruppabili(const TDocumento& doc_in, const
return ok; return ok;
} }
//DA_RAGGRUPPARE: per adesso segnaposto: resituisce sempre false
bool TFatturazione_lavanderie::da_raggruppare(const TRiga_documento & rin) bool TFatturazione_lavanderie::da_raggruppare(const TRiga_documento & rin)
{ {
/* const long clifo = rin.doc().get_long(DOC_CODCF); /* const long clifo = rin.doc().get_long(DOC_CODCF);
@ -107,31 +112,43 @@ bool TFatturazione_lavanderie::da_raggruppare(const TRiga_documento & rin)
return false; return false;
} }
//POST_PROCESS_OUTPUT: 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_output(TLista_documenti& doc_out) void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
{ {
for (int id = 0; id < doc_out.items(); id++) //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]; TDocumento& doc = doc_out[id];
const long clifo = doc.get_long(DOC_CODCF); const long clifo = doc.get_long(DOC_CODCF);
const int indsped = doc.get_int(DOC_CODINDSP); const int indsped = doc.get_int(DOC_CODINDSP);
TLaundry_contract contr(clifo,indsped,_data_elab); TLaundry_contract contr(clifo,indsped,_data_elab);
bool valconvcli=false; //flag per il calcolo sul valore convenzionale e sul fisso per dotazione iniziale
bool fixdotin=false; bool valconvcli = false;
bool fixdotin = false;
//per ogni documento, scorro tutte le sue righe
for (int i = 1; i <= doc.physical_rows(); i++) for (int i = 1; i <= doc.physical_rows(); i++)
{ {
TRiga_documento& rout = doc[i]; TRiga_documento& rout = doc[i];
const TString80 codart=rout.get(RDOC_CODART); const TString80 codart = rout.get(RDOC_CODART);
const TRectype & rcont=contr.row(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 tipodot = rcont.get(LVRCONDV_NOLCIC);
const TString4 artcli = rcont.get(LVRCONDV_VCARTCLI); const TString4 artcli = rcont.get(LVRCONDV_VCARTCLI);
real dot; real dot;
const int annoes = _data_elab.year(); const int annoes = _data_elab.year();
//instanzio il TArticolo_lavanderia
TArticolo_lavanderie artlav(codart, 'C', clifo, indsped); TArticolo_lavanderie artlav(codart, 'C', clifo, indsped);
const int index = artlav.find_clifomag(annoes); //cerco la giacenza per articolo dell'articolo esaminato
const int index = artlav.find_clifomag(annoes);
//se lo trovo e se il tipo dotazione è iniziale 'I', allora leggo la dotazione iniziale
//dalle giacenze articolo per cliente, altrimenti leggo la dotazione odierna
if (index >=0) if (index >=0)
{ {
if (tipodot=="I") if (tipodot=="I")
@ -140,22 +157,27 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
dot=artlav.clifomag(annoes)[index].get_real("DOTOD"); dot=artlav.clifomag(annoes)[index].get_real("DOTOD");
} }
//leggo dalla riga contratto il tipo forfait
const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF); const int tipoforf = rcont.get_int(LVRCONDV_TIPOFORF);
switch (tipoforf) switch (tipoforf)
{ {
case 0: case 0: //forfait = NESSUNO
break; break;
case 1: case 1: //forfait = A VALORE FISSO
{ {
rout.put(RDOC_QTA, UNO); rout.put(RDOC_QTA, UNO); //qta fissa a UNO
rout.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_IMPFISART)); 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 // gestione in base codice per valore fisso ??? tolta la scelta dell'articolo o del cliente
} }
break; break;
case 2: case 2: //forfait = NOLO
{ {
TRiga_documento& nolorow=doc.insert_row(++i, "01"); //aggiungo una riga tipo merce, che contiene tutti i dati della riga del documento
//di partenza, poi costruisco la descrizione in base alla periodicità di fatturazione,
//metto la qta uguale alla dotazione che ho appena letto
//e prendo il prezzo nolo dalla riga contratto
TRiga_documento& nolorow=doc.insert_row(++i, "01");
doc.copy_data(nolorow,rout); doc.copy_data(nolorow,rout);
TString80 descr("Nolo"); TString80 descr("Nolo");
const int contrper = contr.get_int(LVCONDV_PERFAT); const int contrper = contr.get_int(LVCONDV_PERFAT);
@ -183,21 +205,32 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
nolorow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZNOL)); nolorow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZNOL));
} }
break; break;
case 3: // Tipo forfait = CICLAGGIO case 3: //forfait = CICLAGGIO
{ {
const real qta=rout.get_real(RDOC_QTA); //leggo la quantità consegnata e calcolo consumo e ciclaggio secondo le formule
const real consumo=qta * rout.get_real(RDOC_PREZZO); //CONSUMO = QTA * PREZZO(dalla riga documento)
const real ciclaggio=dot * rcont.get_real(LVRCONDV_PREZZO) * rcont.get_real(LVRCONDV_MINCIC); //CLICLAGGIO = DOT * PREZZO(dalla riga contratto) * MINIMO CICLAGGIO
if (consumo<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 è minore del ciclaggio, allora
if (consumo < ciclaggio)
{ {
const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO); //leggo il flag del tipo ciclaggio
const real cicl=rcont.get_real(LVRCONDV_MINCIC)*dot; 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 è su due linee, allora aggiungo una riga merce, per pareggiare il minimo ciclaggio
//che ha come quantità la differenza tra la quantità di minimo cilcaggio
//e la quantità effettivamente consegnata e come prezzo il prezzo preso dalla riga contratto;
//altimenti correggo quantità e prezzo direttamente sulla riga documento che sto analizzando
if (cicl2rig) if (cicl2rig)
{ {
TRiga_documento& congrow=doc.insert_row(++i, "01"); TRiga_documento& congrow = doc.insert_row(++i, "01");
doc.copy_data(congrow,rout); doc.copy_data(congrow,rout);
congrow.put(RDOC_DESCR,"Pareggio minimo ciclaggio"); congrow.put(RDOC_DESCR,"Pareggio minimo ciclaggio");
congrow.put(RDOC_QTA, cicl-qta); congrow.put(RDOC_QTA, cicl - qta);
congrow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO)); congrow.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZZO));
} }
else else
@ -208,22 +241,33 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
} }
} }
break; break;
case 4: // Tipo forfait = & SUL VALORE CONVENZIONALE 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); const char tipovalconv = rcont.get_char(LVRCONDV_VCARTCLI);
if (tipovalconv=='A') // //se la percentuale sul valore convenzionale è sull'articolo, allora:
if (tipovalconv == 'A')
{ {
const real qta=rout.get_real(RDOC_QTA); //leggo la quantità consegnata e calcolo consumo e importo convenzionale secondo le formule
const real consumo=qta * rout.get_real(RDOC_PREZZO); //CONSUMO = QTA * PREZZO(dalla riga documento)
const real impconv=dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL); //IMPCONV = DOT * PREZZO(dalla riga contratto) * PERCENTUALE DI FORFAIT CLIENTE
if (consumo<impconv) 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);
//se il consumo è minore del ciclaggio, allora
if (consumo < impconv)
{ {
const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO); const bool cicl2rig = contr.get_bool(LVCONDV_CICLAGGIO);
//se il ciclaggio è su due linee, allora aggiungo una riga merce, che contiene
//il conguaglio al valore convenzionale, che ha come quantità la costante UNO
//e come prezzo la differenza tra l'importo convenzionale e il consumo;
//altimenti correggo quantità e prezzo direttamente sulla riga documento che sto analizzando
if (cicl2rig) if (cicl2rig)
{ {
TRiga_documento& congrow=doc.insert_row(++i, "01"); TRiga_documento& congrow = doc.insert_row(++i, "01");
doc.copy_data(congrow,rout); doc.copy_data(congrow, rout);
congrow.put(RDOC_DESCR,"Conguaglio valore convenzionale"); congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
congrow.put(RDOC_QTA, UNO); congrow.put(RDOC_QTA, UNO);
congrow.put(RDOC_PREZZO, impconv - consumo); congrow.put(RDOC_PREZZO, impconv - consumo);
} }
@ -236,31 +280,45 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
} }
else else
{ {
//se la percentuale sul valore convenzionale è sul cliente, allora se il flag valconvcli è false
if (!valconvcli) if (!valconvcli)
{ {
valconvcli=true; //pongo valconvcli a true in modo da non tornare più in questo if
valconvcli = true;
//instanzio i due real che andranno a contenere l'importo covenzionale totale e il consumo totale
real impconvtot; real impconvtot;
real consumotot; real consumotot;
//scorro tutte le righe documento dalla riga in esame fino alla fine
for (int j = i; j < doc.physical_rows(); j++) 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 è sul cliente
TRiga_documento& riga = doc[j]; TRiga_documento& riga = doc[j];
const TString80 codart=riga.get(RDOC_CODART); const TString80 codart = riga.get(RDOC_CODART);
const TRectype & rcont=contr.row(codart); const TRectype & rcont = contr.row(codart);
const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI); const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
if (tipvalconvcli=='C') if (tipvalconvcli == 'C')
{ {
impconvtot += dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL); impconvtot += dot * rcont.get_real(LVRCONDV_VALCONV) * rcont.get_real(LVRCONDV_FORFPERCL);
consumotot += riga.get_real(RDOC_QTA) * riga.get_real(RDOC_PREZZO); consumotot += riga.get_real(RDOC_QTA) * riga.get_real(RDOC_PREZZO);
} }
} }
if (consumotot<impconvtot) //se il consumo è minore del ciclaggio, allora
if (consumotot < impconvtot)
{ {
const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO); const bool cicl2rig=contr.get_bool(LVCONDV_CICLAGGIO);
//se il ciclaggio è su due linee, allora aggiungo una riga merce, che contiene
//il conguaglio al valore convenzionale, che ha come quantità la costante UNO
//e come prezzo la differenza tra l'importo convenzionale totale e il consumo totale;
//altimenti correggo quantità 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) if (cicl2rig)
{ {
TRiga_documento& congrow=doc.insert_row(++i, "01"); TRiga_documento& congrow=doc.insert_row(++i, "01");
doc.copy_data(congrow,rout); doc.copy_data(congrow, rout);
congrow.put(RDOC_DESCR,"Conguaglio valore convenzionale"); congrow.put(RDOC_DESCR, "Conguaglio valore convenzionale");
congrow.put(RDOC_QTA, UNO); congrow.put(RDOC_QTA, UNO);
congrow.put(RDOC_PREZZO, impconvtot - consumotot); congrow.put(RDOC_PREZZO, impconvtot - consumotot);
} }
@ -268,14 +326,14 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
{ {
rout.put(RDOC_QTA, UNO); rout.put(RDOC_QTA, UNO);
rout.put(RDOC_PREZZO, impconvtot); rout.put(RDOC_PREZZO, impconvtot);
for (int k = doc.physical_rows(); k>i; k--) for (int k = doc.physical_rows(); k > i; k--)
{ {
TRiga_documento& delrow = doc[k]; TRiga_documento& delrow = doc[k];
const TString80 codart=delrow.get(RDOC_CODART); const TString80 codart = delrow.get(RDOC_CODART);
const TRectype & rcont=contr.row(codart); const TRectype& rcont = contr.row(codart);
const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI); const char tipvalconvcli = rcont.get_char(LVRCONDV_VCARTCLI);
if (tipvalconvcli=='C') if (tipvalconvcli == 'C')
doc.destroy_row(k,true); doc.destroy_row(k, true);
} }
} }
} }
@ -283,7 +341,7 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
} }
} }
break; break;
case 5: case 5: //forfait = FISSO SU DOTAZIONE INIZIALE
{ {
// if (!fixdotin) // if (!fixdotin)
// { // {
@ -310,7 +368,7 @@ void TFatturazione_lavanderie::post_process_output(TLista_documenti& doc_out)
} }
//ADD_ROWS: per adesso un segnaposto
void TFatturazione_lavanderie::add_rows(TRiga_documento & rout, TRiga_documento & rin) void TFatturazione_lavanderie::add_rows(TRiga_documento & rout, TRiga_documento & rin)
{ {
/*const TString8 causale = rin.get(RDOC_CODAGG1); /*const TString8 causale = rin.get(RDOC_CODAGG1);
@ -344,121 +402,162 @@ void TFatturazione_lavanderie::add_rows(TRiga_documento & rout, TRiga_documento
} */ } */
} }
//CAMPI_RAGGRUPPAMENTO_RIGHE: ridefinisco il metodo campi_raggruppamento_righe della TFatturazione_bolle
void TFatturazione_lavanderie::campi_raggruppamento_righe(TToken_string& campi_riga) const void TFatturazione_lavanderie::campi_raggruppamento_righe(TToken_string& campi_riga) const
{ {
//richiamo la funzione standard
TFatturazione_bolle::campi_raggruppamento_righe(campi_riga); TFatturazione_bolle::campi_raggruppamento_righe(campi_riga);
//se lo standard lascia campi_riga vuota, allora la pongo uguale a "CODART|UMQTA"
//che sono sicuramente sempre uguali
if (campi_riga.empty()) if (campi_riga.empty())
campi_riga = "CODART|UMQTA"; // Uguali sempre campi_riga = "CODART|UMQTA"; // Uguali sempre
} }
TRiga_documento& TFatturazione_lavanderie::find_or_create_row(TDocumento& doc_out, const TRiga_documento & rin,const char lavtype) //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
const TString80 codart=rin.get(RDOC_CODARTMAG); //ne crea una nuova
TRiga_documento& TFatturazione_lavanderie::find_or_create_row(TDocumento& doc_out, const TRiga_documento& rin, const char lavtype)
{
int r; int r;
//scorro le righe documetno
for (r=doc_out.physical_rows();r>0;r--) 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)) if (doc_out[r].raggruppabile(rin, _campi_raggruppamento) && (doc_out[r].get_char("LVTYPE") == lavtype))
break; break;
if (r<=0)
//se non ho trovato la riga, ne creo una nuova
if (r <= 0)
{ {
TRiga_documento& row=doc_out.new_row("01"); TRiga_documento& row = doc_out.new_row("01");
doc_out.copy_data(row,rin); doc_out.copy_data(row, rin);
row.put(RDOC_TIPORIGA, "01"); row.put(RDOC_TIPORIGA, "01");
row.zero(RDOC_CODAGG1); row.zero(RDOC_CODAGG1);
row.zero(RDOC_QTA); row.zero(RDOC_QTA);
row.zero(RDOC_QTAGG1); row.zero(RDOC_QTAGG1);
row.zero(RDOC_CODMAGC); row.zero(RDOC_CODMAGC);
row.put("LVTYPE",lavtype); row.put("LVTYPE", lavtype);
r=row.get_int(RDOC_NRIGA); r = row.get_int(RDOC_NRIGA);
} }
return doc_out[r];
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) 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 TString8 causale = rin.get(RDOC_CODAGG1);
const TRectype& cau = cache().get("&CAU", causale); const TRectype& cau = cache().get("&CAU", causale);
//recupero i dati cliente dalla testata del documento e instanzio il contratto
const long clifo = rin.doc().get_long(DOC_CODCF); const long clifo = rin.doc().get_long(DOC_CODCF);
const int indsped = rin.doc().get_int(DOC_CODINDSP); const int indsped = rin.doc().get_int(DOC_CODINDSP);
TLaundry_contract contr(clifo, indsped, _data_elab); TLaundry_contract contr(clifo, indsped, _data_elab);
const TString80 codart=rin.get(RDOC_CODARTMAG); //leggo dal documento i valori che vanno riportati sulla fattura e recupero la riga contratto
const real qta=rin.get_real(RDOC_QTA); //di quell'articolo
const real qta1=rin.get_real(RDOC_QTAGG1); const TString80 codart = rin.get(RDOC_CODARTMAG);
const TRectype & rcont=contr.row(codart); const real qta = rin.get_real(RDOC_QTA);
const int tipoprezzo=ini_get_int(CONFIG_DITTA, "lv", "TipoPr"); const real qta1 = rin.get_real(RDOC_QTAGG1);
real prezzo=rin.get_real(RDOC_PREZZO); 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 (tipoprezzo == 0)
{ {
if (rcont.empty()) if (rcont.empty())
{ {
TArticolo& art=cached_article(codart); TArticolo& art = cached_article(codart);
const TString& um=rin.get(RDOC_UMQTA); const TString& um = rin.get(RDOC_UMQTA);
const int index=art.find_um(um); const int index = art.find_um(um);
if (index>=0) if (index >= 0)
prezzo=art.um()[index].get_real(UMART_PREZZO); prezzo = art.um()[index].get_real(UMART_PREZZO);
} }
else else
prezzo=rcont.get_real(LVRCONDV_PREZZO); prezzo = rcont.get_real(LVRCONDV_PREZZO);
} }
else
prezzo = rin.get_real(RDOC_PREZZO);
// Guardo se è una causale di rotto e se è abilitato nella testata del contratto la fatturazione dei rotti //se è una causale di rotto e se è abilitato nella testata del contratto la fatturazione dei rotti
//e se sto ritirando una quantità di merce diversa da zero, allora:
if (cau.get_bool("B3") && contr.get_int(LVCONDV_ADDCAPROT) && !qta1.is_zero()) if (cau.get_bool("B3") && contr.get_int(LVCONDV_ADDCAPROT) && !qta1.is_zero())
{ {
TRiga_documento& rd=find_or_create_row(doc_out,rin,'D'); //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à da ritirare
//al prezzo segnato in contratto
TRiga_documento& rd = find_or_create_row(doc_out, rin ,'D');
rd.add(RDOC_QTA, qta1); rd.add(RDOC_QTA, qta1);
rd.put(RDOC_PREZZO,contr.row(codart).get_real(LVRCONDV_PREZDAN)); rd.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PREZDAN));
} }
if (cau.get_bool("B0") && !qta1.is_zero()) // movimenta ritirato //se è una causale di ritirato e se sto ritirando una quantità di merce diversa da zero, allora:
if (cau.get_bool("B0") && !qta1.is_zero())
{ {
//leggo la casuale di magazzino associata al ritiro e il suo segno sul consegnato mese
const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1")); const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1"));
const real sgnrit = rit.sgn(s_consmese); 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à 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()) if (!sgnrit.is_zero())
{ {
TRiga_documento& rr=find_or_create_row(doc_out,rin,'C'); TRiga_documento& rr = find_or_create_row(doc_out, rin, 'C');
rr.add(RDOC_QTA,sgnrit * qta1); rr.add(RDOC_QTA, sgnrit * qta1);
rr.put(RDOC_PREZZO,prezzo); rr.put(RDOC_PREZZO, prezzo);
} }
} }
if (cau.get_bool("B1") && !qta.is_zero()) // movimenta consegnato
//se è una causale di consegnato e se sto consegnando una quantità di merce diversa da zero, allora:
if (cau.get_bool("B1") && !qta.is_zero())
{ {
const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2")); //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 = cached_causale_magazzino(cau.get("S2"));
const real sgntmp=con.sgn(s_dottm); 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 è 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à 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)) if (!sgntmp.is_zero() && contr.get_bool(LVCONDV_DOTTMPPRZD))
{ {
TRiga_documento& rt=find_or_create_row(doc_out,rin,'T'); TRiga_documento& rt = find_or_create_row(doc_out, rin, 'T');
rt.add(RDOC_QTA,sgntmp * qta); rt.add(RDOC_QTA, sgntmp * qta);
rt.put(RDOC_PREZZO,contr.row(codart).get_real(LVRCONDV_PRZDTTMP)); rt.put(RDOC_PREZZO, rcont.get_real(LVRCONDV_PRZDTTMP));
} }
const real sgndotin=con.sgn(s_dotin); //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à 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()) if (!sgndotin.is_zero())
{ {
TRiga_documento& rc=find_or_create_row(doc_out,rin,'I'); TRiga_documento& rc = find_or_create_row(doc_out, rin, 'I');
rc.add(RDOC_QTA,sgndotin * qta); rc.add(RDOC_QTA, sgndotin * qta);
rc.put(RDOC_PREZZO,prezzo); rc.put(RDOC_PREZZO, prezzo);
} }
const real sgncons=con.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à 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()) if (!sgncons.is_zero())
{ {
TRiga_documento& rc=find_or_create_row(doc_out,rin,'C'); TRiga_documento& rc = find_or_create_row(doc_out, rin, 'C');
rc.add(RDOC_QTA,sgncons * qta); rc.add(RDOC_QTA, sgncons * qta);
rc.put(RDOC_PREZZO,prezzo); rc.put(RDOC_PREZZO, prezzo);
} }
} }
} }
//ELABORA: metodo che esegue alcune operazioni prliminari, quali settare la data elaborazione e trovare i campi
//in base ai quali è 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, bool TFatturazione_lavanderie::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
const TDate& data_elab, bool interattivo) const TDate& data_elab, bool interattivo)
{ {
@ -467,11 +566,11 @@ bool TFatturazione_lavanderie::elabora(TLista_documenti& doc_in, TLista_document
return TFatturazione_bolle::elabora(doc_in, doc_out, data_elab, interattivo); return TFatturazione_bolle::elabora(doc_in, doc_out, data_elab, interattivo);
} }
/////////////////////////////////////////////////////////// /////////////////////////////////
// TFatturazione_msk //// TFatturazione_msk ////
/////////////////////////////////////////////////////////// /////////////////////////////////
//classe TFatturazione_msk
class TFatturazione_msk: public TAutomask class TFatturazione_msk: public TAutomask
{ {
protected: protected:
@ -484,10 +583,11 @@ TFatturazione_msk::TFatturazione_msk():TAutomask("lv2500a")
{ {
} }
/////////////////////////////////////////////////////////// /////////////////////////////////////
// TFatturazione_lav_app //// TFatturazione_lav_app ////
/////////////////////////////////////////////////////////// /////////////////////////////////////
//classe TFatturazione_lav_app
class TFatturazione_lav_app: public TSkeleton_application class TFatturazione_lav_app: public TSkeleton_application
{ {
protected: protected:
@ -496,59 +596,71 @@ protected:
void TFatturazione_lav_app::main_loop() void TFatturazione_lav_app::main_loop()
{ {
TFatturazione_msk msk; //instanzio la maschera
const TString4 mskzona=msk.get(F_CODZONA); TFatturazione_msk msk;
const TString4 mskcat=(F_CODCATC);
//instanzio i localisamfile che mi servono
TLocalisamfile doc(LF_DOC); TLocalisamfile doc(LF_DOC);
TLocalisamfile rdoc(LF_RIGHEDOC); TLocalisamfile rdoc(LF_RIGHEDOC);
while (msk.run()!=K_QUIT) while (msk.run()!=K_QUIT)
{ {
TString query; //leggo i dati di primo interesse
//&&(BETWEEN(DATADOC,#DADATA,#ADATA))&&(STATO==\"2\")&&(TIPODOC==\"B01\") const TString4 mskzona = msk.get(F_CODZONA);
query << "USE DOC KEY 3 SELECT (TIPOCF==\"C\")\n" const TString4 mskcat = msk.get(F_CODCATC);
<< "BY TIPOCF CODCF DATADOC\n" //preparo le date estremi (dal - al) della query e l'anno dell'esercizio
<< "FROM " << "DATADOC=#DADATA PROVV=D ANNO=#ANNO\n" TDate al = msk.get_date(F_ADATA);
<< "TO " << " DATADOC=#ADATA PROVV=D ANNO=#ANNO\n"; //se la data "al" non è corretta, la pongo uguale alla data fattura
// 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";
TISAM_recordset recset(query);
TDate al = msk.get_date(F_ADATA);
if (!al.ok()) if (!al.ok())
al = msk.get_date(F_DATAFAT); al = msk.get_date(F_DATAFAT);
TDate dal = msk.get_date(F_DADATA);
const long year = al.year();
if (!dal.ok()) const long year = al.year();
TDate dal = msk.get_date(F_DADATA);
//se la data "dal" non è corretta, la pongo uguale a 1/1/annoes
if (!dal.ok())
{ {
dal.set_day(1); dal.set_day(1);
dal.set_month(1); dal.set_month(1);
dal.set_year(year); dal.set_year(year);
} }
recset.set_var("#DADATA", dal);
recset.set_var("#ADATA", al);
recset.set_var("#ANNO", year);
//instanzio una TFatturaziome_lavanderie
TFatturazione_lavanderie elab(msk.get(F_COD_ELAB)); TFatturazione_lavanderie elab(msk.get(F_COD_ELAB));
//preparo le variabili di interesse
TLista_documenti docsin; TLista_documenti docsin;
TLista_documenti docsout; TLista_documenti docsout;
long lastcli=0; long lastcli = 0;
const int period=msk.get_int(F_PERFAT); const int period = msk.get_int(F_PERFAT);
const TDate datafat=msk.get_date(F_DATAFAT); const TDate datafat = msk.get_date(F_DATAFAT);
long indsped; long indsped;
//preparo la query
TString query;
//&&(BETWEEN(DATADOC,#DADATA,#ADATA))&&(STATO==\"2\")&&(TIPODOC==\"B01\")
query << "USE DOC KEY 3 SELECT (TIPOCF==\"C\")\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);
//scorro tutti documenti che la query mi restiuisce
for (bool ok = recset.move_first(); ok; ok = recset.move_next()) for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{ {
//leggo il codcf
const long clifo = recset.get(DOC_CODCF).as_int(); const long clifo = recset.get(DOC_CODCF).as_int();
//se non è l'ultimo cliente, allora:
if (clifo != lastcli) if (clifo != lastcli)
{ {
if (docsin.items()!=0) //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.elabora(docsin, docsout, datafat); elab.elabora(docsin, docsout, datafat);
docsout.write(); docsout.write();
docsout.destroy(-1) ; docsout.destroy(-1) ;
@ -558,38 +670,50 @@ void TFatturazione_lav_app::main_loop()
lastcli = clifo; lastcli = clifo;
} }
//preparo la chiave e recupero da CFVEN i dati di quel cliente
TToken_string key; TToken_string key;
key.add('C'); key.add('C');
key.add(clifo); key.add(clifo);
const TRectype& clienti=cache().get(LF_CFVEN,key); const TRectype& clienti = cache().get(LF_CFVEN,key);
bool cliok=elab.is_document_ok(recset.cursor()->curr());
//se il documento che sto analizzando è corretto, allora:
bool cliok = elab.is_document_ok(recset.cursor()->curr());
if (cliok) if (cliok)
{ {
//se il codice di zona è pieno, allora:
if (mskzona.full()) if (mskzona.full())
{ {
const TString& codzona=clienti.get(CFV_CODZONA); //leggo il codice di zona standard di quel cliente e lo confronto con quello della mascera (V o F)
cliok = (codzona==mskzona); const TString& codzona = clienti.get(CFV_CODZONA);
cliok = (codzona == mskzona);
} }
//se il codice categoria economica è pieno e ho passato il test sul codice di zona, allora:
if (cliok && mskcat.full()) if (cliok && mskcat.full())
{ {
const TString& codcat=clienti.get(CFV_CODCATC); //leggo il codice categoria economica standard di quel cliente e lo confronto con quello della mascera (V o F)
cliok= (codcat==mskcat); const TString& codcat = clienti.get(CFV_CODCATC);
cliok = (codcat == mskcat);
} }
} }
//se ho passato tutti e due i test, allora:
if (cliok) if (cliok)
{ {
indsped = recset.get(DOC_CODINDSP).as_int(); //cerco sul contratto qual'è il periodo di fatturazione di quel cliente
TLaundry_contract contr(clifo, indsped, datafat); indsped = recset.get(DOC_CODINDSP).as_int();
const int contrper = contr.get_int(LVCONDV_PERFAT); TLaundry_contract contr(clifo, indsped, datafat);
const int contrper = contr.get_int(LVCONDV_PERFAT);
if (!contr.get_bool(LVCONDV_FATTSOSP) && contrper <= period)
docsin.add(new TDocumento(recset.cursor()->curr())); //se il cliente non è sospeso e se si è 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()));
} }
} }
if (docsin.items()!=0)
//se ho dei documenti in lista li elaboro e poi svuoto le TList_file
if (docsin.items() != 0)
{ {
elab.elabora(docsin, docsout, datafat); elab.elabora(docsin, docsout, datafat);
docsout.write(); docsout.write();
@ -598,9 +722,7 @@ void TFatturazione_lav_app::main_loop()
docsin.destroy(-1); docsin.destroy(-1);
} }
} }
} }
int lv2500(int argc, char *argv[]) int lv2500(int argc, char *argv[])
{ {