Patch level :10.0

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
cespiti per analitica in corso


git-svn-id: svn://10.65.10.50/trunk@20539 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
luca 2010-06-03 15:04:50 +00:00
parent 0fbec20102
commit 038ca2cab5
3 changed files with 225 additions and 172 deletions

View File

@ -15,8 +15,6 @@
#include "cetbccb.h" #include "cetbccb.h"
#include "cetbccc.h" #include "cetbccc.h"
#include "../ca/calib01.h"
#define MIN_CAT_COM 40 #define MIN_CAT_COM 40
#ifndef TTable_application #ifndef TTable_application
@ -192,6 +190,7 @@ TCCE_mask::TCCE_mask() : TAutomask("cetbcce")
if (has_ca) if (has_ca)
{ {
enable_page(1, true); enable_page(1, true);
/* QUESTO NON E' ASSOLUTAMENTE DETTO; E' DA VERIFICARE!
//se ha l'analitica gli tocca pure controllare la configurazione per sapere.. //se ha l'analitica gli tocca pure controllare la configurazione per sapere..
//..quali campi diventano obbligatori! //..quali campi diventano obbligatori!
TConfig& cfg = ca_config(); TConfig& cfg = ca_config();
@ -210,7 +209,7 @@ TCCE_mask::TCCE_mask() : TAutomask("cetbcce")
{ {
TEdit_field& e_fase = efield(F_CODFASE); TEdit_field& e_fase = efield(F_CODFASE);
e_fase.check_type(CHECK_REQUIRED); e_fase.check_type(CHECK_REQUIRED);
} }*/
} }
else else
enable_page(1, false); enable_page(1, false);

View File

@ -20,11 +20,13 @@ struct date_commessa : public TObject
class TCesp_anal_mask: public TAutomask class TCesp_anal_mask: public TAutomask
{ {
int _pos_cms, _pos_fase, _pos_cdc, _pos_dtiniuse, _pos_dtfinuse, _pos_util; int _pos_cms, _pos_fase, _pos_cdc, _pos_dtiniuse, _pos_dtfinuse, _pos_util,
_pos_dtinicms, _pos_dtfincms, _pos_dtprorcms;
protected: protected:
int calc_durata_esercizio_cespitizzata(TDate& dtinies, TDate& dtfines); int calc_date_cespite(TDate& dtini, TDate& dtfine);
void calc_date_limite(const TString& codcms, TDate& dtini, TDate& dtfine); void calc_date_limite(const TString& codcms, TDate& dtini, TDate& dtfine);
void calc_percutil();
public: public:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
@ -44,6 +46,9 @@ TCesp_anal_mask::TCesp_anal_mask() : TAutomask ("ce4100a")
_pos_dtiniuse = sf_righe.cid2index(S_DTINIUSE); _pos_dtiniuse = sf_righe.cid2index(S_DTINIUSE);
_pos_dtfinuse = sf_righe.cid2index(S_DTFINUSE); _pos_dtfinuse = sf_righe.cid2index(S_DTFINUSE);
_pos_util = sf_righe.cid2index(S_PERCUTIL); _pos_util = sf_righe.cid2index(S_PERCUTIL);
_pos_dtinicms = sf_righe.cid2index(S_DTINICMS);
_pos_dtfincms = sf_righe.cid2index(S_DTFINCMS);
_pos_dtprorcms = sf_righe.cid2index(S_DTPRORCMS);
//mette i checktype sui campi dello sheet in base alla configurazione.. //mette i checktype sui campi dello sheet in base alla configurazione..
//..analitica della ditta //..analitica della ditta
@ -67,38 +72,48 @@ TCesp_anal_mask::TCesp_anal_mask() : TAutomask ("ce4100a")
} }
} }
real TCesp_anal_mask::somma_perc() const
{
TSheet_field& ss = sfield(F_RIGHE);
real tot_perc;
FOR_EACH_SHEET_ROW(ss,i,r)
tot_perc += real(r->get(_pos_util));
return tot_perc;
}
int TCesp_anal_mask::calc_durata_esercizio_cespitizzata(TDate& dtinies, TDate& dtfines) int TCesp_anal_mask::calc_date_cespite(TDate& dtini, TDate& dtfine)
{ {
//si informa sulla vita del cespite
const TString& idcespite = get(F_IDCESPITE);
//controlla che il cespite sia vivo nell'esercizio selezionato e quanto dura tale esistenza
const TRectype& rec_cespi = cache().get(LF_CESPI, idcespite);
const TDate dtcomp = rec_cespi.get_date(CESPI_DTCOMP);
const TDate dtalien = rec_cespi.get_date(CESPI_DTALIEN);
const int anno = get_int(F_ESERCIZIO); const int anno = get_int(F_ESERCIZIO);
TEsercizi_contabili esc; TEsercizi_contabili esc;
esc.code2range(anno, dtinies, dtfines); esc.code2range(anno, dtini, dtfine);
//vita cespite long durata = dtfine - dtini + 1;
const TString& cespite = get(F_IDCESPITE);
const TRectype& rec_cespi = cache().get(LF_CESPI, cespite); if (dtalien.ok())
const TDate& dtcomp = rec_cespi.get_date(CESPI_DTCOMP); {
const TDate& dtalien = rec_cespi.get_date(CESPI_DTALIEN); //cespite alienato prima dell'esercizio
//cespite acquistato durante l'esercizio if (dtalien < dtini)
if (dtcomp.ok() && dtcomp > dtinies) return 0;
dtinies = dtcomp;
//cespite alienato durante l'esercizio //cespite alienato durante l'esercizio
if (dtalien.ok() && dtalien < dtfines) if (dtalien < dtfine)
dtfines = dtalien; dtfine = dtalien;
}
if (dtcomp.ok())
{
//cespite acquistato dopo l'esercizio
if (dtcomp.ok() && dtcomp > dtfine)
return 0;
//cespite acquistato durante l'esercizio
if (dtcomp.ok() && dtcomp > dtini)
dtini = dtcomp;
}
//durata "cespitizzata" dell'esercizio //durata "cespitizzata" dell'esercizio
const int durata = dtfines - dtinies + 1; durata = dtfine - dtini + 1;
return durata; return durata;
} }
void TCesp_anal_mask::calc_date_limite(const TString& codcms, TDate& dtini, TDate& dtfine) void TCesp_anal_mask::calc_date_limite(const TString& codcms, TDate& dtini, TDate& dtfine)
{ {
//date limite coincidenti con date vita cespite nell'esercizio (caso standard, senza commessa) //date limite coincidenti con date vita cespite nell'esercizio (caso standard, senza commessa)
@ -124,113 +139,10 @@ void TCesp_anal_mask::calc_date_limite(const TString& codcms, TDate& dtini, TDat
} }
} }
bool TCesp_anal_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
//maschera principale //questo è il metodo supermagico ed iperdecisivo per calcolare la %utilizzo in base a tutti i dati..
//------------------- //..vaganti nella maschera e nello sheet. E' il cuore del programma!
case F_IDCESPITE: void TCesp_anal_mask::calc_percutil()
case F_ESERCIZIO:
if (e == fe_modify)
{
//nel caso vengano cambiati il cespite e/o l'esercizio, deve controllare la vita del cespite..
//..nell'esercizio
TDate dtinies = get_date(F_INIZIO_ES);
TDate dtfines = get_date(F_FINE_ES);
calc_durata_esercizio_cespitizzata(dtinies, dtfines);
set(F_INIZIO_CES, dtinies);
set(F_FINE_CES, dtfines);
}
break;
case F_RIGHE:
if (e == se_notify_add) //quando si aggiunge una riga...
{
TSheet_field& ss = (TSheet_field&)o;
//propone come date iniziale e finale di uso quelle dell'esercizio selezionato!
const int anno = get_int(F_ESERCIZIO);
TDate dtinies, dtfines;
TEsercizi_contabili esc;
esc.code2range(anno, dtinies, dtfines);
calc_durata_esercizio_cespitizzata(dtinies, dtfines);
TToken_string& new_row = ss.row(jolly);
new_row.add(dtinies, _pos_dtiniuse);
new_row.add(dtfines, _pos_dtfinuse);
//mette nel campo %util il valore max possibile al momento
real residuo = CENTO - somma_perc();
if (residuo > 0)
{
TToken_string& row = ss.row(jolly);
row.add(residuo.string(),_pos_util);
}
}
if (e == fe_close && (insert_mode() || edit_mode()))
{
//controllo sulle percentuali totali di un cespite
if (somma_perc() != CENTO)
return noyes_box("La percentuale complessiva di utilizzo del cespite e' diversa da 100"
"\nSi desidera proseguire ugualmente?");
TAssoc_array keys_list;
TSheet_field& ss = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(ss,i,r)
{
//controllo di esistenza codici commessa e cdc
const TString& cms = r->get(_pos_cms);
if (cms.blank())
return error_box("Specificare la commessa sulla riga %d", i+1);
const TString& cdc = r->get(_pos_cdc);
if (cdc.blank())
return error_box("Specificare il centro di costo sulla riga %d", i+1);
//controllo di duplicazione chiave della riga (cms/fase/cdc)
TToken_string row_key;
row_key.add(cms);
const TString& fase = r->get(_pos_fase);
row_key.add(fase);
row_key.add(cdc);
if (keys_list.is_key(row_key))
return error_box("Codice riga %s duplicato", (const char *)row_key);
keys_list.add(row_key);
}
}
break;
//maschera di riga sheet
//----------------------
//controllo sulle date limite di utilizzo: se c'è la commessa le date lim uso devono ricadere..
//..all'interno della vita della commessa, se invece la commessa non c'è le date lim uso devono..
//..ricadere all'interno della vita utile del cespite nell'esercizio
case S_DTINIUSE:
if (e == fe_modify || e == fe_close)
{
TDate dtini, dtfine;
const TString& codcms = get(S_CODCMS);
calc_date_limite(codcms, dtini, dtfine);
if (o.get() < dtini)
return error_box("La data inizio uso non può essere antecedente alla data inizio commessa!");
}
break;
case S_DTFINUSE:
if (e == fe_modify || e == fe_close)
{
TDate dtini, dtfine;
const TString& codcms = get(S_CODCMS);
calc_date_limite(codcms, dtini, dtfine);
if (o.get() > dtfine)
return error_box("La data fine uso non può essere successiva alla data fine commessa!");
}
break;
//bottoni
//-------
case DLG_CALCPERC:
if (e == fe_button)
{ {
//ripartisce in automatico le percentuali di utilizzo analizzando le durate e le compresenze.. //ripartisce in automatico le percentuali di utilizzo analizzando le durate e le compresenze..
//..delle commesse sullo sheet nell'anno selezionato, oltre che ovviamente la durata del cespite.. //..delle commesse sullo sheet nell'anno selezionato, oltre che ovviamente la durata del cespite..
@ -240,7 +152,7 @@ bool TCesp_anal_mask::on_field_event(TOperable_field& o, TField_event e, long jo
//..nel corso dell'esercizio stesso //..nel corso dell'esercizio stesso
TDate dtini, dtfine; TDate dtini, dtfine;
//durata "cespitizzata" dell'esercizio //durata "cespitizzata" dell'esercizio
const int durata = calc_durata_esercizio_cespitizzata(dtini, dtfine); const long durata = calc_date_cespite(dtini, dtfine);
// 2) chiave generale su cui mettere le quote che non appartengono ad alcuna.. // 2) chiave generale su cui mettere le quote che non appartengono ad alcuna..
//..commessa! La si trova nella configurazione esercizio cespiti (tanto per incasinarci.. //..commessa! La si trova nella configurazione esercizio cespiti (tanto per incasinarci..
@ -299,28 +211,173 @@ bool TCesp_anal_mask::on_field_event(TOperable_field& o, TField_event e, long jo
// 4) attenzione alla commesse generica di riempimento (cms_genspa!) se non esiste va aggiunta // 4) attenzione alla commesse generica di riempimento (cms_genspa!) se non esiste va aggiunta
//se invece la cms_genspa ha già la sua riga -> deve solo aggiornare la %util (lo fa dopo.. //se invece la cms_genspa ha già la sua riga -> deve solo aggiornare la %util (lo fa dopo..
//..assieme alle commesse normali) //..assieme alle commesse normali)
if (riga_genspa < 0) if (riga_genspa < 0 && giorni_genspa > 0)
{ {
TToken_string& row_genspa = sf_righe.row(-1); TToken_string& row_genspa = sf_righe.row(-1);
row_genspa = key_genspa; row_genspa = key_genspa;
row_genspa.add(dtini, _pos_dtinicms);
row_genspa.add(dtfine, _pos_dtfincms);
//aggiunge la commessa genspa all'array dei giorni_commessa, in modo che venga poi considerata.. //aggiunge la commessa genspa all'array dei giorni_commessa, in modo che venga poi considerata..
//..nel riproporzionamento successivo con il distrib //..nel riproporzionamento successivo con il distrib
riga_genspa = sf_righe.items() - 1; riga_genspa = sf_righe.items() - 1;
} }
//se la riga genspa esiste (sia che l'abbia appena creata che esistesse da tempo immemorabile)...
//..calcola la % di giorni genspa nell'esercizio cespitizzato (è la %util di genspa)
real perc_genspa = ZERO;
if (riga_genspa >= 0)
{
giorni_commessa.add_long(giorni_genspa, riga_genspa); giorni_commessa.add_long(giorni_genspa, riga_genspa);
perc_genspa = giorni_genspa * CENTO / durata;
perc_genspa.round(2);
sf_righe.row(riga_genspa).add(perc_genspa.string(), _pos_util);
}
// 5) procede a caricare un distrib con i valori di giorni_commessa // 5) procede a caricare un distrib con i valori di giorni_commessa
TGeneric_distrib tamoil(CENTO, 2); TGeneric_distrib tamoil(CENTO - perc_genspa, 2);
for (int i = 0 ; i < sf_righe.items(); i++) for (int i = 0 ; i < sf_righe.items(); i++)
{
if (i != riga_genspa)
tamoil.add(giorni_commessa.get_long(i)); tamoil.add(giorni_commessa.get_long(i));
}
// 6) adesso scarica il distrib, mettendo la % di ogni commessa nel campo di %di utilizzo // 6) adesso scarica il distrib, mettendo la % di ogni commessa nel campo di %di utilizzo
FOR_EACH_SHEET_ROW(sf_righe, gg, linea) FOR_EACH_SHEET_ROW(sf_righe, gg, linea)
{
if (gg != riga_genspa)
linea->add(tamoil.get().string(), _pos_util); linea->add(tamoil.get().string(), _pos_util);
}
//..e alla fine vediamo che succede! //..e alla fine vediamo che succede!
sf_righe.force_update(); sf_righe.force_update();
} }
bool TCesp_anal_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
//maschera principale
//-------------------
case F_IDCESPITE:
case F_IDCESPITE_N:
case F_ESERCIZIO:
if (e == fe_modify || e == fe_close)
{
//nel caso vengano cambiati il cespite e/o l'esercizio, deve controllare la vita del cespite..
//..nell'esercizio
TDate dtinies = get_date(F_INIZIO_ES);
TDate dtfines = get_date(F_FINE_ES);
if (calc_date_cespite(dtinies, dtfines) <= 0)
return error_box("Cespite NON appartenente all'esercizio selezionato!");
set(F_INIZIO_CES, dtinies);
set(F_FINE_CES, dtfines);
}
break;
case F_RIGHE:
//all'uscita della riga...
if (e == se_notify_modify)
{
//controllo di duplicazione chiave della riga (cms/fase/cdc)
TAssoc_array keys_list;
TSheet_field& ss = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(ss,i,r)
{
const TString& cms = r->get(_pos_cms);
const TString& cdc = r->get(_pos_cdc);
const TString& fase = r->get(_pos_fase);
TToken_string row_key;
row_key.add(cms, _pos_cms);
row_key.add(fase, _pos_fase);
row_key.add(cdc, _pos_cdc);
if (keys_list.is_key(row_key))
return error_box("Codice riga %s duplicato", (const char *)row_key);
keys_list.add(row_key);
}
//ricalcola le percentuali !!!
calc_percutil();
}
break;
//maschera di riga sheet
//----------------------
//controllo sulle date limite di utilizzo: se c'è la commessa le date lim uso devono ricadere..
//..all'interno della vita della commessa, se invece la commessa non c'è le date lim uso devono..
//..ricadere all'interno della vita utile del cespite nell'esercizio
case S_CODCDC:
if (e == fe_modify && !o.empty())
{
TMask& mask_riga = o.mask();
const int anno = get_int(F_ESERCIZIO);
TDate dtini, dtfine;
TEsercizi_contabili esc;
esc.code2range(anno, dtini, dtfine);
calc_date_cespite(dtini, dtfine);
TDate dtiniuse = mask_riga.get_date(S_DTINIUSE);
if (dtiniuse.empty())
mask_riga.set(S_DTINIUSE, dtini);
TDate dtfinuse = mask_riga.get_date(S_DTFINUSE);
if (dtfinuse.empty())
mask_riga.set(S_DTFINUSE, dtfine);
}
break;
case S_CODCMS:
if (e == fe_modify && !o.empty())
{
TMask& mask_riga = o.mask();
const TString& codcms = o.get();
TDate dtini, dtfine;
calc_date_limite(codcms, dtini, dtfine);
TDate dtiniuse = mask_riga.get_date(S_DTINIUSE);
if (dtiniuse.empty())
mask_riga.set(S_DTINIUSE, dtini);
TDate dtfinuse = mask_riga.get_date(S_DTFINUSE);
if (dtfinuse.empty())
mask_riga.set(S_DTFINUSE, dtfine);
}
break;
case S_DTINIUSE:
if (e == fe_modify || e == fe_close)
{
TDate dtini, dtfine;
const TString& codcms = o.mask().get(S_CODCMS);
calc_date_limite(codcms, dtini, dtfine);
const TDate dtiniuse = o.get();
if (dtiniuse < dtini)
return error_box("La data inizio uso non può essere antecedente alla data inizio commessa!");
}
break;
case S_DTFINUSE:
if (e == fe_modify || e == fe_close)
{
TDate dtini, dtfine;
const TString& codcms = o.mask().get(S_CODCMS);
calc_date_limite(codcms, dtini, dtfine);
const TDate dtfinuse = o.get();
if (dtfinuse > dtfine)
return error_box("La data fine uso non può essere successiva alla data fine commessa!");
}
break;
//bottoni
//-------
case DLG_CALCPERC:
if (e == fe_button)
{
//in caso di richiesta esplicita di ricalcolo, viene ordinato lo sheet..
//..in base al primo campo (in genere cms) e poi effettuato il calcolo
TSheet_field& sf_righe = sfield(F_RIGHE);
sf_righe.sort();
calc_percutil();
}
break; break;
default: default:

View File

@ -77,18 +77,14 @@ STRING F_IDCESPITE 10
BEGIN BEGIN
PROMPT 1 4 "Cespite " PROMPT 1 4 "Cespite "
FLAGS "UZ" FLAGS "UZ"
USE LF_SALCECMS SELECT NRIGA==1 USE LF_SALCECMS KEY 2 SELECT NRIGA==1
JOIN LF_CESPI INTO IDCESPITE==IDCESPITE JOIN LF_CESPI INTO IDCESPITE==IDCESPITE
INPUT CODES F_ESERCIZIO INPUT CODES F_ESERCIZIO SELECT
INPUT IDCESPITE F_IDCESPITE INPUT IDCESPITE F_IDCESPITE
DISPLAY "Codice@10" IDCESPITE DISPLAY "Codice@10" IDCESPITE
DISPLAY "Descrizione@50" LF_CESPI->DESC DISPLAY "Descrizione@50" LF_CESPI->DESC
DISPLAY "Cat." LF_CESPI->CODCAT DISPLAY "Cat." LF_CESPI->CODCAT
DISPLAY "Commessa@20" CODCMS DISPLAY "Esercizio" CODES
DISPLAY "Fase@10" CODFASE
DISPLAY "Centro di costo@20" CODCDC
DISPLAY "Data Acq.@10" LF_CESPI->DTCOMP
DISPLAY "Data Ali.@10" LF_CESPI->DTALIEN
OUTPUT F_IDCESPITE IDCESPITE OUTPUT F_IDCESPITE IDCESPITE
OUTPUT F_IDCESPITE_N IDCESPITE OUTPUT F_IDCESPITE_N IDCESPITE
OUTPUT F_DESC LF_CESPI->DESC OUTPUT F_DESC LF_CESPI->DESC
@ -131,7 +127,7 @@ END
STRING F_DESC_N 60 50 STRING F_DESC_N 60 50
BEGIN BEGIN
PROMPT 24 6 "" PROMPT 24 4 ""
USE LF_CESPI KEY 3 USE LF_CESPI KEY 3
INPUT DESC F_DESC_N INPUT DESC F_DESC_N
DISPLAY "Descrizione@50" DESC DISPLAY "Descrizione@50" DESC
@ -188,7 +184,7 @@ ENDPAGE
ENDMASK ENDMASK
//maschera di riga dello sheet //maschera di riga dello sheet
PAGE "Riga" -1 -1 76 8 PAGE "Riga" -1 -1 76 9
STRING S_CODCMS 20 STRING S_CODCMS 20
BEGIN BEGIN
@ -286,6 +282,7 @@ BEGIN
FLAGS "U" FLAGS "U"
FIELD PERCUTIL FIELD PERCUTIL
CHECKTYPE REQUIRED CHECKTYPE REQUIRED
FLAGS "D"
END END
DATE S_DTINICMS DATE S_DTINICMS
@ -296,13 +293,13 @@ END
DATE S_DTFINCMS DATE S_DTFINCMS
BEGIN BEGIN
PROMPT 22 2 "Fine " PROMPT 30 2 "Fine "
FLAGS "D" FLAGS "D"
END END
DATE S_DTPRORCMS DATE S_DTPRORCMS
BEGIN BEGIN
PROMPT 44 2 "Proroga " PROMPT 54 2 "Proroga "
FLAGS "D" FLAGS "D"
END END