1 /***************************************************************************
2 floskeltemplate.cpp -
3 -------------------
4 begin : Don Jan 1 2004
5 copyright : (C) 2004 by Klaas Freitag
6 email : freitag@kde.org
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include <QString>
19 #include <QObject>
20 #include <QDebug>
21
22 #include "kraftdb.h"
23 #include "templatesaverbase.h"
24 #include "templatesaverdb.h"
25 #include "floskeltemplate.h"
26 #include "unitmanager.h"
27 #include "calcpart.h"
28 #include "materialcalcpart.h"
29 #include "fixcalcpart.h"
30 #include "timecalcpart.h"
31 #include "stockmaterial.h"
32
33
FloskelTemplate()34 FloskelTemplate::FloskelTemplate()
35 : CatalogTemplate(),
36 mTemplId(-1),
37 m_chapter(0),
38 mTimeAdd(true),
39 m_listViewItem(0),
40 m_saver(0)
41 {
42 m_calcType = Calculation;
43 }
44
FloskelTemplate(int tID,const QString & text,int einheit,int chapter,int calcKind)45 FloskelTemplate::FloskelTemplate( int tID, const QString& text,
46 int einheit, int chapter, int calcKind )
47 : CatalogTemplate(),
48 mTemplId(tID),
49 m_chapter(chapter),
50 mTimeAdd(true),
51 m_preis(long(0)),
52 m_listViewItem(0),
53 m_saver(0)
54 {
55 if( calcKind == 1 ) {
56 setCalculationType( ManualPrice );
57 } else if( calcKind == 2 ) {
58 setCalculationType( Calculation );
59 } else if ( calcKind == 3 ) {
60 setCalculationType( AutoCalc );
61 }
62
63 setText( text );
64 this->setUnitId(einheit);
65 setChapterId( dbID(chapter), false );
66 }
67
FloskelTemplate(FloskelTemplate & templ)68 FloskelTemplate::FloskelTemplate( FloskelTemplate& templ )
69 : CatalogTemplate( templ ),
70 mTemplId( templ.mTemplId ),
71 m_preis( templ.m_preis ),
72 m_listViewItem(templ.m_listViewItem ),
73 m_saver( 0 )
74 {
75 deepCopyCalcParts( templ );
76 setModifyDate( templ.modifyDate() );
77 setEnterDate( templ.enterDate() );
78 setText( templ.getText() );
79 setUnitId(templ.unit().id());
80 // m_calcParts.setAutoDelete(true);
81 }
82
operator =(FloskelTemplate & src)83 FloskelTemplate& FloskelTemplate::operator= ( FloskelTemplate& src )
84 {
85 if ( this == &src ) return *this;
86
87 mText = src.mText;
88 setUnitId(src.unit().id());
89 mTemplId = src.mTemplId;
90 mChapterId = src.mChapterId;
91 m_preis = src.m_preis;
92 m_listViewItem = src.m_listViewItem;
93 m_saver = 0; // src.m_saver;
94
95 deepCopyCalcParts( src );
96
97 return *this;
98 }
99
~FloskelTemplate()100 FloskelTemplate::~FloskelTemplate()
101 {
102 delete m_saver;
103 }
104
deepCopyCalcParts(FloskelTemplate & templ)105 void FloskelTemplate::deepCopyCalcParts( FloskelTemplate& templ )
106 {
107 CalcPart *cp = 0;
108
109 m_calcParts.clear();
110
111 QListIterator<CalcPart*> i( templ.m_calcParts );
112 while( i.hasNext()) {
113 cp = i.next();
114 CalcPart *ncp = 0;
115
116 if( cp->getType() == KALKPART_TIME ) {
117 ncp = new TimeCalcPart( *( static_cast<TimeCalcPart*>(cp) ) );
118 } else if( cp->getType() == KALKPART_FIX ) {
119 ncp = new FixCalcPart( *( static_cast<FixCalcPart*>(cp) ) );
120 } else if( cp->getType() == KALKPART_MATERIAL ) {
121 ncp = new MaterialCalcPart( *( static_cast<MaterialCalcPart*>(cp) ) );
122 } else {
123 // qDebug () << "ERROR: Unknown Calculation-Type!" << endl;
124 }
125 m_calcParts.append( ncp );
126 }
127 }
128
setBenefit(double g)129 void FloskelTemplate::setBenefit( double g )
130 {
131 /* Every calc part has an value for benefit. Set the benefit value for
132 each calc part, later on each can have its own value
133 */
134 for( auto *cp: m_calcParts) {
135 cp->setProzentPlus(g);
136 }
137 }
138
getBenefit()139 double FloskelTemplate::getBenefit( )
140 {
141 bool first = true;
142 double b = 0.0;
143
144 for( auto *cp: m_calcParts) {
145 if( first ) {
146 b = cp->getProzentPlus();
147 first = false;
148 }
149 // all benefits are the same atm, thus this ASSERT.
150 Q_ASSERT( fabs(b - cp->getProzentPlus()) < std::numeric_limits<double>::epsilon());
151 }
152 return b;
153 }
154
setTemplID(int newID)155 void FloskelTemplate::setTemplID( int newID )
156 {
157 mTemplId = newID;
158 }
159
unitPrice()160 Geld FloskelTemplate::unitPrice()
161 {
162 return calcPreis();
163 }
164
165
calcPreis()166 Geld FloskelTemplate::calcPreis()
167 {
168 Geld g;
169
170 if( calcKind() == ManualPrice ) {
171 g = m_preis;
172 } else {
173 g = m_calcParts.calcPrice();
174 double b = getBenefit();
175 g += g.percent(b);
176 }
177 return g;
178 }
179
getCalcPartsList()180 CalcPartList FloskelTemplate::getCalcPartsList()
181 {
182 return getCalcPartsList(ALL_KALKPARTS);
183 }
184
185 // Returns a calcpartlist where all calcparts have lost their connection
186 // to the database from the dbID POV. That's needed for the transition
187 // from template -> document calculations.
decoupledCalcPartsList()188 CalcPartList FloskelTemplate::decoupledCalcPartsList()
189 {
190 return m_calcParts.decoupledCalcPartsList();
191 }
192
getCalcPartsList(const QString & calcPart)193 CalcPartList FloskelTemplate::getCalcPartsList( const QString& calcPart )
194 {
195 return m_calcParts.getCalcPartsList( calcPart );
196 }
197
addCalcPart(CalcPart * cpart)198 void FloskelTemplate::addCalcPart( CalcPart* cpart )
199 {
200 m_calcParts.append(cpart);
201 }
202
removeCalcPart(CalcPart * cpart)203 void FloskelTemplate::removeCalcPart( CalcPart *cpart )
204 {
205 if( cpart) {
206 cpart->setToDelete(true);
207 cpart->setDirty(true);
208
209 }
210 }
211
clearCalcParts()212 void FloskelTemplate::clearCalcParts()
213 {
214 for(int i=0; i<m_calcParts.count(); ++i)
215 {
216 delete m_calcParts[i];
217 }
218
219 m_calcParts.clear();
220 }
221
costsByCalcPart(const QString & part)222 Geld FloskelTemplate::costsByCalcPart( const QString& part )
223 {
224 return m_calcParts.costPerCalcPart( part );
225 }
226
getSaver()227 TemplateSaverBase* FloskelTemplate::getSaver()
228 {
229 if( ! m_saver )
230 {
231 m_saver = new TemplateSaverDB();
232 }
233 return m_saver;
234 }
235
save()236 bool FloskelTemplate::save()
237 {
238 TemplateSaverBase *saver = getSaver();
239 // qDebug () << "Saver is " << saver << endl;
240 if( saver ) {
241 return saver->saveTemplate( this );
242 } else {
243 // qDebug () << "ERR: No saver available!" << endl;
244 return false;
245 }
246 }
247
saveChapterId()248 void FloskelTemplate::saveChapterId()
249 {
250 TemplateSaverBase *saver = getSaver();
251 if( saver ) {
252 saver->saveTemplateChapter( this );
253 }
254 }
255
256 #if 0
257 QDomElement FloskelTemplate::toXML( QDomDocument& doc)
258 {
259 QDomElement templ = doc.createElement("template");
260
261 templ.appendChild( createDomNode(doc, "unit", getUnit().einheitSingular()));
262 templ.appendChild( createDomNode(doc, "text", getText()));
263 templ.appendChild( createDomNode(doc, "id", QString::number(getTemplID())));
264 templ.appendChild( createDomNode(doc, "benefit", QString::number(getBenefit())));
265 templ.appendChild( createDomNode(doc, "timecount", hasTimeslice() ? "yes": "no" ));
266
267 QDomElement calcParts = doc.createElement( "calcParts" );
268 templ.appendChild(calcParts);
269 fixPartsToXML(doc, calcParts);
270 timePartsToXML(doc, calcParts);
271 materialPartsToXML(doc, calcParts);
272
273 /* Material Calculation Parts */
274 materialPartsToXML(doc);
275 CalcPartList tpList = getCalcPartsList(KALKPART_MATERIAL);
276 MaterialCalcPart *mc = 0;
277 mc = static_cast<MaterialCalcPart*>(tpList.first());
278 for( ; mc; mc = static_cast<MaterialCalcPart*>(tpList.next()) )
279 {
280 QDomElement calcPart = doc.createElement( "MaterialCalcpart" );
281 calcParts.appendChild(calcPart);
282 calcPart.appendChild(createDomNode(doc, "name", mc->getName()));
283 calcPart.appendChild(createDomNode(doc, "dbid", mc->getDbID().toString()));
284
285 StockMaterialList materials = mc->getCalcMaterialList();
286 StockMaterialListIterator it( materials );
287
288 StockMaterial *mat=0;
289 while ( (mat = it.current()) != 0 )
290 {
291 ++it;
292 QDomElement matElem = doc.createElement("Material");
293 matElem.appendChild(createDomNode(doc, "MatName", mat->getName()));
294 QString h;
295 h = h.setNum(mc->getCalcAmount(mat));
296 matElem.appendChild(createDomNode(doc, "Amount", h));
297 matElem.appendChild(createDomNode(doc, "PriceSum", mc->getPriceForMaterial(mat).toString()));
298 matElem.appendChild(createDomNode(doc, "CostSum", mc->getCostsForMaterial(mat).toString()));
299 matElem.appendChild(createDomNode(doc, "Price", mat->salesPrice().toString()));
300 matElem.appendChild(createDomNode(doc, "Cost", mat->purchPrice().toString()));
301 Einheit e = mat->getUnit();
302 h = e.einheitSingular();
303 matElem.appendChild(createDomNode(doc, "Unit", h));
304 calcPart.appendChild(matElem);
305 }
306 }
307 return templ;
308 }
309
310 void FloskelTemplate::fixPartsToXML( QDomDocument& doc, QDomElement& calcParts )
311 {
312 CalcPartList tpList = getCalcPartsList(KALKPART_FIX);
313
314 FixCalcPart *fc = 0;
315 fc = static_cast<FixCalcPart*>(tpList.first());
316 for( ; fc; fc = static_cast<FixCalcPart*>(tpList.next()) ) {
317 QDomElement calcPart = doc.createElement("FixCalcPart");
318 calcParts.appendChild(calcPart);
319 calcPart.appendChild(createDomNode(doc, "name", fc->getName()));
320 calcPart.appendChild(createDomNode(doc, "dbid", fc->getDbID().toString()));
321
322 QString h;
323 h.setNum(fc->getMenge());
324 calcPart.appendChild(createDomNode(doc, "amount", h));
325
326 Geld g = fc->unitPreis();
327 calcPart.appendChild(createDomNode(doc, "price", g.toString( mLocale )));
328 }
329 }
330
331 void FloskelTemplate::timePartsToXML( QDomDocument& doc, QDomElement& calcParts )
332 {
333 CalcPartList tpList = getCalcPartsList(KALKPART_TIME);
334
335 TimeCalcPart *tc = 0;
336 tc = static_cast<TimeCalcPart*>(tpList.first());
337 for( ; tc; tc = static_cast<TimeCalcPart*>(tpList.next()) ) {
338 QDomElement calcPart = doc.createElement("TimeCalcPart");
339 calcParts.appendChild(calcPart);
340 calcPart.appendChild(createDomNode(doc, "name", tc->getName()));
341 calcPart.appendChild(createDomNode(doc, "dbid", tc->getDbID().toString()));
342
343 QString h;
344 h.setNum( tc->getMinuten());
345 calcPart.appendChild(createDomNode(doc, "minutes", h));
346 StdSatz ss = tc->getStundensatz();
347 calcPart.appendChild(createDomNode(doc, "stundensatz", ss.getName()));
348 calcPart.appendChild(createDomNode(doc, "globalHourSetup",
349 tc->globalStdSetAllowed() ? "yes" : "no"));
350 }
351 }
352
353 void FloskelTemplate::materialPartsToXML( QDomDocument& doc, QDomElement& calcParts )
354 {
355 /* Material Calculation Parts */
356 CalcPartList tpList = getCalcPartsList(KALKPART_MATERIAL);
357 MaterialCalcPart *mc = 0;
358 mc = static_cast<MaterialCalcPart*>(tpList.first());
359 for( ; mc; mc = static_cast<MaterialCalcPart*>(tpList.next()) )
360 {
361 QDomElement calcPart = doc.createElement( "MaterialCalcpart" );
362 calcParts.appendChild(calcPart);
363 calcPart.appendChild(createDomNode(doc, "name", mc->getName()));
364 calcPart.appendChild(createDomNode(doc, "dbid", mc->getDbID().toString()));
365
366 StockMaterialList materials = mc->getCalcMaterialList();
367 StockMaterialListIterator it( materials );
368
369 StockMaterial *mat=0;
370 while ( (mat = it.current()) != 0 )
371 {
372 ++it;
373 QDomElement matElem = doc.createElement("Material");
374 matElem.appendChild(createDomNode(doc, "MaterialName", mat->name()));
375 QString h;
376 h = h.setNum(mc->getCalcAmount(mat));
377 matElem.appendChild(createDomNode(doc, "Amount", h));
378 matElem.appendChild(createDomNode(doc, "Price", mc->getCostsForMaterial(mat).toString()));
379 Einheit e = mat->getUnit();
380 h = e.einheitSingular();
381 matElem.appendChild(createDomNode(doc, "Unit", h));
382 calcPart.appendChild(matElem);
383 }
384 }
385 }
386
387 QDomElement FloskelTemplate::createDomNode( QDomDocument doc,
388 const QString& name, const QString& value)
389 {
390 QDomElement elem = doc.createElement(name);
391 QDomText text = doc.createTextNode(value);
392 elem.appendChild(text);
393 return elem;
394 }
395 #endif
396
397