Patch level :10.0

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
gestione budget: aggiunto impegnato


git-svn-id: svn://10.65.10.50/branches/R_10_00@20746 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
luca 2010-08-03 13:46:41 +00:00
parent dc03bcaac1
commit 5d09453f72
3 changed files with 298 additions and 57 deletions

View File

@ -3,6 +3,7 @@
#include <config.h>
#include <defmask.h>
#include <progind.h>
#include <recarray.h>
#include <textset.h>
#include "../ca/calib01.h"
@ -12,6 +13,8 @@
#include "../ca/rmovana.h"
#include "../ca/saldana.h"
#include "../ve/velib.h"
#include "ps1001.h"
#include "ps1001300a.h"
@ -107,7 +110,7 @@ class TVariazione_budget_mask : public TAutomask
bool _dirty;
//posizioni dei vari campi dello sheet: vengono assegnati nel costruttore
int _pos_cms, _pos_check, _pos_cdc, _pos_fase, _pos_conto, _pos_datacomp, _pos_autofcomp, _pos_datafcomp,
_pos_cosric, _pos_imp, _pos_prev, _pos_mat, _pos_descr, _pos_numreg, _pos_numrig, _pos_tipomov;
_pos_cosric, _pos_imp, _pos_prev, _pos_mat, _pos_ipg, _pos_descr, _pos_numreg, _pos_numrig, _pos_tipomov;
TToken_string _cms_supporto;
@ -118,6 +121,7 @@ protected:
int load(); //(costruttore e on_field) carica i dati per riempire lo sheet
long load_rmovana(const TString& cms, const bool include_cms_supp, TSheet_field& sf_righe); //(load()) carica le righe analitiche di preventivo
int load_saldana(const TString& cms, const long max_numreg, TSheet_field& sf_righe); //(load()) carica le righe di saldo consuntivo
void calcola_impegnato(const TString& cms, const bool include_cms_supp, TSheet_field& sf_righe); //(load()) aggiunge il valore dell'impegnato nella colonna corrispondente
TToken_string& add_rmovana(const TRectype& movana, const TRectype& rmovana, TSheet_field& sf_righe); //(load_rmovana()) metodo di basso livello..
//..per caricare fisicamente le righe sullo sheet
@ -131,6 +135,8 @@ protected:
void sistema_date_cms(TDate& datainicms, TDate& datafinecms);
void trova_cms_supporto(const TString& codcms); //(load(),on_field()) riempie la lista con le commesse di supporto valide
int trova_riga_sullo_sheet(TSheet_field& sf_righe, const TString& cms, const TString& cdc,
const TString& conto, const TString& fase, const bool exclude_fasi);
void aggiorna_saldi_preventivi(TSheet_field& sf_righe, const int curr_riga); //(load()) crea i saldi preventivi in base agli importi
bool save_commessa(); //(save()) salva i cambiamenti di date della commessa esaminata
@ -150,6 +156,7 @@ TVariazione_budget_mask::TVariazione_budget_mask() : TAutomask ("ps1001300a")
TConfig ditta_ini(CONFIG_DITTA, "ps1001");
set(F_CODCAUS, ditta_ini.get("CodCaus"), 0x3);
set(F_INCLUDESUPP, ditta_ini.get_bool("InclSupp"));
set(F_EXCLUDEFASI, ditta_ini.get_bool("ExclFasi"));
//setta le posizioni dei campi dello sheet
TSheet_field& sf_righe = sfield(F_RIGHE);
@ -165,6 +172,7 @@ TVariazione_budget_mask::TVariazione_budget_mask() : TAutomask ("ps1001300a")
_pos_imp = sf_righe.cid2index(S_IMPORTO);
_pos_prev = sf_righe.cid2index(S_PREVENTIVO);
_pos_mat = sf_righe.cid2index(S_MATURATO);
_pos_ipg = sf_righe.cid2index(S_IMPEGNATO);
_pos_descr = sf_righe.cid2index(S_DESCR);
_pos_numreg = sf_righe.cid2index(S_NUMREG);
_pos_numrig = sf_righe.cid2index(S_NUMRIG);
@ -177,6 +185,7 @@ TVariazione_budget_mask::~TVariazione_budget_mask()
TConfig ditta_ini(CONFIG_DITTA, "ps1001");
ditta_ini.set("CodCaus", get(F_CODCAUS));
ditta_ini.set("InclSupp", get_bool(F_INCLUDESUPP));
ditta_ini.set("ExclFasi", get_bool(F_EXCLUDEFASI));
}
//crea la chiave cdc/fase/conto
@ -848,67 +857,117 @@ void TVariazione_budget_mask::trova_cms_supporto(const TString& codcms)
}
int TVariazione_budget_mask::trova_riga_sullo_sheet(TSheet_field& sf_righe, const TString& cms, const TString& cdc,
const TString& conto, const TString& fase, const bool exclude_fasi)
{
int index = -1;
//cerca una riga con la medesima chiave sullo sheet
for (index = sf_righe.items() - 1; index >= 0; index--)
{
TToken_string& row = sf_righe.row(index);
TString80 cod_row = row.get(_pos_cms);
cod_row.trim();
if (cms != cod_row)
continue;
cod_row = row.get(_pos_cdc);
cod_row.trim();
if (cdc != cod_row)
continue;
cod_row = row.get(_pos_conto);
cod_row.trim();
if (conto != cod_row)
continue;
if (!exclude_fasi)
{
cod_row = row.get(_pos_fase);
cod_row.trim();
if (fase != cod_row)
continue;
}
break;
}
return index;
}
TToken_string& TVariazione_budget_mask::add_rmovana(const TRectype& movana, const TRectype& rmovana, TSheet_field& sf_righe)
{
TToken_string& row = sf_righe.row(-1);
//chiave iniziale di riga
const TString& cms = rmovana.get(RMOVANA_CODCMS);
row.add(cms, _pos_cms);
const TString& cdc = rmovana.get(RMOVANA_CODCCOSTO);
row.add(cdc, _pos_cdc);
const TString& fase = rmovana.get(RMOVANA_CODFASE);
row.add(fase, _pos_fase);
const TString& conto = rmovana.get(RMOVANA_CODCONTO);
row.add(conto, _pos_conto);
const TString80 cms = rmovana.get(RMOVANA_CODCMS);
const TString80 cdc = rmovana.get(RMOVANA_CODCCOSTO);
const TString80 conto = rmovana.get(RMOVANA_CODCONTO);
TString80 fase = rmovana.get(RMOVANA_CODFASE);
//date competenza iniziale e finale
const TDate datacomp = movana.get_date(MOVANA_DATACOMP);
TDate datafcomp = movana.get_date(MOVANA_DATAFCOMP);
const bool autofcomp = movana.get_bool(MOVANA_AUTOFCOMP);
if (!datafcomp.ok() && !autofcomp)
datafcomp = datacomp;
row.add(datacomp, _pos_datacomp);
row.add(autofcomp ? "X" : "", _pos_autofcomp);
//se c'è l'auto fine competenza la cella con la data fine competenza va svuotata..
//..e disabilitata senno' ci va messa e basta
if (!autofcomp)
row.add(datafcomp, _pos_datafcomp);
else
sf_righe.disable_cell(sf_righe.items() - 1, _pos_datafcomp);
int index = -1;
const bool exclude_fasi = get_bool(F_EXCLUDEFASI);
if (exclude_fasi)
{
fase.cut(0);
index = trova_riga_sullo_sheet(sf_righe, cms, cdc, conto, fase, exclude_fasi);
}
TToken_string& row = sf_righe.row(index);
//Perte comune a un sacco di campi; va fatta comunque
//costo o ricavo? all'indbil l'ardua sentenza!
TAnal_bill bill(conto, cdc, cms, fase);
const int indbil = bill.indicatore_bilancio();
const char* str_indbil = indbil == 3 ? "C" : "R";
row.add(str_indbil, _pos_cosric);
//deve creare una riga nuova
if (index < 0)
{
row.add(cms, _pos_cms);
row.add(cdc, _pos_cdc);
row.add(conto, _pos_conto);
row.add(fase, _pos_fase);
//date competenza iniziale e finale
const TDate datacomp = movana.get_date(MOVANA_DATACOMP);
TDate datafcomp = movana.get_date(MOVANA_DATAFCOMP);
const bool autofcomp = movana.get_bool(MOVANA_AUTOFCOMP);
if (!datafcomp.ok() && !autofcomp)
datafcomp = datacomp;
row.add(datacomp, _pos_datacomp);
row.add(autofcomp ? "X" : "", _pos_autofcomp);
//se c'è l'auto fine competenza la cella con la data fine competenza va svuotata..
//..e disabilitata senno' ci va messa e basta
if (!autofcomp)
row.add(datafcomp, _pos_datafcomp);
else
sf_righe.disable_cell(sf_righe.items() - 1, _pos_datafcomp);
//completa la riga
row.add(rmovana.get(RMOVANA_DESCR), _pos_descr);
//il numreg lo deve ricordare per le righe di appoggio
const long numreg = rmovana.get_long(RMOVANA_NUMREG);
row.add(numreg, _pos_numreg);
row.add(rmovana.get_int(RMOVANA_NUMRIG), _pos_numrig);
const TString& tipomov = movana.get(MOVANA_TIPOMOV);
row.add(tipomov, _pos_tipomov);
const TDate dataini, datafin;
//recupera il saldo finale consuntivo! in base alla chiave cms/cdc/fase/conto e lo mette nel campo consuntivo
const TSaldanal& saldanal_cons = ca_saldo(bill, dataini, datafin, _saldanal_consuntivo | _saldanal_ultima_imm);
TImporto saldo_cons = saldanal_cons._fin;
saldo_cons.normalize(indbil == 3 ? 'D' : 'A');
const real saldo_cons_valore = saldo_cons.valore();
row.add(saldo_cons_valore.string(), _pos_mat);
}
real valore = rmovana.get_real(RMOVANA_IMPORTO);
const char sezione = rmovana.get_char(RMOVANA_SEZIONE);
TImporto importo(sezione, valore);
importo.normalize(indbil == 3 ? 'D' : 'A');
valore = importo.valore();
valore = row.get(_pos_imp);
valore += importo.valore();
row.add(valore.string(), _pos_imp);
const TDate dataini, datafin;
//recupera il saldo finale consuntivo! in base alla chiave cms/cdc/fase/conto e lo mette nel campo consuntivo
const TSaldanal& saldanal_cons = ca_saldo(bill, dataini, datafin, _saldanal_consuntivo | _saldanal_ultima_imm);
TImporto saldo_cons = saldanal_cons._fin;
saldo_cons.normalize(indbil == 3 ? 'D' : 'A');
const real saldo_cons_valore = saldo_cons.valore();
row.add(saldo_cons_valore.string(), _pos_mat);
//completa la riga
row.add(rmovana.get(RMOVANA_DESCR), _pos_descr);
//il numreg lo deve ricordare per le righe di appoggio
const long numreg = rmovana.get_long(RMOVANA_NUMREG);
row.add(numreg, _pos_numreg);
row.add(rmovana.get_int(RMOVANA_NUMRIG), _pos_numrig);
const TString& tipomov = movana.get(MOVANA_TIPOMOV);
row.add(tipomov, _pos_tipomov);
return row;
}
@ -1071,8 +1130,6 @@ int TVariazione_budget_mask::load_saldana(const TString& cms, const long max_num
if (!pi.addstatus(1))
break;
TToken_string& row = sf_righe.row(-1);
//estrae l'elemento dell'assoc_array
TToken_string key_bill(key);
const TString80 conto = key_bill.get(0);
@ -1081,7 +1138,9 @@ int TVariazione_budget_mask::load_saldana(const TString& cms, const long max_num
TString16 fase;
if (!exclude_fasi)
fase << key_bill.get(3);
TToken_string& row = sf_righe.row(-1);
row.add(cms, _pos_cms);
row.add(cdc, _pos_cdc);
if (!exclude_fasi)
@ -1111,6 +1170,7 @@ int TVariazione_budget_mask::load_saldana(const TString& cms, const long max_num
row.add(max_numreg, _pos_numreg);
//segna il tipo riga come saldo
row.add("P", _pos_tipomov);
}
//prima di riempire lo sheet a video ordina le righe per tipo/cms/sede/fase/numreg/numrig
@ -1120,6 +1180,176 @@ int TVariazione_budget_mask::load_saldana(const TString& cms, const long max_num
}
void TVariazione_budget_mask::calcola_impegnato(const TString& cms, const bool include_cms_supp, TSheet_field& sf_righe)
{
const bool exclude_fasi = get_bool(F_EXCLUDEFASI);
//trova tutte le numerazioni di tipo ordine valide in base ai tipi documento ordine (metodo di velib01 preso da ca3883)
//solo le numerazioni con almeno un tipo documento ordine interessano
TString_array num_ordini, tip_ordini;
const int numerazioni_tipo_ordine = numerazioni_ordini(num_ordini, tip_ordini);
//le commesse di cui tenere conto sono quella selezionata dall'utente e quelle di supporto; questo elenco di commesse è..
//..già stato riempito ad inizio programma e messo nella token_string _cms_supporto
const int commesse_da_controllare = _cms_supporto.items();
//date ed anni degli ordini; sono ammessi ordini di 1 anno prima dell'inizio commessa, ma entro l'anno di fine (non esistono..
//..in genere ordini successivi alla fine della commessa, ma solo fatture e parcelle)
const TDate data_inizio_cms = get_date(F_DATAINICMS);
const int da_anno = data_inizio_cms.year() - 1;
const TDate data_fine_cms = get_date(F_DATAFINECMS);
const int a_anno = data_fine_cms.year();
for (int n = 0; n < numerazioni_tipo_ordine; n++)
{
const TString4 codnum = num_ordini.row(n);
//cerca tutte le righe documento che soddisfano i numerosi parametri
TString query;
query << "USE RDOC";
query << "\nSELECT (RIGAEVASA!=\"X\")&&(";
FOR_EACH_TOKEN(_cms_supporto, codcms)
query << "(CODCMS==\"" << codcms << "\")||";
query.rtrim(2);
query << ')';
query << "\nJOIN DOC INTO PROVV==PROVV ANNO==ANNO CODNUM==CODNUM NDOC==NDOC"; //le testate servono per controllo tipo (vedi sotto)
query << "\nFROM CODNUM=#CODNUM ANNO=#DAANNO";
query << "\nTO CODNUM=#CODNUM ANNO=#AANNO";
TISAM_recordset recset(query);
recset.set_var("#CODNUM", codnum);
recset.set_var("#DAANNO", (long)da_anno);
recset.set_var("#AANNO", (long)a_anno);
const TRecnotype recset_items = recset.items();
//simpatica progind per intrattenere l'utonto
TProgind pi(recset_items, "Calcolo dell'impegnato...", true, true);
//memorizza l'ultimo doc per evitare doppioni in caso di doc con più righe (rielaborerebbe..
//..lo stesso documento tante volte quante sono le sue righe!)
TString old_key;
//deve controllare che le righe appartengano a documenti di TIPO valido (il filtro è stato sulle numerazioni,..
//..quindi ci potrebbero essere finiti dentro tipi non desiderati)
for (bool ok = recset.move_first(); ok; ok = recset.move_next()) //giro sulle varie rdoc...
{
//aggiornamento progind intrattenitiva
if (!pi.addstatus(1))
break;
const TRectype& curr_doc = recset.cursor()->curr(LF_DOC);
//controlla se il documento contenente la riga è davvero un ordine ricontrollando il suo tipo nell'array..
//..con i tipi validi; se non lo fosse...ciao ciao rigadocumento!
const TString& tipodoc = curr_doc.get(DOC_TIPODOC);
if (tip_ordini.find(tipodoc) < 0)
continue;
//ovviamente non è finita qui...
//la riga documento non deve risultare contabilizzata! infatti, se lo fosse, i suoi valori apparirebbero..
//..nella sezione delle rmovana
const long numregca = curr_doc.get_long(DOC_NUMREGCA);
//se la rigadoc non è stata contabilizzata..
if (numregca == 0)
{
//magico trucco per non dover ricontabilizzare lo stesso documento tante volte quante sono le righe consecutive
const TString curr_key = curr_doc.build_key();
if (curr_key == old_key)
continue;
else
old_key = curr_key;
//crea il documento virtuale in memoria; se non è ordine oppure lo è ma è già evaso, lo saltiamo!!! ole'!
TDocumento doc(curr_doc);
if (!doc.is_ordine() || doc.is_evaso())
continue;
const char tipocf = doc.tipocf();
//il documento virtuale è adesso un ordine non evaso
//tarocchiamo il documento prendendo solo le righe non evase (almeno una ci sarà, perchè la query del recordset..
//..richiedeva che la rigadoc fosse non evasa, quindi quella riga nel doc esiste, magari in compagnia di altre)
for (int r = doc.body().last_row(); r > 0; r = doc.body().pred_row(r))
{
TRiga_documento& rigadoc = doc[r];
//trattamento delle righe non evase di tipo merce o prestazione
if (rigadoc.is_merce() || rigadoc.is_prestazione())
{
if (!rigadoc.is_evasa())
{
const TString80 rigadoc_cms = rigadoc.codice_commessa();
if (_cms_supporto.get_pos(rigadoc_cms) >= 0) //deve avere commessa valida!!!
{
//deve ricavare anche il conto attraverso il codart, sennò non riesce a completare la chiave dello sheet
int gr = 0, co = 0;
long so = 0L;
TString80 codart = rigadoc.get(RDOC_CODARTMAG);
if (codart.empty())
codart = rigadoc.get(RDOC_CODART);
const TRectype& rec_anamag = cache().get(LF_ANAMAG, codart);
if (rec_anamag.empty())
{
TToken_string cazzo_codart(codart, '*');
gr = cazzo_codart.get_int(0);
co = cazzo_codart.get_int(1);
so = cazzo_codart.get_long(2);
}
else
{
if (tipocf == 'F')
{
gr = rec_anamag.get_int(ANAMAG_GRUPPOA);
co = rec_anamag.get_int(ANAMAG_CONTOA);
so = rec_anamag.get_long(ANAMAG_SOTTOCA);
}
else
{
gr = rec_anamag.get_int(ANAMAG_GRUPPOV);
co = rec_anamag.get_int(ANAMAG_CONTOV);
so = rec_anamag.get_long(ANAMAG_SOTTOCV);
}
}
//se il conto non è completo non può riuscire a piazzare il valore dell'impegnato in una riga dello sheet..
//..in quanto la chiave di riga risulta comunque incompleta nel conto! Quindi prosegue con la riga dopo
if (so <= 0)
continue;
//conto
TString16 rigadoc_conto;
rigadoc_conto.format("%03d%03d%06ld", gr, co, so);
//cdc
const TString80 rigadoc_cdc = rigadoc.codice_costo();
//eventuale fase
TString16 rigadoc_fase;
if (!exclude_fasi)
rigadoc_fase = rigadoc.fase_commessa();
//cerca una riga con la medesima chiave sullo sheet
int index = trova_riga_sullo_sheet(sf_righe, rigadoc_cms, rigadoc_cdc, rigadoc_conto, rigadoc_fase, exclude_fasi);
if (index >= 0)
{
//trasforma tutte le righe a valore, assegnando al prezzo il valore del residuo
//const real valore = rigadoc.valore(true, false, AUTO_DECIMALS);
const real residuo = rigadoc.valore(false, false, AUTO_DECIMALS);
if (!residuo.is_zero())
{
TToken_string& row = sf_righe.row(index);
real row_valore_impegnato = row.get(_pos_ipg);
row_valore_impegnato += residuo;
row.add(row_valore_impegnato.string(), _pos_ipg);
}
}
} //if (rigadoc.codice_commessa()...
} //if (!rigadoc.is_evasa())..
} //if (rigadoc.is_merce()
} //for (int r = doc.body().last_row()
} //if (numregca == 0)...
} //for (bool ok = recset.move_first()...
} //for (int n = 0...
}
int TVariazione_budget_mask::load()
{
//commessa in esame
@ -1138,6 +1368,9 @@ int TVariazione_budget_mask::load()
//carica le righe dei saldi consuntivi
const int righe_saldana = load_saldana(cms, max_numreg, sf_righe);
//calcola l'impegnato per ogni riga dello sheet che è stato riempito
calcola_impegnato(cms, include_cms_supp, sf_righe);
//e poi aggiorna il video!
sf_righe.force_update();

View File

@ -33,10 +33,11 @@
#define S_IMPORTO 110
#define S_PREVENTIVO 111
#define S_MATURATO 112
#define S_DESCR 113
#define S_NUMREG 114
#define S_NUMRIG 115
#define S_TIPOMOV 116
#define S_IMPEGNATO 113
#define S_DESCR 114
#define S_NUMREG 115
#define S_NUMRIG 116
#define S_TIPOMOV 117
#define S_CMS_DESCR 142
#define S_CDC_DESCR 143

View File

@ -180,6 +180,7 @@ BEGIN
ITEM "Importo@15"
ITEM "Saldo\nPreventivo@15"
ITEM "Saldo\nMaturato@15"
ITEM "Saldo\nImpegnato@15"
ITEM "Descrizione riga@50"
ITEM "Numero\nRegistr@7"
ITEM "Riga"
@ -441,18 +442,24 @@ END
NUMBER S_MATURATO 15 2
BEGIN
PROMPT 34 10 "Maturato "
PROMPT 1 11 "Maturato "
FLAGS "D"
END
NUMBER S_IMPEGNATO 15 2
BEGIN
PROMPT 1 12 "Impegnato "
FLAGS "D"
END
STRING S_DESCR 50
BEGIN
PROMPT 1 12 "Descrizione"
PROMPT 1 14 "Descrizione"
END
NUMBER S_NUMREG 7
BEGIN
PROMPT 1 13 "N. reg. "
PROMPT 1 15 "N. reg. "
FLAGS "GD"
MESSAGE EMPTY ENABLE,1@
MESSAGE DISABLE,1@
@ -460,13 +467,13 @@ END
NUMBER S_NUMRIG 3
BEGIN
PROMPT 1 14 "Num. riga "
PROMPT 1 16 "Num. riga "
FLAGS "D"
END
STRING S_TIPOMOV 1
BEGIN
PROMPT 1 15 "Tipo mov. "
PROMPT 1 17 "Tipo mov. "
FLAGS "D"
END