campo-sirio/ve/ve2800.cpp

617 lines
15 KiB
C++

#include <applicat.h>
#include <automask.h>
#include <colors.h>
#include <recarray.h>
#include <dongle.h>
#include <progind.h>
#include <textset.h>
#include <reputils.h>
#include <relation.h>
#include <utility.h>
#include "ve2800.h"
#include "../mg/anamag.h"
#include "rcondv.h"
////////////////////////////////////////////////////////
// MASCHERA
////////////////////////////////////////////////////////
class TRicarico_listini_mask : public TAutomask
{
TBit_array _dirty;
bool _loading;
TString4 _curlis;
TString _codart; // Nuovo articolo
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void load();
void save();
bool save_if_dirty();
void recalc();
bool import();
void set_dirty();
public:
TRicarico_listini_mask() : TAutomask("ve2800a"), _loading(false) {}
};
void TRicarico_listini_mask::set_dirty()
{
if (is_running() && !_loading)
{
TSheet_field& s = sfield(F_LISTINO);
const int row = s.selected();
if (!_dirty[row])
{
s.set_back_and_fore_color(EASY_RIDER_COLOR, NORMAL_COLOR, row, -1);
_dirty.set(row);
s.force_update(row);
enable(DLG_SAVEREC);
disable(DLG_RECALC);
}
}
}
void TRicarico_listini_mask::save()
{
TSheet_field& s = sfield(F_LISTINO);
TFast_isamfile anamag(LF_ANAMAG);
TFast_isamfile rcondv(LF_RCONDV);
TProgind pi(s.items(), TR("Salvataggio modifiche"), false, true);
FOR_EACH_SHEET_ROW(s, r, row) if (_dirty[r])
{
const TString80 codart = row->get(s.cid2index(F_CODART));
const real sconto = row->get(s.cid2index(F_SCONTO));
const real costo = row->get(s.cid2index(F_COSTO));
const TString8 ricarico = row->get(s.cid2index(F_RICARICO));
const real prezzo = row->get(s.cid2index(F_OLDPRICE));
if (costo.is_zero() && prezzo.is_zero())
{
rcondv.zero();
rcondv.put(RCONDV_TIPO, "L");
rcondv.put(RCONDV_COD, _curlis);
rcondv.put(RCONDV_TIPORIGA, "A");
rcondv.put(RCONDV_CODRIGA, codart);
rcondv.remove();
}
else
{
anamag.put(ANAMAG_CODART, codart);
if (anamag.read() == NOERR)
{
anamag.put(ANAMAG_ULTCOS1, costo);
anamag.put(ANAMAG_USER3, ricarico);
anamag.rewrite();
}
rcondv.zero();
rcondv.put(RCONDV_TIPO, "L");
rcondv.put(RCONDV_COD, _curlis);
rcondv.put(RCONDV_TIPORIGA, "A");
rcondv.put(RCONDV_CODRIGA, codart);
if (rcondv.read() == NOERR)
{
rcondv.put(RCONDV_SCONTO, sconto);
rcondv.put(RCONDV_PREZZO, prezzo);
rcondv.rewrite();
}
}
const char* cod = "FGDI";
TLocalisamfile deslin(LF_DESLIN); deslin.setkey(2);
for (int lingua = 0; cod[lingua]; lingua++)
{
TString desc = row->get(s.cid2index(F_DESCFRA+lingua));
if (desc.full())
{
desc.trim();
deslin.zero();
deslin.put("CODART", codart);
deslin.put("CODLIN", cod[lingua]);
if (deslin.read() == NOERR)
{
if (deslin.get("DESCR") != desc)
{
deslin.put("DESCR", desc);
deslin.rewrite();
}
}
else
{
TISAM_recordset rsdeslin("USE DESLIN\nFROM CODART=#ART\nTO CODART=#ART");
rsdeslin.set_var("#ART", codart);
int nriga = 1;
if (rsdeslin.move_last())
nriga += rsdeslin.get("NRIGA").as_int();
deslin.zero();
deslin.put("CODART", codart);
deslin.put("NRIGA", nriga);
deslin.put("CODLIN", cod[lingua]);
deslin.put("DESCR", desc);
const int err = deslin.write();
if (err != NOERR)
{
TString msg;
msg << TR("Descrizione in lingua ") << cod[lingua] << TR(" articolo ") << codart;
cantwrite_box(msg);
}
}
}
}
if (!pi.setstatus(r+1))
break;
}
_dirty.reset();
disable(DLG_SAVEREC);
enable(DLG_RECALC);
}
void TRicarico_listini_mask::recalc()
{
TSheet_field& s = sfield(F_LISTINO);
TFast_isamfile rcondv(LF_RCONDV);
TProgind pi(s.items(), TR("Aggiornamento prezzi"), true, true);
FOR_EACH_SHEET_ROW(s, r, row)
{
if (!pi.setstatus(r))
break;
const real oldprice = row->get(s.cid2index(F_OLDPRICE));
const real newprice = row->get(s.cid2index(F_NEWPRICE));
if (oldprice != newprice)
{
const TString80 codart = row->get(s.cid2index(F_CODART));
rcondv.zero();
rcondv.put(RCONDV_TIPO, "L");
rcondv.put(RCONDV_COD, _curlis);
rcondv.put(RCONDV_TIPORIGA, "A");
rcondv.put(RCONDV_CODRIGA, codart);
if (rcondv.read() == NOERR)
{
rcondv.put(RCONDV_PREZZO, newprice);
rcondv.rewrite();
}
}
}
}
bool TRicarico_listini_mask::save_if_dirty()
{
bool done = true;
const long n = _dirty.ones();
if (n > 0)
{
const KEY k = yesnocancel_box(FR("Si desiderano registrare le %ld righe modificate?"), n);
switch (k)
{
case K_YES: save(); break;
case K_NO : break;
default : done = false; break;
}
}
return done;
}
void TRicarico_listini_mask::load()
{
_loading = true;
_curlis = get(F_CODLIS);
TSheet_field& s = sfield(F_LISTINO);
TMask& sm = s.sheet_mask();
TLocalisamfile deslin(LF_DESLIN);
deslin.setkey(2);
s.destroy();
TString query;
query << "USE RCONDV";
if (!field(F_FILTRIC).empty())
query << " SELECT ANAMAG.USER3==\"" << get(F_FILTRIC) << '"';
query << "\nJOIN ANAMAG INTO CODART==CODRIGA";
query << "\nFROM TIPO=L TIPORIGA=A COD=" << _curlis;
if (!field(F_FROMCOD).empty())
query << " CODRIGA=" << get(F_FROMCOD);
query << "\nTO TIPO=L TIPORIGA=A COD=" << _curlis;
if (!field(F_TOCOD).empty())
query << " CODRIGA=" << get(F_TOCOD);
TISAM_recordset rcondv(query);
TProgind pi(rcondv.items(), TR("Caricamento..."), false, true);
const TRelation& rel = *rcondv.cursor()->relation();
for (bool ok = rcondv.move_first(); ok; ok = rcondv.move_next())
{
if (!pi.addstatus(1))
break;
FOR_EACH_MASK_FIELD(sm, i, f) if (f->field())
{
const char* val = f->field()->read(rel);
f->set(val);
}
const TString& codart = sm.get(F_CODART);
const char* cod = "FGDI";
for (int lingua = 0; cod[lingua]; lingua++)
{
deslin.zero();
deslin.put("CODART", codart);
deslin.put("CODLIN", cod[lingua]);
if (deslin.read() == NOERR)
sm.set(F_DESCFRA+lingua, deslin.get("DESCR"));
else
sm.reset(F_DESCFRA+lingua);
}
TToken_string& r = s.row(-1);
if (r.empty_items()) // Dummy test
{
sm.efield(F_RICARICO).on_hit();
sm.efield(F_OLDPRICE).on_hit();
sm.efield(F_NEWPRICE).on_hit();
FOR_EACH_MASK_FIELD(sm, i, f)
{
const short id = f->dlg();
if (id >= 101 && id < 200)
r.add(f->get(), (id % 100) -1);
}
}
}
if (get(F_SORT) != "A")
send_key(K_SPACE, F_SORT);
else
s.force_update();
_dirty.reset();
disable(DLG_SAVEREC);
enable(DLG_RECALC);
set(F_RECORDS, s.items());
_loading = false;
}
bool TRicarico_listini_mask::import()
{
TRecnotype n = 0;
TFilename name;
name.tempdir();
name.add("*.csv");
if (!input_filename(name) || !name.exist())
return false;
TString msg;
msg << TR("Importazione ") << name;
TLog_report log(msg);
TCSV_recordset txt(name);
if (txt.items() > 0)
{
TFast_isamfile rcondv(LF_RCONDV);
TFast_isamfile anamag(LF_ANAMAG);
TAssoc_array codarts;
TProgind pi(txt.items(), msg);
for (bool ok = txt.move_first(); ok; ok = txt.move_next())
{
if (!pi.addstatus(1))
break;
TString80 codart = txt.get(0L).as_string();
codart.trim();
if (codart.not_empty() && !codarts.is_key(codart))
{
codarts.add(codart);
anamag.put(ANAMAG_CODART, codart);
if (anamag.read() == NOERR)
{
rcondv.zero();
rcondv.put(RCONDV_TIPO, "L");
rcondv.put(RCONDV_COD, _curlis);
rcondv.put(RCONDV_TIPORIGA, "A");
rcondv.put(RCONDV_CODRIGA, codart);
if (rcondv.write() == NOERR)
{
msg = codart;
msg << TR(" articolo inserito a listino");
log.log(1, msg);
n++;
}
}
else
{
msg = codart;
msg << TR(" articolo non presente in anagrafica");
log.log(2, msg);
}
}
}
}
msg.format(FR("Sono stati importati %ld nuovi articoli su %ld righe"), n, txt.items());
log.log(0, "");
log.log(0, msg);
log.preview();
return n > 0;
}
static int sort_by_artic(const TSortable& r1, const TSortable& r2, void* jolly)
{
const TToken_string& row1 = (const TToken_string&)r1;
const TToken_string& row2 = (const TToken_string&)r2;
return xvt_str_compare_ignoring_case(row1, row2);
}
static int sort_by_delta(const TSortable& r1, const TSortable& r2, void* jolly)
{
const TSheet_field& s = *(TSheet_field*)jolly;
const int i = s.cid2index(F_DELTAPRICE);
const TToken_string& row1 = (const TToken_string&)r1;
const TToken_string& row2 = (const TToken_string&)r2;
real d1, d2;
row1.get(i, d1);
row2.get(i, d2);
if (d1 == d2)
return sort_by_artic(r1, r2, jolly);
return d1 > d2 ? +1 : -1;
}
static int sort_by_price(const TSortable& r1, const TSortable& r2, void* jolly)
{
const TSheet_field& s = *(TSheet_field*)jolly;
const int i = s.cid2index(F_OLDPRICE);
const TToken_string& row1 = (const TToken_string&)r1;
const TToken_string& row2 = (const TToken_string&)r2;
real p1, p2;
row1.get(i, p1);
row2.get(i, p2);
if (p1 == p2)
return sort_by_artic(r1, r2, jolly);
return p1 > p2 ? +1 : -1;
}
bool TRicarico_listini_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_CODLIS:
if (e == fe_init || e == fe_modify)
{
const bool good = !o.empty();
enable(DLG_NEWREC, good);
enable(DLG_PRINT, good);
}
case F_FILTRIC:
case F_FROMCOD:
case F_TOCOD:
if (e == fe_modify)
{
if (save_if_dirty())
load();
}
break;
case F_COSTO:
case F_RICARICO:
if (e == fe_modify && jolly)
{
TSheet_field& s = sfield(F_LISTINO);
TMask& sm = s.sheet_mask();
const real costo = sm.get(F_COSTO);
real price = 0.10;
if (costo > 0.03)
{
const real ricarico = cache().get("&RIC", sm.get(F_RICARICO), "R0");
const TPrice p = costo * (CENTO + ricarico) / CENTO;
price = p.get_num();
}
sm.set(F_NEWPRICE, price, 0x3);
}
break;
case F_SCONTO:
if (e == fe_modify && jolly)
{
on_field_event(o.mask().efield(F_OLDPRICE), e, jolly);
on_field_event(o.mask().efield(F_NEWPRICE), e, jolly);
}
break;
case F_OLDPRICE:
case F_NEWPRICE:
if (e == fe_modify && jolly)
{
TMask& sm = o.mask();
const real costo = sm.get(F_COSTO);
const real sconto = sm.get(F_SCONTO);
const real prezzo = o.get();
real scontato = prezzo * (CENTO - sconto) / CENTO;
scontato.round(2);
real margine = (scontato > ZERO) ? CENTO * (scontato - costo) / scontato : ZERO;
margine.round(0);
sm.set(o.dlg() + (F_NEWMARGIN-F_NEWPRICE), margine, 0x3);
const real oldprice = sm.get(F_OLDPRICE);
if (oldprice> ZERO)
{
const real newprice = sm.get(F_NEWPRICE);
real delta = (newprice - oldprice) * CENTO / oldprice;
delta.round(0);
sm.set(F_DELTAPRICE, delta);
}
const real deltam = sm.get_real(F_NEWMARGIN) - sm.get_real(F_OLDMARGIN);
sm.set(F_DELTAMARGIN, deltam);
}
break;
case F_LISTINO:
switch (e)
{
case se_notify_modify:
set_dirty();
break;
case se_query_add:
if (_curlis.full())
{
TMask m("ve2800b");
m.set(F_CODLIS, _curlis, 0x3);
if (m.run() == K_ENTER)
{
_codart = m.get(F_FROMCOD);
return _codart.full();
}
}
return false;
case se_notify_add:
if (_codart.full())
{
TSheet_field& s = sfield(F_LISTINO);
TToken_string& r = s.row(jolly);
r = _codart;
TMask& m = s.sheet_mask();
const TRectype& anamag = cache().get(LF_ANAMAG, _codart);
FOR_EACH_MASK_FIELD(m, i, f)
{
const TFieldref* fld = f->field();
if (fld != NULL && fld->file() == LF_ANAMAG)
r.add(anamag.get(fld->name()), s.cid2index(f->dlg()));
}
_codart.cut(0);
return true;
}
return false;
case se_query_del:
return false;
default:
break;
}
break;
case F_SORT:
if (e == fe_modify)
{
TWait_cursor hourglass;
TSheet_field& s = sfield(F_LISTINO);
TArray& r = s.rows_array();
switch (o.get()[0])
{
case 'D': r.sort(sort_by_delta, &s); break;
case 'P': r.sort(sort_by_price, &s); break;
default : r.sort(sort_by_artic, &s); break;
}
s.force_update();
}
break;
case DLG_EDIT:
if (e == fe_button && jolly == 1)
{
TMask& msk = o.mask();
msk.reset(F_SCONTO);
msk.reset(F_COSTO);
msk.reset(F_RICARICO);
msk.reset(F_OLDPRICE);
}
break;
case DLG_EXPORT:
if (e == fe_button && jolly == 0)
{
TSheet_field& s = sfield(F_LISTINO);
s.esporta();
}
break;
case DLG_SAVEREC:
if (e == fe_button && jolly == 0 && _dirty.first_one() >= 0)
{
save();
load();
}
break;
case DLG_RECALC:
if (e == fe_button && jolly == 0 && _dirty.first_one() < 0)
{
const TSheet_field& s = sfield(F_LISTINO);
if (yesno_box(FR("Si desidera aggiornare il prezzo di %ld articoli"), s.items()))
{
recalc();
load();
}
}
break;
case DLG_NEWREC:
if (e == fe_button && jolly == 0)
{
if (save_if_dirty() && import())
load();
}
break;
case DLG_PRINT:
case DLG_PREVIEW:
if (e == fe_button && jolly == 0)
{
TReport rep;
if (rep.load("ve2800"))
{
rep.recordset()->set_var("#COD", _curlis);
if (o.dlg() == DLG_PRINT)
rep.print();
else
rep.preview();
}
else
cantread_box("ve2800.rep");
}
break;
case DLG_CANCEL:
case DLG_QUIT:
if (e == fe_button && jolly == 0)
save_if_dirty();
break;
default:
break;
}
return true;
}
////////////////////////////////////////////////////////
// APPLICAZIONE
////////////////////////////////////////////////////////
class TRicarico_listini : public TSkeleton_application
{
protected:
virtual bool create();
public:
virtual void main_loop();
};
void TRicarico_listini::main_loop()
{
TRicarico_listini_mask mask;
while (mask.run() == K_ENTER);
}
bool TRicarico_listini::create()
{
#ifndef DBG
Tdninst dninst;
if (!dninst.can_I_run(true))
return cantaccess_box(title());
#endif
TSheet_field::set_line_number_width(4);
return TSkeleton_application::create();
}
int ve2800(int argc, char* argv[])
{
TRicarico_listini a;
a.run(argc, argv, TR("Ricarico Listini"));
return 0;
}