campo-sirio/mr/mr2201.cpp

1901 lines
53 KiB
C++
Raw Normal View History

#include <execp.h>
#include <printer.h>
#include <progind.h>
#include <utility.h>
#include "../mg/mglib.h"
#include "../ve/veconf.h"
#include "mr2100.h"
#include "mr2200.h"
#include "mr2200a.h"
// albero per le ricerche sulle dist
static TDistinta_tree *_dist_tree=NULL;
TDistinta_tree &dist_tree()
{
if (_dist_tree == NULL)
_dist_tree = new TDistinta_tree();
return *_dist_tree;
}
///////////////////////////////////////////////////////////
// triga ordine
///////////////////////////////////////////////////////////
TMSP_form::TMSP_form (TIsamtempfile * report) : TForm("mr2200a")
{
TRelation* rel = relation();
rel->replace(report);
const int hh = 7;
const int fl = printer().formlen();
int rows[4]; // Righe orizzontali
rows[0] = hh-3;
rows[1] = hh;
rows[2] = fl;
rows[3] = 0;
genera_intestazioni(odd_page, hh-2);
genera_fincatura(odd_page, hh-3, fl, rows);
}
bool TMSP_form::validate(TForm_item &cf, TToken_string &cmd)
{
TString s;
cmd.get(0,s);
if (s=="_USER")
{
TRelation* rel = relation();
cmd.get(1,s);
if (s=="CODART")
{
TString val;
if (rel->lfile().get("TIPO")=="C")
{
val=TR("Ordini da soddisfare");
}
else if (rel->lfile().get("TIPO")=="G")
val=TR("Giacenza proiettata");
else
val=TR("Ordini pianificati");
cf.set(val);
}
return TRUE;
}
return TForm::validate(cf,cmd);
}
TCRP_form::TCRP_form(TIsamtempfile* report, TSheet_field& sf)
: TForm("mr2200b")
{
TRelation* rel = relation();
rel->replace(report);
// Modifica oppportunamente le intestazioni dei bucket
TPrint_section& body = section('B', odd_page);
for (word i = 2; i < body.fields(); i++)
{
TForm_item& fi = body.field(i);
fi.set_col_head(sf.get_column_header(i+2));
}
const int hh = 7;
const int fl = printer().formlen();
int rows[4]; // Righe orizzontali
rows[0] = hh-3;
rows[1] = hh;
rows[2] = fl;
rows[3] = 0;
genera_intestazioni(odd_page, hh-2);
genera_fincatura(odd_page, hh-3, fl, rows);
}
bool TCRP_form::validate(TForm_item &cf, TToken_string &cmd)
{
TString val;
cmd.get(0,val);
if (val=="_USER")
{
cmd.get(1,val);
if (val=="CODART")
{
const TRectype& curr = relation()->curr();
const char type = curr.get_char("TIPO");
switch (type)
{
case 'D': val = TR(" Capacit<69> totale"); break;
case 'd': val = TR(" Carico totale"); break;
case 'I': val = TR(" Capacit<69> impianto "); val << curr.get("IMPIANTO"); break;
case 'i': val = TR(" Carico impianto "); val << curr.get("IMPIANTO"); break;
case 'L': val = TR(" Capacit<69> linea "); val << curr.get("LINEA"); break;
case 'l': val = TR(" Carico linea "); val << curr.get("LINEA"); break;
default:
val = curr.get("CODART");
val << " " << relation()->curr(LF_ANAMAG).get("DESCR");
break;
}
cf.set(val);
}
return TRUE;
}
return TForm::validate(cf,cmd);
}
int TRiga_articolo::order_comparePCAL(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PCAL);}
int TRiga_articolo::order_comparePCLA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PCLA);}
int TRiga_articolo::order_comparePALC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PALC);}
int TRiga_articolo::order_comparePACL(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PACL);}
int TRiga_articolo::order_comparePLAC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PLAC);}
int TRiga_articolo::order_compareLPAC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_LPAC);}
int TRiga_articolo::order_comparePLCA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PLCA);}
int TRiga_articolo::order_compareCAL(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_CAL);}
int TRiga_articolo::order_compareCLA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_CLA);}
int TRiga_articolo::order_compareALC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_ALC);}
int TRiga_articolo::order_compareACL(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_ACL);}
int TRiga_articolo::order_compareLAC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_LAC);}
int TRiga_articolo::order_compareLCA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_LCA);}
int TRiga_articolo::order_comparePCA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PCA);}
int TRiga_articolo::order_compareCA(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_CA);}
int TRiga_articolo::order_compareAC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_AC);}
int TRiga_articolo::order_comparePAC(TSheet_field & s, int i1, int i2)
{ return TRiga_articolo::order_compare(s, i1, i2,SORT_BY_PAC);}
///////////////////////////////////////////////////////////
int TRiga_articolo::find_block_constr(const TSheet_field& sf, const int riga)
{
const int narticoli=sf.items();
const int b1 = sf.cid2index(F_BUCKET1);
int first_row;
for (first_row = riga; first_row > 0; first_row--)
{
if (sf.cell_disabled(first_row, b1))
break;
}
if (first_row+1 < narticoli && sf.cell_disabled(first_row+1, b1)) first_row++;
return first_row;
}
// ritorna se tutto OK
bool TRiga_articolo::find_block(const TSheet_field& sf, const int riga, int &first_row, int &last_row )
{
const int narticoli = sf.items();
if (riga < 0 || riga >= narticoli)
return false;
// Calcola l'indice c della riga coi vincoli
const int b1 = sf.cid2index(F_BUCKET1);
first_row = find_block_constr(sf, riga);
// Calcola l'indice r dell'ultima riga articoli
last_row = riga;
if (last_row <= first_row) last_row=first_row+1;
for ( ; last_row < narticoli-1; last_row++)
{
if (sf.cell_disabled(last_row+1, b1))
break;
}
return true;
}
int TRiga_articolo::order_compare( const TToken_string &r1, const TToken_string &r2, int level, bool ascending)
{
TString80 str0, str1;
int cmp = 0;
if (level>=0)
{
for (int i = 2; i <= level && cmp == 0; i++)
{
r1.get(i, str0);
r2.get(i, str1);
cmp=TRiga_articolo::compare_field(str0,str1,short(i+FIRST_FIELD));
}
}
else
{
// ordinamenti non standard
static const short fields_ACL[] = { F_PRIORITA, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_CLIENTE, F_SORTCODIMP, F_SORTCODLIN, 0 };
static const short fields_ALC[] = { F_PRIORITA, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_SORTCODIMP, F_SORTCODLIN, F_CLIENTE, 0 };
static const short fields_LAC[] = { F_PRIORITA, F_SORTCODIMP, F_SORTCODLIN, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_CLIENTE, 0 };
static const short fields_LCA[] = { F_PRIORITA, F_SORTCODIMP, F_SORTCODLIN, F_CLIENTE, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, 0 };
static const short fields_CLA[] = { F_PRIORITA, F_CLIENTE, F_SORTCODIMP, F_SORTCODLIN, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, 0 };
static const short fields_LPAC[]= { F_SORTCODIMP, F_SORTCODLIN, F_PRIORITA, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_CLIENTE, 0 };
static const short fields_CAL[] = { F_PRIORITA, F_CLIENTE, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_SORTCODIMP, F_SORTCODLIN, 0 };
static const short fields_CA[] = { F_PRIORITA, F_CLIENTE, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, 0, 0, 0 };
static const short fields_AC[] = { F_PRIORITA, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_CLIENTE, 0, 0, 0 };
for (int ii = 0; cmp == 0; ii++)
{
const int i = ii + (-level <= SORT_BY_PRIORITY ? 0 : 1);
short f = 0;
switch (level)
{
case SORT_BY_PCAL:
case SORT_BY_CAL:
f=fields_CAL[i]; break;
case SORT_BY_PCLA:
case SORT_BY_CLA:
f=fields_CLA[i]; break;
case SORT_BY_PLCA:
case SORT_BY_LCA:
f=fields_LCA[i]; break;
case SORT_BY_PLAC:
case SORT_BY_LAC:
f=fields_LAC[i]; break;
case SORT_BY_LPAC:
f=fields_LPAC[i]; break;
case SORT_BY_PACL:
case SORT_BY_ACL:
f=fields_ACL[i]; break;
case SORT_BY_PALC:
case SORT_BY_ALC:
f=fields_ALC[i]; break;
case SORT_BY_PAC:
case SORT_BY_AC:
f=fields_AC[i]; break;
case SORT_BY_PCA:
case SORT_BY_CA:
f=fields_CA[i]; break;
default:
NFCHECK("Ordinamento sconosciuto");
break;
}
if (f <= 0)
break;
r1.get(f-FIRST_FIELD, str0);
r2.get(f-FIRST_FIELD, str1);
cmp = TRiga_articolo::compare_field(str0,str1,f) * ((ascending && f != F_PRIORITA) ? 1 : -1);
}
}
return cmp;
}
// aggiunge li codici di linea/impianto se non presenti usando i default sulle lavorazioni critiche
// cio' permette di ordinare per impianto anche le linee di ordine che non hanno solitamente
// questa indicazione ma solo il codice articolo
void complete_codlinea(TToken_string &r2, bool ignore_imp)
{
TString8 codimp;
r2.get(F_SORTCODIMP-FIRST_FIELD, codimp);
if (codimp.blank())
{
r2.get(F_CODIMP-FIRST_FIELD, codimp);
r2.add(codimp, F_SORTCODIMP-FIRST_FIELD);
}
TString8 codlin;
r2.get(F_SORTCODLIN-FIRST_FIELD, codlin);
// if (codlin.blank())
// r2.get(F_CODLIN-FIRST_FIELD, codlin); // F_CODLIN == F_SORTCODLIN
if (codlin.blank())
{
if (dist_tree().set_root(r2.get(F_ARTICOLO-FIRST_FIELD)))
{
dist_tree().set_global("_IMPIANTO",codimp);
dist_tree().set_global("_LINEA","");
TArray labors;
TRiga_esplosione * l=dist_tree().first_critical_labor(labors);
if (l != NULL)
{
TLavorazione *curr_labor=TDistinta_tree::find_labor(l);
CHECK(curr_labor,TR("Lavorazione non trovata"));
for (int nlinea=0; nlinea < curr_labor->linee_standard(); nlinea++)
{
const TRectype &linea_prod= cache().get("LNP",curr_labor->cod_linea(nlinea));
if ( ignore_imp || codimp.blank() || codimp==linea_prod.get("S6"))
{
codlin = linea_prod.get("CODTAB");
r2.add(codlin, F_SORTCODLIN-FIRST_FIELD);
codimp = linea_prod.get("S6");
r2.add(codimp, F_SORTCODIMP-FIRST_FIELD);
return;
}
}
}
}
r2.add("_", F_SORTCODLIN-FIRST_FIELD);
}
}
int TRiga_articolo::order_compare(TSheet_field& s, int i1, int i2, int level)
{
const TMask &m = s.mask();
const bool ascending=!m.get_bool(F_MSP_SORT_ORDER);
int first1 = 0, first2 = 0, last1 = 0, last2 = 0;
if (find_block(s, i1, first1, last1 )) first1--;
if (find_block(s, i2, first2, last2 )) first2--;
if (s.cell_enabled(i1, F_BUCKET1-FIRST_FIELD) && s.cell_enabled(i2, F_BUCKET1-FIRST_FIELD) )
{
// confronto tra righe dello stesso vincolo
if (first1 == first2)
{
const TToken_string &r1 = s.row(i1);
const TToken_string &r2 = s.row(i2);
return order_compare(r1, r2, level, ascending);
}
}
else
{
// Confronto solo le prime righe dei blocchi
if (first1 != first2 && first1 == i1 && first2 == i2)
{
const bool line_matters = !(-level & SORT_WITHOUT_LINE);
// in casi non ambigui ordino in base alla linea dell'ultima riga!
if (line_matters && last1-first1==2 && last2-first2 == 2)
{
i1 = last1;
i2 = last2;
}
TToken_string& blockr1 = s.row(i1);
TToken_string& blockr2 = s.row(i2);
const int lin_pos = F_SORTCODLIN-FIRST_FIELD;
const TString16 l1(blockr1.get(lin_pos));
const TString16 l2(blockr2.get(lin_pos));
if (line_matters)
{
const bool noimpin = m.get_bool(F_NOIMP_IN);
complete_codlinea(blockr1, noimpin);
complete_codlinea(blockr2, noimpin);
if (i1 > first1) // Ricopio la linea eventualmente vuota anche sull'ordine
{
TToken_string& firstr1 = s.row(first1);
if (firstr1.get(lin_pos)[0] <= ' ')
firstr1.add(l1, lin_pos);
TToken_string& firstr2 = s.row(first2);
if (firstr2.get(lin_pos)[0] <= ' ')
firstr2.add(l2, lin_pos);
}
}
int cmp = 0;
const bool lpri = (level == SORT_BY_LPAC) || (level == SORT_BY_LAC);
if (lpri && m.get_bool(F_MSP_SORT_PRILIN) && l1 != l2)
{
TLinea_prod lp1(l1);
TLinea_prod lp2(l2);
cmp = lp2.priority() - lp1.priority();
}
// confronto tra blocchi ed eventuale swap direttamente qui nella compare
if (cmp == 0)
cmp = order_compare(blockr1, blockr2, level, ascending);
if (cmp > 0)
{
for (int bubble=first2; bubble <= last2; bubble++)
{
for (int r = bubble; r > bubble+first1-first2; r--)
s.swap_rows(r, r-1);
}
}
}
}
return 0;
}
int TRiga_articolo::compare_field(TString &str0, TString &str1,short field_no)
{
int cmp;
switch (field_no)
{
case F_CLIENTE:
{
const long f0 = atol(str0);
const long f1 = atol(str1);
cmp = f0 == f1 ? 0 : (f0 > f1 ? +1 : -1);
}
break;
case F_PRIORITA:
cmp = atoi(str0) - atoi(str1);
break;
default:
cmp = str0.compare(str1);
break;
}
return cmp;
}
TRiga_articolo& TRiga_articolo::operator=(TToken_string& r)
{
this->TToken_string::operator=(r);
return *this;
}
TRiga_articolo& TRiga_articolo::operator+=(TRiga_articolo& r)
{
NFCHECK( "Can't add incompatible order line");
return *this;
}
TRiga_articolo::TRiga_articolo(const TMSP_constraint& line)
: TToken_string(128)
{
format("%ld", line.codclifor());
add(line.articolo(),F_CLIENTE-FIRST_FIELD);
add(" ",F_PRIORITA-FIRST_FIELD);
const TString& liv = line.livgiac();
for (int l = 1; l <= 4; l++)
{
if (livelli_giacenza().enabled(l))
add(livelli_giacenza().unpack_grpcode(liv,l),F_LIV1+l-1-FIRST_FIELD);
else
add(" ",F_LIV1+l-1-FIRST_FIELD);
}
add(line.description(),F_DESCART-FIRST_FIELD);
add(line.codimp(),F_CODIMP-FIRST_FIELD);
add(line.codlin(),F_CODLIN-FIRST_FIELD);
TString8 str = line.codmagdep().left(3);
add(str,F_MAGAZZINO-FIRST_FIELD);
str = line.codmagdep().mid(3);
add(str, F_DEPOSITO-FIRST_FIELD);
const TCodice_um um;
const TQuantita qta_art(line.articolo(), um, ZERO);
add(qta_art.um(),F_UM-FIRST_FIELD);
TMSP_constraint& lin=(TMSP_constraint& )line;
const int last_buck= line.last();
for (int bu = 0; bu <= last_buck; bu ++)
{
add(lin.qta(bu).string(), bu*2+F_BUCKET0-FIRST_FIELD);
}
}
///////////////////////////////////////////////////////////
////////////////////
TMSP_record::TMSP_record() :
_curr_ref(-1), _qta_locked(FALSE), _qta_min(ZERO),_qta(ZERO),_price(ZERO)
{ }
TObject* TMSP_record::dup() const
{
TMSP_record* o=new TMSP_record();
o->_docrefs =_docrefs;
o->_qta_locked=_qta_locked;
o->_qta_min=_qta_min;
o->_qta=_qta;
o->_price=_price;
return o;
}
void TMSP_record::remove_rigaref()
{
CHECK(_curr_ref>0,"Nessun riferimento a riga documento da cancellare");
_docrefs.remove(_curr_ref-1);
if (_curr_ref>=_docrefs.items())
_curr_ref--;
}
void TMSP_record::add_rigaref(TMRP_docref *r)
{
_docrefs.add(r);
_curr_ref = _docrefs.items();
}
TMRP_docref *TMSP_record::first_rigaref()
{
_curr_ref=0;
return next_rigaref();
}
TMRP_docref* TMSP_record::next_rigaref()
{
if (_docrefs.items()<=_curr_ref)
return NULL;
return _docrefs.get_ref_ptr(_curr_ref++);
}
TMRP_docref* TMSP_record::rigaref(int n)
{
if (_docrefs.items()<=n)
return NULL;
return _docrefs.get_ref_ptr(_curr_ref=n);
}
///////////////////////////////////////////////////////////
TMSP_record& TMSP_record_array::operator[](int b)
{
CHECKD(b >= 0, "Invalid TMSP_record_array ", b);
TMSP_record* rec = (TMSP_record*)_buckets.objptr(b);
if (rec == NULL)
{
rec = new TMSP_record;
_buckets.add(rec, b);
}
return *rec;
}
TMSP_record_array& TMSP_record_array::operator=(const TMSP_record_array& a)
{
_buckets = a._buckets;
return *this;
}
///////////////////////////////////////////////////////////
TCapacity_record::TCapacity_record() :
_machine(ZERO), _human(ZERO),_money(ZERO), _pieces(ZERO)
{}
TCapacity_record::TCapacity_record(const real & machine, const real & human) :
_machine(machine), _human(human)
{}
TCapacity_record& TCapacity_record::operator= (const TCapacity_record&c)
{
_machine = c._machine;
_human = c._human;
_pieces = c._pieces;
_money = c._money;
return *this;
}
TCapacity_record::TCapacity_record(const TCapacity_record&c) :
_machine(c._machine), _human(c._human), _pieces(c._pieces),_money(c._money)
{
}
///////////////////////////////////////////////////////////
TCapacity_load::TCapacity_load () :
_capacity(), _load()
{ }
void TCapacity_load::copy(const TCapacity_load & q)
{
_capacity=q._capacity;
_load=q._load;
}
int TCapacity_load::compare(const TSortable& s) const
{
TCapacity_load& c=(TCapacity_load&)s;
real r=_capacity.machine()-c._capacity.machine();
return r.sign();
}
// calcola al volo la capacit<69>
const real &TCapacity_load::pieces_capacity()
{
if (capacity().pieces().is_zero())
{
const real &r = load().machine();
if (!r.is_zero())
_capacity.set_pieces(capacity().machine() / r * load().pieces());
else
_capacity.set_pieces(1.0);
}
return capacity().pieces();
}
///////////////////////////////////////
TCRP_line::TCRP_line(const TString& codimp,const TString& codlin,const TString& codart, long codcli)
: _lineap(codlin),_codart(codart), _codcli(codcli), _on_sheet(FALSE)
{
if (!codlin.blank())
{
const TRectype & rec = cache().get("LNP",_lineap);
_desc = rec.get("S0");
_imp = rec.get("S6");
}
else
{
_imp = codimp ;
if (!codimp.blank())
{
const TRectype & rec = cache().get("IMP",_imp);
_desc = rec.get("S0");
}
else
{
_desc = TR("Totale ditta");
}
}
if (!codart.blank())
{
const TRectype & rec = cache().get(LF_ANAMAG,_codart);
_desc = rec.get("DESCR");
}
}
int TCRP_line::compare(const TSortable& s) const
{
const TCRP_line& c = (const TCRP_line&)s;
int cmp = _imp.compare(c._imp);
if (cmp == 0)
cmp = _lineap.compare(c._lineap);
if (cmp == 0)
cmp = _codart.compare(c._codart);
return cmp;
}
// carica una riga di sheet con i dati dell'oggetto vincolo
void TCRP_line::fill_capacity_row(TToken_string& row, char load_type, bool percent)
{
row.add(codimp(),F_CODIMPCRP -FIRST_FIELD);
row.add(codlin(),F_CODLINCRP -FIRST_FIELD);
row.add(TR("Capacit<EFBFBD>"),F_CODARTCRP -FIRST_FIELD);
row.add(percent ? "%" : (load_type == '$' ? " $ " :( load_type == 'P' ? "Pz." : "ore")),F_LUM -FIRST_FIELD);
real r,l;
for (int bu = last(); bu > 0; bu = pred(bu))
{
switch (load_type)
{
case 'H': r = capacity(bu).human() ; break;
case 'M': r = capacity(bu).machine(); break;
case 'P': r = pieces_capacity(bu); break;
case '$': r = ZERO; break;
default: NFCHECK("Tipo di carico non riconosciuto");
}
if (!r.is_zero())
row.add(percent ? "100" : r.string(), bu + F_LBUCKET0 -FIRST_FIELD); // buckets
else
row.add("", bu + F_LBUCKET0 -FIRST_FIELD);
}
}
// carica una riga di sheet con i dati dell'oggetto vincolo
void TCRP_line::fill_load_row(TToken_string& row, char load_type, bool percent)
{
row.add(codimp(),F_CODIMPCRP -FIRST_FIELD);
row.add(codlin(),F_CODLINCRP -FIRST_FIELD);
if (codart().blank())
row.add(TR("Carico"),F_CODARTCRP -FIRST_FIELD);
else
row.add(codart(),F_CODARTCRP -FIRST_FIELD);
row.add(percent ? "%" : (load_type == '$' ? " $ " :( load_type == 'P' ? "Pz." : "ore")),F_LUM -FIRST_FIELD);
real c,l;
for (int bu = last(); bu > 0; bu = pred(bu))
{
switch (load_type)
{
case 'H':
c = capacity(bu).human() ;
l = load(bu).human() ;
break;
case 'M':
c = capacity(bu).machine() ;
l = load(bu).machine() ;
break;
case 'P':
c = pieces_capacity(bu);
l = load(bu).pieces() ;
break;
case '$':
c = capacity(bu).money();
l = load(bu).money() ;
break;
default:
NFCHECK("Tipo di carico non riconosciuto");
}
if (percent)
l = c.is_zero() ? ZERO : (100L * l / c);
row.add(l.string(), bu + F_LBUCKET0 -FIRST_FIELD); // buckets
}
}
TCapacity_load& TCRP_line::bucket(int n)
{
TCapacity_load *o;
o=(TCapacity_load *)_bucket.objptr(n);
if (o==NULL)
{
o=new TCapacity_load();
_bucket.add(o,n);
}
return *o;
}
///////////////////////////////////////////////////////////
// TCRP_lines ; carichi delle varie linee
///////////////////////////////////////////////////////////
TSortable* TCRP_lines::new_obj(const TToken_string& key) const
{
TString8 codimp, codlin;
TCodice_articolo codart;
key.get(3,codart);
long codcli = atoi(codart);
key.get(2,codart);
key.get(1,codlin);
key.get(0,codimp);
return new TCRP_line(codimp, codlin, codart, codcli);
}
TCRP_line* TCRP_lines::find(const TLinea_prod& linea_prod, const char * codart, long codcli, bool create)
{
TString8 codimp(linea_prod.codimp());
TString8 codlin(linea_prod.codice());
return find(codimp, codlin ,codart, codcli, create);
}
TCRP_line* TCRP_lines::find(const char * codimp, const char * codlin, const char * codart, long codcli, bool create)
{
_key.add(codimp,0);
_key.add(codlin,1);
TCRP_line * l = NULL;
if (create && codart && *codart)
{
l = (TCRP_line*)find_obj(_key);
CHECK(l,"Impossibile trovare la linea di Capacity review per un articolo");
}
_key.add(codart,2); // articolo
_key.add(format("%ld",codcli),3); // cliente
TCRP_line *s = (TCRP_line*)(create ? add_obj(_key) : find_obj(_key));
if (create && l)
for (int b = l->last(); b >=0; b--)
{
s->capacity(b).set_machine(l->capacity(b).machine());
s->capacity(b).set_human(l->capacity(b).human());
s->capacity(b).set_pieces(l->capacity(b).pieces());
}
return s;
}
///////////////////////////////////////////////////////////
// TMaster_code
///////////////////////////////////////////////////////////
TMaster_code::TMaster_code(const char *code, const char *liv,const char *ummaster, const real &expr, const real &leadtime, const char *codimp, const char *codlin, const char *codmag)
: _code(code), _liv (liv), _um(ummaster), _expr(expr), _leadtime(leadtime),
_codimp(codimp), _codlin(codlin), _codmag(codmag)
{
}
TMaster_code::TMaster_code(const char *code, const char *liv,const char *ummaster, const real &expr, int leadtime, const char *codimp, const char *codlin, const char *codmag)
: _code(code), _liv (liv), _um(ummaster), _expr(expr), _leadtime(format("%d",leadtime)),
_codimp(codimp), _codlin(codlin), _codmag(codmag)
{
}
///////////////////////////////////////////////////////////
// TMSP_line2
///////////////////////////////////////////////////////////
void TMSP_line2::add_mastercode (TMaster_code *mc)
{
_mastercodes.add(mc);
}
TMaster_code *TMSP_line2::get_mastercode (int i)
{
if (i>=0 && i < _mastercodes.items())
return (TMaster_code *) _mastercodes.objptr(i);
return NULL;
}
TMSP_line2::TMSP_line2(const TMSP_constraint &c)
{
_constraint = new TMSP_constraint(c);
*_constraint = c;
}
///////////////////////////////////////////////////////////
// TMSP_constraint
///////////////////////////////////////////////////////////
TString16 TMSP_constraint::_substr;
int TMSP_constraint::compare(const TSortable& s) const
{
const TMSP_constraint& c = (const TMSP_constraint&)s;
const long diff = _codclifor - c._codclifor;
int cmp = diff == 0L ? 0 : (diff > 0 ? +1 : -1);
if (cmp == 0)
{
cmp = _codart.compare(c._codart);
if (cmp == 0)
{
cmp = _livgiac.compare(c._livgiac);
if (cmp == 0)
{
cmp = _codimp.compare(c._codimp);
if (cmp == 0)
{
cmp = _codlin.compare(c._codlin);
if (cmp == 0)
cmp = _codmag.compare(c._codmag);
}
}
}
}
return cmp;
}
// carica una riga di sheet con i dati dell'oggetto vincolo
void TMSP_constraint::fill_sheet_row(TToken_string& row, const TMask & m, const char * descr, bool codes_only)
{
const TString& tipocf = m.get(F_TIPOCF);
row.add(m.get_bool(F_NOCLI_IN) ? "" : tipocf,F_TIPOCF_SHEET-FIRST_FIELD);
row.add(format("%ld", codclifor()),F_CLIENTE-FIRST_FIELD);
row.add(articolo(),F_ARTICOLO-FIRST_FIELD);
if (_priority != 0)
row.add(_priority, F_PRIORITA-FIRST_FIELD);
else
row.add(" ",F_PRIORITA-FIRST_FIELD);
const TString& liv = livgiac();
for (int l = 1; l <= 4; l++)
{
if (livelli_giacenza().enabled(l))
row.add(livelli_giacenza().unpack_grpcode(liv,l),F_LIV1+l-1-FIRST_FIELD);
else
row.add(" ",F_LIV1+l-1-FIRST_FIELD);
}
// row.add(description(),F_DESCART-FIRST_FIELD);
TString val(descr && *descr ? descr :description());
const TString80 da_rdoc_key(da_rdoc_key());
if (da_rdoc_key.full())
{
TDocumento d('D', atoi(da_rdoc_key.smid(4,4)), da_rdoc_key.sleft(4).trim(), atoi(da_rdoc_key.smid(9,7)));
TDate cons(d.get_date("DATAORIG"));
if (!cons.ok())
cons = d.get_date(DOC_DATACONS);
if (cons.ok())
val << ' ' << cons.string() << ' ';
val << '<EFBFBD>' << da_rdoc_key;
}
if ((descr == NULL || *descr == '\0') && __userflds != NULL && __userflds->full())
{
TString userdesc;
TString16 fldname;
TString16 codnum;
TString fldval;
const TRectype & anamag = cache().get(LF_ANAMAG, articolo());
TToken_string fld("", '#');
for (fld = __userflds->get(0); fld.full(); fld = __userflds->get())
{
fldname = fld.get(0);
codnum = fld.get();
if (codnum.blank())
fldval = anamag.get(fldname);
else
{
fldval.cut(0);
TRelation rel(LF_RIGHEDOC);
TRectype& curr = rel.curr();
curr.put(RDOC_DAPROVV, 'D');
curr.put(RDOC_DAANNO, da_rdoc_key.smid(4,4));
curr.put(RDOC_DACODNUM, da_rdoc_key.sleft(4));
curr.put(RDOC_DANDOC, da_rdoc_key.smid(9,7));
curr.put(RDOC_DAIDRIGA, da_rdoc_key.smid(16));
TRectype filter_fr(curr), filter_to(curr);
TCursor cur(&rel, "", 4, &filter_fr, &filter_to);
const int items = cur.items();
for (cur = 0L; cur.pos() < items; ++cur)
if (cur.curr().get(RDOC_CODNUM) == codnum)
{
fldval = cur.curr().get(fldname);
break;
}
}
if (fldval.full())
{
if (userdesc.full())
userdesc << __sep;
userdesc << fldval;
}
}
if (userdesc.full())
{
const int p0 = val.find(__sep);
int p1 = val.find(',');
if (p1 >= 0 && val[p1 + 1] != ' ')
p1 = -1;
userdesc << ", ";
if ((p0 >= 0) && (p1 > p0))
{
val = userdesc;
val << cache().get(LF_ANAMAG, articolo(), ANAMAG_DESCR);
if (da_rdoc_key.full())
val << '<EFBFBD>' << da_rdoc_key;
}
else
val.insert(userdesc);
}
}
row.add(val, F_DESCART-FIRST_FIELD);
row.add(codimp(),F_CODIMP-FIRST_FIELD);
row.add(codlin(),F_CODLIN-FIRST_FIELD);
//TString8 str = _codmag.left(3);
row.add(codmag(), F_MAGAZZINO-FIRST_FIELD);
row.add(coddep(),F_DEPOSITO-FIRST_FIELD);
row.add(codmag_coll(), F_MAG_COLL-FIRST_FIELD);
row.add(coddep_coll(),F_DEP_COLL-FIRST_FIELD);
const TCodice_um um;
const TQuantita qta_art(articolo(), um, ZERO);
row.add(qta_art.um(),F_UM-FIRST_FIELD);
if (codes_only)
return;
real needs=ZERO;
const int last_buck= last();
for (int bu = 0; bu <= last_buck; bu ++)
{
needs=qta(bu);
row.add(needs.string(), bu*2+F_BUCKET0-FIRST_FIELD);
needs=price(bu);
row.add(needs.string(), bu*2+F_BUCKET0+1-FIRST_FIELD);
}
row.add(mastercodes2check() ? MASTERCODE_CHAR : ' ',F_MASTERCODE-FIRST_FIELD);
// CHECK((_sheet_row == NULL) || (_sheet_row == &row), "TMSP_constraint splitted upon two rows");
if (_sheet_row == NULL)
_sheet_row = &row;
}
TMRP_docref* TMSP_constraint::first_rigaref(int buck)
{
TMSP_record& b = _bucket_qta[buck];
TMRP_docref* rdr=b.first_rigaref();
return rdr;
}
TMRP_docref* TMSP_constraint::next_rigaref(int buck)
{
TMSP_record& b = _bucket_qta[buck];
TMRP_docref* rdr=b.next_rigaref();
return rdr;
}
int TMSP_constraint::rigarefs(int buck)
{
return _bucket_qta[buck].rigarefs();
}
TMRP_docref * TMSP_constraint::rigaref(int buck, int n)
{
return _bucket_qta[buck].rigaref(n);
}
const char *TMSP_constraint::um()
{
TToken_string key=articolo();
key.add("1");
return cache().get(LF_UMART,key).get("UM");
}
TMRP_docref* TMSP_constraint::add_rigaref(int buck, TString& codnum, int annodoc, long ndoc, int nrig, const char * um, const real & qta, const real &prz)
{
TMSP_record& b = _bucket_qta[buck];
TMRP_docref *rdr= new TMRP_docref(annodoc, codnum, ndoc, nrig, um, qta,prz);
b.add_rigaref(rdr);
return rdr;
}
void TMSP_constraint::add_rigaref(int buck, TMRP_docref *rdr)
{
TMSP_record& b = _bucket_qta[buck];
b.add_rigaref(rdr);
}
void TMSP_constraint::remove_rigaref(int buck)
{
TMSP_record& b = _bucket_qta[buck];
b.remove_rigaref();
}
int TMSP_constraint::find_distinta_master(const TMSP_constraint & constr, TString & master,TString & livmaster,TString & um, real & expr, TString & imp,TString & lin,TString & magdep, int fromindex)
{
dist_tree().set_global("_LIVELLO",constr.livgiac());
dist_tree().set_global("_IMPIANTO",constr.codimp());
dist_tree().set_global("_LINEA",constr.codlin());
dist_tree().set_global("_MAGDEP",constr.codmagdep());
if (dist_tree().set_root(constr.articolo()))
{
TArray sons;
dist_tree().explode(sons, FALSE, RAGGR_EXP_NONE, 1, "AV");
TRiga_esplosione* riga;
while (riga=(TRiga_esplosione* )sons.objptr(fromindex))
{
if (distinta_master(riga->articolo(), TRUE))
{
master = riga->articolo();
livmaster = riga->livello();
um = riga->um();
expr = riga->val();
return fromindex;
}
fromindex=sons.succ(fromindex);
}
}
master.cut(0);
return -1;
}
bool TMSP_constraint::mastercodes2check() const
{
return _check_master;
}
void TMSP_constraint::set_mastercode_check(bool on)
{
_check_master=on;
}
TMSP_line2 *TMSP_constraint::use_mspline2(TToken_string & row)
{
TString16 liv;
TString8 mag,magc,imp,lin;
long codcli=row.get_long(F_CLIENTE-FIRST_FIELD);
livelli_giacenza().pack_grpcode(liv, row.get(F_LIV1-FIRST_FIELD),1);
livelli_giacenza().pack_grpcode(liv, row.get(F_LIV2-FIRST_FIELD),2);
livelli_giacenza().pack_grpcode(liv, row.get(F_LIV3-FIRST_FIELD),3);
livelli_giacenza().pack_grpcode(liv, row.get(F_LIV4-FIRST_FIELD),4);
imp=row.get(F_CODIMP-FIRST_FIELD);
lin=row.get(F_CODLIN-FIRST_FIELD);
add_magcode(mag, row.get(F_MAGAZZINO-FIRST_FIELD));
add_depcode(mag, row.get(F_DEPOSITO-FIRST_FIELD));
add_magcode(magc, row.get(F_MAG_COLL-FIRST_FIELD));
add_depcode(magc, row.get(F_DEP_COLL-FIRST_FIELD));
codcli=row.get_long(F_CLIENTE-FIRST_FIELD);
TMSP_line mspline(codcli, articolo(), liv, imp, lin, mag, magc, da_rdoc_key());
for (int b= 0 ; b< LAST_BUCKET ; b++)
{
real q(row.get(F_BUCKET0+b*2-FIRST_FIELD));
mspline.qta(b) = q;
}
return use_mspline2(mspline);
}
TMSP_line2 *TMSP_constraint::use_mspline2(TMSP_constraint &line)
{
TMSP_line2 *a=NULL;
if (_lines2)
{
for (int i=_lines2->items()-1; i>=0 && a==NULL; i--)
{
a=(TMSP_line2 *) _lines2->objptr(i);
if (a->constraint() != line)
a=NULL;
}
}
if (a == NULL)
{
TString master;
TString4 ummaster;
TString16 livmaster;
TString8 impmaster(codimp()), linmaster(codlin()),magmaster(codmagdep());
real expr;
int dm=0;
while ((dm=find_distinta_master(line, master, livmaster, ummaster, expr, impmaster, linmaster, magmaster,dm)+1) >0)
{
if (a == NULL)
{
a = new TMSP_line2(line);
if (!_lines2) _lines2 = new TArray();
_lines2->add(a);
}
a->add_mastercode(new TMaster_code (master, livmaster, ummaster, expr, cache().get(LF_ANAMAG,master).get_real(ANAMAG_GIORNIRIOR), codimp(), codlin(), codmagdep()));
}
}
if (a)
{
a->set_use(TRUE);
a->constraint() = line;
}
return a;
}
void TMSP_constraint::reset_unused_line2()
{
if (_lines2)
{
TMSP_line2 *a;
for (int i=_lines2->items()-1; i>=0; i--)
{
a=(TMSP_line2 *) _lines2->objptr(i);
a->set_use(FALSE);
}
}
}
TMSP_line2 * TMSP_constraint::get_unused_line2()
{
if (_lines2)
{
TMSP_line2 *a;
for (int i=_lines2->items()-1; i>=0; i--)
{
a=(TMSP_line2 *) _lines2->objptr(i);
if (!a->used())
return a;
}
}
return NULL;
}
void TMSP_constraint::discard_line2(TMSP_line2 * l)
{
if (_lines2)
{
TMSP_line2 *a;
int i=_lines2->items();
while (--i>=0)
{
a=(TMSP_line2 *) _lines2->objptr(i);
if (a==l)
{
_lines2->destroy(i,TRUE);
break;
}
}
}
}
// cerca ed eventualmente aggiunge la linea di articolo non-Master nell'elenco
// degli articoli "upper", ovvero vincolanti per questo articolo Master
TMSP_constraint * TMSP_constraint::add_upperline(const TMSP_constraint& mc)
{
TMSP_constraint * upl;
if (_upperlines == NULL)
_upperlines = new TMSP_constraints();
if (_upperlines->items()==0)
{
// aggiunge se stesso
upl=_upperlines->find(codclifor(), articolo(), livgiac(),
codimp(),codlin(),codmagdep(), da_rdoc_key(), true);
*upl=*this;
}
return _upperlines->find(mc.codclifor(), mc.articolo(), mc.livgiac(),
mc.codimp(),mc.codlin(),mc.codmagdep(), mc.da_rdoc_key(), true);
}
TMSP_constraint* TMSP_constraint::get_upperline(TMSP_constraint& mc)
{
if (_upperlines)
return _upperlines->find(mc.codclifor(), mc.articolo(), mc.livgiac(),
mc.codimp(),mc.codlin(),mc.codmagdep(), mc.da_rdoc_key(), false);
else
return NULL;
}
TMSP_constraint & TMSP_constraint::operator=(const TMSP_constraint & line)
{
_codclifor=line.codclifor();
_codart=line.articolo();
_livgiac=line.livgiac();
_codimp=line.codimp();
_codlin=line.codlin();
_codmag=line.codmagdep();
_codmag_coll=line.codmagdep_coll();
_da_rdoc_key=line.da_rdoc_key();
_on_sheet=_on_sheet;
_descr=line.description();
_bucket_qta=line._bucket_qta;
return *this;
}
TToken_string * TMSP_constraint::__userflds = NULL;
char TMSP_constraint::__sep = ';';
void TMSP_constraint::init()
{
if (__userflds == NULL)
{
TConfig c(CONFIG_DITTA, "mr");
__userflds = new TToken_string(c.get("USERFLDS"));
if (c.exist("FLDSEP"))
__sep = c.get_char("FLDSEP");
}
}
TMSP_constraint::TMSP_constraint(long cliente,
const TCodice_articolo& codart,
const TString& giac,
const TString& imp,
const TString& lin,
const TString& mag,
const TString& magc,
const TString& da_rdoc_key)
: _codclifor(cliente), _codart(codart), _livgiac(giac),
_codimp(imp), _codlin(lin), _codmag(mag), _codmag_coll(magc), _da_rdoc_key(da_rdoc_key),_on_sheet(false),_check_master(false),
_upperlines(NULL), _lines2(NULL), _priority(0), _sheet_row(NULL)
{
init();
}
TMSP_constraint::TMSP_constraint(const TMSP_constraint & line)
: _codclifor(line.codclifor()), _codart(line.articolo()), _livgiac(line.livgiac()),
_codimp(line.codimp()), _codlin(line.codlin()), _codmag(line.codmagdep()), _codmag_coll(line.codmagdep_coll()), _da_rdoc_key(line.da_rdoc_key()),
_descr(line.description()), _on_sheet(false), _check_master(false), _upperlines(NULL), _lines2(NULL),
_priority(0), _sheet_row(NULL)
{
init();
}
TMSP_constraint::~TMSP_constraint()
{
if (_lines2) delete _lines2;
if (_upperlines) delete _upperlines;
}
///////////////////////////////////////////////////////////
// TMSP_constraints
///////////////////////////////////////////////////////////
TSortable* TMSP_constraints::new_obj(const TToken_string& key) const
{
long cli; key.get(0, cli);
TCodice_articolo art; key.get(1, art); art.trim();
TString80 gia; key.get(2, gia); gia.trim();
TString8 imp; key.get(3, imp); imp.trim();
TString8 lin; key.get(4, lin); lin.trim();
TString8 mag; key.get(5, mag); mag.trim();
TString8 magc; key.get(6, magc); magc.trim();
TString80 rdoc_key; key.get(7, rdoc_key); rdoc_key.trim();
return new TMSP_constraint(cli, art, gia, imp, lin, mag, magc, rdoc_key);
}
TMSP_constraint* TMSP_constraints::find(long cliente,
const TString& art,
const TString& gia,
const TString& imp,
const TString& lin,
const TString& mag,
const TString& magc,
const TString& da_rdoc_key,
bool create)
{
_key.format("%ld", cliente);
_key.add(art);_key.trim();
_key.add(gia);_key.trim();
_key.add(imp);_key.trim();
_key.add(lin);_key.trim();
_key.add(mag);_key.trim();
_key.add(magc);_key.strip_spaces();
_key.add(da_rdoc_key);_key.trim();
TSortable* s = create ? add_obj(_key) : find_obj(_key);
TMSP_constraint* c = (TMSP_constraint*)(create ? add_obj(_key) : find_obj(_key));
if (create)
{
if (c->description().blank())
c->set_description(cache().get(LF_ANAMAG, art, ANAMAG_DESCR));
}
return c;
}
TMSP_constraint* TMSP_constraints::find(const TToken_string& row, bool create)
{
TString80 giaclev;
TString str;
_key.cut(0);
for (int i = 0; i <= 11; i++)
{
row.get(i, str);
str.trim();
switch (i+FIRST_FIELD)
{
case F_LIV1:
case F_LIV2:
case F_LIV3:
livelli_giacenza().pack_grpcode(giaclev, str, i+FIRST_FIELD-F_LIV1+1);
break;
case F_LIV4:
livelli_giacenza().pack_grpcode(giaclev, str, 4);
_key.add(giaclev);
break; // Concatena i livelli
case F_MAGAZZINO:
// case F_MAG_COLL:
_key.add(str);
row.get(i+1, str);
_key << str;
break; // Concatena magazzini e depositi
case F_CLIENTE:
if (str.blank())
str = "0";
case F_ARTICOLO:
case F_CODIMP:
case F_CODLIN:
_key.add(str);
break; // Aggiungi normalmente
default:
break;
}
_key.trim();
}
row.get(F_MAG_COLL-FIRST_FIELD, str);
_key.add(str);
row.get(F_DEP_COLL-FIRST_FIELD, str);
_key << str;
_key.strip_spaces();
row.get(F_DESCART-FIRST_FIELD, str);
const int pos = str.find('<EFBFBD>');
if (pos >= 0)
_key.add(str.mid(pos +1));
else
_key.add("");
TMSP_constraint* c = (TMSP_constraint*)(create ? add_obj(_key) : find_obj(_key));
if (create)
{
if (c->description().blank())
{
row.get(F_ARTICOLO, str);
c->set_description(cache().get(LF_ANAMAG,str, ANAMAG_DESCR));
}
}
return c;
}
//////////////////////////////////////////////////////////
// TMSP_line
///////////////////////////////////////////////////////////
void TMSP_line::fill_sheet_row(TToken_string& row, const TMask & m, const char * desc, bool codes_only)
{
TMSP_constraint::fill_sheet_row(row, m, desc, codes_only);
row.add(m.get(F_TIPOCF),F_TIPOCF_SHEET-FIRST_FIELD);
}
TMSP_line::TMSP_line(long cliente, const TCodice_articolo& codart,
const TString& giac, const TString& imp,
const TString& lin, const TString& mag, const TString& magc, const TString& rdoc_key)
: TMSP_constraint(cliente, codart, giac, imp, lin, mag, magc, rdoc_key)
{ }
TMSP_line::TMSP_line(TMSP_constraint & cons)
:TMSP_constraint(cons)
{ }
TMSP_line::TMSP_line(TMSP_line & line)
:TMSP_constraint((TMSP_constraint &)line)
{
}
///////////////////////////////////////////////////////////
// TMSP_lines
///////////////////////////////////////////////////////////
TSortable* TMSP_lines::new_obj(const TToken_string& key) const
{
long cliente; key.get(0, cliente);
TCodice_articolo art; key.get(1, art); art.trim();
TString80 gia; key.get(2, gia); gia.trim();
TString8 imp; key.get(3, imp); imp.trim();
TString8 lin; key.get(4, lin); lin.trim();
TString8 mag; key.get(5, mag); mag.trim();
TString8 magc; key.get(6, magc); magc.trim();
TString80 rdoc_key; key.get(7, rdoc_key); rdoc_key.trim();
return new TMSP_line(cliente, art, gia, imp, lin, mag, magc, rdoc_key);
}
TMSP_line* TMSP_lines::find(long cliente, const TString& art,
const TString& gia, const TString& imp, const TString& lin,
const TString& mag, const TString& magc, const TString & rdoc_key, bool create)
{
_key.format("%ld", cliente);
_key.add(art);
_key.add(gia);
_key.add(imp);
_key.add(lin);
_key.add(mag);
_key.add(magc);
_key.add(rdoc_key);
TSortable * s = create ? add_obj(_key) : find_obj(_key);
return (TMSP_line*)s;
}
TMSP_line* TMSP_lines::find(const TToken_string& row, bool create)
{
if (row.items() > 14) // Riga di sheet (NON semplice chiave)
{
for (long i = 0; i < items(); i++)
{
TMSP_line& tmp = (TMSP_line&)find_obj(i);
if (tmp.sheet_row_ptr() == &row)
return &tmp;
}
}
TString str;
TString80 giaclev;
_key.cut(0);
for (int i = 0; i <= 13; i++)
{
row.get(i, str);
str.trim();
switch (i+FIRST_FIELD)
{
case F_LIV1:
case F_LIV2:
case F_LIV3:
livelli_giacenza().pack_grpcode(giaclev, str, i+FIRST_FIELD-F_LIV1+1);
break;
case F_LIV4:
livelli_giacenza().pack_grpcode(giaclev, str, 4);
giaclev.trim();
_key.add(giaclev);
break; // Concatena i livelli
case F_MAGAZZINO:
case F_MAG_COLL:
_key.add(str);
row.get(i+1, str);
str.trim();
_key << str;
break; // Concatena magazzini e depositi
case F_DEPOSITO:
case F_DEP_COLL:
break; // Ignora (vedi sopra)
case F_CLIENTE:
if (str.blank()) str = "0";
case F_ARTICOLO:
case F_CODIMP:
case F_CODLIN:
_key.add(str); break; // Aggiungi normalmente
default:
break;
}
}
row.get(F_DESCART-FIRST_FIELD, str);
const int pos = str.find('<EFBFBD>');
if (pos >= 0)
_key.add(str.mid(pos +1));
else
_key.add("");
TMSP_line* s = (TMSP_line*)(create ? add_obj(_key) : find_obj(_key));
return s;
}
///////////////////////////////////////////////////////////
// TPlan_docs
///////////////////////////////////////////////////////////
TSortable* TPlan_docs::new_obj(const TToken_string& key) const
{
TString8 codnum; key.get(0, codnum);
int anno; key.get(1, anno);
long num; key.get(2, num);
TDocumento* doc = new TDocumento('D', anno, codnum, num);
doc->head().put(DOC_TIPODOC, _doc);
doc->head().put(DOC_CAUSMAG, doc->tipo().caus_mov());
return doc;
}
TDocumento& TPlan_docs::find(const TMRP_docref* rdr)
{
if (rdr)
_key.format("%s|%d|%ld",(const char *)rdr->codnumdoc(), rdr->annodoc(), rdr->numdoc());
else
_key = " |0|0";
return *(TDocumento*)add_obj(_key);
}
TRiga_documento* TPlan_docs::find_row(const TMRP_docref* rdr)
{
TRiga_documento* rdoc = NULL;
if (rdr != NULL)
{
const int riga = rdr->numrig();
if (riga > 0)
{
TDocumento& doc = find(rdr);
if (riga > 0 && riga <= doc.physical_rows())
rdoc = &doc[riga];
}
}
return rdoc;
}
TRiga_documento& TPlan_docs::add_to_row(TMRP_docref* rdr, const real& qta)
{
CHECK(rdr,"TPlan_docs::add_to_row :passare un rigaref fvalido");
TDocumento& doc = find(rdr);
int riga = rdr->numrig();
if (riga <= 0 || riga > doc.physical_rows())
{
TRiga_documento& r = doc.new_row(_rig);
riga = r.get_int(RDOC_NRIGA);
rdr->set_numrig(riga);
}
TRiga_documento& rdoc = doc[riga];
real val = rdoc.get(RDOC_QTA);
val += qta;
if (val <= ZERO)
val = ZERO;
rdoc.put(RDOC_QTA, val);
rdr->set_qta_residua(val);
return rdoc;
}
long TPlan_docs::flush(const TDate& data, const char * codart)
{
const long tot = items();
long retv=tot;
if (tot > 0L)
{
TString msg;
msg << TR("Registrazione dei documenti di planning");
if (codart)
msg << TR(" articolo ") << codart;
if (data.ok())
msg << TR(" per il ") << data;
TProgind *pi = NULL;
if (tot > 1)
pi = new TProgind(tot, msg, false, true);
TLocalisamfile lfdoc(LF_DOC);
for (long d = 0; d < tot; d++)
{
if (pi) pi->addstatus(1);
TDocumento& doc = (TDocumento&)find_obj(d);
lfdoc.curr() = doc.head();
int err = lfdoc.read(_isequal, _lock);
if (err == _iseof || err == _iskeynotfound || err == NOERR)
{
for (int r = doc.physical_rows(); r > 0; r--)
{
const TRiga_documento& riga = doc[r];
// if (riga.is_articolo() && riga.quantita().is_zero())
if (riga.quantita().is_zero())
doc.destroy_row(r, TRUE);
}
if (doc.physical_rows())
{
if (err == NOERR)
err = doc.rewrite(lfdoc);
else
err = doc.write(lfdoc) ;
}
else
err = doc.remove(lfdoc);
}
if (err != NOERR)
{
error_box(FR("Impossibile riscrivere il documento del %d %s %ld"),(int)doc.anno(), (const char *)doc.numerazione(),(long)doc.numero());
retv=-1;
}
}
if (pi)
delete pi;
destroy();
}
return retv;
}
TPlan_docs::TPlan_docs(const char* num, const char* tip, const char* rig)
: _num(num), _doc(tip), _rig(rig)
{
}
bool distinta_master(const char *code, bool is_son)
{
const TRectype &rec=cache().get(LF_DIST,code);
if (rec.empty())
return !is_son;
return rec.get_bool("MASTER");
}
///////////////////////////////////////////////////////////
// Sheet ordini / commessse
///////////////////////////////////////////////////////////
void TLista_dettagli::set_bucket(int b)
{
_curr_bucket=b;
reset_parked();
}
bool TLista_dettagli::reset_bucket_field()
{
int b = 0;
while (b <= LAST_BUCKET && get_items(b)==0)
b++;
TMask_field & f=field(FIRST_FIELD);
f.set(format("%d",b <= LAST_BUCKET ? b : 0));
bucket_handler(f, K_SPACE);
return b <= LAST_BUCKET;
}
bool TLista_dettagli::bucket_handler(TMask_field & f, KEY key)
{
if (key == K_SPACE)
{
TLista_dettagli &m = (TLista_dettagli &)f.mask();
const int buck=atoi(f.get());
if (m.curr_bucket() != buck)
{
m.set_bucket(buck);
int week1=0,week2=0, year1=0, year2=0;
TDate d;
if (buck>0)
{
d = m._from;
d += (buck - 1) * m._bucksize;
if (m._bucksize == 31) // mese solare
d.set_day(1);
TPlanning_mask::get_week_year(d, week1, year1);
}
m.set(FIRST_FIELD+1, d.string());
if (buck == LAST_BUCKET)
d = NULLDATE;
else
{
d = m._from;
d += (buck - 1) * m._bucksize;
if (m._bucksize == 31) // mese solare
d.set_end_month();
else
d += m._bucksize-1;
TPlanning_mask::get_week_year(d, week2, year2);
}
m.set(FIRST_FIELD+2, d.string());
TString ws;
if (week1)
{
ws << (week2 ? "" : ">=");
ws << week1;
if (year1 != year2)
ws << "/" << year1;
} else
ws << "<=";
if (week2)
{
if (week1 != week2 || year1 != year2)
{
if (week1)
ws << "-";
ws << week2;
}
ws << "/" << year2;
}
m.set(FIRST_FIELD+3, format("%s",(const char *)ws));
m.select(0);
m.force_update();
}
}
return TRUE;
}
void TLista_dettagli::init(const char * title, const TDate& fromdate, int bucketsize)
{
_curr_bucket = -1;
_from = fromdate;
_bucksize = bucketsize;
TMask_field &f= add_list(FIRST_FIELD,0,"Bucket ",1,0,2,"","0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30","0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30");
f.set_handler(bucket_handler);
add_date(FIRST_FIELD+1,0,TR("Dal "),16,0,"D");
add_date(FIRST_FIELD+2,0,TR("al "),33,0,"D");
add_string(FIRST_FIELD+3,0,TR("Settimana "),49,0,15,"D");
}
TLista_dettagli::TLista_dettagli(const char * title, const TDate& fromdate, int bucketsize, const char * head) :
TSheet(-1, 5, 80, 15, title, head,0,2)
{
init(title, fromdate, bucketsize);
}
void TLista_docref::get_row(long r, TToken_string& row)
{
row.cut(0);
if (r < _line->rigarefs(curr_bucket()))
{
TMRP_docref * rdr=_line->rigaref(curr_bucket(),(int)r);
if (rdr)
{
const TRectype& doc = rdr->get_doc();
const TRectype& rdoc = rdr->get_rdoc();
row.add(" ");
row.add(rdr->annodoc());
row.add(rdr->codnumdoc());
row.add(rdr->numdoc());
row.add(rdr->numrig());
const TDate dc(rdoc.get(RDOC_DATACONS));
row.add(dc.ok() ? dc : doc.get_date(RDOC_DATACONS));
row.add(rdoc.get(RDOC_UMQTA));
real q(rdoc.get_real(RDOC_QTA));
row.add(q.string("#######@,@@@"));
q -= rdoc.get_real(RDOC_QTAEVASA);
row.add(q.string("#######@,@@@"));
//const char statodef=cache().get("%TIP",doc.get(DOC_TIPODOC)).get("S2")[1];
row.add(doc.get(DOC_STATO));
row.add(rdoc.get(RDOC_DAANNO));
row.add(rdoc.get(RDOC_DACODNUM));
row.add(rdoc.get(RDOC_DANDOC));
enable_row(r);
}
}
else
{
row = "|||||||";
row.add(_line->qta(curr_bucket()).string("#######@,@@@"));
disable_row(r);
}
}
bool TLista_docref::edit_checked()
{
for (long r=0; r < items()-1; r++) if (checked(r))
{
TFilename ininame;
ininame.temp();
ininame.ext("ini");
{
TConfig action(ininame);
action.set("Action","MODIFY","Transaction");
action.set_paragraph(format("%d",LF_DOC));
TToken_string & rw = row(r);
action.set("PROVV","D");
action.set("ANNO",rw.get(1));
action.set("CODNUM",rw.get(2));
action.set("NDOC",rw.get(3));
}
TExternal_app editdoc(format("VE0 -1 -i%s",(const char *)ininame));
editdoc.run();
remove(ininame);
// aggiungere qui il feedback sulla rigaref; per ora c'e' un brutale
/*
TConfig action(ininame);
TMRP_docref * rdr=_line->rigaref(_curr_bucket,(int)r);
*/
}
return TRUE;
}
long TLista_docref::get_items(int b) const
{
if (b >= 0 && _line->rigarefs(b))
return _line->rigarefs(b)+1;
return 0L;
}
TLista_docref::TLista_docref(TMSP_constraint * l, const char * title, TDate fromdate, int bucketsize)
: TLista_dettagli(title, fromdate, bucketsize,
"@1|Anno|CodNum|Numero|Riga|Consegna@10|UM|Q.ta totale@12|Q.ta residua@12|Stato|Da Anno|Da CodNum|Da NDoc"),
_line (l)
{
_r= new TRelation(LF_RIGHEDOC);
_r->add(LF_DOC,"PROVV==PROVV|CODNUM==CODNUM|ANNO==ANNO|NDOC==NDOC");
enable_check();
reset_bucket_field();
// PRESET bucket
}
TLista_docref ::~TLista_docref ()
{
if (_r) delete _r;
}
const char *TLista_mastercodes::header()
{
static TToken_string h;
h = HR("@1|Articolo@20");
for (int l = 1; l <= livelli_giacenza().last_level() ; l++)
h << "|" << livelli_giacenza().name(l) << "@" << livelli_giacenza().code_length(l) ;
h.add(TR("Impianto"));
h.add(HR("Linea|Cod.Mag.|UM|Quantita'@12|Consegna"));
return h;
}
TLista_mastercodes::TLista_mastercodes(TMSP_constraint *c, TToken_string &l, TDate fromdate, int bucketsize):
TLista_dettagli(TR("Articoli Master interessati"), fromdate, bucketsize, header())
{
_line_art = c->use_mspline2(l);
}
void TLista_mastercodes::get_row(long r, TToken_string& row)
{
TMaster_code *mc;
if (mc = _line_art->get_mastercode(int(r)))
{
row = " ";
row.add(mc->articolo());
for (int l = 1; l <= livelli_giacenza().last_level() ; l++)
row.add(livelli_giacenza().unpack_grpcode(mc->livello(),l));
row.add(mc->codimp());
row.add(mc->codlin());
row.add(mc->codmagdep());
row.add(mc->um());
real e = mc->expr();
e *= _line_art->constraint().qta(curr_bucket());
row.add(e.string("#######@,@@@"));
TDate d = get_date(FIRST_FIELD+2);
d -= long(mc->leadtime().integer());
row.add(d.string());
}
}
long TLista_mastercodes::get_items(int b) const
{
if (_line_art)
if (b >= 0 && b < LAST_BUCKET && !_line_art->constraint().qta(b).is_zero())
return _line_art->mastercodes();
return 0L;
}
const char *TLista_upperlines::header()
{
static TToken_string h;
h = HR("@1|Articolo@20");
for (int l = 1; l <= livelli_giacenza().last_level() ; l++)
h << "|" << livelli_giacenza().name(l) << "@" << livelli_giacenza().code_length(l) ;
h.add(HR("Impianto|Linea|Mag.|Dep.|UM|Quantita'@12"));
return h;
}
TLista_upperlines::TLista_upperlines(TMSP_constraint *l, TDate fromdate, int bucketsize):
TLista_dettagli(TR("Vincoli da articoli non Master"), fromdate, bucketsize,header())
{
_line = l;
}
void TLista_upperlines::get_row(long r, TToken_string& row)
{
TMSP_constraint& c = (*_line->upperlines())[r+1];
row = " ";
row.add(c.articolo());
for (int l = 1; l <= livelli_giacenza().last_level() ; l++)
row.add(livelli_giacenza().unpack_grpcode(c.livgiac(),l));
row.add(c.codimp());
row.add(c.codlin());
row.add(c.codmag());
row.add(c.coddep());
row.add(c.um());
row.add(c.qta(curr_bucket()).string("#######@,@@@"));
}
long TLista_upperlines::get_items(int b) const
{
if (_line->upperlines())
if (b >= 0 && !_line->qta(b).is_zero())
return _line->upperlines_items()-1;
return 0L;
}