campo-sirio/ci/ci2400.cpp
guy 28af4b3a34 Esportazione per paghe ed Excel della rilevazione ore
git-svn-id: svn://10.65.10.50/branches/R_10_00@23052 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-03-31 06:05:18 +00:00

1809 lines
51 KiB
C++
Raw Blame History

#include <applicat.h>
#include <colors.h>
#include <controls.h>
#include <modaut.h>
#include <progind.h>
#include <reputils.h>
#include <toolfld.h>
#include <urldefid.h>
#include "../ca/calib01.h"
#include "cilib.h"
#include "ci2.h"
#include "ci2401.h"
#include "ci2400a.h"
#include <causali.h>
#include "../ca/commesse.h"
#include "../ca/cfcms.h"
#include "../ca/movana.h"
#include "../ca/rmovana.h"
#include "rilore.h"
#include "citbore.h"
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
static void advanced_draw_justified_text_line(WINDOW w, const char* text, short x, short y, short dx)
{
TString256 txt(text); txt.rtrim();
int spaces = 0;
for (int s = 0; txt[s]; s++)
if (isspace(txt[s])) spaces++;
// Il testo e' giustificabile se ha degli spazi ed occupa meno della riga
if (spaces > 0)
{
const int tw = xvt_dwin_get_text_width(w, txt, -1);
if (tw < dx)
{
txt << ' '; // Aggiunge spazio finale
const double kspc = double(dx - tw) / spaces;
int start = 0;
double kx = x;
for (int i = 0; txt[i]; i++) if (isspace(txt[i]))
{
const bool last_word = txt[i+1] == '\0';
const TString& parola = txt.sub(start, i + (last_word ? 0 : 1));
const int lw = xvt_dwin_get_text_width(w, parola, -1);
if (last_word) // ultima parola ("vedova")
kx = x+dx-lw;
xvt_dwin_draw_text(w, int(kx+0.5), y, parola, -1);
kx += lw + kspc;
start = i+1;
}
}
else
xvt_dwin_draw_text(w, x, y, txt, -1); // Stringa che deborda dalla riga
}
else
xvt_dwin_draw_text(w, x, y, txt, -1); // Stringa senza spazi
}
static void advanced_draw_text_line(WINDOW w, const char* text, const RCT& r, char halign, char valign)
{
const short dx = r.right-r.left;
const short dy = r.bottom-r.top;
short x = r.left;
short y = r.bottom;
if (halign != 'L')
{
const int tw = xvt_dwin_get_text_width(w, text, -1);
switch (halign)
{
case 'C': x += (dx - tw)/2; break;
case 'R': x = r.right-tw-1; break;
default : break;
}
}
// Text Height
int leading, ascent, descent;
xvt_dwin_get_font_metrics(w, &leading, &ascent, &descent);
switch (valign)
{
case 'C': y -= (dy - ascent-descent)/2; break;
case 'T': y = r.top + ascent; break;
default : y -= descent+leading; break;
}
bool can_draw = true;
RCT orig; xvt_dwin_get_clip(w, &orig);
bool restore_clip = !xvt_rect_is_empty(&orig);
if (restore_clip)
{
RCT clipper;
can_draw = xvt_rect_intersect(&clipper, &orig, &r) != 0;
if (can_draw)
xvt_dwin_set_clip(w, &clipper);
else
restore_clip = false;
}
else
xvt_dwin_set_clip(w, &r);
if (can_draw)
{
if (halign == 'J')
advanced_draw_justified_text_line(w, text, x, y, dx);
else
xvt_dwin_draw_text(w, x, y, text, -1);
if (restore_clip)
xvt_dwin_set_clip(w, &orig);
}
}
///////////////////////////////////////////////////////////
// TConsuntivazione_field
///////////////////////////////////////////////////////////
class TConsuntivazione_window : public TField_window
{
int _rows, _cols;
TDate _date;
protected:
virtual void update();
virtual long handler(WINDOW win, EVENT* ep);
void cell2rct(int c, RCT& rct) const;
void query(TString& month) const;
void set_font(int nHeight);
COLOR day2color(const TDate& d) const;
public:
void set_date(const TDate& d);
TConsuntivazione_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner);
};
void TConsuntivazione_window::cell2rct(int c, RCT& r) const
{
const int row = c / _cols;
const int col = c % _cols;
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
r.left = col * rct.right / _cols;
r.top = row * rct.bottom / _rows;
r.right = (col+1) * rct.right / _cols;
r.bottom = (row+1) * rct.bottom / _rows;
}
void TConsuntivazione_window::set_date(const TDate& d)
{
if (d.ok())
{
const int old_month = _date.month();
const int new_month = d.month();
_date = d;
if (new_month != old_month)
force_update();
}
}
void TConsuntivazione_window::query(TString& busy) const
{
TDate dal = _date; dal.set_day(1);
TDate al = _date; al.set_end_month();
busy.fill(' ', 31);
TString query;
query << "USE RILORE KEY 2";
query << "\nFROM TIPO=C DADATA=" << dal.string()
<< "\nTO TIPO=C DADATA=" << al.string();
TISAM_recordset def(query);
for (bool ok = def.move_first(); ok; ok = def.move_next())
{
const TDate d = def.get("DADATA").as_date();
if (d >= dal && d <= al)
busy.overwrite("W", d.day()-1);
}
}
void TConsuntivazione_window::set_font(int nHeight)
{
XVT_FNTID fontid = xvt_font_create();
xvt_font_set_family(fontid, XVT_FFN_HELVETICA);
xvt_font_set_style(fontid, nHeight > 8 ? XVT_FS_BOLD : XVT_FS_BOLD);
xvt_font_set_size(fontid, nHeight);
xvt_dwin_set_font(win(), fontid);
xvt_font_destroy(fontid);
}
inline bool is_red_day(const TDate& d)
{ return d.wday() >= 6 || d.is_holiday(); }
COLOR TConsuntivazione_window::day2color(const TDate& d) const
{
static const COLOR festivo = COLOR_RED;
static const COLOR feriale = COLOR_BLUE;
static const COLOR ponte = blend_colors(festivo, feriale);
if (is_red_day(d))
return festivo;
if (d.month() == 12 && (d.day() == 24 || d.day() == 31))
return ponte;
TDate yesterday = d; --yesterday;
TDate tomorrow = d; ++tomorrow;
if (is_red_day(yesterday) && is_red_day(tomorrow))
return ponte;
return feriale;
}
void TConsuntivazione_window::update()
{
WINDOW dc = win();
RCT rct; xvt_vobj_get_client_rect(dc, &rct);
xvt_dwin_draw_gradient_linear(dc, &rct, blend_colors(NORMAL_BACK_COLOR, REQUIRED_BACK_COLOR), NORMAL_BACK_COLOR, 90);
int lato = int(sqrt(rct.right * rct.bottom / 32.0));
do
{
_rows = rct.bottom / lato;
_cols = rct.right / lato;
lato--;
}
while (_rows * _cols < 32);
TDate dend = _date; dend.set_end_month();
CBRUSH cbrush = { PAT_HOLLOW, 0 };
set_font(xvt_rect_get_height(&rct)/(2*_rows));
TString16 text;
const int cells = _rows * _cols;
TString80 busy; query(busy);
for (int i = 0; i < cells; i++)
{
RCT r; cell2rct(i, r);
if (busy[i] > ' ' && i < dend.day())
{
cbrush.pat = PAT_SOLID;
cbrush.color = FOCUS_BACK_COLOR;
}
else
{
cbrush.pat = PAT_HOLLOW;
cbrush.color = NORMAL_BACK_COLOR;
}
xvt_dwin_set_cbrush(dc, &cbrush);
xvt_dwin_draw_rect(dc, &r);
if (i < dend.day())
{
set_color(NORMAL_COLOR, cbrush.color);
text.format("%d", i+1);
advanced_draw_text_line(dc, text, r, 'C', 'B');
}
}
for (int i = 0; i < dend.day(); i++)
{
const TDate d(i+1, dend.month(), dend.year());
RCT rc; cell2rct(i, rc);
const int h = xvt_rect_get_height(&rc);
rc.bottom = rc.top + h/3;
xvt_rect_deflate(&rc, 2, 2);
if (i == 0)
set_font(h/6);
cbrush.pat = PAT_SOLID;
cbrush.color = day2color(d);
xvt_dwin_set_cbrush(dc, &cbrush);
const int r = h/16;
xvt_dwin_draw_roundrect(dc, &rc, r, r);
set_color(NORMAL_BACK_COLOR, cbrush.color);
text = itow(d.wday()); text.cut(3);
rc.top--; // Better text position
advanced_draw_text_line(dc, text, rc, 'C', 'T');
}
if (cells > 31)
{
RCT rc; cell2rct(cells-1, rc);
cbrush.pat = PAT_SOLID;
cbrush.color = REQUIRED_BACK_COLOR;
xvt_dwin_set_cbrush(dc, &cbrush);
xvt_dwin_draw_rect(dc, &rc);
set_font(xvt_rect_get_height(&rc)/4);
set_color(NORMAL_COLOR, cbrush.color);
text = itom(_date.month());
text.cut(3);
advanced_draw_text_line(dc, text, rc, 'C', 'T');
text.format("%d", _date.year());
advanced_draw_text_line(dc, text, rc, 'C', 'B');
}
}
long TConsuntivazione_window::handler(WINDOW win, EVENT* ep)
{
switch (ep->type)
{
case E_MOUSE_DOWN:
{
RCT rct; xvt_vobj_get_client_rect(win, &rct);
const int cx = ep->v.mouse.where.h * _cols / rct.right;
const int cy = ep->v.mouse.where.v * _rows / rct.bottom;
const int day = cy * _cols + cx;
TDate d = _date; d.set_end_month();
if (day >= 0 && day < d.day())
{
TMask& m = owner().mask();
d.set_day(day+1);
m.set(F_GIORNO, d.string(), 0x3);
m.send_key(K_CTRL+'+', F_SHEET, &owner());
}
}
break;
default: break;
}
return TField_window::handler(win, ep);
}
TConsuntivazione_window::TConsuntivazione_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner)
: TField_window( x, y, dx, dy, parent, NULL), _date(TODAY)
{
create(x, y, dx, dy, "", 0, W_PLAIN, parent);
set_owner(owner);
}
class TConsuntivazione_field : public TWindowed_field
{
protected:
TField_window* TConsuntivazione_field::create_window(int x, int y, int dx, int dy, WINDOW parent);
public:
virtual void set(const char* s);
TConsuntivazione_field(TMask* m);
};
TField_window* TConsuntivazione_field::create_window(int x, int y, int dx, int dy, WINDOW parent)
{ return new TConsuntivazione_window(x, y, dx, dy, parent, this); }
void TConsuntivazione_field::set(const char* s)
{
TDate d(TODAY);
if (TDate::isdate(s))
{
d = TDate(s);
}
else
{
if (real::is_natural(s))
{
const int y = atoi(s);
if (y >= 2000 && y < 10000)
d.set_year(y);
}
}
if (d.ok())
{
TConsuntivazione_window& cw = (TConsuntivazione_window&)win();
cw.set_date(d);
}
}
TConsuntivazione_field::TConsuntivazione_field(TMask* m) : TWindowed_field(m)
{ }
///////////////////////////////////////////////////////////
// TConsuntivazione_msk
///////////////////////////////////////////////////////////
class TConsuntivazione_msk : public TAutomask
{
short _cdc_sid, _cdc_lid, _cms_sid, _cms_lid, _fase_sid, _fase_lid;
short _scdc_sid, _scdc_lid, _scms_sid, _scms_lid, _sfase_sid, _sfase_lid;
bool _sheet_dirty, _recontabilize, _locked;
protected:
virtual TMask_field* parse_field(TScanner& scanner);
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
protected:
bool cerca_disponibilita(int riga) const;
int aggiungi_straordinario(int riga, const TString& tipo_ora, const real& prz, const real& qta) const;
real ore_totali(int riga, real& this_row) const;
real proponi_costo(TMask& msk) const;
void riempi_nuova_riga(int r);
bool add_ril_to_doc(TRectype& rilore, TDocumento& doc, TLog_report& log) const;
bool add_ril_to_mov(TRectype& rilore, TAnal_mov& mov, TLog_report& log) const;
void get_anal_fields(TString & cdc, TString & cms, TString & fase) const;
void get_row_anal_fields(TToken_string & row, TString & cdc, TString & cms, TString & fase) const;
void put_row_anal_fields(TToken_string & row, const TString & cdc, const TString & cms, const TString & fase);
long save_docs(TAssoc_array& docs, TAssoc_array& movs, TLog_report& log) const;
const TString& good_umart(const TString& codart, const TString& um) const;
public:
bool save_sheet();
bool save_dirty_sheet();
bool load_sheet();
bool contabilizza();
bool esporta();
TConsuntivazione_msk();
};
TMask_field* TConsuntivazione_msk::parse_field(TScanner& scanner)
{
if (scanner.key() == "CA")
{
set_full_screen_interface(page_win(0), true);
return new TConsuntivazione_field(this);
}
return TAutomask::parse_field(scanner);
}
void TConsuntivazione_msk::get_anal_fields(TString & cdc, TString & cms, TString & fase) const
{
TString val;
cdc.cut(0);
if (_cdc_sid >= 0)
for ( short id = _cdc_sid; id <= _cdc_lid; id++)
{
val = get(id);
val.rpad(field(id).size());
cdc << val;
}
cdc.trim();
cms.cut(0);
if (_cms_sid >= 0)
for ( short id = _cms_sid; id <= _cms_lid; id++)
{
val = get(id);
val.rpad(field(id).size());
cms << val;
}
cms.trim();
fase.cut(0);
if (_fase_sid >= 0)
for ( short id = _fase_sid; id <= _fase_lid; id++)
{
val = get(id);
val.rpad(field(id).size());
fase << val;
}
fase.trim();
}
void TConsuntivazione_msk::get_row_anal_fields(TToken_string & row, TString & cdc, TString & cms, TString & fase) const
{
TSheet_field & s = sfield(F_SHEET);
TMask & m = s.sheet_mask();
TString val;
cdc.cut(0);
if (_scdc_sid >= 0)
for ( short id = _scdc_sid; id <= _scdc_lid; id++)
{
val = row.get(s.cid2index(id));
val.rpad(m.field(id).size());
cdc << val;
}
cdc.trim();
cms.cut(0);
if (_scms_sid >= 0)
for ( short id = _scms_sid; id <= _scms_lid; id++)
{
val = row.get(s.cid2index(id));
val.rpad(m.field(id).size());
cms << val;
}
cms.trim();
fase.cut(0);
if (_sfase_sid >= 0)
for ( short id = _sfase_sid; id <= _sfase_lid; id++)
{
val = row.get(s.cid2index(id));
val.rpad(m.field(id).size());
fase << val;
}
fase.trim();
}
void TConsuntivazione_msk::put_row_anal_fields(TToken_string & row, const TString & cdc, const TString & cms, const TString & fase)
{
TSheet_field & s = sfield(F_SHEET);
TMask & m = s.sheet_mask();
int pos = 0;
if (_scdc_sid >= 0)
for (short id = _scdc_sid; id <= _scdc_lid; id++)
{
const int len = m.field(id).size();
row.add(cdc.mid(pos, len), s.cid2index(id));
pos += len;
}
pos = 0;
if (_scms_sid >= 0)
for (short id = _scms_sid; id <= _scms_lid; id++)
{
const int len = m.field(id).size();
row.add(cms.mid(pos, len), s.cid2index(id));
pos += len;
}
pos = 0;
if (_sfase_sid >= 0)
for (short id = _sfase_sid; id <= _sfase_lid; id++)
{
const int len = m.field(id).size();
row.add(fase.mid(pos, len), s.cid2index(id));
pos += len;
}
}
bool TConsuntivazione_msk::save_sheet()
{
TFast_isamfile rilore(LF_RILORE);
long lastid = 0;
{
TISAM_recordset def("USE RILORE\nFROM TIPO=C\nTO TIPO=C");
if (def.move_last())
lastid = def.get("ID").as_int();
}
TSheet_field& sheet = sfield(F_SHEET);
const int posid = sheet.cid2index(S_ID);
TRectype& rec = rilore.curr();
FOR_EACH_SHEET_ROW(sheet, r, row)
{
long id = row->get_long(posid);
const bool is_new = id <= 0;
if (is_new)
{
id = ++lastid;
row->add(id, posid);
}
rec.zero();
rec.put("TIPO", "C");
rec.put("ID", id);
if (!is_new)
rilore.read();
sheet.autosave_line(r+1, rec);
rec.put(RILORE_ADATA, rec.get(RILORE_DADATA)); // copia datata in adata
if (id == lastid)
rilore.write_rewrite();
else
rilore.rewrite_write();
}
enable(DLG_SAVEREC, _sheet_dirty = false);
TConsuntivazione_field& f = (TConsuntivazione_field&)field(F_CALENDAR);
f.win().force_update();
return !sheet.empty();
}
bool TConsuntivazione_msk::save_dirty_sheet()
{
bool done = !_sheet_dirty;
if (_sheet_dirty && yesno_box(TR("Salvare le righe modificate?")))
done = save_sheet();
return done;
}
bool TConsuntivazione_msk::load_sheet()
{
save_dirty_sheet();
TString select;
if (get_bool(C_RISOATT))
{
const TString& risoatt = get(F_RISOATT);
select << "&&(TIPORA==\"" << risoatt << "\")";
if (get_bool(C_CODICE))
{
const TString& codice = get(risoatt == "A" ? F_CODATT : F_CODRIS);
if (codice.full())
select << "&&(CODICE==\"" << codice << "\")";
}
}
if (get_bool(C_TPORA))
{
const TString& tpora = get(F_TPORA);
if (tpora.full())
select << "&&(TPORA==\"" << tpora << "\")";
}
TString codcosto, codcms, codfase;
get_anal_fields(codcosto, codcms, codfase);
if (codcosto.full())
select << "&&(CODCOSTO==\"" << codcosto << "\")";
if (codcms.full())
select << "&&(CODCMS==\"" << codcms << "\")";
if (codfase.full())
select << "&&(CODFASE==\"" << codfase << "\")";
TString query;
query << "USE RILORE KEY 2";
if (select.full())
query << "\nSELECT " << select.mid(2) << "\n";
const TDate oggi(TODAY);
int y = get_int(F_ANNO); if (y < 2000) y = oggi.year();
TDate da_data(1,1,y), a_data(31,12,y);
const TDate d = get(F_GIORNO);
if (d.ok() && get_bool(C_GIORNO))
da_data = a_data = d; else
if (get_bool(C_MESE))
{
const int m = get_int(F_MESE);
da_data.set_month(m);
a_data.set_month(m);
a_data.set_end_month();
}
query << "\nFROM TIPO=C DADATA=" << da_data.string()
<< "\nTO TIPO=C DADATA=" << a_data.string();
TISAM_recordset def(query);
const TRectype& rec = def.cursor()->curr();
TDate last_date = da_data;
TSheet_field& sheet = sfield(F_SHEET);
sheet.destroy();
_locked = true;
TProgress_monitor mon(def.items(), TR("Caricamento ore..."), true);
int r = 0;
for (bool ok = def.move_first(); ok; ok = def.move_next())
{
sheet.autoload_line(++r, rec);
if (!mon.add_status())
break;
if (rec.get_long(RILORE_NDOC) > 0)
{
TToken_string& row = sheet.row(r-1);
row.add(5, sheet.cid2index(S_STATO));
}
last_date = rec.get(RILORE_DADATA);
if (r >= 9999)
break;
}
sheet.force_update();
set(F_CALENDAR, last_date.string());
enable(DLG_SAVEREC, _sheet_dirty = false);
_locked = false;
return !sheet.empty();
}
real TConsuntivazione_msk::proponi_costo(TMask& msk) const
{
const TString& codlist = msk.get(S_CODLIST);
if (codlist.empty())
{
TString80 cdc, cms, fase;
get_anal_fields(cdc, cms, fase);
if (cms.full())
{
const TString& lis = cache().get(LF_COMMESSE, cms, COMMESSE_LISRILCN);
msk.set(S_CODLIST, lis);
}
}
const char tipo = msk.get(S_RISOATT)[0];
const TString& codice = msk.get(tipo=='A' ? S_CODATT : S_CODRIS);
const TString& tpora = msk.get(S_TPORA);
real costo;
if (codlist.full() && codice.full() && tpora.full())
{
const TDate dal = msk.get(S_DATA);
TString80 filtro = codlist; filtro.left_just(4);
filtro << tipo << codice;
TString query;
query << "USE &ROA SELECT CODTAB[22,29]<=\"" << dal.date2ansi() << '"'
<< "\nFROM CODTAB=" << filtro
<< "\nTO CODTAB=" << filtro;
TISAM_recordset roa(query);
for (bool ok = roa.move_last(); ok; ok = roa.move_prev())
{
const TString& codtab = roa.get("CODTAB").as_string();
const TDate data = codtab.mid(21, 8);
const TString& to = codtab.mid(29);
if (to == tpora && data <= dal)
{
costo = roa.get("R1").as_real();
if (!costo.is_zero())
break;
}
}
}
const TRectype& roa = cache().get(tipo == 'A' ? "ATR" : "RSS", codice);
if (costo.is_zero())
{
const char* fld_price = "R10"; // Costo standard risorsa o attrezzatura
if (tipo =='A' && tpora == roa.get("S9") && !roa.get_real("R11").is_zero())
fld_price = "R11"; // costo disponibilit<69> attrezzatura
costo = roa.get_real(fld_price);
}
if (costo > ZERO && costo < 10000)
{
msk.set(S_COSTO, costo);
msk.set(S_CODIVA, roa.get("S3").left(4));
}
return costo;
}
void TConsuntivazione_msk::riempi_nuova_riga(int r)
{
TSheet_field& sheet = sfield(F_SHEET);
TToken_string& riga = sheet.row(r);
//guardo il tipo risorsa / attrezzatura che sto ricercando
const TString& tipo = get(F_RISOATT);
riga.add(get(F_GIORNO), sheet.cid2index(S_DATA));
riga.add(tipo, sheet.cid2index(S_RISOATT));
riga.add(get(tipo=="R" ? F_CODRIS : F_CODATT), sheet.cid2index(S_CODRIS));
riga.add(get(F_TPORA), sheet.cid2index(S_TPORA));
TString codcosto, codcms, codfase;
get_anal_fields(codcosto, codcms, codfase);
put_row_anal_fields(riga, codcosto, codcms, codfase);
sheet.update_mask(r);
TMask& msk = sheet.sheet_row_mask(r);
proponi_costo(msk);
sheet.check_row(r);
sheet.force_update(r);
}
const TString& TConsuntivazione_msk::good_umart(const TString& codart, const TString& um) const
{
// Reperisce unit<69> di misura standard per codart
TString80 key; key << codart << "|1";
const TString& defum = cache().get(LF_UMART, key, UMART_UM);
// Controlla unit<69> di misura fuori standard
if (um.full() && um != defum)
{
TLocalisamfile umart(LF_UMART);
umart.setkey(2);
umart.put(UMART_CODART, codart);
umart.put(UMART_UM, um);
if (umart.read() == NOERR)
return um;
}
return defum;
}
bool TConsuntivazione_msk::add_ril_to_doc(TRectype& rilore, TDocumento& doc, TLog_report& log) const
{
const char tipo_roa = rilore.get_char(RILORE_TIPORA); // 'R'isorsa o 'A'ttrezzatura
const TString& codice_roa = rilore.get(RILORE_CODICE);
const TRectype& roa = cache().get(tipo_roa == 'A' ? "ATR" : "RSS", codice_roa);
const TString& tipo_ora = rilore.get(RILORE_TPORA);
const bool disponibilita = tipo_roa == 'A' && tipo_ora == roa.get("S9");
TString80 codart = roa.get("S2");
if (disponibilita)
codart.ltrim(20);
else
codart.cut(20);
codart.trim();
if (codart.blank())
{
TString msg;
msg << (tipo_roa == 'R' ? TR("Impossibile associare un articolo alla risorsa ")
: TR("Impossibile associare un articolo all'attrezzatura "));
msg << codice_roa;
log.log(2, msg);
return false;
}
const real ore = rilore.get(RILORE_QTAORE);
const real prezzo = rilore.get(RILORE_COSTO);
const TCodice_cms cms = rilore.get(RILORE_CODCMS);
const TCodice_fas fas = rilore.get(RILORE_CODFASE);
if (cms.full() && doc.get(DOC_CODCMS) != cms)
{
doc.put(DOC_CODCMS, cms);
doc.put(DOC_FASCMS, fas);
}
int found = 0;
if (!ore.is_zero() && !prezzo.is_zero())
{
FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
{
if (rdoc->get(RDOC_CODARTMAG) == codart &&
rdoc->get_real(RDOC_PREZZO) == prezzo &&
rdoc->get(RDOC_CODCMS) == cms &&
rdoc->get(RDOC_FASCMS) == fas)
{
found = r;
break;
}
}
if (!found)
{
const TRectype& anamag = cache().get(LF_ANAMAG, codart);
TRiga_documento& riga = doc.new_row("01");
riga.put(RDOC_CODART, codart);
riga.put(RDOC_CODARTMAG, codart);
riga.put(RDOC_CODCMS, cms);
riga.put(RDOC_FASCMS, fas);
riga.put(RDOC_CHECKED, "X");
riga.put(RDOC_GENERATA, "X");
riga.put(RDOC_DESCR, anamag.get(ANAMAG_DESCR));
riga.put(RDOC_PREZZO, prezzo);
riga.put(RDOC_DATACONS, doc.get(DOC_DATADOC));
TString4 codiva = roa.get("S3").left(4);
if (codiva.blank())
codiva = anamag.get(ANAMAG_CODIVA);
riga.put(RDOC_CODIVA, codiva);
// Controllo unit<69> di misura
TString4 um = roa.get("S7");
if (disponibilita)
um = good_umart(codart, EMPTY_STRING);
else
um = good_umart(codart, um);
riga.put(RDOC_UMQTA, um);
found = riga.get_int(RDOC_NRIGA);
}
TRiga_documento& riga = doc[found];
riga.add(RDOC_QTA, ore);
rilore.put(RILORE_PROVV, riga.get(RDOC_PROVV));
rilore.put(RILORE_ANNOD, riga.get(RDOC_ANNO));
rilore.put(RILORE_CODNUM, riga.get(RDOC_CODNUM));
rilore.put(RILORE_NDOC, riga.get(RDOC_NDOC));
rilore.put(RILORE_IDRIGA, found); // IDRIGA is null right now!
}
return found > 0;
}
bool TConsuntivazione_msk::add_ril_to_mov(TRectype& rilore, TAnal_mov& mov, TLog_report& log) const
{
const char tipo_roa = rilore.get_char(RILORE_TIPORA);
const TString& codice_roa = rilore.get(RILORE_CODICE);
const TRectype& roa = cache().get(tipo_roa == 'A' ? "ATR" : "RSS", codice_roa);
TCodice_con conto = roa.get("S1").left(20); // in S1 poi ci sono anche commessa e cantiere!
conto.trim();
if (conto.empty())
{
TString msg; msg << TR("Impossibile associare un conto analitico a ") << codice_roa;
log.log(2, msg);
return false;
}
const real ore = rilore.get(RILORE_QTAORE);
const real prezzo = rilore.get(RILORE_COSTO);
const TCodice_cms cms = rilore.get(RILORE_CODCMS);
const TCodice_fas fas = rilore.get(RILORE_CODFASE);
bool done = !ore.is_zero() && !prezzo.is_zero();
if (done)
{
// Cerca eventuale riga compatibile
int i = 0;
for (i = mov.rows(); i > 0; i--)
{
const TRectype& row = mov.body()[i];
if (row.get(RMOVANA_CODCONTO) == conto && row.get(RMOVANA_CODCMS) == cms && row.get(RMOVANA_CODFASE) == fas)
break;
}
// Crea nuova riga se necessario
if (i <= 0)
{
TRectype& row = mov.new_row();
row.put(RMOVANA_CODCONTO, conto);
row.put(RMOVANA_CODCMS, cms);
row.put(RMOVANA_CODFASE, fas);
i = row.get_int(RMOVANA_NUMRIG);
}
// Incrementa importo
TRectype& row = mov.body()[i];
row.put(RMOVANA_SEZIONE, 'D');
real imp = ore*prezzo; imp.round(2);
row.add(RMOVANA_IMPORTO, imp);
}
return done;
}
static void doc2msg(const TRectype& doc, TString& msg)
{
msg.cut(0) << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << '/' << doc.get(DOC_NDOC)
<< TR(" del ") << doc.get(DOC_DATADOC);
}
long TConsuntivazione_msk::save_docs(TAssoc_array& docs, TAssoc_array& movs, TLog_report& log) const
{
long ndocs = 0;
log.log(0, "");
TString msg = TR("Aggiornamento contabilit<69> industriale");
if (!movs.empty()) msg << TR(" ed analitica");
log.log(0, msg);
TProgind pi(docs.items() + movs.items(), msg);
FOR_EACH_ASSOC_OBJECT(docs, h, k, o)
{
if (!pi.addstatus(1))
break;
TDocumento* doc = (TDocumento*)o;
doc2msg(*doc, msg);
int err = NOERR;
if (doc->rows() > 0)
{
ndocs++;
err = doc->write();
}
else
{
err = doc->remove();
}
if (err != NOERR)
{
msg << TR(" Errore di scrittura ") << err;
log.log(2, msg);
}
else
log.log(0, msg);
}
if (!movs.empty())
{
TFast_isamfile movana(LF_MOVANA);
FOR_EACH_ASSOC_OBJECT(movs, h, k, o)
{
if (!pi.addstatus(1))
break;
TAnal_mov* mov = (TAnal_mov*)o;
msg.cut(0) << TR("Movimento analitico ") << mov->get(MOVANA_NUMREG);
TImporto tot;
for (int r = mov->body().last_row(); r > 0; r--)
{
const TRectype& rmov = mov->body()[r];
const char sez = rmov.get_char(RMOVANA_SEZIONE);
const real imp = rmov.get_real(RMOVANA_IMPORTO);
tot += TImporto(sez, imp);
}
tot.normalize();
mov->put(MOVANA_SEZIONE, tot.sezione());
mov->put(MOVANA_TOTDOC, tot.valore());
int err = NOERR;
if (mov->rows() > 0)
err = mov->write(movana);
else
err = mov->remove(movana);
if (err != NOERR)
{
msg << TR(" Errore di scrittura ") << err;
log.log(2, msg);
}
else
log.log(0, msg);
}
}
return ndocs;
}
bool TConsuntivazione_msk::contabilizza()
{
if (!save_dirty_sheet())
return false;
const int anno = get_int(F_ANNO);
if (anno < 2010)
return field(F_ANNO).on_hit();
const TString4 numcn = ini_get_string(CONFIG_DITTA, "ci", "CODNUMCN");
const TString4 tipocn = ini_get_string(CONFIG_DITTA, "ci", "TIPODOCCN");
if (numcn.blank() || tipocn.blank())
return error_box(TR("Non sono stati impostati numerazione e/o tipo documento per consuntivazione ore"));
// Calcolo il range di date delle ore da consuntivare
TDate dal, al;
bool daily = false;
const char dett = ini_get_string(CONFIG_DITTA, "ci", "DETTCONS")[0];
switch (dett)
{
case 'A':
dal = TDate( 1, 1, anno);
al = TDate(31,12, anno);
break;
case 'M':
dal = TDate( 1, get_int(F_MESE), anno);
al = dal; al.set_end_month();
break;
default:
dal = al = get_date(F_GIORNO);
daily = true;
break;
}
TMask m(TR("Parametri contabilizzazione"), 1, 28, 7);
m.add_button_tool(DLG_OK, "", TOOL_OK);
m.add_button_tool(DLG_CANCEL, "", TOOL_CANCEL);
m.add_button_tool(DLG_INFO, "", TOOL_INFO);
m.add_date(101, 0, PR("Dal giorno "), 1, 1, daily ? "" : "D").check_type(CHECK_REQUIRED);
m.add_date(102, 0, PR("Al giorno "), 1, 2, daily ? "" : "D").check_type(CHECK_REQUIRED);
m.add_boolean(103, 0, TR("Generazione analitica"), 1, 3, "D");
m.set(101, dal);
m.set(102, al);
if (ca_config().get_int("Authorizations") > 1)
{
m.enable(103);
m.set(103, "X");
}
if (m.run() != K_ENTER)
return false;
const bool do_anal = m.get_bool(103);
const TString4 causcn = ini_get_string(CONFIG_DITTA, "ci", "CODCAUSCN");
if (do_anal && causcn.blank())
return error_box(TR("Impostare la causale contabile per i consuntivi in configurazione"));
if (daily)
{
dal = m.get(101);
al = m.get(102);
if (al.year() > dal.year())
al = TDate(31, 12, dal.year());
}
TString msg; msg << TR("Si desidera contabilizzare il periodo dal ") << dal << TR(" al ") << al << " ?";
if (!yesno_box(msg))
return false;
TLog_report log;
msg = TR("Caricamento contabilit<69> industriale");
log.log(0, msg);
TAssoc_array docs, movs;
if (numcn.full() && al >= dal) // dummy bracketing test
{
TString query;
query << "USE DOC SELECT BETWEEN(DATADOC," << dal.date2ansi() << ',' << al.date2ansi() << ')'
<< "\nFROM PROVV=D ANNO=" << dal.year() << " CODNUM=" << numcn << " NDOC=" << date2ndoc(dal)
<< "\nTO PROVV=D ANNO=" << al.year() << " CODNUM=" << numcn << " NDOC=" << date2ndoc(al);
TISAM_recordset docset(query);
TProgind pi(docset.items(), msg);
for (bool ok = docset.move_first(); ok; ok = docset.move_next())
{
if (!pi.addstatus(1))
break;
TDocumento* doc = new TDocumento(docset.cursor()->curr());
const TDoc_key key(doc->get_int(DOC_ANNO), numcn, doc->get_long(DOC_NDOC));
doc->destroy_rows();
docs.add(key, doc);
doc2msg(*doc, msg);
const long numreg = doc->get_long(DOC_NUMREGCA);
if (do_anal && numreg > 0)
{
TAnal_mov* m = new TAnal_mov(numreg);
if (m->rows() > 0)
{
m->destroy_rows();
movs.add(key, m);
msg << TR(" + analitica ") << numreg;
}
else
delete m;
}
log.log(0, msg);
}
}
if (numcn.full() && al >= dal) // dummy bracketing test
{
log.log(0, "");
msg = TR("Caricamento ore consuntivate");
log.log(0, msg);
TFast_isamfile file_ore(LF_RILORE);
TFast_isamfile file_ana(LF_MOVANA);
long last_numregca = 0;
if (do_anal && file_ana.last() == NOERR)
last_numregca = file_ana.get_long(MOVANA_NUMREG);
TString query;
query << "USE RILORE KEY 2"
<< "\nFROM TIPO=C DADATA=" << dal
<< "\nTO TIPO=C DADATA=" << al;
TISAM_recordset recset(query);
TProgress_monitor pi(recset.items(), msg);
TRectype& rilore = recset.cursor()->curr();
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
TDate d = rilore.get("DADATA");
switch (dett)
{
case 'A': d.set_month(12); d.set_day(31); break;
case 'M': d.set_end_month(); break;
default: break;
}
const TDoc_key key(d.year(), numcn, date2ndoc(d));
TDocumento* doc = (TDocumento*)docs.objptr(key);
if (doc == NULL)
{
doc = new TDocumento('D', key.anno(), key.codnum(), key.ndoc());
doc->put(DOC_TIPODOC, tipocn);
doc->put(DOC_DATADOC, d);
doc->put(DOC_STATO, 1);
docs.add(key, doc);
doc2msg(*doc, msg);
msg.insert(TR("Creazione "));
log.log(0, msg);
}
if (add_ril_to_doc(rilore, *doc, log))
{
rilore.rewrite(file_ore);
if (do_anal)
{
TAnal_mov* mov = (TAnal_mov*)movs.objptr(key);
if (mov == NULL)
{
mov = new TAnal_mov(++last_numregca);
movs.add(key, mov);
doc->put(DOC_NUMREGCA, last_numregca);
}
if (mov->rows() == 0)
{
mov->put(MOVANA_DATAREG, TDate(TODAY));
if (daily)
{
mov->put(MOVANA_DATACOMP, doc->get(DOC_DATADOC));
mov->head().zero(MOVANA_DATAFCOMP);
}
else
{
mov->put(MOVANA_DATACOMP, dal);
mov->put(MOVANA_DATAFCOMP, al);
}
mov->put(MOVANA_DATADOC, doc->get(DOC_DATADOC));
mov->put(MOVANA_ANNOES, doc->get(DOC_ANNO));
mov->put(MOVANA_NUMDOC, doc->get(DOC_NDOC));
mov->put(MOVANA_CODCAUS, causcn);
mov->put(MOVANA_TIPODOC, cache().get(LF_CAUSALI, causcn, CAU_TIPODOC));
mov->put(MOVANA_DPROVV, doc->get(DOC_PROVV));
mov->put(MOVANA_DANNO, doc->get(DOC_ANNO));
mov->put(MOVANA_DCODNUM, doc->get(DOC_CODNUM));
mov->put(MOVANA_DNDOC, doc->get(DOC_NDOC));
msg = TR("Consuntivazione ore ");
if (daily)
msg << TR("del ") << rilore.get(RILORE_DADATA);
else
msg << TR("dal ") << dal << TR(" al ") << al;
mov->put(MOVANA_DESCR, msg);
msg.cut(0) << TR("Creazione movimento analitico ") << last_numregca;
log.log(0, msg);
}
add_ril_to_mov(rilore, *mov, log);
}
}
}
}
const long ndocs = save_docs(docs, movs, log);
log.log(0, "");
if (ndocs > 0)
{
msg.format(FR("Sono stati generati %ld documenti"), ndocs);
log.log(0, msg);
}
else
log.log(1, TR("Non sono stati generati documenti"));
log.preview();
_recontabilize = false;
return true;
}
bool TConsuntivazione_msk::esporta()
{
const int anno = get_int(F_ANNO);
const int mese = get_int(F_MESE);
const bool done = esportazione_paghe(anno, mese);
return done && load_sheet();
}
bool TConsuntivazione_msk::cerca_disponibilita(int riga) const
{
TSheet_field& s = sfield(F_SHEET);
const int col_att = s.cid2index(S_CODATT);
const int col_ora = s.cid2index(S_TPORA);
const int col_cms = s.cid2index(S_CDC1);
const TToken_string& r = s.row(riga);
TString80 cod_att; r.get(col_att, cod_att); cod_att.trim();
TString4 tipo_ora; r.get(col_ora, tipo_ora); tipo_ora.trim();
TString80 cod_cms; r.get(col_cms, cod_cms); cod_cms.trim();
for (int i = riga-1; i <= riga+1; i+=2)
{
if (i >= 0 && i < s.items())
{
const TToken_string& ri = s.row(i);
TString80 ca; ri.get(col_att, ca); ca.trim();
TString4 to; ri.get(col_ora, to); to.trim();
TString80 cc; ri.get(col_cms, cc); cc.trim();
if (ca == cod_att && cc == cod_cms && to != tipo_ora)
return true;
}
}
return false;
}
int TConsuntivazione_msk::aggiungi_straordinario(int riga, const TString& tipo_ora, const real& prz, const real& add_qta) const
{
TSheet_field& s = sfield(F_SHEET);
const int col_dat = s.cid2index(S_DATA);
const int col_att = s.cid2index(S_CODRIS);
const int col_ora = s.cid2index(S_TPORA);
const int col_cms = s.cid2index(S_CDC1);
const TToken_string& r = s.row(riga);
TDate data; r.get(col_dat, data);
TCodice_articolo cod_rss; r.get(col_att, cod_rss); cod_rss.trim();
TCodice_cms cod_cms; r.get(col_cms, cod_cms); cod_cms.trim();
int nr = -1;
for (int i = riga-2; i <= riga+2; i++) if (i != riga)
{
if (i >= 0 && i < s.items())
{
const TToken_string& ri = s.row(i);
TDate dt; ri.get(col_dat, dt);
TCodice_articolo ca; ri.get(col_att, ca); ca.trim();
TString4 to; ri.get(col_ora, to); to.trim();
TCodice_cms cc; ri.get(col_cms, cc); cc.trim();
if (dt == data && ca == cod_rss && cc == cod_cms && to == tipo_ora)
{
nr = i;
break;
}
}
}
const int col_qta = s.cid2index(S_QTAORE);
if (nr < 0)
{
nr = s.insert(riga+1);
TToken_string& rowd = s.row(nr);
rowd = r; // Copia dati riga principale
rowd.add(tipo_ora, col_ora); // Modifica tipo ora
rowd.add(add_qta.string(0,2), col_qta);
rowd.add("", s.cid2index(S_ID)); // Azzera id per crearne uno nuovo
rowd.add(prz.string(0,2), s.cid2index(S_COSTO));
}
else
{
TToken_string& row = s.row(nr);
real qta = row.get(col_qta);
qta += add_qta;
row.add(qta.string(0,2), col_qta);
}
return nr;
}
real TConsuntivazione_msk::ore_totali(int riga, real& this_row) const
{
TSheet_field& s = sfield(F_SHEET);
const int col_ris = s.cid2index(S_CODRIS);
const int col_dta = s.cid2index(S_DATA);
const int col_qta = s.cid2index(S_QTAORE);
const TString16 cur_ris = s.cell(riga, col_ris);
const TString16 cur_dta = s.cell(riga, col_dta);
TString16 ris, ora, dta;
real qta;
real total;
total = this_row = ZERO;
FOR_EACH_SHEET_ROW(s, r, row)
{
row->get(col_ris, ris);
row->get(col_dta, dta);
if (ris == cur_ris && dta == cur_dta)
{
if (row->get(col_qta, qta))
{
total += qta;
if (r == riga)
this_row = qta;
}
}
}
return total;
}
bool TConsuntivazione_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_FINDREC:
if (e == fe_button)
load_sheet();
break;
case DLG_SAVEREC:
if (e == fe_button)
{
save_sheet(); // Salva le righe modificate
load_sheet(); // Carica le righe ordinate per data
}
break;
case DLG_ELABORA:
if (e == fe_button && save_dirty_sheet())
{
if (contabilizza())
load_sheet();
}
break;
case DLG_EXPORT:
if (e == fe_button && save_dirty_sheet())
esporta();
break;
case DLG_QUIT:
if (e == fe_button && !check_fields())
return false;
break;
case F_ANNO:
if (e == fe_modify && !o.empty())
{
int y = atoi(o.get());
if (y < 2000)
{
y = TDate(TODAY).year();
o.set(y);
}
TDate d = get(F_GIORNO);
if (!d.ok()) d = TODAY;
if (y % 4 && d.month() == 2 && d.day() > 28)
--d;
d.set_year(y);
set(F_GIORNO, d, 0x3);
load_sheet();
}
break;
case F_MESE:
if (e == fe_modify)
{
const int m = atoi(o.get());
int y = get_int(F_ANNO);
if (y < 2000)
{
y = TDate(TODAY).year();
set(F_ANNO, y);
}
const TDate d(1, m, y);
set(F_GIORNO, d, 0x3);
if (get_bool(C_MESE))
load_sheet();
}
break;
case F_GIORNO:
if (e == fe_modify && !o.empty())
{
if (get_bool(C_GIORNO))
load_sheet();
set(F_CALENDAR, o.get());
}
break;
case C_MESE:
case C_GIORNO:
case C_TPORA:
case F_RISOATT:
if (e == fe_modify)
load_sheet();
break;
case F_SHEET:
switch (e)
{
case fe_close:
save_dirty_sheet();
if (_recontabilize && yesno_box(TR("Avendo modificato ore gi<67> contabilizzate,\nsi desidera ricontabilizzarle ora?")))
contabilizza();
break;
case se_query_del:
{
TSheet_field& sheet = (TSheet_field&)o;
TToken_string& row = sheet.row(jolly);
const int posid = sheet.cid2index(S_ID);
const long id = row.get_long(posid);
if (id > 0)
{
TLocalisamfile rilore(LF_RILORE);
rilore.put("TIPO", "C");
rilore.put("ID", id);
if (rilore.remove() != NOERR)
return error_box(FR("Impossibile eliminare la riga %d"), jolly);
else
set(F_CALENDAR, get(F_GIORNO));
}
}
break;
case se_enter:
{
TSheet_field& sheet = (TSheet_field&)o;
TToken_string& row = sheet.row(jolly);
const TDate d = row.get(0);
if (d.ok())
set(F_CALENDAR, d.string());
}
break;
case se_notify_modify:
enable(DLG_SAVEREC, _sheet_dirty = true);
if (_sheet_dirty)
{
TSheet_field& sheet = (TSheet_field&)o;
const char stato = sheet.cell(jolly, S_STATO)[0];
if (stato > '1')
_recontabilize = _sheet_dirty;
TToken_string& row = sheet.row(jolly);
const char tipo = row.get_char(1);
const TString80 cod = row.get(2);
const TString4 ora = row.get(4);
if (tipo == 'A' && cod.full() && ora.full())
{
const TRectype& atr = cache().get("ATR", cod);
const TString& codartdisp = atr.get("S2").mid(20); // Previsto articolo per disponibilit<69>?
const TString4 orad = atr.get("S9"); // Previsto tipo ora per disponibilit<69>?
if (codartdisp.full() && orad.full() && ora != orad) // Attrezzatura con ora normale
{
if (!cerca_disponibilita(jolly))
{
const int nr = sheet.insert(jolly+1);
TToken_string& rowd = sheet.row(nr);
rowd = row;
rowd.add(orad, 4);
if (atr.get_int("I13") != 2) // Se non <20> un'attrezzatura forza le ore a 1
rowd.add(1, 5); // altrimenti lascia la stessa quantit<69> della riga collegata
rowd.add(atr.get("R11"), 6);
sheet.force_update(nr);
}
}
} else
if (tipo == 'R' && cod.full() && ora.full())
{
const TString& tpo = cache().get("&ORE", ora, "S6"); // tipo ora ordinaria
if ((tpo.blank() || tpo == "O")) // ora ordinaria
{
real questa;
real ore_ord = ore_totali(jolly, questa);
real altre = ore_ord - questa;
if (questa > ZERO)
{
const TRectype& rss = cache().get("RSS", cod);
const real dopo_ora1 = rss.get_real("R5");
const TString4 ora1 = rss.get("S9");
const real prezzo1 = rss.get("R6");
const real dopo_ora2 = rss.get_real("R7");
const TString4 ora2 = rss.get("S10");
const real prezzo2 = rss.get("R8");
real ore0 = questa, ore1, ore2;
if (ora2.full() && altre >= dopo_ora2) // tutte ultraordinarie
{
ore2 = ore0;
ore0 = ZERO;
} else
if (ora1.full() && altre >= dopo_ora1) // tutte straordinarie ed oltre
{
if (ora2.full() && ore_ord >= dopo_ora2)
{
ore2 = ore_ord - dopo_ora2;
if (ore2 > ore0) ore2 = ore0;
ore0 -= ore2;
}
ore1 = ore0;
ore0 = ZERO;
}
else // Fritto misto di ore
{
if (ore_ord > dopo_ora2 && ora2.full()) // ultraordinario
{
ore2 = ore_ord - dopo_ora2;
if (ore2 > ore0)
ore2 = ore0;
ore_ord -= ore2;
ore0 -= ore2;
}
if (ore_ord > dopo_ora1 && ora1.full()) // straordinario
{
ore1 = ore_ord - dopo_ora1;
if (ore1 > ore0)
ore1 = ore0;
ore0 -= ore1;
}
}
if (ore1 > ZERO || ore2 > ZERO) // c'<27> straordinario?
{
if (ore0.is_zero() && ore1.is_zero()) // tutto ultraordinario
{
row.add(ora2, sheet.cid2index(S_TPORA));
row.add(prezzo2.string(0,2), sheet.cid2index(S_COSTO));
} else
if (ore0.is_zero() && ore2.is_zero()) // tutto straordinario
{
row.add(ora1, sheet.cid2index(S_TPORA));
row.add(prezzo1.string(0,2), sheet.cid2index(S_COSTO));
}
else // fritto misto
{
if (ore2 > ZERO)
aggiungi_straordinario(jolly, ora2, prezzo2, ore2);
if (ore1 > ZERO)
aggiungi_straordinario(jolly, ora1, prezzo1, ore1);
if (ore0 <= ZERO)
sheet.destroy(jolly, false); // Elimina riga nulla
else
row.add(ore0.string(0, 2), sheet.cid2index(S_QTAORE)); // Reimposta ore ordinarie
}
sheet.force_update();
}
}
}
}
}
break;
case se_notify_add:
riempi_nuova_riga(jolly);
break;
default : break;
}
break;
case S_DATA:
if (e == fe_modify && !o.empty() && is_running())
set(F_CALENDAR, o.get());
else
break;
// intentionally fall down
case S_CODRIS:
case S_CODATT:
case S_TPORA:
if (e == fe_modify && !o.empty() && !_locked)
proponi_costo(o.mask());
break;
default:
break;
}
if ((e == fe_modify || e == fe_init) && o.dlg() == _scms_lid)
{
const TRectype& curr = ((TEdit_field&)o).browse()->cursor()->curr();
const TString codcms = curr.get(COMMESSE_CODCMS);
TMask& m = o.mask();
m.set(S_CMSH, codcms);
const TRectype& commesse = cache().get(LF_COMMESSE, codcms);
m.set(S_CODLIST, commesse.get(COMMESSE_LISRILCN), 0x3);
if (e == fe_modify)
{
if (codcms.full())
{
TDate inizio, fine;
ca_durata_commessa(commesse, inizio, fine);
const TDate data = m.get(S_DATA);
if (data < inizio)
return error_box(FR("Commessa %s non iniziata"), (const char *) codcms);
if (data > fine)
return error_box(FR("Commessa %s terminata"), (const char *) codcms);
}
if (main_app().has_module(CTAUT))
{
TToken_string key;
key.add(codcms);
key.add("C");
key.add(1);
const TRectype & cfcms = cache().get(LF_CFCMS, key);
m.set(S_CUP, cfcms.get(CFCMS_CUP), 3);
m.set(S_CIG, cfcms.get(CFCMS_CIG), 3);
}
}
}
return true;
}
TConsuntivazione_msk::TConsuntivazione_msk() : _locked(false)
{
read_mask("ci2400a", 0, 1);
const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
TConfig& ini = ca_config();
TSheet_field & s = sfield(F_SHEET);
TMask & sm = s.sheet_mask();
int y = 3;
int sy = 4;
short dlg = F_ANAL; // id del primo codice da generare in testata
short sdlg = S_CDC1 + 100; // id del primo codice da generare nello sheet
_cdc_sid = _cdc_lid = _cms_sid = _cms_lid = _fase_sid = _fase_lid = -1;
_scdc_sid = _scdc_lid = _scms_sid = _scms_lid = _sfase_sid = _sfase_lid = -1;
for (int i = 0; i < 2; i++)
{
const TString& level = ini.get("Level", NULL, i+1); // Legge il livello 1 o 2
if (level == "CDC") // Crea centro di costo
{
if (fasinfo.parent() == LF_CDC)
{
int h = ca_multilevel_code_info(LF_CDC).levels();
const int h1 = ca_create_fields_compact(*this, 0, LF_FASI, 2, y, dlg, dlg + 100);
y += 2;
_cdc_sid = dlg;
_cdc_lid = dlg + h - 1;
_fase_sid = _cdc_lid + 1;
_fase_lid = dlg + h1 - 1;
dlg += h1;
const int sh = ca_create_fields_compact(sm, 0, LF_FASI, 1, sy, sdlg, sdlg + 50);
sy += 2;
_scdc_sid = sdlg;
_scdc_lid = sdlg + h - 1;
_sfase_sid = _scdc_lid + 1;
_sfase_lid = sdlg + sh - 1;
sdlg += sh;
}
else
{
const int h = ca_create_fields_compact(*this, 0, LF_CDC, 2, y++, dlg, dlg + 100);
_cdc_sid = dlg;
_cdc_lid = dlg + h - 1;
dlg += h;
const int sh = ca_create_fields_compact(sm, 0, LF_CDC, 1, sy++, sdlg, sdlg + 50);
_scdc_sid = sdlg;
_scdc_lid = sdlg + sh - 1;
sdlg += h;
}
}
else
if (level == "CMS") // Crea commessa
{
if (fasinfo.parent() == LF_COMMESSE)
{
// Commessa in testata per filtro / proposta
int h = ca_multilevel_code_info(LF_COMMESSE).levels();
const int h1 = ca_create_fields_compact(*this, 0, LF_FASI, 2, y, dlg, dlg + 100);
y += 2;
_cms_sid = dlg;
_cms_lid = dlg + h - 1;
_fase_sid = _cms_lid + 1;
_fase_lid = dlg + h1 - 1;
dlg += h1;
// Commessa nelle righe
const int sh = ca_create_fields_compact(sm, 0, LF_FASI, 1, sy, sdlg, sdlg + 50);
sy += 2;
_scms_sid = sdlg;
_scms_lid = sdlg + h - 1;
_sfase_sid = _scms_lid + 1;
_sfase_lid = sdlg + sh - 1;
sdlg += sh;
}
else
{
const int h = ca_create_fields_compact(*this, 0, LF_COMMESSE, 2, y++, dlg, dlg + 100);
_cms_sid = dlg;
_cms_lid = dlg + h - 1;
dlg += h;
const int sh = ca_create_fields_compact(sm, 0, LF_COMMESSE, 1, sy++, sdlg, sdlg + 50);
_scms_sid = sdlg;
_scms_lid = sdlg + sh - 1;
sdlg += sh;
}
}
}
if (fasinfo.levels() > 0 && fasinfo.parent() <= 0)
{
const int h = ca_create_fields_compact(*this, 0, LF_FASI, 2, y++, dlg, dlg + 100);
_fase_sid = dlg;
_fase_lid = dlg + h - 1;
dlg += h;
const int sh = ca_create_fields_compact(sm, 0, LF_FASI, 1, sy++, sdlg, sdlg + 50);
_sfase_sid = sdlg;
_sfase_lid = sdlg + sh - 1;
sdlg += h;
}
// Sistema nome del campo CODCMS
if (_scms_lid > 0)
{
for (short id = _scms_lid; id >= _scms_sid; id--)
{
TEdit_field& ef = sm.efield(id);
TFieldref* fr = (TFieldref*)ef.field();
if (fr != NULL)
fr->set_name(RILORE_CODCMS);
}
}
for (short id = S_CDC12 + 100; id >= S_CDC1 + 100; id--)
{
const int pos = sm.id2pos(id);
if (pos >= 0)
{
TMask_field& f = sm.fld(pos);
const int size = f.size();
TString80 prompt = f.prompt(); prompt.trim();
if (prompt.blank())
{
TToken_string ts(((TEditable_field &)f).get_warning(), ' ');
prompt = ts.get(0);
}
s.set_column_header(id, prompt);
s.set_column_justify(id, f.is_kind_of(CLASS_REAL_FIELD));
s.set_column_width(id, (max(3+size, prompt.len()+1)) * CHARX);
s.update_column_width(id);
s.enable_column(id);
}
else
s.delete_column(id);
}
set_handlers(); // Fondamentale dopo una read_mask e la generazione dinamica di campi
enable(DLG_SAVEREC, _sheet_dirty = false);
_recontabilize = false;
set(C_MESE, "X");
load_sheet();
}
///////////////////////////////////////////////////////////
// TConsuntivazione_app
///////////////////////////////////////////////////////////
class TConsuntivazione_app : public TSkeleton_application
{
public:
virtual void main_loop();
};
void TConsuntivazione_app::main_loop()
{
TSheet_field::set_line_number_width(4);
TConsuntivazione_msk msk;
while (msk.run() == K_ENTER);
}
int ci2400(int argc, char *argv[])
{
TConsuntivazione_app a;
a.run(argc, argv, TR("Consuntivazione Ore"));
return 0;
}