]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp
Merge branch 'master' into naffanya-dev
[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 std::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("<Period value=\"" + TARIFF::PeriodToString(it->tariffConf.period) + "\"/>");
149
150     answerList->push_back("</tariff>");
151     }
152 answerList->push_back("</Tariffs>");
153 }
154 //-----------------------------------------------------------------------------
155 //  ADD TARIFF
156 //-----------------------------------------------------------------------------
157 int PARSER_ADD_TARIFF::ParseStart(void *, const char * el, const char ** attr)
158 {
159 if (strcasecmp(el, "AddTariff") == 0)
160     {
161     if (attr[1])
162         {
163         tariffToAdd = attr[1];
164         }
165     return 0;
166     }
167 return -1;
168 }
169 //-----------------------------------------------------------------------------
170 int PARSER_ADD_TARIFF::ParseEnd(void *, const char * el)
171 {
172 if (strcasecmp(el, "AddTariff") == 0)
173     {
174     CreateAnswer();
175     return 0;
176     }
177 return -1;
178 }
179 //-----------------------------------------------------------------------------
180 void PARSER_ADD_TARIFF::CreateAnswer()
181 {
182 //answerList->clear();
183 answerList->erase(answerList->begin(), answerList->end());
184
185 if (tariffs->Add(tariffToAdd, currAdmin) == 0)
186     {
187     answerList->push_back("<AddTariff Result=\"Ok\"/>");
188     }
189 else
190     {
191     std::string s;
192     strprintf(&s, "<AddTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
193     answerList->push_back(s);
194     }
195 }
196 //-----------------------------------------------------------------------------
197 //  DEL TARIFF
198 //-----------------------------------------------------------------------------
199 int PARSER_DEL_TARIFF::ParseStart(void *, const char * el, const char ** attr)
200 {
201 strError = "";
202 if (strcasecmp(el, "DelTariff") == 0)
203     {
204     tariffToDel = attr[1];
205     return 0;
206     }
207 return -1;
208 }
209 //-----------------------------------------------------------------------------
210 int PARSER_DEL_TARIFF::ParseEnd(void *, const char * el)
211 {
212 if (strcasecmp(el, "DelTariff") == 0)
213     {
214     CreateAnswer();
215     return 0;
216     }
217 return -1;
218 }
219 //-----------------------------------------------------------------------------
220 void PARSER_DEL_TARIFF::CreateAnswer()
221 {
222 //answerList->clear();
223 answerList->erase(answerList->begin(), answerList->end());
224
225 if (users->TariffInUse(tariffToDel))
226     {
227     std::string s;
228     strprintf(&s, "<DelTariff Result=\"Error. Tariff \'%s\' cannot be deleted. Tariff in use.\"/>", tariffToDel.c_str());
229     answerList->push_back(s);
230     return;
231     }
232
233 if (tariffs->Del(tariffToDel, currAdmin) == 0)
234     {
235     answerList->push_back("<DelTariff Result=\"Ok\"/>");
236     }
237 else
238     {
239     std::string s;
240     strprintf(&s, "<DelTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
241     answerList->push_back(s);
242     }
243 }
244 //-----------------------------------------------------------------------------
245 //-----------------------------------------------------------------------------
246 //  CHG TARIFF
247 //-----------------------------------------------------------------------------
248 //-----------------------------------------------------------------------------
249 int PARSER_CHG_TARIFF::ParseSlashedIntParams(int paramsNum, const std::string & s, int * params)
250 {
251 char * str = new char[s.size() + 1];
252 char * p;
253 strcpy(str, s.c_str());
254 p = strtok(str, "/");
255
256 for (int i = 0; i < paramsNum; i++)
257     {
258     if (p == NULL)
259         {
260         delete[] str;
261         return -1;
262         }
263
264     if (str2x(p, params[i]) != 0)
265         {
266         delete[] str;
267         return -1;
268         }
269
270     p = strtok(NULL, "/");
271     }
272
273 delete[] str;
274 return 0;
275 }
276 //-----------------------------------------------------------------------------
277 int PARSER_CHG_TARIFF::ParseSlashedDoubleParams(int paramsNum, const std::string & s, double * params)
278 {
279 char * str = new char[s.size() + 1];
280 char * p;
281 strcpy(str, s.c_str());
282 p = strtok(str, "/");
283
284 for (int i = 0; i < paramsNum; i++)
285     {
286     if (p == NULL)
287         {
288         delete[] str;
289         return -1;
290         }
291
292     if (strtodouble2(p, params[i]) != 0)
293         {
294         delete[] str;
295         return -1;
296         }
297
298     p = strtok(NULL, "/");
299     }
300
301 delete[] str;
302 return 0;
303 }
304 //-----------------------------------------------------------------------------
305 int PARSER_CHG_TARIFF::ParseStart(void *, const char * el, const char ** attr)
306 {
307 char st[50];
308 double price[DIR_NUM];
309 int t[DIR_NUM];
310 depth++;
311
312 if (depth == 1)
313     {
314     if (strcasecmp(el, "SetTariff") == 0)
315         {
316         td.tariffConf.name = attr[1];
317         return 0;
318         }
319     }
320 else
321     {
322     std::string s;
323
324     if (strcasecmp(el, "PriceDayA") == 0)
325         {
326         s = attr[1];
327         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
328             for (int j = 0; j < DIR_NUM; j++)
329                 td.dirPrice[j].priceDayA = price[j] / pt_mega;
330         return 0;
331         }
332
333     if (strcasecmp(el, "PriceDayB") == 0)
334         {
335         s = attr[1];
336         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
337             for (int j = 0; j < DIR_NUM; j++)
338                 td.dirPrice[j].priceDayB = price[j] / pt_mega;
339         return 0;
340         }
341
342
343     if (strcasecmp(el, "PriceNightA") == 0)
344         {
345         s = attr[1];
346         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
347             for (int j = 0; j < DIR_NUM; j++)
348                 td.dirPrice[j].priceNightA = price[j] / pt_mega;
349         return 0;
350         }
351
352     if (strcasecmp(el, "PriceNightB") == 0)
353         {
354         s = attr[1];
355         if (ParseSlashedDoubleParams(DIR_NUM, s, price) == 0)
356             for (int j = 0; j < DIR_NUM; j++)
357                 td.dirPrice[j].priceNightB = price[j] / pt_mega;
358         return 0;
359         }
360
361     if (strcasecmp(el, "Threshold") == 0)
362         {
363         s = attr[1];
364         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
365             for (int j = 0; j < DIR_NUM; j++)
366                 td.dirPrice[j].threshold = t[j];
367         return 0;
368         }
369
370     if (strcasecmp(el, "SinglePrice") == 0)
371         {
372         s = attr[1];
373         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
374             for (int j = 0; j < DIR_NUM; j++)
375                 td.dirPrice[j].singlePrice = t[j];
376         return 0;
377         }
378
379     if (strcasecmp(el, "NoDiscount") == 0)
380         {
381         s = attr[1];
382         if (ParseSlashedIntParams(DIR_NUM, s, t) == 0)
383             for (int j = 0; j < DIR_NUM; j++)
384                 td.dirPrice[j].noDiscount = t[j];
385         return 0;
386         }
387
388     for (int j = 0; j < DIR_NUM; j++)
389         {
390         snprintf(st, 50, "Time%d", j);
391         if (strcasecmp(el, st) == 0)
392             {
393             int h1 = 0;
394             int m1 = 0;
395             int h2 = 0;
396             int m2 = 0;
397             if (ParseTariffTimeStr(attr[1], h1, m1, h2, m2) == 0)
398                 {
399                 td.dirPrice[j].hDay = h1;
400                 td.dirPrice[j].mDay = m1;
401                 td.dirPrice[j].hNight = h2;
402                 td.dirPrice[j].mNight = m2;
403                 }
404             return 0;
405             }
406         }
407
408     if (strcasecmp(el, "Fee") == 0)
409         {
410         double fee;
411         if (strtodouble2(attr[1], fee) == 0)
412             td.tariffConf.fee = fee;
413         return 0;
414         }
415
416     if (strcasecmp(el, "PassiveCost") == 0)
417         {
418         double pc;
419         if (strtodouble2(attr[1], pc) == 0)
420             td.tariffConf.passiveCost = pc;
421         return 0;
422         }
423     if (strcasecmp(el, "Free") == 0)
424         {
425         double free;
426         if (strtodouble2(attr[1], free) == 0)
427             td.tariffConf.free = free;
428         return 0;
429         }
430
431     if (strcasecmp(el, "TraffType") == 0)
432         {
433         if (strcasecmp(attr[1], "up") == 0)
434             {
435             td.tariffConf.traffType = TRAFF_UP;
436             return 0;
437             }
438
439         if (strcasecmp(attr[1], "down") == 0)
440             {
441             td.tariffConf.traffType = TRAFF_DOWN;
442             return 0;
443             }
444         if (strcasecmp(attr[1], "up+down") == 0)
445             {
446             td.tariffConf.traffType = TRAFF_UP_DOWN;
447             return 0;
448             }
449         if (strcasecmp(attr[1], "max") == 0)
450             {
451             td.tariffConf.traffType = TRAFF_MAX;
452             return 0;
453             }
454         return 0;
455         }
456
457     if (strcasecmp(el, "Period") == 0)
458         {
459         td.tariffConf.period = TARIFF::StringToPeriod(attr[1]);
460         return 0;
461         }
462     }
463 return -1;
464 }
465 //-----------------------------------------------------------------------------
466 int PARSER_CHG_TARIFF::ParseEnd(void *, const char * el)
467 {
468 if (depth == 1)
469     {
470     if (strcasecmp(el, "SetTariff") == 0)
471         {
472         CreateAnswer();
473         depth--;
474         return 0;
475         }
476     }
477
478 depth--;
479 return -1;
480 }
481 //-----------------------------------------------------------------------------
482 void PARSER_CHG_TARIFF::CreateAnswer()
483 {
484 answerList->erase(answerList->begin(), answerList->end());
485
486 if (!td.tariffConf.name.data().empty())
487     {
488     TARIFF_DATA tariffData = td.GetData();
489     if (tariffs->Chg(tariffData, currAdmin) == 0)
490         {
491         answerList->push_back("<SetTariff Result=\"ok\"/>");
492         return;
493         }
494     else
495         {
496         std::string s;
497         strprintf(&s, "<SetTariff Result=\"Change tariff error! %s\"/>", tariffs->GetStrError().c_str());
498         answerList->push_back(s);
499         return;
500         }
501     }
502 answerList->push_back("<SetTariff Result=\"Change tariff error!\"/>");
503 }
504 //-----------------------------------------------------------------------------