search.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // node --require regenerator-runtime/runtime --require ./babel-local search.js ..\out result.csv
  2. import {promises} from 'fs';
  3. import {resolve} from 'path';
  4. import {eachFormElement, eachItem, eachVestnik} from './lib/read';
  5. const {writeFile, truncate} = promises;
  6. async function work (prefix, outfile) {
  7. console.info(`Input directory: ${prefix}`);
  8. await truncate(outfile);
  9. console.info(`Output file: ${outfile}`);
  10. for await (let vestnik of eachVestnik(prefix)) {
  11. for (let item of eachItem(vestnik)) {
  12. const {id = '', url = "about:blank"} = item.zakazka && item.zakazka[0].$ || {};
  13. if (hasCpv("45", item)) {
  14. const v = oddiel_V(item);
  15. if (v) {
  16. processV(v, {
  17. id,
  18. url
  19. }, item, async items => await writeFile(outfile, poorMansCsv(items) + "\r\n", {flag: "a"}));
  20. }
  21. }
  22. }
  23. }
  24. }
  25. const formComponentIdEndsWith = (value, searchString) => value.$.FormComponentId && value.$.FormComponentId.endsWith(searchString);
  26. function processV ({value: oddielV, dive: diveV}, soFar, item, out) {
  27. let processed = false;
  28. for (let {tag, value, cancel, dive} of diveV()) {
  29. if (tag === "RepeatingPart" && formComponentIdEndsWith(value, "-partZmluva")) {
  30. cancel();
  31. processed = processed || processZmluva({value, dive}, soFar, item, out);
  32. }
  33. if (tag === "Part" && (formComponentIdEndsWith(value, "-zadanieZakazky")||formComponentIdEndsWith(value, "-partV_2"))) {
  34. cancel();
  35. processed = processed || processZadanie({value, dive}, soFar, item, out);
  36. }
  37. if (tag === "Part" && formComponentIdEndsWith(value, "-partV_1")) {
  38. cancel();
  39. const {id, url} = soFar;
  40. out([id, url, -1, 0, '-', 0, '-', 0]);
  41. processed = true;
  42. }
  43. }
  44. if (!processed) {
  45. const {id, url} = soFar;
  46. out([id, url, -1, '?', '?', '?', '?', 0]);
  47. }
  48. }
  49. function processZmluva ({value: zmluva, dive: diveZmluva}, {id, url}, item, out) {
  50. let pocetPonuk = 0;
  51. let predpokladanaCena = '?';
  52. let predpokladanaMena = '?';
  53. let konecnaCena = '?';
  54. let konecnaMena = '?';
  55. let vitazIco = 0;
  56. for (let {tag, value, cancel} of diveZmluva()) {
  57. if (tag === "ShortText") {
  58. if (formComponentIdEndsWith(value, "-pocetDorucenychPonuk") && value.$.Value) {
  59. pocetPonuk = +value.$.Value;
  60. }
  61. if ((formComponentIdEndsWith(value, "-MN03_zmluvaPredpokladanaHodnota") || formComponentIdEndsWith(value, "-NM06_cena")) && value.$.Value) {
  62. predpokladanaCena = value.$.Value
  63. }
  64. if (formComponentIdEndsWith(value, "-stCKHZ_Hodnota") && value.$.Value) {
  65. konecnaCena = value.$.Value
  66. }
  67. }
  68. if (tag === "DropDownList") {
  69. if ((formComponentIdEndsWith(value, "-zmluvaMenaOd") || formComponentIdEndsWith(value, "-zmluvaCenaMena")) && value.SelectListValue) {
  70. predpokladanaMena = value.SelectListValue[0].$.Code;
  71. }
  72. if ((formComponentIdEndsWith(value, "-zmluvaCenyMena") || formComponentIdEndsWith(value, "-zmluvaCenaMenaPonuky")) && value.SelectListValue) {
  73. konecnaMena = value.SelectListValue[0].$.Code;
  74. }
  75. }
  76. if (tag === "ContactSelectList" && formComponentIdEndsWith(value, "-zmluvaVitaz")) {
  77. cancel();
  78. vitazIco = (value.PersonData[0].CorporateBody[0].ICO||['?'])[0];
  79. }
  80. }
  81. if (pocetPonuk === 0) return false;
  82. out([id, url, pocetPonuk, predpokladanaCena, predpokladanaMena, konecnaCena, konecnaMena, vitazIco]);
  83. return true;
  84. }
  85. function processZadanie ({value: zmluva, dive: diveZmluva}, {id, url}, item, out) {
  86. let pocetPonuk = 0;
  87. let predpokladanaCena = '?';
  88. let predpokladanaMena = '?';
  89. let konecnaCena = '?';
  90. let konecnaMena = '?';
  91. let vitazIco = 0;
  92. for (let {tag, value, cancel} of diveZmluva()) {
  93. if (tag === "ShortText") {
  94. if (formComponentIdEndsWith(value, "-pocetPrijatychPonuk") && value.$.Value) {
  95. pocetPonuk = +value.$.Value;
  96. }
  97. if (formComponentIdEndsWith(value, "-prepokladanaHZ") && value.$.Value) {
  98. predpokladanaCena = value.$.Value
  99. }
  100. if (formComponentIdEndsWith(value, "-konecnaHZ") && value.$.Value) {
  101. konecnaCena = value.$.Value
  102. }
  103. }
  104. if (tag === "DropDownList") {
  105. if (formComponentIdEndsWith(value, "-menaHZ_SYNCHRONIZE") && value.SelectListValue) {
  106. predpokladanaMena = value.SelectListValue[0].$.Code;
  107. }
  108. if (formComponentIdEndsWith(value, "-menaHZ") && value.SelectListValue) {
  109. konecnaMena = value.SelectListValue[0].$.Code;
  110. }
  111. }
  112. if (tag === "ContactSelectList" && formComponentIdEndsWith(value, "-kontaktNaDodavatela_alt")) {
  113. cancel();
  114. vitazIco = (value.PersonData[0].CorporateBody[0].ICO||['?'])[0];
  115. }
  116. }
  117. if (pocetPonuk === 0) return false;
  118. out([id, url, pocetPonuk, predpokladanaCena, predpokladanaMena, konecnaCena, konecnaMena, vitazIco]);
  119. return true;
  120. }
  121. const poorMansCsv = items => JSON.stringify(items).slice(1, -1);
  122. function hasCpv (prefix, item) {
  123. for (let {tag, value, cancel} of eachFormElement(item)) {
  124. if (tag === "Part") {
  125. const match = value.$.Title && value.$.Title.match(/^ODDIEL\s+(\w+):/);
  126. if (match && match[1] !== "II") cancel();
  127. }
  128. if (tag === "Cpv" && value.$.Code.startsWith(prefix)) return true;
  129. if (tag === "SelectList" && value.$.Type === "CPV" && value.SelectListValue && value.SelectListValue[0].$.Title.startsWith(prefix)) return true;
  130. }
  131. return false;
  132. }
  133. function oddiel_V (item) {
  134. for (let {tag, value, cancel, dive} of eachFormElement(item)) {
  135. if (tag === "Part") {
  136. const match = value.$.Title && value.$.Title.match(/^ODDIEL\s+(\w+):/);
  137. if (match)
  138. if (match[1] === "V") return {value, dive}; else cancel();
  139. }
  140. }
  141. return null;
  142. }
  143. work(resolve(process.argv[2] || ''), resolve(process.argv[3] || 'result.csv'))
  144. .catch(error => console.error(error));