campo-sirio/ps/ps1001300.cpp
luca d241a8d841 Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
personalizzazione crpa in corso


git-svn-id: svn://10.65.10.50/trunk@20385 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-04-28 10:59:13 +00:00

847 lines
27 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <defmask.h>
#include <progind.h>
#include <recarray.h>
#include <textset.h>
#include "../ca/calib01.h"
#include "../ca/calib02.h"
#include "../ca/commesse.h"
#include "../ca/movana.h"
#include "../ca/rmovana.h"
#include "ps1001.h"
#include "ps1001300a.h"
///////////////////////////////////
// Metodi static di ordinamento
///////////////////////////////////
//ordina per numreg/numrig (long+int) oppure per numreg/datacomp/autofcomp/datafcomp
static int compare_by_numrig(TSheet_field & s, int r1, int r2)
{
TToken_string& s1 = s.row(r1);
TToken_string& s2 = s.row(r2);
//prima guarda il numreg..
const int numreg_pos = s.cid2index(S_NUMREG);
const long b11 = s1.get_long(numreg_pos);
const long b21 = s2.get_long(numreg_pos);
int cmp = b11 - b21;
if (cmp == 0)
{
if (b11 > 0) //..poi il numrig
{
const int numrig_pos = numreg_pos + 1;
const int c11 = s1.get_int(numrig_pos);
const int c21 = s2.get_int(numrig_pos);
cmp = c11 - c21;
}
else //..oppure le date se numreg=0 (b11=b12 = 0)
{
const int datacomp_pos = s.cid2index(S_DATACOMP);
const TDate d11 = s1.get(datacomp_pos);
const TDate d21 = s2.get(datacomp_pos);
cmp = int(d11 - d21);
if (cmp == 0)
{
const int autofcomp_pos = s.cid2index(S_AUTOFCOMP);
const char* e11 = s1.get(autofcomp_pos);
const char* e21 = s2.get(autofcomp_pos);
if (e11 == e21)
{
const int datafcomp_pos = s.cid2index(S_DATAFCOMP);
const TDate f11 = s1.get(datafcomp_pos);
const TDate f21 = s2.get(datafcomp_pos);
cmp = int(f11 - f21);
}
}
}
}
return cmp;
}
//nota: nelle ststic non si possono usare i _pos_quel, perchè sono di maschera
//ordina le righe per sede/fase/conto (string+string+string)
static int compare_by_fase(TSheet_field & s, int r1, int r2)
{
TToken_string& s1 = s.row(r1);
TToken_string& s2 = s.row(r2);
TToken_string c1;
c1.add(s1.get(1));
c1.add(s1.get(2));
c1.add(s1.get(3));
TToken_string c2;
c2.add(s2.get(1));
c2.add(s2.get(2));
c2.add(s2.get(3));
int cmp = c1.compare(c2);
if (cmp == 0)
cmp = compare_by_numrig(s, r1, r2);
return cmp;
}
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////
class TVariazione_budget_mask : public TAutomask
{
bool _dirty;
//posizioni dei vari campi dello sheet: vengono assegnati nel costruttore
int _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;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
int load();
bool one_checked() const; //(on_field) controlla se nella colonna dei check ce ne è almeno 1 checkato
void check_all(const bool checked); //(on_field) checka-dechecka la colonna dei check
int find_sister_rows(const int curr_sister, int& first_sister, int& last_sister, const bool by_numreg = false); //(on_field) trova le righe..
//..con la stessa chiave della riga corrente e della chiave selezionata
void build_key(int i, TToken_string& key); //(find_sister_rows) crea la chiave cdc/fase/conto della riga con cui cercare le sorelle
void build_key_by_numreg(int i, TToken_string& key); //(find_sister_rows) crea la chiave numreg della riga con cui cercare le sorelle
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
bool save_sheet(); //(save()) salva i cambiamenti nello sheet
bool save(); //(on_field) gestisce l'ordine dei salvataggi
int modifica_movana(const long numreg, TSheet_field& sf_righe, const int r); //((save_sheet()) gestisce la modifica di movana esistenti
int crea_movana(TSheet_field& sf_righe, const int n); //(save_sheet()) gestisce la creazione dei nuovi movana
public:
TVariazione_budget_mask();
~TVariazione_budget_mask();
};
TVariazione_budget_mask::TVariazione_budget_mask() :TAutomask ("ps1001300a")
{
//carica la causale che trova nel ditta.ini
TConfig ditta_ini(CONFIG_DITTA, "ps1001");
set(F_CODCAUS, ditta_ini.get("CodCaus"));
//setta le posizioni dei campi dello sheet
TSheet_field& sf_righe = sfield(F_RIGHE);
_pos_check = sf_righe.cid2index(S_CHECK);
_pos_cdc = sf_righe.cid2index(S_CDC);
_pos_fase = sf_righe.cid2index(S_FASE);
_pos_conto = sf_righe.cid2index(S_CONTO);
_pos_datacomp = sf_righe.cid2index(S_DATACOMP);
_pos_autofcomp = sf_righe.cid2index(S_AUTOFCOMP);
_pos_datafcomp = sf_righe.cid2index(S_DATAFCOMP);
_pos_cosric = sf_righe.cid2index(S_COSRIC);
_pos_imp = sf_righe.cid2index(S_IMPORTO);
_pos_prev = sf_righe.cid2index(S_PREVENTIVO);
_pos_mat = sf_righe.cid2index(S_MATURATO);
_pos_descr = sf_righe.cid2index(S_DESCR);
_pos_numreg = sf_righe.cid2index(S_NUMREG);
_pos_numrig = sf_righe.cid2index(S_NUMRIG);
_pos_tipomov = sf_righe.cid2index(S_TIPOMOV);
}
TVariazione_budget_mask::~TVariazione_budget_mask()
{
//salva nel ditta.ini la causale sulla maschera
TConfig ditta_ini(CONFIG_DITTA, "ps1001");
ditta_ini.set("CodCaus", get(F_CODCAUS));
}
//crea la chiave cdc/fase/conto
void TVariazione_budget_mask::build_key(int i, TToken_string& key)
{
TSheet_field& sf_righe = sfield(F_RIGHE);
TToken_string curr_riga = sf_righe.row(i);
//chiave della riga sorella originale
key.cut(0);
key.add(curr_riga.get(_pos_cdc));
key.add(curr_riga.get(_pos_fase));
key.add(curr_riga.get(_pos_conto));
}
//crea la chiave numreg/numrig o datacomp/autofcomp/datafcomp
void TVariazione_budget_mask::build_key_by_numreg(int i, TToken_string& key)
{
TSheet_field& sf_righe = sfield(F_RIGHE);
TToken_string curr_riga = sf_righe.row(i);
//chiave della riga sorella originale
key.cut(0);
key.add(curr_riga.get(_pos_numreg));
if (atol(key) == 0)
{
const TDate datacomp = curr_riga.get(_pos_datacomp);
key.add(datacomp.date2ansi());
key.add(curr_riga.get(_pos_autofcomp));
const TDate datafcomp = curr_riga.get(_pos_datafcomp);
key.add(datafcomp.date2ansi());
}
}
//cerca le righe sorelle per chiave cdc/fase/conto o numreg (dipende da by_numreg)
int TVariazione_budget_mask::find_sister_rows(const int curr_sister, int& first_sister, int& last_sister, const bool by_numreg)
{
first_sister = last_sister = curr_sister;
TToken_string key;
if (by_numreg)
build_key_by_numreg(curr_sister, key);
else
build_key(curr_sister, key);
TToken_string key_iesima;
for (int i = curr_sister - 1; i >= 0; i--)
{
if (by_numreg)
build_key_by_numreg(i, key_iesima);
else
build_key(i, key_iesima);
if (key == key_iesima)
first_sister = i;
else
break;
}
TSheet_field& sf_righe = sfield(F_RIGHE);
const long items = sf_righe.items();
for (int i = curr_sister + 1; i < items; i++)
{
if (by_numreg)
build_key_by_numreg(i, key_iesima);
else
build_key(i, key_iesima);
if (key == key_iesima)
last_sister = i;
else
break;
}
return last_sister - first_sister + 1;
}
bool TVariazione_budget_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
//maschera
case F_CODCMS:
if (e == fe_modify)
{
bool e = load() == 0;
o.enable(e);
enable(F_DESCRIZ, e);
}
break;
case F_DATAINICMS:
case F_DATAFINECMS:
_dirty = true;
break;
//sheet
case S_CHECK:
if (e == fe_modify)
{
//se viene checkata una riga deve uncheckare le sue sorelle di chiave
TSheet_field& sf_righe = sfield(F_RIGHE);
int curr = sf_righe.selected(), first, last;
const int sisters = find_sister_rows(curr, first, last);
for (int i = first; i <= last; i++)
sf_righe.row(i).add(i == curr ? "X" : "", _pos_check);
sf_righe.force_update();
}
break;
case S_DATACOMP:
case S_DATAFCOMP:
if (e == fe_modify)
{
const TDate datainicms = get_date(F_DATAINICMS);
TDate datafinecms = get_date(F_DATAPRORCMS);
if (!datafinecms.ok())
datafinecms = get_date(F_DATAFINECMS);
const TDate data = o.get();
if (data < datainicms || (datafinecms.ok() && data > datafinecms))
return error_box("Le date competenza devono rientrare nella durata della commessa!");
_dirty = true;
}
break;
case S_IMPORTO:
if (e == fe_modify)
{
//se viene cambiato a mano un importo, deve aggiornare i saldi preventivi
TSheet_field& sf_righe = sfield(F_RIGHE);
const int curr_riga = sf_righe.selected();
sf_righe.row(curr_riga).add(o.get(), _pos_imp);
aggiorna_saldi_preventivi(sf_righe, curr_riga);
o.mask().set(S_PREVENTIVO, sf_righe.cell(curr_riga, _pos_prev));
sf_righe.force_update();
_dirty = true;
}
break;
//bottoni
case DLG_CANCEL:
if (e == fe_button && jolly == 0) //jolly serve per specificare che è il DLG_CANCEL della maschera principale
{
if (_dirty)
{
if (yesno_box("Salvare le modifiche effettuate?"))
if (!save()) //attenzione! se la save non riesce si deve fermare senza resettare le modifiche!
return false;
}
enable(F_CODCMS);
enable(F_DESCRIZ);
sfield(F_RIGHE).destroy();
return false;
}
break;
case DLG_CHECKALL:
if (e == fe_button)
{
check_all(!one_checked());
}
break;
case DLG_TODATAINI:
if (e == fe_button)
{
const TString& datainicms = get(F_DATAINICMS);
TSheet_field& sf_righe = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(sf_righe, i, riga) if (riga->get_char(0) > ' ') //solo le righe checked!!
riga->add(datainicms, _pos_datacomp);
sf_righe.force_update();
}
break;
case DLG_TODATAFIN:
if (e == fe_button)
{
TString datafinecms = get(F_DATAPRORCMS);
if (!datafinecms.ok())
datafinecms = get(F_DATAFINECMS);
TSheet_field& sf_righe = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(sf_righe, i, riga) if (riga->get_char(0) > ' ') //solo le righe checked!!
riga->add(datafinecms, _pos_datafcomp);
sf_righe.force_update();
}
break;
case DLG_TOMATURATO:
if (e == fe_button)
{
TSheet_field& sf_righe = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(sf_righe, i, riga) if (riga->get_char(0) > ' ') //solo le righe checked!!
{
//cerca le sorelle della riga
int first, last;
const int sisters = find_sister_rows(i, first, last);
//calcola lo sbilancio tra i saldi maturati e preventivi: il suo scopo sarà quello di modificare gli importi in modo..
//..da azzerare tale sbilancio
const real mat = real(riga->get(_pos_mat));
const real prev = real(riga->get(_pos_prev));
real sbilancio = mat - prev;
//legge l'importo della riga checkata
real imp = real(riga->get(_pos_imp));
//1) se la riga non ha sorelle -> modifica l'importo della riga stessa per azzerare lo sbilancio e stop!
//2) se lo sbilancio è > 0 oppure se lo sbilancio è < 0 ma più piccolo dell'importo, basta agire sulla riga stessa..
//..per azzerare lo sbilancio e stop!
if (sbilancio >= -imp || sisters == 1)
{
imp += sbilancio;
sbilancio = ZERO;
riga->add(imp.string(), _pos_imp);
}
//3) se invece ci sono sorelle oppure lo sbilancio è < 0 e più grande dell'importo della riga, allora vanno azzerate le..
//..righe sorelle partendo da quella checkata, poi passando all'ultima e risalendo fino a che lo sbilancio non si annulli..
//..Insomma una strage di righe che si azzerano
else
{
riga->add("", _pos_imp);
sbilancio += imp;
for (int j = last; j >= first && !sbilancio.is_zero(); j--)
{
imp = sf_righe.cell(j, _pos_imp);
if (j == first)
{
imp += sbilancio;
sbilancio = ZERO;
sf_righe.row(j).add(imp.string(), _pos_imp);
}
else
{
const real k = min(imp, -sbilancio);
if (k > ZERO)
{
imp -= k;
sbilancio += k;
sf_righe.row(j).add(imp.string(), _pos_imp);
}
}
}
}
//al termine deve aggiornare la colonna con i preventivi
aggiorna_saldi_preventivi(sf_righe, i);
}
sf_righe.force_update();
_dirty = true;
}
break;
case DLG_SAVEREC:
if (e == fe_button && check_fields())
{
const bool saved = save();
}
break;
default:
break;
}
return true;
}
///////////////////////////////////
// Metodi della on_field_event
///////////////////////////////////
//salva la commessa con le eventuali modifiche effettuate sulle date
bool TVariazione_budget_mask::save_commessa()
{
TLocalisamfile commesse(LF_COMMESSE);
commesse.put(COMMESSE_CODCMS, get(F_CODCMS));
int err = commesse.read(_isequal, _lock);
if (err == NOERR)
{
commesse.put(COMMESSE_DATAINIZIO, get_date(F_DATAINICMS));
commesse.put(COMMESSE_DATAFINE, get_date(F_DATAFINECMS));
commesse.put(COMMESSE_PROROGA, get_bool(F_PROROGATA));
commesse.put(COMMESSE_DATAPROR, get_date(F_DATAPRORCMS));
//solo la rewrite perchè la commessa ovviamente esiste già
err = commesse.rewrite();
}
return err == NOERR;
}
//modifica movana esistente in base alle modifiche sulle righe
int TVariazione_budget_mask::modifica_movana(const long numreg, TSheet_field& sf_righe, const int r)
{
TAnal_mov movana(numreg);
int first, last;
//prende tutte le sorelle della riga, così da aggiornare un movana alla volta
const int sisters = find_sister_rows(r, first, last, true);
//giro di controllo sulle date; le righe sheet, eventualmente modificate, devono avere un intervallo date..
//..compatibile con quello del movimento
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;
//controlla le righe sorelle dello sheet; se le date non rientrano in quelle della testata -> le righe..
//..vanno considerate nuove, e quindi va messo a 0 il loro numreg/numrig
bool row_modified = false;
for (int i = last; i >= first; i--)
{
//date testata
const bool r_autofcomp = *sf_righe.cell(i, _pos_autofcomp) > ' ';
const TDate r_datacomp = sf_righe.cell(i, _pos_datacomp);
TDate r_datafcomp = sf_righe.cell(i, _pos_datafcomp);
if (r_datafcomp < r_datacomp)
r_datafcomp = r_datacomp;
//importo riga: se nullo la riga verrà eliminata in quanto inutile all'umanità
const int r_numrig = atoi(sf_righe.cell(i, _pos_numrig));
const real r_importo = sf_righe.cell(i, _pos_imp);
//le righe da liberare sono quelle che non rispettano i vincoli sulle date
if (r_autofcomp != autofcomp || r_datacomp != datacomp || r_datafcomp != datafcomp || r_importo.is_zero())
{
if (!r_importo.is_zero())
{
sf_righe.row(i).add("", _pos_numreg);
sf_righe.row(i).add("", _pos_numrig);
}
//elimina la riga dal movana
row_modified |= movana.destroy_row(r_numrig, true);
}
else //qui invece ci vanno le righe modificate che sono solo da riscrivere (importo e/o descr modificate)
{
TRectype& rmovana = movana.body()[r_numrig];
//importo
const real importo = rmovana.get_real(RMOVANA_IMPORTO);
if (importo != r_importo)
{
rmovana.put(RMOVANA_IMPORTO, r_importo);
row_modified = true;
}
//descrizione
const char* r_descr = sf_righe.cell(i, _pos_descr);
const TString& descr = rmovana.get(RMOVANA_DESCR);
if (descr != r_descr)
{
rmovana.put(RMOVANA_DESCR, r_descr);
row_modified = true;
}
}
} //for(int i=last;i<=first;i--)...
if (row_modified)
{
TLocalisamfile file_movana(LF_MOVANA);
if (movana.rows() > 0)
{
movana.update_totdoc();
movana.rewrite(file_movana);
}
else
movana.remove(file_movana);
}
return last;
}
//crea un nuovo movana in base alle righe sullo sheet
int TVariazione_budget_mask::crea_movana(TSheet_field& sf_righe, const int n)
{
TAnal_mov new_movana;
//trovando numreg=0, le sorelle saranno solo quelle che hanno la stessa chiave datacomp/autofcomp/datafcomp,..
//..in modo da creare movana corretti in termini di date e coerenti con le righe contenute in loro
int first, last;
const int sisters = find_sister_rows(n, first, last, true);
//datacomp/autofcomp/datafcomp vengono presi una volta per tutte le sorelle in quanto sono la chiave della sorellanza
const bool r_autofcomp = *sf_righe.cell(n, _pos_autofcomp) > ' ';
const TDate r_datacomp = sf_righe.cell(n, _pos_datacomp);
TDate r_datafcomp = sf_righe.cell(n, _pos_datafcomp);
if (r_datafcomp < r_datacomp)
r_datafcomp = r_datacomp;
//riempie la testata del movana
const TEsercizi_contabili ec;
const int annoes = ec.date2esc(r_datacomp);
new_movana.put(MOVANA_ANNOES, annoes);
const TDate& datareg = get_date(F_DATAREG);
new_movana.put(MOVANA_DATAREG, datareg);
new_movana.put(MOVANA_DATACOMP, r_datacomp);
new_movana.put(MOVANA_AUTOFCOMP, r_autofcomp);
if (!r_autofcomp && r_datafcomp > r_datacomp)
new_movana.put(MOVANA_DATAFCOMP, r_datafcomp);
const TString& codcaus = get(F_CODCAUS);
new_movana.put(MOVANA_CODCAUS, codcaus);
TString descr;
descr << TR("Preventivo commessa ") << get(F_CODCMS);
new_movana.put(MOVANA_DESCR, descr);
new_movana.put(MOVANA_TIPOMOV, 'P');
//giro sulle sorelle; ogni riga, se di importo non nullo, va aggiunta al new_movana
for (int i = first; i <= last; i++)
{
const real importo = sf_righe.cell(i, _pos_imp);
if (importo != ZERO)
{
//aggiunge la rmovana al movana
TRectype& new_rmovana = new_movana.new_row();
//compila la rmovana
new_rmovana.put(RMOVANA_ANNOES, annoes);
new_rmovana.put(RMOVANA_DATACOMP, r_datacomp);
new_rmovana.put(RMOVANA_CODCMS, get(F_CODCMS));
const TString& cdc = sf_righe.cell(i, _pos_cdc);
new_rmovana.put(RMOVANA_CODCCOSTO, cdc);
const TString& fase = sf_righe.cell(i, _pos_fase);
new_rmovana.put(RMOVANA_CODFASE, fase);
const TString& conto = sf_righe.cell(i, _pos_conto);
new_rmovana.put(RMOVANA_CODCONTO, conto);
const TString& sezione = sf_righe.cell(i, _pos_cosric);
new_rmovana.put(RMOVANA_SEZIONE, sezione == "C" ? 'D' : 'A');
new_rmovana.put(RMOVANA_IMPORTO, importo);
const TString& descr = sf_righe.cell(i, _pos_descr);
new_rmovana.put(RMOVANA_DESCR, descr);
}
} //for(int i = last; i >= first; i--)...
//alla fine si scrive il nuovo movana solo se ha righe!!!
if (new_movana.rows() > 0)
{
new_movana.update_totdoc();
TLocalisamfile file_movana(LF_MOVANA);
new_movana.write(file_movana);
}
return last;
}
//salva lo sheet...lasciate ogni speranza voi che entrate!
bool TVariazione_budget_mask::save_sheet()
{
//1) ordina le righe per numreg/numrig
TSheet_field& sf_righe = sfield(F_RIGHE);
sf_righe.sort(compare_by_numrig);
//2) Aggiorna i movana con le righe di loro competenza: registra solo le righe con NUMREG !=0
FOR_EACH_SHEET_ROW(sf_righe, r, riga)
{
const long numreg = sf_righe.row(r).get_long(_pos_numreg);
if (numreg > 0)
r = modifica_movana(numreg, sf_righe, r);
} //FOR_EACH_SHEET_ROW(...
//riordina lo sheet per chiave numreg; in questo modo le righe senza numreg vanno all'inizio e vengono..
//..ordinate per datacomp/autofcomp/datafcomp; tali righe, se hanno importo != 0, vengono aggiunte ad..
//..un nuovo movimento analitico che viene creato sul campo!
sf_righe.sort(compare_by_numrig);
//3)cerca le sorelle per numreg/numrig: righe con NUMREG = 0
FOR_EACH_SHEET_ROW(sf_righe, n, line)
{
const long numreg = sf_righe.row(n).get_long(_pos_numreg);
//l'ultima sort mette in cima allo sheet tutte le righe con numreg=0; quindi alla prima con numreg>0..
//..tanto vale uscire definitivamente
if (numreg != 0)
break;
n = crea_movana(sf_righe, n);
} //FOR_EACH_SHEET_ROW(sf_righe,n...
//le righe vanno rimesse in ordine di chiave cdc/fase/conto
load();
return true;
}
bool TVariazione_budget_mask::save()
{
//salva nel ditta.ini la causale sulla maschera
TConfig ditta_ini(CONFIG_DITTA, "ps1001");
ditta_ini.set("CodCaus", get(F_CODCAUS));
//salva le modifiche alle date della commessa e lo sheet
if (save_commessa() && save_sheet())
_dirty = false;
return true;
}
//controlla sulla colonna delle spunte se almeno una è checkata
bool TVariazione_budget_mask::one_checked() const
{
TSheet_field& sf_righe = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(sf_righe, i, riga)
{
if (riga->get_char(0) > ' ')
return true;
}
return false;
}
//checka-dechecka la colonna di spunte dello sheet
void TVariazione_budget_mask::check_all(const bool checked)
{
TSheet_field& sf_righe = sfield(F_RIGHE);
FOR_EACH_SHEET_ROW(sf_righe, i, riga)
{
int first, last;
find_sister_rows(i, first, last);
for (int j = first; j <= last; j++)
sf_righe.row(j).add(j == last ? "X" : "", _pos_check);
i = last;
}
sf_righe.force_update();
}
//aggiorna la colonna con i saldi preventivi sullo sheet
void TVariazione_budget_mask::aggiorna_saldi_preventivi(TSheet_field& sf_righe, const int curr_riga)
{
int first, last;
const int sisters = find_sister_rows(curr_riga, first, last);
//calcola il totale degli importi delle righe sorelle in modo da avere il saldo
real saldo_prev;
for (int j = first; j <= last; j++)
{
TString80 str_imp = sf_righe.row(j).get(_pos_imp);
saldo_prev += real(str_imp);
}
//mette il saldo in tutte le righe sorelle
for (int j = first; j <= last; j++)
{
TToken_string& row = sf_righe.row(j);
row.add(saldo_prev.string(), _pos_prev);
}
}
int TVariazione_budget_mask::load()
{
TString query;
query << "USE RMOVANA KEY 4\n";
query << "SELECT ((MOVANA.TIPOMOV=\"P\")||(MOVANA.TIPOMOV=\"V\"))\n";
query << "JOIN MOVANA INTO NUMREG==NUMREG\n";
query << "FROM CODCMS=#CODCMS\n";
query << "TO CODCMS=#CODCMS\n";
//instanzio un TISAM_recordset sulle rmovana
TISAM_recordset rmovana(query);
const TString cms = get(F_CODCMS);
rmovana.set_var("#CODCMS", cms);
const long rmovana_items = rmovana.items();
TProgind pi(rmovana_items, "Generazione righe in corso...", true, true);
//recupero sheet e realtiva mashera di riga
TSheet_field& sf_righe = sfield(F_RIGHE);
TMask& msk = sf_righe.sheet_mask();
sf_righe.destroy();
//per ogni riga del recordset va ad aggiornare lo sheet sulla maschera (aggiunge la riga)
for (bool ok = rmovana.move_first(); ok; ok = rmovana.move_next())
{
if (!pi.addstatus(1))
break;
TToken_string& row = sf_righe.row(-1);
//chiave iniziale di riga
const TString& cdc = rmovana.get(RMOVANA_CODCCOSTO).as_string();
row.add(cdc, _pos_cdc);
const TString& fase = rmovana.get(RMOVANA_CODFASE).as_string();
row.add(fase, _pos_fase);
const TString& conto = rmovana.get(RMOVANA_CODCONTO).as_string();
row.add(conto, _pos_conto);
//date competenza iniziale e finale
const TDate datacomp = rmovana.get("MOVANA."MOVANA_DATACOMP).as_date();
TDate datafcomp = rmovana.get("MOVANA."MOVANA_DATAFCOMP).as_date();
const bool autofcomp = rmovana.get("MOVANA."MOVANA_AUTOFCOMP).as_bool();
//caso cazzuto della scadenza con la fine della commessa (come nella stampa bilancio commessa)
if (autofcomp)
{
const TRectype& rec_commesse = cache().get(LF_COMMESSE, cms);
//data del cazzo che serve per non rovinare datacomp, che è la data sulla riga, non quella iniziale di cms
TDate datainicms;
ca_durata_commessa(rec_commesse, datainicms, datafcomp);
}
if (!datafcomp.ok())
datafcomp = datacomp;
row.add(datacomp, _pos_datacomp);
row.add(autofcomp ? "X" : "", _pos_autofcomp);
row.add(datafcomp, _pos_datafcomp);
//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);
real valore = rmovana.get(RMOVANA_IMPORTO).as_real();
const char sezione = rmovana.get(RMOVANA_SEZIONE).as_string()[0];
TImporto importo(sezione, valore);
importo.normalize(indbil == 3 ? 'D' : 'A');
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).as_string(), _pos_descr);
row.add(rmovana.get(RMOVANA_NUMREG).as_int(), _pos_numreg);
row.add(rmovana.get(RMOVANA_NUMRIG).as_int(), _pos_numrig);
const TString& tipomov = rmovana.get("MOVANA."MOVANA_TIPOMOV).as_string();
row.add(tipomov, _pos_tipomov);
} //for(bool ok.move....
//prima di riempire lo sheet a video ordina le righe per sede/fase/numreg/numrig
sf_righe.sort(compare_by_fase);
//in base alle righe caricate ricava i saldi preventivi
FOR_EACH_SHEET_ROW(sf_righe, i, riga)
{
//solo le righe a saldo preventivo nullo vanno considerate
const TString& str_saldo_prev = riga->get(_pos_prev);
if (str_saldo_prev == "")
{
aggiorna_saldi_preventivi(sf_righe, i);
}
}
//e poi aggiorna il video!
sf_righe.force_update();
//al momento del caricamento NON ci sono state modifiche!
_dirty = false;
return sf_righe.items();
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TVariazione_budget : public TSkeleton_application
{
virtual bool check_autorization() const { return false; }
virtual const char * extra_modules() const { return "ca"; }
TVariazione_budget_mask* _msk;
protected:
public:
virtual bool create();
virtual bool destroy();
virtual void main_loop();
TVariazione_budget() {};
};
bool TVariazione_budget::create()
{
_msk = new TVariazione_budget_mask();
return TSkeleton_application::create();
}
bool TVariazione_budget::destroy()
{
delete _msk;
return TApplication::destroy();
}
void TVariazione_budget::main_loop()
{
KEY tasto;
tasto = _msk->run();
}
int ps1001300 (int argc, char* argv[])
{
TVariazione_budget main_app;
main_app.run(argc, argv, TR("Variazione budget"));
return true;
}