Patch level : 10.0
Files correlati : lv4.exe lv4300a.msk Ricompilazione Demo : [ ] Commento : Corretta importazione pagamenti e note di credito. git-svn-id: svn://10.65.10.50/trunk@19904 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
d25469a8be
commit
ecf707ab57
328
lv/lv4200.cpp
328
lv/lv4200.cpp
@ -27,29 +27,46 @@ enum CGC_SALDAC { CGC_NULL, CGC_TIPOCF, CGC_ANNO, CGC_NUMPART, CGC_C
|
||||
|
||||
class TCausali_cache : public TCache
|
||||
{
|
||||
TString4 _cln, _frn;
|
||||
|
||||
protected:
|
||||
virtual TObject* key2obj(const char* key);
|
||||
|
||||
public:
|
||||
const TCausale& causale(const char* codice, int annoiva);
|
||||
const TCausale& causale(char tipocf, tipo_movimento tm, const TDate& datadoc);
|
||||
void init(const char* cln, const char* frn) { _cln = cln; _frn = frn; }
|
||||
};
|
||||
|
||||
TObject* TCausali_cache::key2obj(const char* key)
|
||||
{
|
||||
// Metodo bastardo per evitare TToken_string temporanee "a randa"
|
||||
// sfrutto chiave a lunghezza fissa
|
||||
const int anno = atoi(key);
|
||||
const char* codice = key+5;
|
||||
TCausale* pcaus = new TCausale(codice, anno);
|
||||
const char tipocf = key[0];
|
||||
const tipo_movimento tm = tipo_movimento(key[1]-'0');
|
||||
int anno = atoi(key + 2);
|
||||
if (anno <= 0)
|
||||
anno = TDate(TODAY).year();
|
||||
|
||||
TString4 codcaus;
|
||||
if (tm == tm_fattura)
|
||||
codcaus = tipocf == 'F' ? _frn : _cln;
|
||||
if (codcaus.blank())
|
||||
{
|
||||
TString query;
|
||||
query << "USE CAUS\nSELECT (TIPOMOV='" << tm << "')&&(RCAUS->TIPOCF='" << tipocf << "')"
|
||||
<< "\nJOIN RCAUS INTO CODCAUS=CODCAUS NRIGA=1";
|
||||
TISAM_recordset caus(query);
|
||||
if (caus.move_first())
|
||||
codcaus = caus.get(CAU_CODCAUS).as_string();
|
||||
}
|
||||
TCausale* pcaus = new TCausale(codcaus, anno);
|
||||
return pcaus;
|
||||
}
|
||||
|
||||
const TCausale& TCausali_cache::causale(const char* codice, int annoiva)
|
||||
const TCausale& TCausali_cache::causale(const char tipocf, tipo_movimento tm, const TDate& datadoc)
|
||||
{
|
||||
// Metodo bastardo per evitare TToken_string temporanee "a randa"
|
||||
// creo chiave a lunghezza fissa anno+codice = 9999|AAA
|
||||
// creo chiave a lunghezza fissa TIPOCF+TIPOMOV = C1
|
||||
TString8 key;
|
||||
key.format("%04d|%s", annoiva, codice);
|
||||
key.format("%c%1d%4d" , tipocf, tm, datadoc.year());
|
||||
return *(const TCausale*)objptr(key);
|
||||
}
|
||||
|
||||
@ -80,7 +97,7 @@ bool TImporta_sc_mask::on_field_event(TOperable_field& f, TField_event e, long j
|
||||
{
|
||||
TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32");
|
||||
TFilename path = get(F_PATH);
|
||||
path.add("*.txt"); //files delle testate
|
||||
path.add("*.txt"); //file da importare
|
||||
list_files(path, as.rows_array());
|
||||
TFilename name;
|
||||
FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
|
||||
@ -112,12 +129,13 @@ class TImporta_sc : public TSkeleton_application
|
||||
|
||||
private:
|
||||
void nuovo_pagamento_o_nota(const TImporta_cogeco_recset& recset, TPartita& game, tipo_movimento tm);
|
||||
bool paga_rata(TPartita& game, int nrata, int nrigp, real& importo) const;
|
||||
|
||||
protected:
|
||||
bool log_error(TLog_report& log, const char* msg, const TRecordset& recset);
|
||||
const TString& find_causale(char tipocf, tipo_movimento tm) const;
|
||||
const TCausale& causale(char tipocf, tipo_movimento tm, const TDate& datadoc);
|
||||
char get_tmcf(int gruppo, int conto) const;
|
||||
bool find_clifo_bill(char tipocf, int& gruppo, int& conto, long sottoconto) const;
|
||||
bool find_clifo_bill(char tipocf, int& gruppo, int& conto, long sottoconto);
|
||||
|
||||
TRiga_partite& nuova_fattura(const TImporta_cogeco_recset& recset, TPartita& game);
|
||||
void nuova_scadenza(const TImporta_cogeco_recset& recset, TPartita& game);
|
||||
@ -125,34 +143,20 @@ protected:
|
||||
void nuovo_pagamento(const TImporta_cogeco_recset& recset, TPartita& game);
|
||||
void nuova_nota_credito(const TImporta_cogeco_recset& recset, TPartita& game);
|
||||
bool nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita& game, TLog_report& log);
|
||||
void salva_partita(TPartita*& game, bool can_write);
|
||||
void salva_partita(TPartita*& game);
|
||||
|
||||
public:
|
||||
virtual bool create();
|
||||
virtual bool destroy();
|
||||
virtual void main_loop();
|
||||
void transfer(const TFilename& file, bool can_write);
|
||||
void transfer(const TFilename& file);
|
||||
};
|
||||
|
||||
const TString& TImporta_sc::find_causale(char tipocf, tipo_movimento tm) const
|
||||
{
|
||||
TString4 codcaus;
|
||||
if (tm == tm_fattura)
|
||||
codcaus = _msk->get(tipocf == 'F' ? F_CODCAUSF : F_CODCAUSC);
|
||||
if (codcaus.blank())
|
||||
{
|
||||
TString query;
|
||||
query << "USE CAUS\nSELECT (TIPOMOV='" << tm << "')&&(RCAUS->TIPOCF='" << tipocf << "')"
|
||||
<< "\nJOIN RCAUS INTO CODCAUS=CODCAUS NRIGA=1";
|
||||
TISAM_recordset caus(query);
|
||||
if (caus.move_first())
|
||||
codcaus = caus.get(CAU_CODCAUS).as_string();
|
||||
}
|
||||
if (codcaus.full())
|
||||
return get_tmp_string() = codcaus;
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
// Cerca una causale appropriata in base a TIPOCF (C o F) e TIPOMOV (1, 2, 3, ...)
|
||||
const TCausale& TImporta_sc::causale(char tipocf, tipo_movimento tm, const TDate& datadoc)
|
||||
{ return _cache_causali.causale(tipocf, tm, datadoc); }
|
||||
|
||||
// Ricava il campo TMCF (Cliente o Fornitore) di un dato conto
|
||||
char TImporta_sc::get_tmcf(int gruppo, int conto) const
|
||||
{
|
||||
char tmcf = ' ';
|
||||
@ -165,38 +169,37 @@ char TImporta_sc::get_tmcf(int gruppo, int conto) const
|
||||
return tmcf;
|
||||
}
|
||||
|
||||
bool TImporta_sc::find_clifo_bill(char tipocf, int& gruppo, int& conto, long sottoconto) const
|
||||
// Trova il conto cliente di una certa anagrafica
|
||||
bool TImporta_sc::find_clifo_bill(char tipocf, int& gruppo, int& conto, long sottoconto)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
TString8 key;
|
||||
gruppo = conto = 0;
|
||||
|
||||
// Prima lo cerca sull'anagrafica stessa
|
||||
key.format("%c|%ld", tipocf, sottoconto);
|
||||
const TRectype& clifo = cache().get(LF_CLIFO, key);
|
||||
gruppo = clifo.get_int(CLI_GRUPPO);
|
||||
conto = clifo.get_int(CLI_CONTO);
|
||||
|
||||
// Controlla che il conto esista
|
||||
found = get_tmcf(gruppo, conto) == tipocf;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
const TString4 codcaus = find_causale(tipocf, tm_fattura);
|
||||
if (codcaus.full())
|
||||
{
|
||||
key.format("%s|1", (const char*)codcaus);
|
||||
const TRectype& rcaus = cache().get(LF_RCAUSALI, key);
|
||||
if (rcaus.get_char(RCA_TIPOCF) == tipocf)
|
||||
{
|
||||
gruppo = rcaus.get_int(RCA_GRUPPO);
|
||||
conto = rcaus.get_int(RCA_CONTO);
|
||||
found = get_tmcf(gruppo, conto) == tipocf;
|
||||
}
|
||||
}
|
||||
// Cerca sulla prima riga dellla causale
|
||||
const TDate datadoc(TODAY);
|
||||
const TCausale& caus = causale(tipocf, tm_fattura, datadoc);
|
||||
TBill bill; caus.bill(1, bill);
|
||||
gruppo = bill.gruppo();
|
||||
conto = bill.conto();
|
||||
found = get_tmcf(gruppo, conto) == tipocf;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// Usa un conto C/F trovato preventivamente in fase di inizializzazione
|
||||
if (tipocf == 'C')
|
||||
{
|
||||
gruppo = _clienti.gruppo();
|
||||
@ -213,7 +216,7 @@ bool TImporta_sc::find_clifo_bill(char tipocf, int& gruppo, int& conto, long sot
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
// Aggiunge una nuova riga fattura a 'game' in base ai dati in 'recset'
|
||||
TRiga_partite& TImporta_sc::nuova_fattura(const TImporta_cogeco_recset& recset, TPartita& game)
|
||||
{
|
||||
int nriga = game.prima_fattura();
|
||||
@ -227,11 +230,10 @@ TRiga_partite& TImporta_sc::nuova_fattura(const TImporta_cogeco_recset& recset,
|
||||
fattura.put(PART_DESCR, TR("*** Fattura gnerata da COGECO ***"));
|
||||
|
||||
const char tipocf = game.conto().tipo();
|
||||
const TString& codcaus = find_causale(tipocf, tm_fattura);
|
||||
if (codcaus.full())
|
||||
const TCausale& caus = causale(tipocf, tm_fattura, datadoc);
|
||||
if (caus.ok())
|
||||
{
|
||||
const TCausale& caus = _cache_causali.causale(codcaus, game.anno());
|
||||
fattura.put(PART_CODCAUS, codcaus);
|
||||
fattura.put(PART_CODCAUS, caus.codice());
|
||||
fattura.put(PART_REG, caus.reg().name());
|
||||
fattura.put(PART_TIPOMOV, caus.tipomov());
|
||||
fattura.put(PART_SEZ, caus.sezione(1));
|
||||
@ -246,21 +248,25 @@ TRiga_partite& TImporta_sc::nuova_fattura(const TImporta_cogeco_recset& recset,
|
||||
|
||||
TRiga_partite& fattura = game.riga(nriga);
|
||||
const real importo = recset.get_real(CGC_IMPORTO);
|
||||
|
||||
fattura.add(PART_IMPTOTDOC, importo);
|
||||
fattura.add(PART_IMPORTO, importo);
|
||||
|
||||
return fattura;
|
||||
}
|
||||
|
||||
// Aggiunge una nuova rata alla UNICA fattura di 'game'.
|
||||
// Attenzione: in assenza di fattura ne viene creata una "al volo" di pari importo.
|
||||
void TImporta_sc::nuova_scadenza(const TImporta_cogeco_recset& recset, TPartita& game)
|
||||
{
|
||||
int nriga = game.prima_fattura();
|
||||
if (nriga <= 0)
|
||||
int nriga = game.prima_fattura(); // PART_NRIGA della fattura (solitamente = 1)
|
||||
if (nriga <= 0) // Se non ci sono fattura in questa partita ...
|
||||
{
|
||||
nuova_fattura(recset, game);
|
||||
nriga = game.prima_fattura();
|
||||
nuova_fattura(recset, game); // Creo una nuova fattura
|
||||
nriga = game.prima_fattura(); // Aggiorno PART_NRIGA che valeva -1
|
||||
}
|
||||
TRiga_partite& fattura = game.riga(nriga);
|
||||
TRiga_scadenze& scadenza = fattura.new_row();
|
||||
TRiga_partite& fattura = game.riga(nriga); // Accedo alla riga di fattura, che ora DEVE esistere!
|
||||
TRiga_scadenze& scadenza = fattura.new_row(); // Creo nuova rata, alla faccia di SCAD_CODPAG
|
||||
|
||||
const real importo = recset.get_real(CGC_IMPORTO);
|
||||
scadenza.put(SCAD_DATASCAD, recset.get_date(CGC_SCADENZA));
|
||||
@ -268,10 +274,40 @@ void TImporta_sc::nuova_scadenza(const TImporta_cogeco_recset& recset, TPartita&
|
||||
scadenza.put(SCAD_DESCR, TR("*** Rata generata da COGECO ***"));
|
||||
}
|
||||
|
||||
bool TImporta_sc::paga_rata(TPartita& game, int nrata, int nrigp, real& importo) const
|
||||
{
|
||||
const int nriga = game.prima_fattura();
|
||||
if (nriga > 0)
|
||||
{
|
||||
const TRiga_partite& fattura = game.riga(nriga);
|
||||
TRiga_scadenze& scadenza = fattura.rata(nrata);
|
||||
const real residuo = scadenza.residuo(false).valore();
|
||||
if (!residuo.is_zero()) // Considera solo rate aperte
|
||||
{
|
||||
// Elenco dei campi chiave da riportare dalla rata al pagamento
|
||||
const char* const field[] = { PAGSCA_TIPOC, PAGSCA_SOTTOCONTO, PAGSCA_ANNO, PAGSCA_NUMPART,
|
||||
PAGSCA_NRIGA, PAGSCA_NRATA, NULL };
|
||||
const real pagare = residuo > importo ? importo : residuo; // Importo da pagare sulla rata
|
||||
TRectype rpag(LF_PAGSCA);
|
||||
for (int k = 0; field[k]; k++)
|
||||
rpag.put(field[k], scadenza.get(field[k]));
|
||||
rpag.put(PAGSCA_NRIGP, nrigp); // Completa la chiave di PAGSCA col numero riga di partita
|
||||
rpag.put(PAGSCA_IMPORTO, pagare);
|
||||
const TValuta euro;
|
||||
game.modifica_pagamento(rpag, euro, true); // Speriamo che faccia tutto lei :-)
|
||||
importo -= pagare;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Aggiunge una nuova riga tipo 2 (n.c.) o 3 (pag.) alla partita
|
||||
void TImporta_sc::nuovo_pagamento_o_nota(const TImporta_cogeco_recset& recset, TPartita& game, tipo_movimento tm)
|
||||
{
|
||||
// Crea una nuova riga di partita
|
||||
TRiga_partite& pagamento = game.new_row();
|
||||
const int nrigp = pagamento.get_int(PART_NRIGA);
|
||||
const int nrigp = pagamento.get_int(PART_NRIGA); // Ricorda numero da mettere in PAGSCA_NRIGP
|
||||
|
||||
const TDate datadoc = recset.get_date(CGC_DATADOC);
|
||||
pagamento.put(PART_DATAREG, datadoc);
|
||||
@ -281,12 +317,12 @@ void TImporta_sc::nuovo_pagamento_o_nota(const TImporta_cogeco_recset& recset, T
|
||||
else
|
||||
pagamento.put(PART_DESCR, TR("*** Pagamento generato da COGECO ***"));
|
||||
|
||||
// Cerca di inizlizzare la riga con una causale appropriata
|
||||
const char tipocf = game.conto().tipo();
|
||||
const TString& codcaus = find_causale(tipocf, tm);
|
||||
if (codcaus.full())
|
||||
const TCausale& caus = causale(tipocf, tm, datadoc);
|
||||
if (caus.ok())
|
||||
{
|
||||
const TCausale& caus = _cache_causali.causale(codcaus, game.anno());
|
||||
pagamento.put(PART_CODCAUS, codcaus);
|
||||
pagamento.put(PART_CODCAUS, caus.codice());
|
||||
pagamento.put(PART_REG, caus.reg().name());
|
||||
pagamento.put(PART_TIPOMOV, caus.tipomov());
|
||||
pagamento.put(PART_SEZ, caus.sezione(1));
|
||||
@ -294,87 +330,112 @@ void TImporta_sc::nuovo_pagamento_o_nota(const TImporta_cogeco_recset& recset, T
|
||||
else
|
||||
{
|
||||
pagamento.put(PART_TIPOMOV, tm);
|
||||
pagamento.put(PART_SEZ, tipocf == 'F' ? 'A' : 'D');
|
||||
pagamento.put(PART_SEZ, tipocf == 'F' ? 'D' : 'A');
|
||||
}
|
||||
|
||||
// Somma da distribuire sulle rate aperte
|
||||
real importo = recset.get_real(CGC_IMPORTO);
|
||||
pagamento.put(PART_IMPORTO, importo);
|
||||
pagamento.put(PART_IMPTOTDOC, importo);
|
||||
|
||||
const TValuta euro;
|
||||
// Se esiste una fattura cerca di saldare il residuo delle rate aperte
|
||||
const int nriga = game.prima_fattura();
|
||||
if (nriga > 0)
|
||||
{
|
||||
const TRiga_partite& fattura = game.riga(nriga);
|
||||
for (int nrata = 1; nrata <= fattura.rate() && !importo.is_zero(); nrata++)
|
||||
|
||||
// Si assicura che la sezione sia inversa rispetto alla fattura
|
||||
pagamento.put(PART_SEZ, fattura.sezione() == 'D' ? 'A' : 'D');
|
||||
|
||||
while (true)
|
||||
{
|
||||
TRiga_scadenze& scadenza = fattura.rata(nrata);
|
||||
const real residuo = scadenza.residuo(false).valore();
|
||||
if (!residuo.is_zero())
|
||||
int best_rata = 0, best_score = 0;
|
||||
for (int nrata = 1; nrata <= fattura.rate() && !importo.is_zero(); nrata++)
|
||||
{
|
||||
const real pagare = residuo > importo ? importo : residuo;
|
||||
TRectype rpag(LF_PAGSCA);
|
||||
const char* const field[] = { PAGSCA_TIPOC, PAGSCA_SOTTOCONTO, PAGSCA_ANNO, PAGSCA_NUMPART,
|
||||
PAGSCA_NRIGA, PAGSCA_NRATA, NULL };
|
||||
for (int k = 0; field[k]; k++)
|
||||
rpag.put(field[k], scadenza.get(field[k]));
|
||||
rpag.put(PAGSCA_NRIGP, nrigp);
|
||||
rpag.put(PAGSCA_IMPORTO, pagare);
|
||||
game.modifica_pagamento(rpag, euro, true);
|
||||
importo -= pagare;
|
||||
const TRiga_scadenze& rata = fattura.rata(nrata);
|
||||
const real residuo = rata.residuo(false).valore();
|
||||
const TDate data_scad = rata.get(SCAD_DATASCAD);
|
||||
int score = data_scad == datadoc ? 2 : 0;
|
||||
if (score == 0 && datadoc == data_scad+1L)
|
||||
score++;
|
||||
if (residuo >= importo)
|
||||
{
|
||||
score++;
|
||||
if (residuo == importo)
|
||||
score++;
|
||||
}
|
||||
if (score > best_score)
|
||||
{
|
||||
best_rata = nrata;
|
||||
best_score = score;
|
||||
}
|
||||
}
|
||||
if (best_rata > 0)
|
||||
paga_rata(game, best_rata, nrigp, importo);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Se ci rimane qualcosa o non e' stata trovata una rata aperta allora crea un pagamento non assegnato
|
||||
if (!importo.is_zero())
|
||||
{
|
||||
TRectype rpag(LF_PAGSCA);
|
||||
const char* const field[] = { PAGSCA_TIPOC, PAGSCA_SOTTOCONTO, PAGSCA_ANNO, PAGSCA_NUMPART, NULL };
|
||||
for (int k = 0; field[k]; k++)
|
||||
rpag.put(field[k], pagamento.get(field[k]));
|
||||
rpag.put(PAGSCA_NRIGA, 9999);
|
||||
rpag.put(PAGSCA_NRATA, 9999);
|
||||
rpag.put(PAGSCA_NRIGP, nrigp);
|
||||
rpag.put(PAGSCA_NRIGA, 9999); // Questo 9999 significa "fattura ignota"
|
||||
rpag.put(PAGSCA_NRATA, 9999); // Questo 9999 significa "rata ignota"
|
||||
rpag.put(PAGSCA_NRIGP, nrigp); // Completa la chiave di PAGSCA col numero riga di partita
|
||||
rpag.put(PAGSCA_IMPORTO, importo);
|
||||
const TValuta euro;
|
||||
game.modifica_pagamento(rpag, euro, true);
|
||||
}
|
||||
}
|
||||
|
||||
// In COGECO le riba si intendono pagate automaticamente,
|
||||
// per cui in CAMPO viene aperta una scadenza ed immediatamente chiusa col relativo pagamento
|
||||
void TImporta_sc::nuova_riba(const TImporta_cogeco_recset& recset, TPartita& game)
|
||||
{
|
||||
nuova_scadenza(recset, game);
|
||||
nuovo_pagamento(recset, game);
|
||||
}
|
||||
|
||||
// Creo una nuova riga partita corrispondente ad una riga pagamento in PAGSCA
|
||||
void TImporta_sc::nuovo_pagamento(const TImporta_cogeco_recset& recset, TPartita& game)
|
||||
{ nuovo_pagamento_o_nota(recset, game, tm_pagamento); }
|
||||
|
||||
// Creo una nuova riga partita corrispondente ad una riga nota di credito in PAGSCA
|
||||
void TImporta_sc::nuova_nota_credito(const TImporta_cogeco_recset& recset, TPartita& game)
|
||||
{ nuovo_pagamento_o_nota(recset, game, tm_nota_credito); }
|
||||
|
||||
// Creo una nuova riga partita corrispondente ad una riga di insoluto PAGSCA
|
||||
bool TImporta_sc::nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita& game, TLog_report& log)
|
||||
{
|
||||
const int nriga = game.prima_fattura();
|
||||
if (nriga <= 0)
|
||||
const int nriga = game.prima_fattura(); // Cerco la fattura insoluta
|
||||
if (nriga <= 0) // Non e' carino creare un insoluto non assegnato
|
||||
return log_error(log, TR("Impossibile associare insoluto"), recset);
|
||||
|
||||
const TDate datadoc = recset.get_date(CGC_DATADOC);
|
||||
const real importo = recset.get_real(CGC_IMPORTO);
|
||||
real importo = recset.get_real(CGC_IMPORTO);
|
||||
|
||||
// Cerca la miglior rata possibile da mandare insoluta
|
||||
// Per fare cio', si assegna un punteggio ad ogni rata, basato sulla data e sull'importo
|
||||
int best_rata = 0, best_score = 0;
|
||||
|
||||
const TRiga_partite& fattura = game.riga(nriga);
|
||||
for (int nrata = fattura.rate(); nrata > 0; nrata--)
|
||||
{
|
||||
const TRiga_scadenze& scadenza = fattura.rata(nrata);
|
||||
const TImporto imp = scadenza.importo_pagato(false);
|
||||
const TDate data = scadenza.get(SCAD_DATASCAD);
|
||||
int score = 0;
|
||||
if (imp.valore() == importo)
|
||||
score++;
|
||||
int score = datadoc == data ? 2 : 0;
|
||||
if (score == 0 && datadoc == data+1L)
|
||||
score++;
|
||||
if (imp.valore() >= importo)
|
||||
{
|
||||
score++;
|
||||
if (datadoc == data)
|
||||
score++;
|
||||
if (imp.valore() == importo)
|
||||
score++;
|
||||
}
|
||||
if (score > best_score)
|
||||
{
|
||||
best_rata = nrata;
|
||||
@ -382,7 +443,7 @@ bool TImporta_sc::nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita&
|
||||
}
|
||||
}
|
||||
|
||||
if (best_rata > 0)
|
||||
if (best_rata > 0) // Se ho trovato almeno una rata compatibile con l'insoluto...
|
||||
{
|
||||
const TRiga_scadenze& scadenza = fattura.rata(best_rata);
|
||||
TRiga_partite& insoluto = game.new_row();
|
||||
@ -391,13 +452,13 @@ bool TImporta_sc::nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita&
|
||||
insoluto.put(PART_DATAREG, datadoc);
|
||||
insoluto.put(PART_DATADOC, datadoc);
|
||||
insoluto.put(PART_DESCR, TR("*** Insoluto trasferito da COGECO ***"));
|
||||
insoluto.put(PART_IMPTOTDOC, importo);
|
||||
|
||||
const char tipocf = game.conto().tipo();
|
||||
const TString& codcaus = find_causale(tipocf, tm_insoluto);
|
||||
if (codcaus.full())
|
||||
const TCausale& caus = causale(tipocf, tm_insoluto, datadoc);
|
||||
if (caus.ok())
|
||||
{
|
||||
const TCausale& caus = _cache_causali.causale(codcaus, game.anno());
|
||||
insoluto.put(PART_CODCAUS, codcaus);
|
||||
insoluto.put(PART_CODCAUS, caus.codice());
|
||||
insoluto.put(PART_REG, caus.reg().name());
|
||||
insoluto.put(PART_TIPOMOV, caus.tipomov());
|
||||
insoluto.put(PART_SEZ, caus.sezione(1));
|
||||
@ -407,17 +468,7 @@ bool TImporta_sc::nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita&
|
||||
insoluto.put(PART_TIPOMOV, tm_insoluto);
|
||||
insoluto.put(PART_SEZ, fattura.sezione());
|
||||
}
|
||||
insoluto.put(PART_IMPORTO, importo);
|
||||
|
||||
const TValuta euro;
|
||||
TRectype rpag(LF_PAGSCA);
|
||||
const char* const field[] = { PAGSCA_TIPOC, PAGSCA_SOTTOCONTO, PAGSCA_ANNO, PAGSCA_NUMPART,
|
||||
PAGSCA_NRIGA, PAGSCA_NRATA, NULL };
|
||||
for (int k = 0; field[k]; k++)
|
||||
rpag.put(field[k], scadenza.get(field[k]));
|
||||
rpag.put(PAGSCA_NRIGP, nrigp);
|
||||
rpag.put(PAGSCA_IMPORTO, importo);
|
||||
game.modifica_pagamento(rpag, euro, true);
|
||||
paga_rata(game, best_rata, nrigp, importo);
|
||||
}
|
||||
else
|
||||
log_error(log, TR("Impossibile associare insoluto"), recset);
|
||||
@ -425,11 +476,12 @@ bool TImporta_sc::nuovo_insoluto(const TImporta_cogeco_recset& recset, TPartita&
|
||||
return best_rata > 0;
|
||||
}
|
||||
|
||||
|
||||
bool TImporta_sc::log_error(TLog_report& log, const char* msg, const TRecordset& recset)
|
||||
{
|
||||
TString message;
|
||||
message << TR("Riga") << ' ' << recset.current_row() << ": " << msg;
|
||||
message << recset.get(CGC_TIPOCF) << recset.get(CGC_CODCF) << '-'
|
||||
<< recset.get(CGC_ANNO) << '/' << recset.get(CGC_NUMPART)
|
||||
<< '.' << recset.get(CGC_NUMEROREC) << " : " << msg;
|
||||
log.log(2, message);
|
||||
return false;
|
||||
}
|
||||
@ -469,6 +521,16 @@ static int game_sorter(const TObject** o1, const TObject** o2)
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
const TString datadoc1 = r1.get(CGC_DATADOC);
|
||||
if (datadoc1.blank() || datadoc1 == "00/00/0000")
|
||||
return -1;
|
||||
const TString datadoc2 = r2.get(CGC_DATADOC);
|
||||
if (datadoc2.blank() || datadoc2 == "00/00/0000")
|
||||
return +1;
|
||||
cmp = TDate(datadoc1)-TDate(datadoc2);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
const TString data1 = r1.get(CGC_SCADENZA);
|
||||
if (data1.blank() || data1 == "00/00/0000")
|
||||
return -1;
|
||||
@ -480,32 +542,33 @@ static int game_sorter(const TObject** o1, const TObject** o2)
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
// I tipi documento vanno ordinati in base alla sequenza sequente, non in base al valore numerico!
|
||||
TToken_string priority = "1|3|15|2|4|5|6|7|8|9|10|11";
|
||||
const int tipodoc1 = r1.get_int(CGC_TIPODOC);
|
||||
const int tipodoc2 = r2.get_int(CGC_TIPODOC);
|
||||
cmp = tipodoc1 - tipodoc2;
|
||||
int pri1 = priority.get_pos(tipodoc1);
|
||||
if (pri1 < 0) pri1 = 100+tipodoc1;
|
||||
int pri2 = priority.get_pos(tipodoc2);
|
||||
if (pri2 < 0) pri2 = 100+tipodoc2;
|
||||
cmp = pri1 - pri2;
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
void TImporta_sc::salva_partita(TPartita*& game, bool can_write)
|
||||
void TImporta_sc::salva_partita(TPartita*& game)
|
||||
{
|
||||
if (game != NULL)
|
||||
{
|
||||
if (can_write)
|
||||
{
|
||||
// for (int r = game->last(); r > 0; r = game->pred(r))
|
||||
// game->riga(r).put(PART_IMPTOTDOC, totdoc);
|
||||
game->write();
|
||||
}
|
||||
game->write();
|
||||
delete game;
|
||||
game = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void TImporta_sc::transfer(const TFilename& file, bool can_write)
|
||||
void TImporta_sc::transfer(const TFilename& file)
|
||||
{
|
||||
TImporta_cogeco_recset recset(file);
|
||||
recset.sort(game_sorter);
|
||||
recset.save_as("c:/temp/topartite.txt");
|
||||
|
||||
TString caption; _msk->get_caption(caption);
|
||||
TProgind pi(recset.items(), caption, true, true);
|
||||
@ -537,23 +600,23 @@ void TImporta_sc::transfer(const TFilename& file, bool can_write)
|
||||
|
||||
if (tipocf != t || sottoconto != s || anno != a || p != part)
|
||||
{
|
||||
salva_partita(game, can_write); // Salva parita corrente se non nulla
|
||||
salva_partita(game); // Salva parita corrente se non nulla
|
||||
|
||||
TToken_string key; key.format("%c|%ld", t, s);
|
||||
const TRectype& clifo = cache().get(LF_CLIFO, key);
|
||||
if (clifo.empty())
|
||||
{
|
||||
can_write = log_error(log, TR("Codice Cliente/Fornitore non valido"), recset);
|
||||
log_error(log, TR("Codice Cliente/Fornitore non valido"), recset);
|
||||
continue;
|
||||
}
|
||||
if (a < 2000)
|
||||
{
|
||||
can_write = log_error(log, TR("Anno partita non valido"), recset);
|
||||
log_error(log, TR("Anno partita non valido"), recset);
|
||||
continue;
|
||||
}
|
||||
if (p <= 0)
|
||||
{
|
||||
can_write = log_error(log, TR("Numero partita non valido"), recset);
|
||||
log_error(log, TR("Numero partita non valido"), recset);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -572,7 +635,7 @@ void TImporta_sc::transfer(const TFilename& file, bool can_write)
|
||||
}
|
||||
else
|
||||
{
|
||||
can_write = log_error(log, TR("Impossibile determinare il conto cliente/fornitore"), recset);
|
||||
log_error(log, TR("Impossibile determinare il conto cliente/fornitore"), recset);
|
||||
break; // Esce subito, probabilmente il piano dei conti non e' stato ancora importato
|
||||
}
|
||||
}
|
||||
@ -586,19 +649,24 @@ void TImporta_sc::transfer(const TFilename& file, bool can_write)
|
||||
case 1: nuova_fattura(recset, *game); break; // Fattura
|
||||
case 2: nuova_nota_credito(recset, *game); break; // Nota di credito
|
||||
case 3: nuova_fattura(recset, *game); break; // Fattura in sospensione
|
||||
case 4: nuova_nota_credito(recset, *game); break; // Reso su fattura in sospensione
|
||||
case 5: nuovo_pagamento(recset, *game); break; // Pagamento fattura in sospeso
|
||||
case 6: nuovo_insoluto(recset, *game, log); break; // Insoluto
|
||||
case 8: // Tratta
|
||||
case 9: // Ri.Ba.
|
||||
case 10: nuova_riba(recset, *game); break; // Cambiale
|
||||
case 11: nuovo_pagamento(recset, *game); break; // Pagamento
|
||||
case 19: nuova_riba(recset, *game); break; // Avviso di scadenza
|
||||
case 13: nuova_nota_credito(recset, *game); break; // Nota di credito su RB clienti
|
||||
case 14: nuova_nota_credito(recset, *game); break; // Abbuono
|
||||
case 15: nuova_scadenza(recset, *game); break;
|
||||
case 18: nuova_riba(recset, *game); break; // Paghero'
|
||||
case 19: nuova_riba(recset, *game); break; // Avviso di scadenza
|
||||
case 20: nuova_riba(recset, *game); break; // R.I.D.
|
||||
default: log_error(log, TR("Tipo documento non riconosciuto"), recset); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
salva_partita(game, can_write); // Salva ultima partita se non nulla
|
||||
salva_partita(game); // Salva ultima partita se non nulla
|
||||
|
||||
if (log.recordset()->items() > 0)
|
||||
log.preview();
|
||||
@ -606,6 +674,7 @@ void TImporta_sc::transfer(const TFilename& file, bool can_write)
|
||||
|
||||
bool TImporta_sc::create()
|
||||
{
|
||||
// Determina i conti per clienti e fornitori nel caso non siano in anagrafica
|
||||
TString query; query << "USE PCON SELECT TMCF!=\'\'";
|
||||
TISAM_recordset pcon(query);
|
||||
for (bool ok = pcon.move_first(); ok; ok = pcon.move_next())
|
||||
@ -617,7 +686,6 @@ bool TImporta_sc::create()
|
||||
if (tmcf == 'F' && _fornitori.gruppo() == 0)
|
||||
_fornitori.get(rec);
|
||||
}
|
||||
|
||||
_msk = new TImporta_sc_mask();
|
||||
return TSkeleton_application::create();
|
||||
}
|
||||
@ -630,14 +698,14 @@ bool TImporta_sc::destroy()
|
||||
|
||||
void TImporta_sc::main_loop()
|
||||
{
|
||||
KEY tasto;
|
||||
tasto = _msk->run();
|
||||
if (tasto == K_ENTER)
|
||||
if (_msk->run() == K_ENTER)
|
||||
{
|
||||
_cache_causali.init(_msk->get(F_CODCAUSC), _msk->get(F_CODCAUSF));
|
||||
|
||||
//genero il nome del file da caricare
|
||||
TFilename name = _msk->get(F_PATH);
|
||||
name.add(_msk->get(F_NAME));
|
||||
transfer(name, true);
|
||||
transfer(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,3 +8,4 @@
|
||||
#define F_CODCAUSF 106
|
||||
#define F_DESCRCAUSC 107
|
||||
#define F_DESCRCAUSF 108
|
||||
|
||||
|
@ -57,7 +57,7 @@ BEGIN
|
||||
CHECKTYPE REQUIRED
|
||||
END
|
||||
|
||||
GROUPBOX DLG_NULL 90 6
|
||||
GROUPBOX DLG_NULL 90 4
|
||||
BEGIN
|
||||
PROMPT 2 8 "Causali"
|
||||
END
|
||||
|
Loading…
x
Reference in New Issue
Block a user