campo-sirio/ha/ha0600.cpp
guy 0acd0807c0 Corretta gestione articoli per Aerea che non è limitata a 5 caratteri
git-svn-id: svn://10.65.10.50/branches/R_10_00@22870 c028cbd2-c16b-5b4b-a496-9718f37d4682
2013-06-20 13:22:10 +00:00

302 lines
8.2 KiB
C++

#include "ha0600a.h"
#include <applicat.h>
#include <automask.h>
#include <recarray.h>
#include <recset.h>
#include <clifo.h>
#include <multirel.h>
#include "../mg/anamag.h"
#include "../db/dblib.h"
///////////////////////////////////////////////////////////
// TCodcorr_msk
///////////////////////////////////////////////////////////
class TCodcorr_msk : public TAutomask
{
char _mode;
TCodice_articolo _code;
bool _dirty;
private:
bool load_articles();
bool load_customers();
bool load();
bool save();
bool save_if_needed();
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TCodcorr_msk() : TAutomask("ha0600a"), _mode(' '), _dirty(false) {}
} ;
// Salva le righe attuali (articoli o clienti)
bool TCodcorr_msk::save()
{
if (_mode <= ' ' || _code.blank())
return false;
TSheet_field& sf = sfield(_mode == 'A' ? F_ARTICOLI : F_CLIENTI);
TFast_isamfile multirel(LF_MULTIREL);
TCodice_articolo code, codalt;
TString80 descr, data;
FOR_EACH_SHEET_ROW(sf, r, row)
{
row->get(0, code); // Puo' essere un articolo o un cliente
if (code.blank())
continue;
row->get(2, codalt);
row->get(3, descr);
multirel.zero();
multirel.put(MULTI_COD, "HACOR");
// Compila opportunamente la chiave di multirel: FIRST=cliente; SECOND=articolo;
if (_mode == 'A')
{
multirel.put(MULTI_FIRST, _code); // Cliente
multirel.put(MULTI_SECOND, code); // Articolo
}
else
{
multirel.put(MULTI_FIRST, code); // Cliente
multirel.put(MULTI_SECOND, _code); // Articolo
}
int err = NOERR;
if (codalt.full() || descr.full()) // Riga da aggiornare in quanto piena
{
// Il campo DATA è così organizzato: DATA[1,6]=codalt; DATA[7,36]=descr
data = codalt;
data.overwrite(descr, 6, 30);
multirel.put(MULTI_DATA, data);
err = multirel.rewrite_write();
}
else
err = multirel.remove(); // Riga da eliminare in quanto vuota
if (err != NOERR)
return cantwrite_box(multirel.name());
}
_dirty = false;
return true;
}
// In caso ci siano state modifiche (_dirty) chiede di salvare i dati
bool TCodcorr_msk::save_if_needed()
{
if (_dirty && _mode > ' ' && _code.full())
{
const int ret = yesnocancel_box(TR("Si desidera salvare le righe modificate?"));
switch(ret)
{
case K_YES: save(); break; // Salva e resetta _dirty
case K_NO : _dirty = false; break; // Resetta _dirty ignorando le modifiche
default : break; // Annulla l'operazione senza fare nulla
}
}
return !_dirty;
}
bool TCodcorr_msk::load_articles()
{
TString query;
query << "USE MULTIREL SELECT FIRST==#CLIENTE" // Sembra inutile ... ma non lo è!
<< "\nFROM COD=HACOR FIRST=#CLIENTE"
<< "\nTO COD=HACOR FIRST=#CLIENTE";
TISAM_recordset multirel(query);
multirel.set_var("#CLIENTE", _code);
TSheet_field& sf = sfield(F_ARTICOLI);
sf.destroy();
for (bool ok = multirel.move_first(); ok; ok = multirel.move_next())
{
TToken_string& row = sf.row(-1);
TCodice_articolo cod = multirel.get(MULTI_SECOND).as_string();
row = cod; // Codice articolo
row.add(cache().get(LF_ANAMAG, cod, ANAMAG_DESCR)); // Descrizione articolo
// Spezza il campo DATA in codice alternativo [1,6] e descrizione [7,36]
const TString& data = multirel.get(MULTI_DATA).as_string();
cod = data.left(6);
row.add(cod);
if (data.len() > 6)
row.add(data.mid(6, 30));
else
row.add(cache().get(LF_ANAMAG, cod, ANAMAG_DESCR));
// Disabilita codice articolo e descrizione
const int r = sf.items()-1;
sf.disable_cell(r, 0);
sf.disable_cell(r, 1);
}
sf.force_update();
return true;
}
bool TCodcorr_msk::load_customers()
{
TString query;
query << "USE MULTIREL KEY 2 SELECT SECOND==#CODART" // Sembra inutile ... ma non lo è!
<< "\nFROM COD=HACOR SECOND=#CODART"
<< "\nTO COD=HACOR SECOND=#CODART";
TISAM_recordset multirel(query);
multirel.set_var("#CODART", _code);
TSheet_field& sf = sfield(F_CLIENTI);
sf.destroy();
for (bool ok = multirel.move_first(); ok; ok = multirel.move_next())
{
TToken_string& row = sf.row(-1);
TString8 cod = multirel.get(MULTI_FIRST).as_string(); // Codice cliente
row.add(cod);
cod.insert("C|"); // Chiave cliente
row.add(cache().get(LF_CLIFO, cod, CLI_RAGSOC)); // Ragione sociale
// Spezza il campo DATA in codice alternativo [1,6] e descrizione [7,36]
const TString& data = multirel.get(MULTI_DATA).as_string();
cod = data.left(6);
row.add(cod);
if (data.len() > 6)
row.add(data.mid(6, 30));
else
row.add(cache().get(LF_ANAMAG, cod, ANAMAG_DESCR));
// Disabilita codice e ragione sociale
const int r = sf.items()-1;
sf.disable_cell(r, 0);
sf.disable_cell(r, 1);
}
sf.force_update();
return true;
}
bool TCodcorr_msk::load()
{
if (!check_fields()) // Controlla che tutto sia valido
return false;
bool done = false; // Flag di operazione riuscita
_mode = ' '; // Modalità indeterminata (nè A nè C)
_code.cut(0); // Codice Cliente/Articolo nullo
_dirty = false; // Nessuna modifica effettuata
if (get(F_TIPO)[0] == 'C') // Selezione articoli di un 'C'liente
{
_code = get(F_CLIENTE); // Legge codice cliente
if (_code.full())
{
_mode = 'A'; // Imposta modalità lista 'A'rticoli
done = load_articles(); // Carica articoli associati al cliente _code
}
}
else
{
_code = get(F_ARTICOLO); // Legge codice articolo
if (_code.full())
{
_mode = 'C'; // Imposta modalità lista 'C'lienti
done = load_customers(); // Carica clienti dell'articolo _code
}
}
// Mostra solo lo sheet interessato nella modalità corrente
sfield(F_ARTICOLI).show(_mode == 'A');
sfield(F_CLIENTI).show(_mode != 'A');
return done;
}
bool TCodcorr_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_SAVEREC:
if (e == fe_button)
{
if (save()) // Salva tutto lo sheet corrente
load(); // Lo ricarica per eliminare duplicati e riordinarlo
}
break;
case F_CLIENTE:
case F_ARTICOLO:
if (e == fe_modify || e == fe_init) // fe_init scatta nel caso di collegamento da anagrafica
{
if (!o.empty() && save_if_needed()) // Se il codice cliente è valido e dopo aver salvato ...
load(); // ... carica lo sheet con gli articoli del nuovo cliente
}
break;
case F_ARTICOLI:
case F_CLIENTI:
switch (e)
{
case se_notify_modify:
case se_notify_add: _dirty = true; break; // Memorizza l'avventua modifica dello sheet
case se_query_del: return false; // Impedisce cancellazione di righe: solo azzeramenti!
default: break;
}
break;
default: break;
}
return true;
}
///////////////////////////////////////////////////////////
// TCodcorr_app
///////////////////////////////////////////////////////////
class TCodcorr_app : public TSkeleton_application
{
public:
virtual void main_loop();
};
void TCodcorr_app::main_loop()
{
TCodcorr_msk msk;
// Gestione collegamento da parte dell'anagrafica clienti:
// ha0 -5 C 883 -> Visualizza gli articoli del cliente "883"
// ha0 -5 A A/1 -> Visualizza chi compra l'articolo "A/1"
if (argc() >= 4)
{
const TFixed_string tipo(argv(2));
const TFixed_string codice(argv(3));
if (tipo == "A")
{
msk.set(F_TIPO, "A", 0x3);
msk.set(F_ARTICOLO, codice);
}
else
{
msk.set(F_TIPO, "C", 0x3);
msk.set(F_CLIENTE, codice);
}
// Una volta impostato il codice del cliente (o articolo),
// l'evento e_init del codice farà scattare il caricamento dello spreasheet opportuno
}
msk.run();
}
///////////////////////////////////////////////////////////
// main
///////////////////////////////////////////////////////////
int ha0600(int argc, char* argv[])
{
TCodcorr_app app;
app.run(argc, argv, TR("Prodotti corrispondenti"));
return 0;
}