Greasy Fork is available in English.

Virtonomica: заказ всех товаров группы в магазин из выбранного склада

Заказ всех товаров группы в магазин/ресторан/мед.центр/автомастерскую из выбранного склада. После посещения закладки "сбыт" на всех своих складах, в магазине на странице "снабжение" будет доступен массовый заказ товаров со своих складов.

  1. // ==UserScript==
  2. // @name Virtonomica: заказ всех товаров группы в магазин из выбранного склада
  3. // @namespace virtonomica
  4. // @version 2.8
  5. // @description Заказ всех товаров группы в магазин/ресторан/мед.центр/автомастерскую из выбранного склада. После посещения закладки "сбыт" на всех своих складах, в магазине на странице "снабжение" будет доступен массовый заказ товаров со своих складов.
  6. // @include http*://virtonomic*.*/*/main/unit/view/*/supply
  7. // @include http*://virtonomic*.*/*/main/unit/view/*/sale
  8. // ==/UserScript==
  9. var run = function() {
  10.  
  11. var win = (typeof(unsafeWindow) != 'undefined' ? unsafeWindow : top.window);
  12. $ = win.$;
  13.  
  14. function getRealm(){
  15. var svHref = window.location.href;
  16. var matches = svHref.match(/\/(\w+)\/main\/unit\/view\//);
  17. return matches[1];
  18. }
  19. var stockStorageName = "stockStorageName_" + getRealm();
  20. function getUnitId(){
  21. var svHref = window.location.href;
  22. var matches = svHref.match(/\/main\/unit\/view\/(\d+)\//);
  23. return matches[1];
  24. }
  25. function getLast(str){
  26. var matches = str.match(/\/(\d+)$/);
  27. return matches[1];
  28. }
  29. Object.size = function(obj) {
  30. var size = 0, key;
  31. for (key in obj) {
  32. if (obj.hasOwnProperty(key)) size++;
  33. }
  34. return size;
  35. };
  36. function isObject(item) {
  37. //console.log("item = " + (typeof item === "object" && Object.size(item) == 1 && item !== null));
  38. return (typeof item === "object" && Object.size(item) == 1 && item !== null);
  39. }
  40. function addAllProducts(){
  41. var stocks = JSON.parse(window.localStorage.getItem(stockStorageName));
  42. if (!$.isArray(stocks)){
  43. alert('После посещения закладки "сбыт" на всех своих складах, в магазине на странице "снабжение" будет доступен массовый заказ товаров со своих складов.');
  44. return;
  45. }
  46. var idvStock = $("select#AddAllProducts").val();
  47. if(idvStock == '') return;
  48. if(idvStock == getUnitId()) {
  49. alert('Перевозить внутри одного склада нельзя');
  50. return;
  51. }
  52. console.log("stock id = " + idvStock);
  53. var idvProduct = '';
  54. var svUrl = '';
  55. var exist = 0;
  56. var idvShop = getUnitId();
  57. var data = {};
  58. var postCount = 0;
  59. var postDoneCount = 0;
  60. //в магазине
  61. if($('div#productsHereDiv > a').length > 0){
  62. console.log("в магазине, " + $('div#productsHereDiv > a').length);
  63. $('div#productsHereDiv > a').each(function() {
  64. idvProduct = $(this).attr('href').match(/\d+/g)['0'];
  65. console.log("idvProduct = " + idvProduct);
  66. //https://virtonomica.ru/olga/window/unit/supply/multiple/vendor:5619658/product:422435/brandname:0
  67. //https://virtonomica.ru/olga/window/unit/supply/create/6751546/step2
  68. svUrl = window.location.href.replace(/\/main\/unit\/view\/\d+\/supply/,'/window/unit/supply/multiple/vendor:'+idvStock+'/product:'+idvProduct+'/brandname:0');
  69. var svStockUrl = window.location.href.replace(/\/\d+\/supply/,'/'+idvStock);
  70. var ovStock = $.grep(stocks, function(e){ return e.stockId == idvStock && e.productId == idvProduct; });
  71. //console.log("isObject(ovStock) = " + isObject(ovStock));
  72. if(isObject(ovStock)) {
  73. exist += 1;
  74. if(!$('td#name_'+idvProduct+'-0_0 > div > a[href="'+svStockUrl+'"]').length){
  75. data = {};
  76. postCount += 1;
  77. data['unit['+idvShop+'][qty]'] = 1;
  78. console.log("svUrl = " + svUrl);
  79. console.log("idvProduct = " + idvProduct);
  80. console.log("data = " + JSON.stringify(data));
  81. $.post( svUrl, data )
  82. .done(function() {
  83. console.log( "success" );
  84. })
  85. .fail(function() {
  86. console.log( "error" );
  87. })
  88. .always(function() {
  89. console.log( "always" );
  90. postDoneCount += 1;
  91. if(postCount === postDoneCount){
  92. window.location = window.location.href;//.reload();
  93. /*setTimeout(function(){
  94. console.log( "reload" );
  95. if(confirm('Товары заказаны. Перезагрузить страницу?')){
  96. window.location = window.location.href;//.reload();
  97. }
  98. }, 1000);*/
  99. }
  100. });
  101. }
  102. }
  103. });
  104. if(exist === 0){
  105. alert('На складе "' + $("select#AddAllProducts > option:selected").text() + '" не найдены товары группы "'+$("select[name='productCategory'] > option:selected").text()+'"');
  106. } else if (postCount === 0) {
  107. alert('Товары уже заказаны со склада "' + $("select#AddAllProducts > option:selected").text() + '" ');
  108. }
  109. } else if($('tr[id^="product_row_"] > th > table > tbody > tr:nth-child(1) > td:nth-child(1) > a:has(img)').length > 0){
  110. $('tr[id^="product_row_"] > th > table > tbody > tr:nth-child(1) > td:nth-child(1) > a:has(img)').each(function() {
  111. //href="https://virtonomica.ru/olga/window/product/info/359862"
  112. idvProduct = getLast($(this).attr('href'));
  113. //https://virtonomica.ru/olga/window/unit/supply/multiple/vendor:5619658/product:422435/brandname:0
  114. svUrl = window.location.href.replace(/\/main\/unit\/view\/\d+\/supply/,'/window/unit/supply/multiple/vendor:'+idvStock+'/product:'+idvProduct+'/brandname:0');
  115. console.log("svUrl = " + svUrl);
  116. var svStockUrl = window.location.href.replace(/\/\d+\/supply/,'/'+idvStock);
  117. var ovStock = $.grep(stocks, function(e){ return e.stockId == idvStock && e.productId == idvProduct; });
  118. if(isObject(ovStock)) {
  119. exist += 1;
  120. //console.log('exits = $(\'td#name_'+idvProduct+'_0 > a[href="'+svStockUrl+'"]\')');
  121. if($('td#name_'+idvProduct+'_0 > a[href="'+svStockUrl+'"]').length == 0){
  122. data = {};
  123. postCount += 1;
  124. data['unit['+idvShop+'][qty]'] = 1;
  125. console.log("idvProduct = " + idvProduct);
  126. console.log("data = " + JSON.stringify(data));
  127. $.post( svUrl, data )
  128. .done(function() {
  129. console.log( "success" );
  130. })
  131. .fail(function() {
  132. console.log( "error" );
  133. })
  134. .always(function() {
  135. console.log( "always" );
  136. postDoneCount += 1;
  137. if(postCount === postDoneCount){
  138. window.location = window.location.href;//.reload();
  139. /*setTimeout(function(){
  140. console.log( "reload" );
  141. if(confirm('Товары заказаны. Перезагрузить страницу?')){
  142. window.location = window.location.href;//.reload();
  143. }
  144. }, 1000);*/
  145. }
  146. });
  147. }
  148. }
  149. });
  150. if(exist === 0){
  151. alert('На складе "' + $("select#AddAllProducts > option:selected").text() + '" не найдены необходимые товары');
  152. } else if (postCount === 0) {
  153. alert('Товары уже заказаны со склада "' + $("select#AddAllProducts > option:selected").text() + '" ');
  154. }
  155. } else {
  156. //на складе
  157. var idavProducts = [];
  158. $('img[src="/img/supplier_add.gif"]').each(function() {
  159. idavProducts.push(getLast($(this).parent().attr('href')));
  160. });
  161. $('#mainContent > div.add_contract > a > img').each(function() {
  162. idavProducts.push(getLast($(this).parent().attr('href')));
  163. });
  164. for(var i = 0; i < idavProducts.length; ++i) {
  165. idvProduct = idavProducts[i];
  166. //https://virtonomica.ru/olga/window/unit/supply/multiple/vendor:5619658/product:422435/brandname:0
  167. svUrl = window.location.href.replace(/\/main\/unit\/view\/\d+\/supply/,'/window/unit/supply/multiple/vendor:'+idvStock+'/product:'+idvProduct+'/brandname:0');
  168. console.log("svUrl = " + svUrl);
  169. var svStockUrl = window.location.href.replace(/\/\d+\/supply/,'/'+idvStock);
  170. var ovStock = $.grep(stocks, function(e){ return e.stockId == idvStock && e.productId == idvProduct; });
  171. if(isObject(ovStock)) {
  172. exist += 1;
  173. //console.log('exits = $(\'td#name_'+idvProduct+'_0 > a[href="'+svStockUrl+'"]\')');
  174. if($('td#name_'+idvProduct+'_0 > a[href="'+svStockUrl+'"]').length == 0){
  175. data = {};
  176. postCount += 1;
  177. data['unit['+idvShop+'][qty]'] = 1;
  178. console.log("idvProduct = " + idvProduct);
  179. console.log("data = " + JSON.stringify(data));
  180. $.post( svUrl, data )
  181. .done(function() {
  182. console.log( "success" );
  183. })
  184. .fail(function() {
  185. console.log( "error" );
  186. })
  187. .always(function() {
  188. console.log( "always" );
  189. postDoneCount += 1;
  190. if(postCount === postDoneCount){
  191. window.location = window.location.href;//.reload();
  192. /*setTimeout(function(){
  193. console.log( "reload" );
  194. if(confirm('Товары заказаны. Перезагрузить страницу?')){
  195. window.location = window.location.href;//.reload();
  196. }
  197. }, 1000);*/
  198. }
  199. });
  200. }
  201. }
  202. }
  203. if(exist === 0){
  204. alert('На складе "' + $("select#AddAllProducts > option:selected").text() + '" не найдены необходимые товары');
  205. } else if (postCount === 0) {
  206. alert('Товары уже заказаны со склада "' + $("select#AddAllProducts > option:selected").text() + '" ');
  207. }
  208. }
  209. }
  210. function changeSelectStockByProductOnPage(stocks, productsOnPage){
  211. var uniqStocks = [];
  212. stocks.forEach(function(a) {
  213. if (productsOnPage === null || a.productId in productsOnPage) {
  214. if (a.stockId in uniqStocks) {
  215. uniqStocks[a.stockId]['caption'] += ', ' + productsOnPage[a.productId];
  216. uniqStocks[a.stockId]['count'] += 1;
  217. } else {
  218. uniqStocks[a.stockId] = []
  219. uniqStocks[a.stockId]['caption'] = a.stockHL + ': ' + productsOnPage[a.productId];
  220. uniqStocks[a.stockId]['count'] = 1;
  221. uniqStocks[a.stockId]['stockId'] = a.stockId;
  222. }
  223. }
  224. });
  225. return uniqStocks;
  226. }
  227. function getUniqStocksByProductOnPage(stocks){
  228. var productsOnPage = [];
  229. $('div#productsHereDiv > span > input[type="radio"]').each(function() {
  230. productsOnPage[$(this).attr('value')] = $('> label > img', $(this).parent()).attr('title');
  231. });
  232. var uniqStocks = changeSelectStockByProductOnPage(stocks, productsOnPage);
  233. uniqStocks.sort(function(a, b) {
  234. return parseFloat(b.count) - parseFloat(a.count);
  235. });
  236. return uniqStocks;
  237. }
  238. function changeProductCategory(first_val, stocks){
  239. var valForCat = first_val;
  240. var uniqStocks = getUniqStocksByProductOnPage(stocks);
  241. for (var key in uniqStocks) {
  242. valForCat += '<option value="'+uniqStocks[key]['stockId']+'">'+uniqStocks[key]['caption']+'</option>';
  243. }
  244. $('select#AddAllProducts').html(valForCat);
  245. }
  246. //если страница "снабжение" магазина
  247. if (/\w*virtonomic\w+.\w+\/\w+\/main\/unit\/view\/\d+\/supply/.test(window.location)) {
  248. var stocks = JSON.parse(window.localStorage.getItem(stockStorageName));
  249. // кнопки
  250. var first_val = '<option value="">Заказ всех товаров группы в магазин из выбранного склада</option>';
  251. var vals = first_val;
  252. if ($.isArray(stocks)){
  253. var uniqStocks = [];
  254. //если категория продуктов уже выбрана в магазине (и других где есть радио-кнопки для добавления поставщика)
  255. if($('div#productsHereDiv > span > input[type="radio"]').length > 0){
  256. uniqStocks = getUniqStocksByProductOnPage(stocks);
  257. $('select[name="productCategory"]').change(function(){
  258. changeProductCategory(first_val, stocks);
  259. });
  260. //если категория продуктов еще не выбрана в магазине (и других где есть радио-кнопки для добавления поставщика)
  261. } else if($('select[name="productCategory"]').length > 0){
  262. stocks.forEach(function(a) {
  263. if (a.stockId in uniqStocks) {
  264. uniqStocks[a.stockId]['count'] += 1;
  265. } else {
  266. uniqStocks[a.stockId] = []
  267. uniqStocks[a.stockId]['caption'] = a.stockHL + ': ' + a.stockSpecHL;
  268. uniqStocks[a.stockId]['count'] = 1;
  269. uniqStocks[a.stockId]['stockId'] = a.stockId;
  270. }
  271. });
  272. $('select[name="productCategory"]').change(function(){
  273. changeProductCategory(first_val, stocks);
  274. });
  275. } else {
  276. var productsOnPage = [];
  277. $('tr[id^="product_row_"] > th > table > tbody > tr:nth-child(1) > td:nth-child(1) > a:has(img)').each(function() {
  278. productsOnPage[getLast($(this).attr('href'))] = $(this).attr('title');
  279. });
  280. if(productsOnPage.length === 0){
  281. $('img[src="/img/supplier_add.gif"]').each(function() {
  282. productsOnPage[getLast($(this).parent().attr('href'))] = $(this).attr('title');
  283. });
  284. $('#mainContent > div.add_contract > a > img').each(function() {
  285. productsOnPage[getLast($(this).parent().attr('href'))] = $(this).attr('title');
  286. });
  287. }
  288. uniqStocks = changeSelectStockByProductOnPage(stocks, productsOnPage);
  289. }
  290. uniqStocks.sort(function(a, b) {
  291. return parseFloat(b.count) - parseFloat(a.count);
  292. });
  293. for (var key in uniqStocks) {
  294. vals += '<option value="'+uniqStocks[key]['stockId']+'">'+uniqStocks[key]['caption']+'</option>';
  295. }
  296. } else {
  297. first_val = '<option value="">После посещения закладки "сбыт" на всех своих складах, в магазине на странице "снабжение" будет доступен массовый заказ товаров со своих складов.</option>';
  298. vals = first_val;
  299. }
  300. var selAddAllProducts = $('<select id="AddAllProducts">'+vals+'</select>').change(function() {
  301. addAllProducts();
  302. });
  303. var clearSelBtn = $('<input type="button" value="Очистить список быстрого заказа"/>').click(function() {
  304. if(confirm('Очистить список быстрого заказа?')) {
  305. $('#AddAllProducts').html(first_val);
  306. var stocks = [];
  307. window.localStorage.setItem(stockStorageName,JSON.stringify(stocks));
  308. }
  309. });
  310. var panel = $("div#childMenu");
  311. panel.append(selAddAllProducts);
  312. panel.append(clearSelBtn);
  313. }
  314. //если страница "сбыт" склада
  315. if (/\w*virtonomic\w+.\w+\/\w+\/main\/unit\/view\/\d+\/sale/.test(window.location)) {
  316. var stocks = JSON.parse(window.localStorage.getItem(stockStorageName));
  317. if (!$.isArray(stocks)){
  318. stocks = [];
  319. }
  320. var idvStock = getUnitId();
  321. var svStock = $('div.metro_header div.title > h1').text();
  322. var changeSperUrl = window.location.href.replace(/\/main\/unit\/view\/\d+\/sale/,'/window/unit/speciality_change/'+idvStock);
  323. var svStockSpec = $('a[href="'+changeSperUrl+'"]').parent().prev().prev().text();
  324. console.log(svStockSpec);
  325. var idvProduct = '';
  326. var matches = [];
  327. stocks = stocks.filter(function (el) {
  328. return el.stockId !== idvStock;
  329. });
  330. $('table[class="grid"] > tbody > tr > td:nth-child(1) > a:has(img[src="/img/supplier_add.gif"])').each(function() {
  331. matches = $(this).attr('href').match(/\/product:(\d+)\//);
  332. idvProduct = matches[1];
  333. console.log("idvProduct = " + idvProduct);
  334. var ovStock = $.grep(stocks, function(e){ return e.stockId == idvStock && e.productId == idvProduct; });
  335. if(!isObject(ovStock)){
  336. stocks.push({
  337. stockId: idvStock,
  338. stockHL: svStock,
  339. stockSpecHL: svStockSpec,
  340. productId: idvProduct
  341. });
  342. }
  343. });
  344. window.localStorage.setItem(stockStorageName,JSON.stringify(stocks));
  345. }
  346. }
  347.  
  348. if(window.top == window) {
  349. var script = document.createElement("script");
  350. script.textContent = '(' + run.toString() + ')();';
  351. document.documentElement.appendChild(script);
  352. }