]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp
Merge branch 'master' into full-month-stats
[stg.git] / projects / stargazer / plugins / configuration / sgconfig / parser_tariff.cpp
1 #include <cstdio> // snprintf
2 #include <cstring>
3
4 #include "stg/tariffs.h"
5 #include "parser.h"
6
7 const int pt_mega = 1024 * 1024;
8 //-----------------------------------------------------------------------------
9 //  GET TARIFFS
10 //-----------------------------------------------------------------------------
11 int PARSER_GET_TARIFFS::ParseStart(void *, const char * el, const char **)
12 {
13 if (strcasecmp(el, "GetTariffs") == 0)
14     {
15     return 0;
16     }
17 return -1;
18 }
19 //-----------------------------------------------------------------------------
20 int PARSER_GET_TARIFFS::ParseEnd(void *, const char * el)
21 {
22 if (strcasecmp(el, "GetTariffs") == 0)
23     {
24     CreateAnswer();
25     return 0;
26     }
27 return -1;
28 }
29 //-----------------------------------------------------------------------------
30 void PARSER_GET_TARIFFS::CreateAnswer()
31 {
32 string s;
33 char vs[100];
34 int hd, hn, md, mn;
35
36 answerList->erase(answerList->begin(), answerList->end());
37
38 answerList->push_back("<Tariffs>");
39
40 std::list<TARIFF_DATA> dataList;
41 tariffs->GetTariffsData(&dataList);
42 std::list<TARIFF_DATA>::const_iterator it = dataList.begin();
43 for (; it != dataList.end(); ++it)
44     {
45     s = "<tariff name=\"" + it->tariffConf.name + "\">";
46     answerList->push_back(s);
47
48     for (int j = 0; j < DIR_NUM; j++)
49         {
50         hd = it->dirPrice[j].hDay;
51         md = it->dirPrice[j].mDay;
52
53         hn = it->dirPrice[j].hNight;
54         mn = it->dirPrice[j].mNight;
55
56         strprintf(&s, "<Time%d value=\"%d:%d-%d:%d\"/>", j, hd, md, hn, mn);
57         answerList->push_back(s);
58         }
59
60     strprintf(&s, "    <PriceDayA value=\"");
61     for (int i = 0; i < DIR_NUM; i++)
62         {
63         snprintf(vs, 100, "%.5f%s", it->dirPrice[i].priceDayA * pt_mega, i+1 == DIR_NUM?"":"/");
64         s += vs;
65         }
66     s += "\"/>";
67     answerList->push_back(s);
68
69     strprintf(&s, "    <PriceDayB value=\"");
70     for (int i = 0; i < DIR_NUM; i++)
71         {
72         snprintf(vs, 100, "%.5f%s", it->dirPrice[i].priceDayB * pt_mega, i+1 == DIR_NUM?"":"/");
73         s += vs;
74         }
75     s += "\"/>";
76     answerList->push_back(s);
77
78     strprintf(&s, "    <PriceNightA value=\"");
79     for (int i = 0; i < DIR_NUM; i++)
80         {
81         snprintf(vs, 100, "%.5f%s", it->dirPrice[i].priceNightA * pt_mega, i+1 == DIR_NUM?"":"/");
82         s += vs;
83         }
84     s += "\"/>";
85     answerList->push_back(s);
86
87     strprintf(&s, "    <PriceNightB value=\"");
88     for (int i = 0; i < DIR_NUM; i++)
89         {
90         snprintf(vs, 100, "%.5f%s", it->dirPrice[i].priceNightB * pt_mega, i+1 == DIR_NUM?"":"/");
91         s += vs;
92         }
93     s += "\"/>";
94     answerList->push_back(s);
95
96     strprintf(&s, "    <Threshold value=\"");
97     for (int i = 0; i < DIR_NUM; i++)
98         {
99         snprintf(vs, 100, "%d%s", it->dirPrice[i].threshold, i+1 == DIR_NUM?"":"/");
100         s += vs;
101         }
102     s += "\"/>";
103     answerList->push_back(s);
104
105     strprintf(&s, "    <SinglePrice value=\"");
106     for (int i = 0; i < DIR_NUM; i++)
107         {
108         snprintf(vs, 100, "%d%s", it->dirPrice[i].singlePrice, i+1 == DIR_NUM?"":"/");
109         s += vs;
110         }
111     s += "\"/>";
112     answerList->push_back(s);
113
114     strprintf(&s, "    <NoDiscount value=\"");
115     for (int i = 0; i < DIR_NUM; i++)
116         {
117         snprintf(vs, 100, "%d%s", it->dirPrice[i].noDiscount, i+1 == DIR_NUM?"":"/");
118         s += vs;
119         }
120     s += "\"/>";
121     answerList->push_back(s);
122
123     strprintf(&s, "    <Fee value=\"%.5f\"/>", it->tariffConf.fee);
124     answerList->push_back(s);
125
126     strprintf(&s, "    <PassiveCost value=\"%.5f\"/>", it->tariffConf.passiveCost);
127     answerList->push_back(s);
128
129     strprintf(&s, "    <Free value=\"%.5f\"/>", it->tariffConf.free);
130     answerList->push_back(s);
131
132     switch (it->tariffConf.traffType)
133         {
134         case TRAFF_UP:
135             answerList->push_back("<TraffType value=\"up\"/>");
136             break;
137         case TRAFF_DOWN:
138             answerList->push_back("<TraffType value=\"down\"/>");
139             break;
140         case TRAFF_UP_DOWN:
141             answerList->push_back("<TraffType value=\"up+down\"/>");
142             break;
143         case TRAFF_MAX:
144             answerList->push_back("<TraffType value=\"max\"/>");
145             break;
146         }
147
148     answerList->push_back("</tariff>");
149     }
150 answerList->push_back("</Tariffs>");
151 }
152 //-----------------------------------------------------------------------------
153 //  ADD TARIFF
154 //-----------------------------------------------------------------------------
155 int PARSER_ADD_TARIFF::ParseStart(void *, const char * el, const char ** attr)
156 {
157 if (strcasecmp(el, "AddTariff") == 0)
158     {
159     if (attr[1])
160         {
161         tariffToAdd = attr[1];
162         }
163     return 0;
164     }
165 return -1;
166 }
167 //-----------------------------------------------------------------------------
168 int PARSER_ADD_TARIFF::ParseEnd(void *, const char * el)
169 {
170 if (strcasecmp(el, "AddTariff") == 0)
171     {
172     CreateAnswer();
173     return 0;
174     }
175 return -1;
176 }
177 //-----------------------------------------------------------------------------
178 void PARSER_ADD_TARIFF::CreateAnswer()
179 {
180 //answerList->clear();
181 answerList->erase(answerList->begin(), answerList->end());
182
183 if (tariffs->Add(tariffToAdd, currAdmin) == 0)
184     {
185     answerList->push_back("<AddTariff Result=\"Ok\"/>");
186     }
187 else
188     {
189     string s;
190     strprintf(&s, "<AddTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
191     answerList->push_back(s);
192     }
193 }
194 //-----------------------------------------------------------------------------
195 //  DEL TARIFF
196 //-----------------------------------------------------------------------------
197 int PARSER_DEL_TARIFF::ParseStart(void *, const char * el, const char ** attr)
198 {
199 strError = "";
200 if (strcasecmp(el, "DelTariff") == 0)
201     {
202     tariffToDel = attr[1];
203     return 0;
204     }
205 return -1;
206 }
207 //-----------------------------------------------------------------------------
208 int PARSER_DEL_TARIFF::ParseEnd(void *, const char * el)
209 {
210 if (strcasecmp(el, "DelTariff") == 0)
211     {
212     CreateAnswer();
213     return 0;
214     }
215 return -1;
216 }
217 //-----------------------------------------------------------------------------
218 void PARSER_DEL_TARIFF::CreateAnswer()
219 {
220 //answerList->clear();
221 answerList->erase(answerList->begin(), answerList->end());
222
223 if (users->TariffInUse(tariffToDel))
224     {
225     string s;
226     strprintf(&s, "<DelTariff Result=\"Error. Tariff \'%s\' cannot be deleted. Tariff in use.\"/>", tariffToDel.c_str());
227     answerList->push_back(s);
228     return;
229     }
230
231 if (tariffs->Del(tariffToDel, currAdmin) == 0)
232     {
233     answerList->push_back("<DelTariff Result=\"Ok\"/>");
234     }
235 else
236     {
237     string s;
238     strprintf(&s, "<DelTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
239     answerList->push_back(s);
240     }
241 }
242 //-----------------------------------------------------------------------------
243 //-----------------------------------------------------------------------------
244 //  CHG TARIFF
245 //-----------------------------------------------------------------------------
246 //-----------------------------------------------------------------------------
247 int PARSER_CHG_TARIFF::ParseSlashedIntParams(int paramsNum, const string & s, int * params)
248 {
249 char * str = new char[s.size() + 1];
250 char * p;
251 strcpy(str, s.c_str());
252 p = strtok(str, "/");
253
254 for (int i = 0; i < paramsNum; i++)
255     {
256     if (p == NULL)
257         {
258         delete[] str;
259         return -1;
260         }
261
262     if (str2x(p, params[i]) != 0)
263         {
264         delete[] str;
265         return -1;
266         }
267
268     p = strtok(NULL, "/");
269     }
270
271 delete[] str;
272 return 0;
273 }
274 //-----------------------------------------------------------------------------
275 int PARSER_CHG_TARIFF::ParseSlashedDoubleParams(int paramsNum, const string & s, double * params)
276 {
277 char * str = new char[s.size() + 1];
278 char * p;
279 strcpy(str, s.c_str());
280 p = strtok(str, "/");
281
282 for (int i = 0; i < paramsNum; i++)
283     {
284     if (p == NULL)
285         {
286         delete[] str;
287         return -1;
288         }
289
290     if (strtodouble2(p, params[i]) != 0)
291         {
292         delete[] str;
293         return -1;
294         }
295
296     p = strtok(NULL, "/");
297     }
298
299 delete[] str;
300 return 0;
301 }
302 //-----------------------------------------------------------------------------
303 int PARSER_CHG_TARIFF::ParseStart(void *, const char * el, const char ** attr)
304 {
305 char st[50];
306 double price[DIR_NUM];
307 int t[DIR_NUM];
308 depth++;
309
310 if (depth == 1)
311     {
312     if (strcasecmp(el, "SetTariff") == 0)
313         {
314         td.tariffConf.name = attr[1];
315         return 0;
316         }
317     }
318 else
319     {
320     string s;
321
322     if (strcasecmp(el, "PriceDayA") == 0)
323         {
324         s = attr[1];
325         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
326             for (int j = 0; j < DIR_NUM; j++)
327                 td.dirPrice[j].priceDayA = price[j] / pt_mega;
328         return 0;
329         }
330
331     if (strcasecmp(el, "PriceDayB") == 0)
332         {
333         s = attr[1];
334         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
335             for (int j = 0; j < DIR_NUM; j++)
336                 td.dirPrice[j].priceDayB = price[j] / pt_mega;
337         return 0;
338         }
339
340
341     if (strcasecmp(el, "PriceNightA") == 0)
342         {
343         s = attr[1];
344         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
345             for (int j = 0; j < DIR_NUM; j++)
346                 td.dirPrice[j].priceNightA = price[j] / pt_mega;
347         return 0;
348         }
349
350     if (strcasecmp(el, "PriceNightB") == 0)
351         {
352         s = attr[1];
353         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
354             for (int j = 0; j < DIR_NUM; j++)
355                 td.dirPrice[j].priceNightB = price[j] / pt_mega;
356         return 0;
357         }
358
359     if (strcasecmp(el, "Threshold") == 0)
360         {
361         s = attr[1];
362         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
363             for (int j = 0; j < DIR_NUM; j++)
364                 td.dirPrice[j].threshold = t[j];
365         return 0;
366         }
367
368     if (strcasecmp(el, "SinglePrice") == 0)
369         {
370         s = attr[1];
371         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
372             for (int j = 0; j < DIR_NUM; j++)
373                 td.dirPrice[j].singlePrice = t[j];
374         return 0;
375         }
376
377     if (strcasecmp(el, "NoDiscount") == 0)
378         {
379         s = attr[1];
380         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
381             for (int j = 0; j < DIR_NUM; j++)
382                 td.dirPrice[j].noDiscount = t[j];
383         return 0;
384         }
385
386     for (int j = 0; j < DIR_NUM; j++)
387         {
388         snprintf(st, 50, "Time%d", j);
389         if (strcasecmp(el, st) == 0)
390             {
391             int h1 = 0;
392             int m1 = 0;
393             int h2 = 0;
394             int m2 = 0;
395             if (ParseTariffTimeStr(attr[1], h1, m1, h2, m2) == 0)
396                 {
397                 td.dirPrice[j].hDay = h1;
398                 td.dirPrice[j].mDay = m1;
399                 td.dirPrice[j].hNight = h2;
400                 td.dirPrice[j].mNight = m2;
401                 }
402             return 0;
403             }
404         }
405
406     if (strcasecmp(el, "Fee") == 0)
407         {
408         double fee;
409         if (strtodouble2(attr[1], fee) == 0)
410             td.tariffConf.fee = fee;
411         return 0;
412         }
413
414     if (strcasecmp(el, "PassiveCost") == 0)
415         {
416         double pc;
417         if (strtodouble2(attr[1], pc) == 0)
418             td.tariffConf.passiveCost = pc;
419         return 0;
420         }
421     if (strcasecmp(el, "Free") == 0)
422         {
423         double free;
424         if (strtodouble2(attr[1], free) == 0)
425             td.tariffConf.free = free;
426         return 0;
427         }
428
429     if (strcasecmp(el, "TraffType") == 0)
430         {
431         if (strcasecmp(attr[1], "up") == 0)
432             {
433             td.tariffConf.traffType = TRAFF_UP;
434             return 0;
435             }
436
437         if (strcasecmp(attr[1], "down") == 0)
438             {
439             td.tariffConf.traffType = TRAFF_DOWN;
440             return 0;
441             }
442         if (strcasecmp(attr[1], "up+down") == 0)
443             {
444             td.tariffConf.traffType = TRAFF_UP_DOWN;
445             return 0;
446             }
447         if (strcasecmp(attr[1], "max") == 0)
448             {
449             td.tariffConf.traffType = TRAFF_MAX;
450             return 0;
451             }
452         return 0;
453         }
454     }
455 return -1;
456 }
457 //-----------------------------------------------------------------------------
458 int PARSER_CHG_TARIFF::ParseEnd(void *, const char * el)
459 {
460 if (depth == 1)
461     {
462     if (strcasecmp(el, "SetTariff") == 0)
463         {
464         CreateAnswer();
465         depth--;
466         return 0;
467         }
468     }
469
470 depth--;
471 return -1;
472 }
473 //-----------------------------------------------------------------------------
474 void PARSER_CHG_TARIFF::CreateAnswer()
475 {
476 answerList->erase(answerList->begin(), answerList->end());
477
478 if (!td.tariffConf.name.data().empty())
479     {
480     TARIFF_DATA tariffData = td.GetData();
481     if (tariffs->Chg(tariffData, currAdmin) == 0)
482         {
483         answerList->push_back("<SetTariff Result=\"ok\"/>");
484         return;
485         }
486     else
487         {
488         string s;
489         strprintf(&s, "<SetTariff Result=\"Change tariff error! %s\"/>", tariffs->GetStrError().c_str());
490         answerList->push_back(s);
491         return;
492         }
493     }
494 answerList->push_back("<SetTariff Result=\"Change tariff error!\"/>");
495 }
496 //-----------------------------------------------------------------------------