Changeset 3444321
- Timestamp:
- 01/21/2026 05:33:05 PM (2 months ago)
- Location:
- catapultodelivery/trunk
- Files:
-
- 3 added
- 32 edited
-
README.md (added)
-
assets/css/admin.css (modified) (2 diffs)
-
assets/css/send_panel.css (modified) (3 diffs)
-
assets/js/admin.js (modified) (4 diffs)
-
assets/js/send_panel.js (modified) (6 diffs)
-
assets/js/widget_handler.js (modified) (2 diffs)
-
build/catapulto-checkout-block-frontend.asset.php (modified) (1 diff)
-
build/catapulto-checkout-block-frontend.js (modified) (1 diff)
-
catapultodelivery.php (modified) (1 diff)
-
composer.phar (added)
-
languages/ipol_catapultodelivery-ru_RU.mo (modified) (previous)
-
languages/ipol_catapultodelivery-ru_RU.po (modified) (5 diffs)
-
libs/Api/Entity/Request/Part/ShipmentNpData/Item.php (modified) (3 diffs)
-
libs/Api/Entity/Request/Terminal.php (modified) (2 diffs)
-
libs/Core/Delivery/Cargo.php (modified) (2 diffs)
-
libs/Core/Delivery/CargoItem.php (modified) (1 diff)
-
libs/Core/Entity/Money.php (modified) (1 diff)
-
libs/Core/Order/Item.php (modified) (3 diffs)
-
libs/Core/Order/Payment.php (modified) (3 diffs)
-
libs/Wordpress/CatapultoPlugin.php (modified) (18 diffs)
-
libs/Wordpress/CatapultoShippingMethod.php (modified) (29 diffs)
-
libs/Wordpress/Controller/AbstractController.php (modified) (1 diff)
-
libs/Wordpress/Controller/MainController.php (modified) (2 diffs)
-
libs/Wordpress/Controller/OrderController.php (modified) (8 diffs)
-
libs/Wordpress/DB/AbstractDB.php (modified) (2 diffs)
-
libs/Wordpress/DB/DBTools.php (modified) (3 diffs)
-
libs/Wordpress/DB/OrdersDB.php (modified) (2 diffs)
-
libs/Wordpress/Frontend/AdminPages.php (modified) (11 diffs)
-
libs/Wordpress/Frontend/CheckoutBlock.php (modified) (7 diffs)
-
libs/Wordpress/Rest/RestHandler.php (modified) (10 diffs)
-
libs/Wordpress/Shipping/Calculator.php (modified) (8 diffs)
-
libs/Wordpress/Tools/TemplateRender.php (modified) (2 diffs)
-
readme.txt (modified) (4 diffs)
-
readme_build.md (added)
-
templates/admin/orderPanel.tpl (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
catapultodelivery/trunk/assets/css/admin.css
r3417476 r3444321 1 .ctpt_tab_hidden { 2 display: none; 3 } 1 4 .ctpt_tbl { 2 5 width: 100%; … … 205 208 max-width: 240px !important; 206 209 } 210 211 /* Warehouses */ 212 .ctpt_wh_actions p { 213 display: flex; 214 height: 34px; 215 align-items: center; 216 float: left; 217 margin: 0 20px 0 0; 218 margin-top: 0 !important; 219 } 220 .ctpt_wh_actions select { 221 float:left; 222 } 223 .ctpt_wh_actions button { 224 float: left; 225 margin-left: 30px; 226 height: 34px; 227 } 228 229 .ctpt_warehouse { 230 border: 1px solid #000; 231 } 232 .ctpt_warehouse_after td { 233 padding: 8px; 234 } 235 236 .ctpt_sender { 237 padding-right: 20px; 238 vertical-align: top !important; 239 } 240 .ctpt_operators { 241 padding-left: 20px; 242 vertical-align: top !important; 243 } 244 .ctpt_sender label, 245 .ctpt_operators label { 246 width: 150px; 247 min-width: 150px; 248 max-width: 150px; 249 } 250 .ctpt_sender fieldset { 251 width: 100%; 252 display: flex; 253 gap: 20px; 254 align-items: center; 255 } 256 .ctpt_sender input[type=text] { 257 width: 100% !important; 258 } 259 .ctpt_sender fieldset fieldset { 260 261 } 262 263 .ctpt_operators fieldset { 264 width: 100%; 265 display: flex; 266 gap: 20px; 267 align-items: center; 268 } 269 .ctpt_bl_d4 { 270 flex-basis: 25%; 271 } 272 .ctpt_operators input[type=text], 273 .ctpt_operators select { 274 width: 100% !important; 275 } 276 277 .ctpt_wh_delete_wr { 278 width: 100%; 279 display: flex; 280 justify-content: end; 281 } 282 283 #ctpt_wh_delete { 284 background: #D30000; 285 } 286 #ctpt_wh_delete:hover:not(:disabled) { 287 background: var(--wc-red); 288 } 289 290 .ctpt_wh_select_dlv_code.hid input { 291 display: none; 292 } 293 294 .ctpt_warehouse.new_wh { 295 display: none; 296 } 297 298 .ctpt_err { 299 border-color: #D30000 !important; 300 } 301 302 303 /* /Warehouses */ 304 305 -
catapultodelivery/trunk/assets/css/send_panel.css
r3417476 r3444321 17 17 18 18 .ctpt_order_panel input[type=text] { 19 width: 100%;19 width: 98%; 20 20 margin-bottom: 8px; 21 21 } … … 38 38 .ctpt_datablock { 39 39 width: 100%; 40 overflow: hidden; 40 41 } 41 42 … … 46 47 .ctpt_warnempty { 47 48 margin-top: 10px !important; 48 font-weight: bold;49 49 display: none; 50 50 } 51 52 /* Cargoes */ 53 54 .ctpt_cargowin_close { 55 position: absolute; 56 right: 8px; 57 top: 55px; 58 width: 30px; 59 height: 30px; 60 cursor: pointer; 61 } 62 .ctpt_cargowin_close:before, 63 .ctpt_cargowin_close:after { 64 display: block; 65 content: ''; 66 position: absolute; 67 left:50%; 68 top: 50%; 69 transform:translate(-50%,-50%) rotate(-45deg); 70 width: 33px; 71 height: 2px; 72 background:#000; 73 margin-left: -1px; 74 transition: 0.5s; 75 } 76 .ctpt_cargowin_close:after { 77 transform:translate(-50%,-50%) rotate(45deg); 78 } 79 .ctpt_cargowin_close:hover:before, 80 .ctpt_cargowin_close:hover:after { 81 background-color: #0d6efd; 82 } 83 84 .rate_update_errors, 85 .rate_update_success { 86 display: none; 87 margin-top: 20px; 88 } 89 body { 90 max-height: 100%; 91 } 92 93 .body { 94 min-height: 100vh; 95 height: auto !important; 96 padding-bottom: 50px; 97 } 98 .ctpt_cargo_table { 99 width: 800px; 100 margin: 0 auto; 101 padding: 20px; 102 background: #fff; 103 border-radius: 20px; 104 position: relative; 105 106 -webkit-box-shadow: 4px 4px 50px 0px rgba(34, 60, 80, 0.25); 107 -moz-box-shadow: 4px 4px 50px 0px rgba(34, 60, 80, 0.25); 108 box-shadow: 4px 4px 50px 0px rgba(34, 60, 80, 0.25); 109 110 } 111 112 .cargoes { 113 width: 100%; 114 } 115 .cargo { 116 padding: 10px; 117 border: 1px solid #ccc; 118 margin-bottom: 20px; 119 position: relative; 120 } 121 .cargo .close { 122 position: absolute; 123 right: 8px; 124 top: 8px; 125 width: 20px; 126 height: 20px; 127 cursor: pointer; 128 } 129 .cargo .close:before, 130 .cargo .close:after { 131 display: block; 132 content: ''; 133 position: absolute; 134 left:50%; 135 top: 50%; 136 transform:translate(-50%,-50%) rotate(-45deg); 137 width: 22px; 138 height: 1px; 139 background:#000; 140 margin-left: -1px; 141 transition: 0.5s; 142 } 143 .cargo .close:after { 144 transform:translate(-50%,-50%) rotate(45deg); 145 } 146 .cargo .close:hover:before, 147 .cargo .close:hover:after { 148 background-color: #0d6efd; 149 } 150 151 .ctpt_cargo_table table { 152 width: 100%; 153 } 154 155 .ctpt_cargo_table h1 { 156 margin-bottom: 30px; 157 text-align:center; 158 } 159 160 .ctpt_cargo_table .hdr { 161 width: 100%; 162 display: table; 163 margin-bottom: 20px; 164 } 165 .ctpt_cargo_table .crg_name { 166 text-align: center; 167 width: 100%; 168 font-weight: 700; 169 } 170 171 .ctpt_cargo_table .left { 172 float: left; 173 width: 50%; 174 } 175 176 .ctpt_cargo_table input[type=text] { 177 height: 26px; 178 } 179 180 .ctpt_cargo_table .cargo_l, 181 .ctpt_cargo_table .cargo_w, 182 .ctpt_cargo_table .cargo_h, 183 .ctpt_cargo_table .gds_l, 184 .ctpt_cargo_table .gds_w, 185 .ctpt_cargo_table .gds_h { 186 float: left; 187 width: 65px; 188 } 189 190 .ctpt_cargo_table .cargo_wei { 191 width: 149px; 192 } 193 194 .ctpt_cargo_table .gds_wei { 195 width: 80px; 196 margin: 0 auto; 197 display: block; 198 } 199 200 .ctpt_cargo_table .gds_art { 201 width: 140px; 202 margin: 0 auto; 203 display: block; 204 } 205 206 .ctpt_cargo_table .gabs_wr { 207 display: table; 208 margin: 0 auto; 209 } 210 .ctpt_cargo_table .gabs_wr span { 211 display: inline-block; 212 float: left; 213 line-height: 26px; 214 padding: 0 5px; 215 font-weight: 500; 216 } 217 218 .ctpt_cargo_table .cargo_gabs, 219 .ctpt_cargo_table .cargo_wei { 220 display: table; 221 width: 100%; 222 margin-bottom: 15px; 223 } 224 .ctpt_cargo_table .cargo_gabs p, 225 .ctpt_cargo_table .cargo_wei p { 226 margin: 0; 227 line-height: 26px; 228 display: block; 229 width: 130px; 230 float: left; 231 } 232 233 .ctpt_cargo_table .cargo_gabs .gabs_wr, 234 .ctpt_cargo_table .cargo_wei .field_wr { 235 float: left; 236 } 237 238 .ctpt_cargo_table .hdr button { 239 display: block; 240 margin-bottom: 10px; 241 } 242 243 .ctpt_cargo_table .gds_name { 244 text-align: center; 245 padding-bottom: 5px; 246 } 247 248 .ctpt_cargo_table th { 249 text-align: center; 250 padding: 0 5px; 251 } 252 .ctpt_cargo_table td { 253 padding: 0 5px; 254 } 255 256 .ctpt_cargo_table .line { 257 height: 11px; 258 position: relative; 259 } 260 .ctpt_cargo_table .line:before { 261 display: block; 262 content: ""; 263 position: absolute; 264 left: 0; 265 top: 50%; 266 width: 100%; 267 height: 1px; 268 transform: translateY(-50%); 269 background: #000; 270 } 271 272 .ctpt_cargo_table .gds_cnt { 273 display: flex; 274 padding: 0 10px; 275 justify-content: center; 276 } 277 .ctpt_cargo_table .gds_cnt p { 278 margin-bottom: 0; 279 margin-top: 0; 280 float: left; 281 margin-right: 10px; 282 line-height: 26px; 283 } 284 285 .ctpt_cargo_table .move_ico { 286 margin-top: 3px; 287 width: 20px; 288 height: 20px; 289 float: left; 290 position: relative; 291 cursor: pointer; 292 } 293 .ctpt_cargo_table .move_ico:before, 294 .ctpt_cargo_table .move_ico:after { 295 display: block; 296 content: ""; 297 position: absolute; 298 left: 0; 299 top: 0; 300 width: 100%; 301 height: 100%; 302 background: url(../images/move.svg) no-repeat; 303 background-size: contain; 304 transition: 0.5s; 305 } 306 .ctpt_cargo_table .move_ico:after { 307 opacity: 0; 308 background-image: url(../images/move_blue.svg); 309 } 310 .ctpt_cargo_table .move_ico:hover:before { 311 opacity: 0; 312 } 313 .ctpt_cargo_table .move_ico:hover:after { 314 opacity: 1; 315 } 316 317 .ctpt_cargo_table .gds_price p { 318 line-height: 26px; 319 text-align: center; 320 margin: 0; 321 } 322 323 .ctpt_cargo_table .btm_buttons { 324 display: table; 325 width: 100%; 326 padding-top: 30px; 327 } 328 .ctpt_cargo_table .btm_buttons .btn { 329 float: left; 330 margin-right: 10px; 331 } 332 .ctpt_cargo_table .btm_buttons .btn-primary { 333 float: right; 334 } 335 336 /* Popup window */ 337 .ctpt_move_win { 338 border: 1px solid #999; 339 position: absolute; 340 left: -100000px; 341 top:0; 342 opacity: 0; 343 transition: left 0s linear 0.5s, top 0s linear 0.5s, opacity 0.5s linear 0s; 344 z-index: 50; 345 width: 150px; 346 background: #fff; 347 border-radius: 4px; 348 -webkit-box-shadow: 10px 10px 19px 0px rgba(34, 60, 80, 0.4); 349 -moz-box-shadow: 10px 10px 19px 0px rgba(34, 60, 80, 0.4); 350 box-shadow: 10px 10px 19px 0px rgba(34, 60, 80, 0.4); 351 padding: 20px 5px 5px 5px; 352 } 353 .ctpt_move_win.sh { 354 opacity: 1; 355 transition: left 0s linear 0s, top 0s linear 0s, opacity 0.5s linear 0s; 356 } 357 358 .ctpt_move_win .close { 359 position: absolute; 360 right: 8px; 361 top: 8px; 362 width: 20px; 363 height: 20px; 364 cursor: pointer; 365 } 366 .ctpt_move_win .close:before, 367 .ctpt_move_win .close:after { 368 display: block; 369 content: ''; 370 position: absolute; 371 left:50%; 372 top: 50%; 373 transform:translate(-50%,-50%) rotate(-45deg); 374 width: 22px; 375 height: 1px; 376 background:#000; 377 margin-left: -1px; 378 transition: 0.5s; 379 } 380 .ctpt_move_win .close:after { 381 transform:translate(-50%,-50%) rotate(45deg); 382 } 383 .ctpt_move_win .close:hover:before, 384 .ctpt_move_win .close:hover:after { 385 background-color: #0d6efd; 386 } 387 388 .ctpt_move_win > p { 389 text-align: center; 390 padding-right: 10px; 391 } 392 .ctpt_move_win p { 393 font-size: 12px; 394 margin-bottom: 15px; 395 } 396 .ctpt_move_win select { 397 width: 100%; 398 margin-bottom: 15px; 399 } 400 .ctpt_move_win .place { 401 width: 100%; 402 display: flex; 403 margin-bottom: 15px; 404 justify-content: center; 405 } 406 .ctpt_move_win .place p { 407 padding-right: 5px; 408 margin-bottom: 0; 409 margin-top: 0; 410 line-height: 26px; 411 } 412 .ctpt_move_win input { 413 width: 50px; 414 height: 26px; 415 } 416 .ctpt_move_win input.err { 417 background-color: #ffb3b3; 418 } 419 .ctpt_move_win .btn { 420 width: 100%; 421 } 422 423 .ctpt_crg_itm_warn p { 424 text-align: center; 425 width: 100%; 426 color: #f00; 427 margin: 0; 428 font-size:12px; 429 padding-top: 5px; 430 } 431 432 #ctpt_cargoes { 433 margin-bottom: 15px; 434 } 435 436 .cargo_gabs_block { 437 cursor: pointer; 438 color: #2271b1; 439 position:relative; 440 display: inline-block; 441 } 442 .cargo_gabs_block:before, 443 .cargo_gabs_block:after { 444 display: block; 445 font-family: dashicons; 446 font-feature-settings: normal; 447 content: "\f343"; 448 width: 20px; 449 height: 20px; 450 position: absolute; 451 right: -30px; 452 top: 50%; 453 transform: translateY(-50%); 454 transition: 0.5s; 455 } 456 .cargo_gabs_block:after { 457 content: "\f347"; 458 opacity: 0; 459 } 460 .cargo_gabs_block.sh:before { 461 opacity: 0; 462 } 463 .cargo_gabs_block.sh:after { 464 opacity: 1; 465 } 466 467 .cargo_gabs_block_content .cnm { 468 padding-top: 5px; 469 font-family: bold; 470 font-size: 16px; 471 } 472 473 .cargo_gabs_block_content { 474 display: none; 475 } 476 477 .ctpt_hidden { 478 display: none !important; 479 } 480 481 .ctpt_hint_block { 482 display: inline-block; 483 width:100%; 484 position:relative; 485 } 486 .ctpt_hint_block p { 487 float:left; 488 } 489 490 .ctpt_hintlbl { 491 margin: 0 5px 0 0; 492 color: #666; 493 display: inline-block; 494 font-style: normal; 495 height: 16px; 496 line-height: 16px; 497 position: relative; 498 vertical-align: middle; 499 width: 16px; 500 font-size: 1.2em; 501 cursor: help; 502 float: left; 503 position: relative; 504 top: 4px; 505 } 506 .ctpt_hintlbl:before { 507 font-family: Dashicons; 508 speak: never; 509 font-weight: 400; 510 font-variant: normal; 511 text-transform: none; 512 line-height: 1; 513 -webkit-font-smoothing: antialiased; 514 margin: 0; 515 text-indent: 0; 516 position: absolute; 517 top: 0; 518 left: 0; 519 width: 100%; 520 height: 100%; 521 text-align: center; 522 content: "\f223"; 523 cursor: help; 524 } 525 526 .ctpt_hint_content { 527 width: 100%; 528 z-index: 8675309; 529 position: absolute; 530 top: 12px; 531 pointer-events: none; 532 left: -10000px; 533 padding-top: 5px; 534 opacity: 0; 535 transition: left 0s linear 0.3s, opacity 0.3s linear 0s; 536 } 537 .ctpt_hint_content.sh { 538 opacity:1; 539 left: 0; 540 transition: left 0s linear 0s, opacity 0.3s linear 0s; 541 } 542 .ctpt_hint_content p { 543 display: block; 544 width: 100%; 545 box-sizing: border-box; 546 color: #fff; 547 font-size: .8em; 548 background: #333; 549 text-align: center; 550 border-radius: 3px; 551 padding: .618em 1em; 552 box-shadow: 0 1px 3px rgba(0,0,0,.2); 553 } 554 -
catapultodelivery/trunk/assets/js/admin.js
r3417476 r3444321 1 1 (function($) { 2 2 $(document).ready(function () { 3 const errClass = 'ctpt_err'; 3 4 4 5 $(document).on('click', '.ctpt-tab', function(e){ … … 8 9 self.addClass('nav-tab-active'); 9 10 10 $('.ctpt-tab-content-' + tabsContentLevel). hide();11 $('#' + self.data('tab-content-id')). show();11 $('.ctpt-tab-content-' + tabsContentLevel).addClass('ctpt_tab_hidden') 12 $('#' + self.data('tab-content-id')).removeClass('ctpt_tab_hidden') 12 13 }); 13 14 … … 40 41 }); 41 42 42 $('.ctpt_op_element').each( function(){43 let t=$(this);44 if (t.find('select option:selected').attr('value') == 'door') t.find('input').val('').css('display','none');45 });46 47 $('.ctpt_op_element select').change( function(){48 let t=$(this);49 if (t.find('option:selected').attr('value') == 'door') {50 t.next().val('').css('display','none');51 } else {52 t.next().css('display','');53 }54 } );55 56 $('#ctpt_op_setalldoors').click(function(e){57 e.preventDefault();58 59 $('.ctpt_op_element select option').removeAttr('selected');60 $('.ctpt_op_element').each( function() {61 let t=$(this);62 t.find('select option[value=door]').prop('selected', true);63 t.find('input').val('').css('display','none');64 } );65 $('button[name=save]').removeAttr('disabled');66 67 return false;68 });69 $('#ctpt_op_setallwh').click(function(e){70 e.preventDefault();71 72 $('.ctpt_op_element select option').removeAttr('selected');73 $('.ctpt_op_element').each( function() {74 let t=$(this);75 t.find('select option[value=warehouse]').prop('selected', true);76 t.find('input').css('display','');77 } );78 $('button[name=save]').removeAttr('disabled');79 80 return false;81 });82 83 43 function numberValidator(input, validator = /^([0-9]){0,6}$/) { 84 44 let vl = input.value; … … 124 84 } 125 85 86 if (document.querySelector('#woocommerce_catapultodelivery_isFitting') !== null) { 87 const isFitting = document.querySelector('#woocommerce_catapultodelivery_isFitting'), 88 fittingDefaultEnabled = document.querySelector('#woocommerce_catapultodelivery_fittingDefaultEnabled'), 89 onFittingOff = () => { 90 fittingDefaultEnabled.checked = false; 91 fittingDefaultEnabled.setAttribute('disabled', 'disabled'); 92 }; 93 isFitting.onchange = function() { 94 if (isFitting.checked) { 95 fittingDefaultEnabled.removeAttribute('disabled'); 96 } else onFittingOff(); 97 } 98 if (!isFitting.checked) onFittingOff(); 99 fittingDefaultEnabled.onchange = function() { 100 if (fittingDefaultEnabled.checked && !isFitting.checked) fittingDefaultEnabled.checked = false; 101 } 102 } 103 104 //Warehouses 105 const isSavePermitted = () => { 106 let isPermitted = true; 107 document.querySelectorAll('.ctpt_warehouse').forEach( wh => { 108 let isValid = true; 109 if (wh.querySelector('.wh_name_fs input').value.length == 0) { 110 isValid = false; 111 wh.querySelector('.wh_name_fs input').classList.add(errClass); 112 } 113 114 if (wh.querySelector('.ctpt_wh_active input').checked) { 115 if (wh.querySelector('.wh_coords input:first-child').value.length == 0) { 116 wh.querySelector('.wh_coords input:first-child').classList.add(errClass); 117 isValid = false; 118 } 119 if (wh.querySelector('.wh_coords input:last-child').value.length == 0) { 120 wh.querySelector('.wh_coords input:last-child').classList.add(errClass); 121 isValid = false; 122 } 123 if (wh.querySelector('.wh_cityid input').value.length == 0) { 124 isValid = false; 125 wh.querySelector('.wh_cityid input').classList.add(errClass); 126 } 127 if (wh.querySelector('.wh_cityzip input').value.length == 0) { 128 isValid = false; 129 wh.querySelector('.wh_cityzip input').classList.add(errClass); 130 } 131 if (wh.querySelector('.wh_senderid input').value.length == 0) { 132 isValid = false; 133 wh.querySelector('.wh_senderid input').classList.add(errClass); 134 } 135 } 136 if (wh.querySelector('.wh_poa_enable input').checked) { 137 if (wh.querySelector('.wh_poa_fio input').value.length == 0) { 138 isValid = false; 139 wh.querySelector('.wh_poa_fio input').classList.add(errClass); 140 } 141 if (wh.querySelector('.wh_poa_p_ser input').value.length == 0) { 142 isValid = false; 143 wh.querySelector('.wh_poa_p_ser input').classList.add(errClass); 144 } 145 if (wh.querySelector('.wh_poa_p_num input').value.length == 0) { 146 isValid = false; 147 wh.querySelector('.wh_poa_p_num input').classList.add(errClass); 148 } 149 if (wh.querySelector('.wh_poa_p_date input').value.length == 0) { 150 isValid = false; 151 wh.querySelector('.wh_poa_p_date input').classList.add(errClass); 152 } 153 if (wh.querySelector('.wh_poa_p_mail input').value.length == 0) { 154 isValid = false; 155 wh.querySelector('.wh_poa_p_mail input').classList.add(errClass); 156 } 157 } 158 159 if (!isValid) { 160 isPermitted = false; 161 } 162 setTimeout( () => { 163 wh.querySelectorAll('input').forEach( el => el.classList.remove(errClass) ); 164 }, 20000 ); 165 } ); 166 return isPermitted; 167 } 168 169 if (document.querySelector('#ctpt_new_wh') != null) 170 document.querySelector('#ctpt_new_wh').onclick = e => { 171 e.preventDefault(); 172 if (isSavePermitted()) { 173 document.querySelector('input[name=is_new_wh]').value = 'Y'; 174 document.querySelector('.woocommerce-save-button').removeAttribute('disabled'); 175 document.querySelector('.woocommerce-save-button').click(); 176 } else { 177 alert('Вначале необходимо заполнить необходимые данные по складам.'); 178 e.preventDefault(); 179 e.stopPropagation(); 180 return false; 181 } 182 } 183 184 let isDelFunction = false; 185 if (document.querySelectorAll('#ctpt_wh_delete') != null) 186 document.querySelectorAll('#ctpt_wh_delete').forEach(el => { 187 el.onclick = (e) => { 188 e.preventDefault(); 189 if (confirm("Действительно удалить склад?\nЭто действие необратимо.")) { 190 isDelFunction = true; 191 document.querySelector('input[name=is_wh_del]').value = el.attributes['wh_id'].value; 192 document.querySelector('.woocommerce-save-button').removeAttribute('disabled'); 193 document.querySelector('.woocommerce-save-button').click(); 194 } 195 } 196 }); 197 198 if (document.querySelector('#mainform') != null) 199 document.querySelector('#mainform').onsubmit = e => { 200 if (!isSavePermitted() && !isDelFunction) { 201 e.preventDefault(); 202 setTimeout(() => { 203 document.querySelectorAll('.is-busy').forEach(el => { 204 el.classList.remove('is-busy'); 205 }); 206 },1000); 207 alert('Вначале необходимо заполнить данные по складам.'); 208 return false; 209 } 210 } 211 212 function bindWhTriggers() { 213 document.querySelectorAll('.ctpt_wh_select_dlv_type').forEach( e => { 214 const inp = e.parentNode.querySelector('.ctpt_wh_select_dlv_code'); 215 const s = e.querySelector('select'); 216 s.onchange = () => { 217 if (s.value === 'door') { 218 inp.classList.add('hid'); 219 } else { 220 inp.classList.remove('hid'); 221 } 222 } 223 if (s.value === 'warehouse') inp.classList.remove('hid'); 224 } ); 225 226 //Проверка заполнения координат... 227 document.querySelectorAll('.wh_coords').forEach(e=> { 228 e.querySelectorAll('input').forEach(t => { 229 t.onchange = () => { 230 let r = /^([0-9]){0,2}(\.){1}([0-9]){1,10}$/; 231 t.value = t.value.replaceAll(',', '.'); 232 if (!r.test(t.value)) { 233 t.classList.add(errClass) 234 } else { 235 t.classList.remove(errClass) 236 } 237 } 238 }); 239 }); 240 //Проверка заполнения числовых значений 241 document.querySelectorAll('.wh_digits').forEach(e=> { 242 const t = e.querySelector('input'); 243 t.onchange = () => { 244 let r = /^([0-9]*)$/; 245 if (!r.test(t.value)) t.value = ''; 246 } 247 }); 248 249 document.querySelectorAll('.wh_amount').forEach(e=>{ 250 const t = e.querySelector('input'); 251 t.onchange = () => { 252 let r = /^([0-9]){0,7}(\.){0,1}([0-9]){0,2}$/; 253 t.value = t.value.replaceAll(',', '.'); 254 if (!r.test(t.value)) t.value = ''; 255 } 256 }); 257 document.querySelectorAll('.wh_poa_p_ser').forEach(e=>{ 258 const t = e.querySelector('input'); 259 t.onchange = () => { 260 let r = /^[0-9]{4}$/; 261 if (!r.test(t.value)) t.value = ''; 262 } 263 }); 264 document.querySelectorAll('.wh_poa_p_num').forEach(e=>{ 265 const t = e.querySelector('input'); 266 t.onchange = () => { 267 let r = /^[0-9]{6}$/; 268 if (!r.test(t.value)) t.value = ''; 269 } 270 }); 271 document.querySelectorAll('.wh_poa_p_date').forEach(e=>{ 272 const t = e.querySelector('input'); 273 t.onchange = () => { 274 let r = /^([0-9]{2})(\.)([0-9]{2})(\.)([0-9]{4})$/; 275 if (!r.test(t.value)) t.value = ''; 276 if (t.value.length > 10) t.value = ''; 277 } 278 }); 279 document.querySelectorAll('.wh_poa_p_mail').forEach(e=>{ 280 const t = e.querySelector('input'); 281 t.onchange = () => { 282 let r = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/; 283 if (!r.test(t.value)) t.value = ''; 284 } 285 }); 286 } 287 bindWhTriggers(); 126 288 127 289 }); -
catapultodelivery/trunk/assets/js/send_panel.js
r3417476 r3444321 1 const cseWarnMsg = document.querySelector('.ctpt_cse_warn'), 2 suid = window.ctptData.suid, 3 orderId = window.ctptData.orderId, 4 operator = window.ctptData.operator, 5 goodsPrice = window.ctptData.goodsPrice, 6 shippingPrice = window.ctptData.shippingPrice, 7 isCod = window.ctptData.isCod, 8 codAmount = window.ctptData.codAmount, 9 isInsured = window.ctptData.isEnsurance, 10 isCSE = operator === 'cse'; 1 const cseWarnMsg = document.querySelector('.ctpt_cse_warn') 2 ,suid = window.ctptData.suid 3 ,orderId = window.ctptData.orderId 4 ,operator = window.ctptData.operator 5 ,goodsPrice = window.ctptData.goodsPrice 6 ,shippingPrice = window.ctptData.shippingPrice 7 ,ratePrice = window.ctptData.ratePrice 8 ,isCod = window.ctptData.isCod 9 ,codAmount = window.ctptData.codAmount 10 ,isInsured = window.ctptData.isEnsurance 11 ,isCSE = operator === 'cse' 12 ,cData = window.ctptData.cargoData 13 ,basePrice = window.ctptData.basePrce 14 ,isFitting = window.ctptData.isFitting 15 ,isSingleProd = window.ctptData.isProductSingle 16 ,isPR = window.ctptData.isPR 17 ,insuranceVal = window.ctptData.insurance_cost / 100 18 19 20 ,orderPaidCheckbox = document.getElementById('ctpt_isBeznal') 21 ,needInsuranceCheckbox = document.getElementById('ctpt_needInsurance') 22 ,deliveryPaySideCheckbox = document.getElementById('ctpt_deliveryPaySide') 23 ,fittingCheckbox = document.getElementById('ctpt_is_fitting') 24 ,partialDedemptionCheckbox = document.getElementById('ctpt_is_pr') 25 ,insuranceValueInput = document.getElementById('ctpt_insuranceValue') 26 ,sumToPay = document.getElementById('ctpt_sumToPay') 27 //,cseWarn = document.querySelector('.ctpt_warnempty') 28 29 ,whSelect = document.getElementById('ctpt_adm_selected_wh') 30 ; 11 31 12 32 if (isCSE) cseWarnMsg.classList.remove('hide'); … … 42 62 frm.append('ctpt_buyerDoorNumber', document.querySelector('input[name=ctpt_buyerDoorNumber]').value); 43 63 frm.append('ctpt_comment', document.querySelector('textarea[name=ctpt_comment]').value); 44 frm.append('ctpt_needInsurance', document.querySelector('input[name=ctpt_needInsurance]').checked ? 'Y' : 'N' ); 45 frm.append('ctpt_insuranceValue', document.querySelector('input[name=ctpt_insuranceValue]').value); 46 frm.append('ctpt_isBeznal', document.querySelector('input[name=ctpt_isBeznal]').checked ? 'Y' : 'N' ); 47 frm.append('ctpt_sumToPay', document.querySelector('input[name=ctpt_sumToPay]').value); 48 frm.append('ctpt_deliveryPaySide', document.querySelector('input[name=ctpt_deliveryPaySide]').checked ? 'Y' : 'N' ); 64 frm.append('ctpt_needInsurance', needInsuranceCheckbox.checked ? 'Y' : 'N' ); 65 frm.append('ctpt_insuranceValue', insuranceValueInput.value); 66 frm.append('ctpt_isBeznal', orderPaidCheckbox.checked ? 'Y' : 'N' ); 67 frm.append('ctpt_sumToPay', sumToPay.value); 68 frm.append('ctpt_deliveryPaySide', deliveryPaySideCheckbox.checked ? 'Y' : 'N' ); 69 frm.append('ctpt_is_fitting', fittingCheckbox.checked ? 'Y' : 'N' ); 70 frm.append('ctpt_is_pr', partialDedemptionCheckbox.checked ? 'Y' : 'N' ); 49 71 50 72 const response= await fetch('/?rest_route=/catapultodelivery/ordersend', { … … 97 119 order_id: orderId, 98 120 isEmpty: false, 121 insurance: window.Ctpt_widgetParams.need_insurance, 122 pr: window.Ctpt_widgetParams.is_partial_redemption, 99 123 }; 100 124 sendVariant(Item); … … 108 132 order_id: orderId, 109 133 isEmpty: false, 134 insurance: window.Ctpt_widgetParams.need_insurance, 135 pr: window.Ctpt_widgetParams.is_partial_redemption, 110 136 }; 111 137 if (typeof(Item['Variant']) !== 'undefined') { … … 117 143 } 118 144 145 whSelect.onchange = ev => { 146 const selectedWhId = Number(ev.target.value); 147 if (selectedWhId != window.ctptData.selectedwh) { 148 if (confirm('Вы уверены, что хотите изменить склад? Если да, то будет запущен выбор способа доставки для выбранного склада.')) { 149 for (let i in window.ctptData.warehouses) { 150 if (window.ctptData.warehouses[i].id == selectedWhId) { 151 window.Ctpt_widgetParams.sender_contact_params.locality_id = window.ctptData.warehouses[i].lid; 152 window.Ctpt_widgetParams.sender_contact_params.zip = window.ctptData.warehouses[i].zip; 153 window.Ctpt_widgetParams.sender_contact_params.cityFrom = window.ctptData.warehouses[i].city; 154 window.Ctpt_widgetParams.warehouseId = selectedWhId; 155 document.getElementById('ctpt_reselect').click(); 156 } 157 } 158 } 159 } 160 } 161 119 162 document.querySelector('#ctpt_reselect').onclick = e => { 120 163 e.preventDefault(); 121 164 window.Ctpt_widgetParams.onSelectPvzItem = selectPVZItem; 122 165 window.Ctpt_widgetParams.onSelectCourierItem = selectCourierItem; 123 window.Ctpt_widgetParams.need_insurance = document.getElementById('ctpt_needInsurance').checked;124 window.Ctpt_widgetParams.insured_value = Number( document.getElementById('ctpt_insuranceValue').value);166 window.Ctpt_widgetParams.need_insurance = needInsuranceCheckbox.checked; 167 window.Ctpt_widgetParams.insured_value = Number(insuranceValueInput.value); 125 168 if (isNaN(window.Ctpt_widgetParams.insured_value)) window.Ctpt_widgetParams.insured_value = 0; 169 window.Ctpt_widgetParams.is_fitting = fittingCheckbox.checked; 170 window.Ctpt_widgetParams.fitting_default = fittingCheckbox.checked; 171 window.Ctpt_widgetParams.is_partial_redemption = partialDedemptionCheckbox.checked; 172 173 if (typeof(window.ctptData.w_geo_data_empty_message) != 'string') window.ctptData.w_geo_data_empty_message = ''; 174 if (typeof(window.ctptData.w_ws_api_domain) != 'string') window.ctptData.w_ws_api_domain = ''; 175 176 if (window.ctptData.w_geo_data_empty_message != '') window.Ctpt_widgetParams.geo_data_empty_message = window.ctptData.w_geo_data_empty_message; 177 if (window.ctptData.w_ws_api_domain != '') window.Ctpt_widgetParams.ws_api_domain = window.ctptData.w_ws_api_domain; 178 179 //cargoes 180 window.Ctpt_widgetParams.cargo = []; 181 for (let i in cData) { 182 window.Ctpt_widgetParams.cargo.push({ 183 quantity: 1, 184 height: cData[i].height, 185 length: cData[i].length, 186 width: cData[i].width, 187 weight: cData[i].weight, 188 cargo_comment: cData[i].descr, 189 190 crg_id: cData[i].id, 191 ord: cData[i].ord, 192 }); 193 } 194 195 console.log('widget_init_params', window.Ctpt_widgetParams); 196 126 197 if (!window.CatapultoWidget) { 127 198 window.CatapultoWidget = new CatapultoWidget2(window.Ctpt_widgetParams); … … 134 205 } 135 206 136 const onInsuranceChange = () => { 137 const 138 needInsurance = document.getElementById('ctpt_needInsurance'), 139 insuranseVal = document.getElementById('ctpt_insuranceValue'); 140 141 if (needInsurance.checked) insuranseVal.readOnly = false; 142 else insuranseVal.readOnly = true; 143 onPayChange(false); 144 } 145 const onDeliveryPaySideChange = () => { 146 const paySide = document.getElementById('ctpt_deliveryPaySide'); 147 if (paySide.checked && paySide.disabled) paySide.checked = false; 148 if (paySide.checked) onPayChange(); 149 else document.getElementById('ctpt_sumToPay').value = goodsPrice; 150 } 151 152 const onPayChange = (changeDeliveryPaySide = true) => { 153 const 154 needInsurance = document.getElementById('ctpt_needInsurance'), 155 isBeznal = document.getElementById('ctpt_isBeznal'), 156 paySide = document.getElementById('ctpt_deliveryPaySide'), 157 toPay = document.getElementById('ctpt_sumToPay'); 158 159 if (isBeznal.checked) { 160 toPay.value = '0'; 161 162 paySide.checked = false; 163 paySide.disabled = true; 164 207 needInsuranceCheckbox.checked = window.ctptData.isEnsurance; 208 209 210 jQuery('#ctpt_cargoes').click(function(e){ 211 e.preventDefault(); 212 jQuery('.ctpt_cargowin,.ctpt_cargowinbg').addClass('sh'); 213 return false; 214 }); 215 jQuery('.ctpt_cargowin_close').click(function(){ 216 jQuery('.ctpt_cargowin,.ctpt_cargowinbg').removeClass('sh'); 217 }); 218 219 //////////////// CALC EVENTS //////////////////////// 220 221 //страховка 222 needInsuranceCheckbox.onchange = () => { 223 if(!needInsuranceCheckbox.checked) { 224 insuranceValueInput.setAttribute('disabled', 'disabled'); 225 } else { 226 insuranceValueInput.removeAttribute('disabled'); 227 } 228 229 calculate(); 230 }; 231 //примерка 232 fittingCheckbox.onchange = () => { 233 if (fittingCheckbox.checked) { 234 partialDedemptionCheckbox.checked = true; 235 partialDedemptionCheckbox.setAttribute('disabled', 'disabled'); 236 } else { 237 partialDedemptionCheckbox.removeAttribute('disabled'); 238 } 239 if (isSingleProd) { 240 partialDedemptionCheckbox.checked = false; 241 partialDedemptionCheckbox.setAttribute('disabled', 'disabled'); 242 } 243 244 calculate(); 245 } 246 //частичный выкуп 247 partialDedemptionCheckbox.onchange = () => { 248 calculate(); 249 } 250 //заказ оплачен 251 orderPaidCheckbox.onchange = () => { 252 const maxDlvPrice = Math.min(Number(basePrice), Number(ratePrice)); 253 if ( 254 !orderPaidCheckbox.checked 255 && maxDlvPrice > 0 256 ) { 257 deliveryPaySideCheckbox.checked = true; 258 deliveryPaySideCheckbox.removeAttribute('readonly'); 259 } else { 260 deliveryPaySideCheckbox.checked = false; 261 deliveryPaySideCheckbox.setAttribute('readonly', 'readonly'); 262 } 263 264 calculate(); 265 } 266 //плательщик 267 deliveryPaySideCheckbox.onchange = () => { 268 if (deliveryPaySideCheckbox.checked && (deliveryPaySideCheckbox.attributes.getNamedItem('readonly') !== null)) { 269 deliveryPaySideCheckbox.checked = false; 270 } 271 272 calculate(); 273 } 274 275 calculate(); 276 277 //////////////// CALCPRICE //////////////////////// 278 //calculate delivery cost 279 function calculate() { 280 const productsPrice = parseFloat(goodsPrice) 281 ,baseDLVPrice = parseFloat(basePrice) 282 ,baseRatePrice = parseFloat(ratePrice) 283 ,maxDlvPrice = Math.min(baseDLVPrice, baseRatePrice) 284 //,priceLabel = $('#'+t.moduleLbl+'hidLabel_delivery_sum') 285 ; 286 let dlvSum = baseDLVPrice; 287 288 sumToPay.setAttribute('readonly', 'readonly'); 289 290 //calc delivery cost.. 291 //if (s.isSending) priceLabel.html(dlvSum); 292 if (maxDlvPrice > 0) { 293 if (insuranceValueInput.checked) dlvSum += Math.ceil(productsPrice * insuranceVal); 294 //Additinal services 295 dlvSum += calcAdditionalServiceCost(); 296 //if (s.isSending) priceLabel.html(dlvSum); 297 } 298 299 if (orderPaidCheckbox.checked) { 300 sumToPay.value = 0; 301 //priceLabel.html(baseDLVPrice); 302 303 deliveryPaySideCheckbox.checked = false; 304 deliveryPaySideCheckbox.setAttribute('readonly', 'readonly'); 165 305 if (isCSE) cseWarnMsg.classList.add('hide'); 166 306 } else { 167 let insuranseValue = Number(document.getElementById('ctpt_insuranceValue').value), 168 sumToPay = parseFloat(goodsPrice); 169 if (isNaN(insuranseValue)) insuranseValue = 0; 170 const insValue = Math.ceil(parseFloat(insuranseValue) * 0.01); 171 if (parseFloat(shippingPrice) == 0) { 172 paySide.checked = false; 173 changeDeliveryPaySide = false; 174 paySide.disabled = true; 175 } 176 if ( changeDeliveryPaySide || paySide.checked ) { 177 if ( !isInsured && needInsurance.checked ) sumToPay += insValue; 178 if ( isInsured && !needInsurance.checked ) sumToPay -= insValue; 179 180 sumToPay += parseFloat(shippingPrice); 181 } 182 toPay.value = sumToPay; 183 if (changeDeliveryPaySide || parseFloat(shippingPrice) > 0) { 184 paySide.checked = true; 185 paySide.disabled = false; 186 } 187 if (isCSE) cseWarnMsg.classList.remove('hide'); 188 } 189 190 } 191 307 let fullSum = productsPrice; 308 sumToPay.removeAttribute('readonly'); 309 /*if (s.isSending)*/ sumToPay.value = fullSum; 310 311 if (maxDlvPrice > 0) { 312 313 if (deliveryPaySideCheckbox.checked) { 314 315 fullSum += baseDLVPrice; 316 if (needInsuranceCheckbox.checked) fullSum += Math.ceil(productsPrice * insuranceVal); 317 318 fullSum += calcAdditionalServiceCost(); 319 } 320 321 /*if (s.isSending)*/ sumToPay.value = fullSum; 322 323 deliveryPaySideCheckbox.removeAttribute('readonly'); 324 //cseWarn.css('display','block'); 325 if (isCSE) cseWarnMsg.classList.remove('hide'); 326 } 327 328 } 329 } 330 331 function calcAdditionalServiceCost() { 332 let i, adtCost, cost = 0, dlvs = window.ctptData.services; 333 try { 334 dlvs = JSON.parse(dlvs); 335 } catch (e) { 336 alert('Не могу распознать сервисы. Выберите новый вариант расчета.'); 337 return 0; 338 } 339 340 for (i in dlvs) { 341 switch (dlvs[i]['name']) { 342 case 'cod_amount': 343 if (deliveryPaySideCheckbox.checked) { 344 adtCost = Number(dlvs[i]['cost']); 345 if (isNaN(adtCost)) adtCost = 0; 346 cost += adtCost; 347 } 348 break; 349 case 'fitting_amount': 350 if (fittingCheckbox.checked) { 351 adtCost = Number(dlvs[i]['cost']); 352 if (isNaN(adtCost)) adtCost = 0; 353 cost += adtCost; 354 } 355 break; 356 case 'partial_redemption_amount': 357 if (partialDedemptionCheckbox.checked) { 358 adtCost = Number(dlvs[i]['cost']); 359 if (isNaN(adtCost)) adtCost = 0; 360 cost += adtCost; 361 } 362 break; 363 } 364 } 365 return cost; 366 } 367 368 //////////////// EVENTS //////////////////////// 192 369 document.getElementById('ctpt_sendorder').onclick = sendOrder; 193 document.getElementById('ctpt_needInsurance').onchange = onInsuranceChange; 194 document.getElementById('ctpt_deliveryPaySide').onchange = onDeliveryPaySideChange; 195 document.getElementById('ctpt_isBeznal').onchange = onPayChange; 196 onPayChange(); 197 198 if (window.ctptData.isEnsurance) { 199 document.getElementById('ctpt_needInsurance').checked = true; 200 } else { 201 document.getElementById('ctpt_insuranceValue').readOnly = true; 202 } 370 if (isFitting) fittingCheckbox.checked = true; 371 let isPRDisabled = false 372 ,isPRChecked = false; 373 if (!isSingleProd && ( isFitting || isPR ) ) isPRChecked = true; 374 if ( (/*isPRChecked ||*/ isFitting) || isSingleProd ) isPRDisabled = true; 375 partialDedemptionCheckbox.checked = isPRChecked; 376 if (isPRDisabled) partialDedemptionCheckbox.setAttribute('disabled', 'disabled'); 377 378 calculate(); 379 380 //////////////// CARGO //////////////////////// 381 const tbl_header = `<tr> 382 <th>Габариты (мм)</th> 383 <th>Вес (г)</th> 384 <th>Кол-во</th> 385 <th>Артикул</th> 386 <th>Стоимость</th> 387 </tr>`; 388 const copyObj = function(obj){ 389 return JSON.parse(JSON.stringify(obj)); 390 }; 391 392 const cargoes = []; 393 // Заполнение карги здесь... 394 for (let i in cData) { 395 const crg = { 396 id: cData[i].id, 397 cargoId: cData[i].ccargo_id, 398 orderId: cData[i].ord, 399 length: cData[i].length, 400 width: cData[i].width, 401 height: cData[i].height, 402 weight: cData[i].weight, 403 volume: 0, 404 items: [], 405 }; 406 for (let j in cData[i].items) { 407 crg.items.push({ 408 id: cData[i].items[j].id, 409 productId: cData[i].items[j].id, ////////// 410 variantId: cData[i].items[j].fields.sku, 411 quantity: cData[i].items[j].quantity, 412 price: { 413 amount: cData[i].items[j].price.amount, 414 currency: cData[i].items[j].price.currency, 415 }, 416 name: cData[i].items[j].name, 417 articul: cData[i].items[j].articul, 418 weight: cData[i].items[j].weight, 419 length: cData[i].items[j].length, 420 width: cData[i].items[j].width, 421 height: cData[i].items[j].height, 422 dimEmpty: cData[i].items[j].fields.dimEmpty === true, 423 }); 424 } 425 cargoes.push(crg); 426 } 427 428 let crgdata = copyObj(cargoes); //объект для модификации... 429 430 function onReady() { 431 closeMoverWin(); 432 //generate saved cargo html 433 let i, html = '', htmlinfo = '',isFirst = true; 434 for (i in crgdata) { 435 html += addCargo(crgdata[i], Number(i)+1, isFirst); 436 htmlinfo += addCargoInfo(crgdata[i], Number(i)+1); 437 isFirst = false; 438 } 439 jQuery('.ctpt_cargo_table .cargoes').html(html); 440 jQuery('.cargo_gabs_block_content').html(htmlinfo); 441 rebindEvents(); 442 } 443 444 function addCargo(cargo, crgNum = 0, isFirst = false) { 445 let i, cargo_items='', name='', frst = isFirst ? 1 : 0; 446 if (crgNum > 0) name = 'Место ' + Number(crgNum); 447 //gen_html_items 448 for (i in cargo.items) { 449 let itm_id = cargo.items[i].id, 450 itm_prodid = cargo.items[i].productId, 451 itm_varid = cargo.items[i].variantId, 452 itm_name = cargo.items[i].name, 453 itm_art = cargo.items[i].articul, 454 itm_l = cargo.items[i].length, 455 itm_w = cargo.items[i].width, 456 itm_h = cargo.items[i].height, 457 itm_wei = cargo.items[i].weight, 458 itm_qty = cargo.items[i].quantity, 459 itm_price = cargo.items[i].price.amount, 460 itm_empty = cargo.items[i].dimEmpty ? `<tr class="ctpt_crg_itm_warn" i="${itm_id}"><td colspan="5"><p>Внимание! Габариты установлены по умолчанию. Проверьте габариты!</p></td></tr>` : ''; 461 cargo_items += `<tr class="ctpt_crg_itm_nm" i="${itm_id}"><td colspan="5" class="gds_name">${itm_name}</td></tr> 462 <tr class="ctpt_crg_itm" i="${itm_id}" pi="${itm_prodid}" vi="${itm_varid}" q="${itm_qty}"> 463 <td> 464 <div class="gabs_wr"> 465 <input class="gds_l" type="text" value="${itm_l}" /> 466 <span>X</span> 467 <input class="gds_w" type="text" value="${itm_w}" /> 468 <span>X</span> 469 <input class="gds_h" type="text" value="${itm_h}" /> 470 </div> 471 </td> 472 <td> 473 <input class="gds_wei" type="text" value="${itm_wei}" /> 474 </td> 475 <td> 476 <div class="gds_cnt"> 477 <p>${itm_qty}</p> 478 <div class="move_ico"></div> 479 </div> 480 </td> 481 <td> 482 <input class="gds_art" type="text" value="${itm_art}" /> 483 </td> 484 <td> 485 <div class="gds_price"> 486 <p>${itm_price}</p> 487 </div> 488 </td> 489 </tr> 490 ${itm_empty} 491 <tr class="ctpt_crg_itm_ln" i="${itm_id}"><td class="line" colspan="5"></td></tr>`; 492 } 493 // <p class="crg_name">${name}</p> 494 return `<div class="cargo" i="${cargo.id}" crgid="${cargo.cargoId}" frst="${frst}"> 495 <div class="close"></div> 496 <div class="hdr"> 497 <p class="crg_name">${name}</p> 498 <div class="left"> 499 <div class="cargo_gabs"> 500 <p>Габариты (мм)</p> 501 <div class="gabs_wr"> 502 <input class="cargo_l" type="text" value="${cargo.length}" /> 503 <span>X</span> 504 <input class="cargo_w" type="text" value="${cargo.width}" /> 505 <span>X</span> 506 <input class="cargo_h" type="text" value="${cargo.height}" /> 507 </div> 508 </div> 509 <div class="cargo_wei"> 510 <p>Вес (г)</p> 511 <div class="field_wr"> 512 <input class="cargo_wei" type="text" value="${cargo.weight}" /> 513 </div> 514 </div> 515 </div> 516 <div class="left"> 517 <div class="ctpt_btn ctpt_calc_cargo_gabs">Рассчитать по размерам товаров</div> 518 <div class="ctpt_btn ctpt_calc_cargo_wei">Рассчитать по весу товаров</div> 519 </div> 520 </div> 521 <table class="cargo_goods">${tbl_header}${cargo_items}</table> 522 </div>`; 523 } 524 function addCargoInfo(cargo, crgNum = 0) { 525 let name=''; 526 if (crgNum > 0) name = 'Место ' + Number(crgNum); 527 return `<p class="cnm"><b>${name}</b></p> 528 <p><b>Размеры (мм):</b> ${cargo.length} x ${cargo.width} x ${cargo.height}</p> 529 <p><b>Вес (г):</b> ${cargo.weight}</p>`; 530 } 531 532 function addNewCargo() { 533 //Проверяем - есть ли у нас грузоместа с незаполненными товарами? Если есть - не даем создавать грузоместо 534 for (let i in crgdata) { 535 if (crgdata[i].items.length == 0) { 536 alert('Уже есть грузоместо для заполнения товаров.'); 537 return false; 538 } 539 } 540 541 let newCargo = { 542 id: Date.now(), 543 cargoId: 0, 544 orderId: orderId, 545 length: 0, 546 width: 0, 547 height: 0, 548 weight: 0, 549 volume: 0, 550 items: [], 551 }; 552 crgdata.push(newCargo); 553 jQuery(addCargo(newCargo, crgdata.length)).appendTo('.ctpt_cargo_table .cargoes'); 554 rebindEvents(); 555 closeMoverWin(); 556 } 557 558 jQuery('.add_new_cargo').click(addNewCargo); 559 560 function showMoveWindow() { 561 const th=jQuery(this),t=th.parents('.ctpt_crg_itm'), crg=t.parents('.cargo'), pp=jQuery('.ctpt_move_win'); 562 if (crgdata.length < 2) { 563 alert('Необходимо создать больше грузомест для перемещения...'); 564 return; 565 } 566 let i, cnt = Number(t.attr('q')); 567 if (cnt === 0) return; 568 pp.attr('cnt', cnt); 569 pp.attr('crg_itm', crg.attr('i')); 570 pp.attr('gds_id', t.attr('i')); 571 jQuery('.ctpt_move_win select').html(''); 572 jQuery('.ctpt_move_win .place input').val(''); 573 let selects = ''; 574 for (i in crgdata) { 575 if (Number(crg.attr('i')) == Number(crgdata[i].id)) continue; 576 const nm = 'Место ' + (Number(i) + 1); 577 selects += `<option value="${crgdata[i].id}">${nm}</option>`; 578 } 579 jQuery('.ctpt_move_win select').html(selects); 580 if (crg.attr('frst') == '1') { 581 jQuery('.ctpt_move_win select option:nth-child(2)').prop('selected', true); 582 } 583 jQuery('.ctpt_move_win select option:first-child').attr('selected', 'selected'); 584 jQuery('.ctpt_move_win .place p').html(cnt + ' /'); 585 pp.addClass('sh'); 586 pp.css('left', th.offset().left - 160); 587 pp.css('top', th.offset().top - 170 + jQuery('.ctpt_cargowin')[0].scrollTop - window.pageYOffset ); 588 589 jQuery('.ctpt_move_win input').focus(); 590 } 591 function moverValidate() { 592 const t=document.querySelector('.ctpt_move_win .place input'), th=jQuery(this); 593 th.removeClass('err'); 594 t.value = t.value.replace(/\D/g, ""); 595 let vl = Number(t.value), max = jQuery('.ctpt_move_win').attr('cnt'); 596 if (vl > max) { 597 th.addClass('err'); 598 return false; 599 } 600 if (vl == 0) { 601 th.addClass('err'); 602 return false; 603 } 604 return true; 605 } 606 function digitValidate(ev) { 607 const input = ev.target; 608 input.value = input.value.replace(/\D/g, ""); 609 } 610 function saveGdsValue(ev) { 611 const input = ev.target, crg_id = jQuery(input).parents('.cargo').attr('i'); 612 let i, vl = Number(input.value); 613 for (i in crgdata) { 614 if (crgdata[i].id == crg_id) { 615 if (input.classList.contains('cargo_l')) crgdata[i].length = vl; 616 if (input.classList.contains('cargo_w')) crgdata[i].width = vl; 617 if (input.classList.contains('cargo_h')) crgdata[i].height = vl; 618 if (input.classList.contains('cargo_wei')) crgdata[i].weight = vl; 619 } 620 } 621 } 622 function saveProductValue(ev) { 623 const 624 input = ev.target, 625 crg_id = jQuery(input).parents('.cargo').attr('i'), 626 gds_id = jQuery(input).parents('.ctpt_crg_itm').attr('i'); 627 let i, j, vl = Number(input.value); 628 for (i in crgdata) { 629 if (crgdata[i].id == crg_id) { 630 for (j in crgdata[i].items) { 631 if (crgdata[i].items[j].id == gds_id) { 632 if (input.classList.contains('gds_l')) crgdata[i].items[j].length = vl; 633 if (input.classList.contains('gds_w')) crgdata[i].items[j].width = vl; 634 if (input.classList.contains('gds_h')) crgdata[i].items[j].height = vl; 635 if (input.classList.contains('gds_wei')) crgdata[i].items[j].weight = vl; 636 if (input.classList.contains('gds_art')) crgdata[i].items[j].articul = input.value; 637 } 638 } 639 } 640 } 641 } 642 643 function calcWeiForCargo(crg_id) { 644 let i, j, weight = 0; 645 for (i in crgdata) { 646 if (crgdata[i].id == crg_id) { 647 for (j in crgdata[i].items) { 648 weight += crgdata[i].items[j].weight * crgdata[i].items[j].quantity; 649 } 650 crgdata[i].weight = weight; 651 } 652 } 653 return weight; 654 } 655 656 function autoWeight(ev) { 657 const crg = jQuery(ev.target).parents('.cargo'), crg_id = crg.attr('i'), wei_inp = crg.find('.cargo_wei'); 658 wei_inp.val(calcWeiForCargo(crg_id)); 659 } 660 async function autoGabs(ev){ 661 const t=jQuery(ev.target), crg_el = t.parents('.cargo'), crg_id = crg_el.attr('i'); 662 let i, crg = []; 663 for(i in crgdata) { 664 if (crgdata[i].id == crg_id) { 665 crg = crgdata[i]; 666 break; 667 } 668 } 669 670 t.css('visibility', 'hidden'); 671 // Здесь - обработчик для калькуляции данных грузоместа.... 672 let frm = new FormData(); 673 frm.append('crg', JSON.stringify(crg)); 674 const response= await fetch('/?rest_route=/catapultodelivery/cargocalc', { 675 method: 'POST', 676 headers: headers, 677 body: frm, 678 }), res = await response.json(); 679 if (res.res) { 680 crg_el.find('.cargo_l').val(res.l); 681 crg_el.find('.cargo_w').val(res.w); 682 crg_el.find('.cargo_h').val(res.h); 683 crg.width = res.w; 684 crg.length = res.l; 685 crg.height = res.h; 686 t.css('visibility', ''); 687 } 688 } 689 690 function move(crg_from, crg_to, itm_from, cnt) { 691 //find cargo... 692 let i,j,from = false, to = false, crgFrom = false, crgTo = false; 693 for (i in crgdata) { 694 // findFrom 695 if (crgdata[i].id == crg_from) { 696 crgFrom = crgdata[i]; 697 for(j in crgdata[i].items) { 698 if (crgdata[i].items[j].id == itm_from) { 699 from = crgdata[i].items[j]; 700 crgdata[i].items[j].quantity -= cnt; 701 if (crgdata[i].items[j].quantity == 0) { 702 crgdata[i].items.splice(j,1); 703 } 704 } 705 } 706 } 707 //findTo 708 if (crgdata[i].id == crg_to) { 709 crgTo = crgdata[i]; 710 for(j in crgdata[i].items) { 711 if (crgdata[i].items[j].id == itm_from) to = crgdata[i].items[j]; 712 } 713 } 714 } 715 if (to === false) { 716 //create new item 717 crgTo.items.push({ 718 id: from.id, 719 productId: from.productId, 720 variantId: from.variantId, 721 quantity: cnt, 722 price: { 723 amount: from.price.amount, 724 currency: from.price.currency 725 }, 726 name: from.name, 727 articul: from.articul, 728 weight: from.weight, 729 length: from.length, 730 width: from.width, 731 height: from.height, 732 dimEmpty: from.dimEmpty, 733 }); 734 } else { 735 to.quantity += cnt; 736 } 737 738 calcWeiForCargo(crg_from); 739 calcWeiForCargo(crg_to); 740 } 741 742 function deleteCargo(ev) { 743 const crg_el=jQuery(ev.target).parent(), 744 first_crg_id = jQuery('.ctpt_cargo_table .cargo:first-child').attr('i'), 745 second_crg_id = jQuery('.ctpt_cargo_table .cargo:nth-child(2)').attr('i'), 746 crg_from = crg_el.attr('i'); 747 if (crgdata.length < 2) return false; //нет достаточного кол-ва грузомест 748 let i, crg_to = first_crg_id; 749 if (crg_to == crg_from) crg_to = second_crg_id; 750 751 crg_el.find('.ctpt_crg_itm').each(function(){ 752 const t=jQuery(this), itmId = t.attr('i'), qty = Number(t.attr('q')); 753 move(crg_from, crg_to, itmId, qty); 754 }); 755 //delete empty cargo 756 for (i in crgdata) { 757 if (crgdata[i].items.length == 0) crgdata.splice(i,1); 758 } 759 760 onReady(); 761 } 762 763 jQuery('#ctpt_cargoer_del').click(async function(e){ 764 e.preventDefault(); 765 if (confirm('Действительно удалить данные грузомест?')) { 766 let frm = new FormData(); 767 frm.append('order_id', orderId); 768 const response= await fetch('/?rest_route=/catapultodelivery/cargoclear', { 769 method: 'POST', 770 headers: headers, 771 body: frm, 772 }), res = await response.json(); 773 if (res.res && res.res === true) { 774 alert('Данные грузомест сброшены.') 775 setTimeout(function(){ 776 window.location.reload(); 777 },1000); 778 } 779 if (typeof(res.res) !== 'undefined' && res.res === false) { 780 let errMsg = 'Произошла неизвестная ошибка. Попробуйте снова.'; 781 switch (res.e) { 782 case 'NoOrder': 783 errMsg = 'Ошибка заказа (заказ не найден)'; 784 break; 785 } 786 jQuery('.rate_update_errors').html(errMsg).css('display','block'); 787 } 788 } 789 return false; 790 }); 791 792 jQuery('.ctpt_move_win .place input').keyup(moverValidate); 793 jQuery('.ctpt_move_win .ctpt_btn_green').click(function(){ 794 const valid = moverValidate(), pp=jQuery('.ctpt_move_win'); 795 if (!valid) return; 796 797 const crg_from = pp.attr('crg_itm'), 798 itm_from = pp.attr('gds_id'), 799 crg_to = pp.find('select').val(), 800 cnt = Number(pp.find('.place input').val()); 801 802 if (crg_from == crg_to) return; 803 move(crg_from, crg_to, itm_from, cnt); 804 onReady(); 805 }); 806 807 function rebindEvents() { 808 jQuery('.ctpt_cargo_table .move_ico').click(showMoveWindow); 809 //cargoValsInputs 810 jQuery('.ctpt_cargo_table .cargo_l').keyup(digitValidate); 811 jQuery('.ctpt_cargo_table .cargo_w').keyup(digitValidate); 812 jQuery('.ctpt_cargo_table .cargo_h').keyup(digitValidate); 813 jQuery('.ctpt_cargo_table .cargo_wei').keyup(digitValidate); 814 jQuery('.ctpt_cargo_table .cargo_l').blur(saveGdsValue); 815 jQuery('.ctpt_cargo_table .cargo_w').blur(saveGdsValue); 816 jQuery('.ctpt_cargo_table .cargo_h').blur(saveGdsValue); 817 jQuery('.ctpt_cargo_table .cargo_wei').blur(saveGdsValue); 818 819 //itemsValsInputs 820 jQuery('.ctpt_cargo_table .gds_l').keyup(digitValidate); 821 jQuery('.ctpt_cargo_table .gds_w').keyup(digitValidate); 822 jQuery('.ctpt_cargo_table .gds_h').keyup(digitValidate); 823 jQuery('.ctpt_cargo_table .gds_wei').keyup(digitValidate); 824 jQuery('.ctpt_cargo_table .gds_l').blur(saveProductValue); 825 jQuery('.ctpt_cargo_table .gds_w').blur(saveProductValue); 826 jQuery('.ctpt_cargo_table .gds_h').blur(saveProductValue); 827 jQuery('.ctpt_cargo_table .gds_wei').blur(saveProductValue); 828 jQuery('.ctpt_cargo_table .gds_art').blur(saveProductValue); 829 830 //recalc gabs 831 jQuery('.ctpt_cargo_table .ctpt_calc_cargo_gabs').click(autoGabs); 832 jQuery('.ctpt_cargo_table .ctpt_calc_cargo_wei').click(autoWeight); 833 834 //delete cargo 835 jQuery('.ctpt_cargo_table .cargo .close').click(deleteCargo); 836 } 837 838 function closeMoverWin() { 839 jQuery('.ctpt_move_win').removeClass('sh').css({left:'',top:''}); 840 } 841 842 jQuery('.ctpt_move_win .close').click(closeMoverWin); 843 844 jQuery('.ctpt_gdsdata_reset').click(function(){ 845 crgdata = copyObj(cargoes); 846 onReady(); 847 }); 848 jQuery('.ctpt_gdsdata_save').click(async function(){ 849 //check data... 850 let i,j,k,v,isValid = true; 851 const vars = ['length','width','height','weight']; 852 for (i in crgdata) { 853 for (j in vars) { 854 v = Number(crgdata[i][vars[j]]); 855 if (isNaN(v)) v = 0; 856 if (v == 0) isValid = false; 857 } 858 for (k in crgdata[i].items) { 859 for (j in vars) { 860 v = Number(crgdata[i].items[k][vars[j]]); 861 if (isNaN(v)) v = 0; 862 if (v == 0) isValid = false; 863 } 864 } 865 } 866 if (!isValid) { 867 alert('Невозможно сохранить габариты. Проверьте данные.') 868 return; 869 } 870 871 //save new crgdata 872 let frm = new FormData(); 873 frm.append('order_id', orderId); 874 frm.append('crg', JSON.stringify(crgdata)); 875 const response= await fetch('/?rest_route=/catapultodelivery/cargosave', { 876 method: 'POST', 877 headers: headers, 878 body: frm, 879 }), res = await response.json(); 880 if (res.res && res.res === true) { 881 jQuery('.ctpt_cargo_table, .ctpt_alert').css('display','none'); 882 jQuery('.rate_update_success').css('display','block'); 883 884 setTimeout(function(){ 885 window.location.reload(); 886 },5000); 887 888 } 889 if (typeof(res.res) !== 'undefined' && res.res === false) { 890 let errMsg = 'Произошла неизвестная ошибка. Попробуйте снова.'; 891 switch (res.e) { 892 case 'NoOrder': 893 errMsg = 'Ошибка заказа (заказ не найден)'; 894 break; 895 case 'corrupted': 896 errMsg = 'Данные грузоместа повреждены. Перезагрузите страницу и попробуйте сохранить снова.'; 897 break; 898 } 899 jQuery('.rate_update_errors').html(errMsg).css('display','block'); 900 } 901 }); 902 903 document.addEventListener('DOMContentLoaded',onReady); 904 905 jQuery('.cargo_gabs_block').click(function(e){ 906 const t=jQuery(this), d=jQuery('.cargo_gabs_block_content'); 907 if (t.hasClass('sh')) { 908 t.removeClass('sh'); 909 d.slideUp(); 910 } else { 911 t.addClass('sh'); 912 d.slideDown(); 913 } 914 }); 915 916 if (window.ctptData.cargo_valid === true) jQuery('.ctpt_custom_cargo_valid').css('display','none'); 917 918 jQuery('.ctpt_hintlbl').hover(function(){ 919 const el=jQuery(this).parent().find('.ctpt_hint_content'); 920 el.addClass('sh'); 921 },function(){ 922 const el=jQuery(this).parent().find('.ctpt_hint_content'); 923 el.removeClass('sh'); 924 }); 925 -
catapultodelivery/trunk/assets/js/widget_handler.js
r3417476 r3444321 8 8 isEmpty: false, 9 9 insurance: window.Ctpt_widgetParams.need_insurance, 10 pr: window.Ctpt_widgetParams.is_partial_redemption, 10 11 }; 11 12 if (typeof(Item['Variant']) !== 'undefined') { … … 23 24 isEmpty: false, 24 25 insurance: window.Ctpt_widgetParams.need_insurance, 26 pr: window.Ctpt_widgetParams.is_partial_redemption, 25 27 }; 26 28 sendVariant(Item); -
catapultodelivery/trunk/build/catapulto-checkout-block-frontend.asset.php
r3417476 r3444321 1 <?php return array('dependencies' => array('jquery', 'lodash', 'react', 'wc-blocks-checkout', 'wc-settings', 'wp-data', 'wp-element'), 'version' => ' 8fd4e5056a7c48ee2dea');1 <?php return array('dependencies' => array('jquery', 'lodash', 'react', 'wc-blocks-checkout', 'wc-settings', 'wp-data', 'wp-element'), 'version' => '6622efd779a2848fc955'); -
catapultodelivery/trunk/build/catapulto-checkout-block-frontend.js
r3417476 r3444321 1 (()=>{"use strict";var e={20:(e,t,a)=>{var r=a(609),o=Symbol.for("react.element"),i=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,n=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,d={key:!0,ref:!0,__self:!0,__source:!0};function p(e,t,a){var r,i={},p=null,c=null;for(r in void 0!==a&&(p=""+a),void 0!==t.key&&(p=""+t.key),void 0!==t.ref&&(c=t.ref),t)s.call(t,r)&&!d.hasOwnProperty(r)&&(i[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===i[r]&&(i[r]=t[r]);return{$$typeof:o,type:e,key:p,ref:c,props:i,_owner:n.current}}t.Fragment=i,t.jsx=p,t.jsxs=p},848:(e,t,a)=>{e.exports=a(20)},609:e=>{e.exports=window.React}},t={};const a=window.wc.blocksCheckout,r=window.wp.element,o=window.lodash,i=window.wc.wcSettings;window.wp.data,window.jQuery;var s=function a(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,a),i.exports}(848);const n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"catapultodelivery/catapulto-checkout-block","version":"1.0.0","title":"Catapulto Widget","category":"widgets","description":"Adds a Catapulto widget on checkout to allow user select delivery variant.","supports":{"html":false,"align":false,"multiple":false,"reusable":false},"parent":["woocommerce/checkout-shipping-methods-block"],"attributes":{"lock":{"type":"object","default":{"remove":true,"move":true}},"text":{"type":"string","default":""}},"textdomain":"catapultodelivery"}');(0,a.registerCheckoutBlock)({metadata:n,component:({checkoutExtensionData:e,extensions:t,cart:a,validation:n})=>{const d="catapultodelivery",p={isFirstSended:!1,isWidgetRun:!1},[c,l]=(0,r.useState)({isSelected:!1,isPVZ:!1,operator:"",operatorLogo:"",tarif:"",pvz:"",dlvTime:""}),[u,g]=(0,r.useState)(!1),[_,m]=(0,r.useState)(!1),[h,y]=(0,r.useState)(""),[w,f]=(0,r.useState)(!0),[v,S]=(0,r.useState)(0),[k,b]=(0,r.useState)(""),[C,x]=(0,r.useState)(""),[W,R]=(0,r.useState)(""),E={popup_mode:!0,service_path:"",sender_contact_params:{locality_id:"",zip:"",cityFrom:""},dadata_token:"",only_delivery_type:"",startTabMap:!1,delivery_type:"door",day_shift:0,inverse_delivery_type_for_operators:[],location:{address:""},cargo:{weight:0,height:0,length:0,width:0,quantity:1},need_insurance:!1,insured_value:0},[j,D]=(0,r.useState)({services_filter:"",filter_cash:!1,filter_card:!1}),[O,P]=(0,r.useState)(!1),[T,L]=(0,r.useState)(E),{setExtensionData:V}=e,{isTestMode:z,customWss:A,servicePath:F,senderLocalityId:M,senderZip:q,senderCityFrom:I,dadataToken:N,cargoHeight:Z,cargoLength:U,cargoWidth:J,cargoWeight:$,cargoComment:B,insuredValue:H,needInsurance:Q,PSCard:Y,PSCash:G,widgetDeliveryTypes:K,deliveryType:X,dayShift:ee,mapOpenMode:te,inverseOperators:ae,freeDeliveryOperators:re,operatorsSettings:oe,runOnStart:ie,opIcons:se,geoEmptyMessage:ne,freeDlvMinCourier:de,freeDlvMinPVZ:pe}=(0,i.getSetting)(d+"_data"),ce=(0,r.useCallback)((0,o.debounce)((e=>{if(V(d,"ctpt_ratedata",""),V(d,"ctpt_paychanged","true"),!a.cartNeedsShipping)return;const t=e.flatMap((e=>e.shipping_rates)).find((e=>e.selected));if(t&&Object.prototype.hasOwnProperty.call(t,"method_id")&&t.method_id===d){if(S(wc.wcSettings.getSetting("checkoutData").order_id),t.meta_data.length>0){let e={},a={isSelected:!1,isPVZ:!1,operator:"",operatorLogo:"",tarif:"",pvz:"",dlvTime:""},r="";for(let o in t.meta_data)switch(t.meta_data[o].key){case"ctpt_params":a.isPVZ="pvz"===t.meta_data[o].value.rate_type,e.ctpt_params=t.meta_data[o].value;break;case"variant":a.isSelected=!0,a.operator=t.meta_data[o].value.operator,void 0!==se[a.operator]&&(a.operatorLogo=se[a.operator]),a.tarif=t.meta_data[o].value.rate,e.variant=t.meta_data[o].value;break;case"selected":e.selected=t.meta_data[o].value;break;case"Terminal":r=t.meta_data[o].value.address+"#"+t.meta_data[o].value.code,e.Terminal=t.meta_data[o].value;break;case"dadata":e.dadata=t.meta_data[o].value;break;case"rate_param":e.rate_param=t.meta_data[o].value}a.isPVZ&&(a.pvz=r),l(a),V(d,"ctpt_ratedata",JSON.stringify(e)),V(d,"ctpt_paychanged","false")}y(t.method_id),g(!0)}else g(!1)}),1e3),[]),le=()=>{void 0===window.ctptData&&(window.ctptData=p)};(0,r.useEffect)((()=>{le()}),[]),(0,r.useEffect)((()=>{le(),a.isLoading||a.isLoadingRates||ce(a.shippingRates)}),[a.isLoading,a.isLoadingRates,a.shippingRates,a.shippingAddress]),(0,r.useEffect)((()=>{let e="";"string"==typeof a.shippingAddress.state&&a.shippingAddress.state.length>2&&(e+=a.shippingAddress.state+", "),"string"==typeof a.shippingAddress.city&&a.shippingAddress.city.length<=2||b(e+a.shippingAddress.city)}),[a.shippingAddress.city,a.shippingAddress.state]),(0,r.useEffect)((()=>{const e=document.querySelector("#payment-method .wc-block-components-radio-control"),t=document.querySelectorAll("input[name=radio-control-wc-payment-method-options]");if(null==t||null==e)return;const a=e=>{R(e.target.value)};t.forEach((e=>{e.checked&&R(e.value),e.onchange=a})),document.querySelector("#payment-method .wc-block-components-radio-control").addEventListener("DOMSubtreeModified",(()=>{document.querySelectorAll("input[name=radio-control-wc-payment-method-options]").forEach((e=>{e.checked&&R(e.value),e.onchange=a}))}))}),[document.querySelector("input[name=radio-control-wc-payment-method-options]"),document.querySelector("#payment-method .wc-block-components-radio-control")]),(0,r.useEffect)((()=>{let e=Y.includes(W),t=G.includes(W);V(d,"ctpt_paychanged","true"),D(e||t?{services_filter:"NP,COD",filter_cash:t,filter_card:e}:{services_filter:"",filter_cash:!1,filter_card:!1})}),[W]),(0,r.useEffect)((()=>{let e={...E,...j,location:{address:k},service_path:F,sender_contact_params:{locality_id:M,zip:q,cityFrom:I},dadata_token:N,only_delivery_type:K,delivery_type:X,inverse_delivery_type_for_operators:ae,free_delivery_operators:re,operators_settings:oe,day_shift:ee,cargo:{weight:$,height:Z,width:J,length:U,cargo_comment:B,quantity:1},need_insurance:Q,insured_value:H,startTabMap:te,onSelectPvzItem:we,onSelectCourierItem:ye,onRateResponse:me,onPopupClose:()=>{"function"==typeof window.CatapultoWidget.destroy&&window.CatapultoWidget.destroy(),delete window.CatapultoWidget,_e()}};(null!=z?z:"string"==typeof A)&&(e.ws_api_domain=A),ne.length>2&&(e.geo_data_empty_message=ne),de>0&&(e.free_delivery_min_courier=de),pe>0&&(e.free_delivery_min_pvz=pe),L(e),P(!0)}),[j,k]);const[ue,ge]=(0,r.useState)(0),_e=()=>{if(ge(0),window.CatapultoWidget?("function"==typeof window.CatapultoWidget.destroy&&window.CatapultoWidget.destroy(),delete window.CatapultoWidget,window.CatapultoWidget=new CatapultoWidget2(T)):window.CatapultoWidget=new CatapultoWidget2(T),_||m(!0),void 0===window.ctpt_widgetRunned&&(window.ctpt_widgetRunned=!1),!1===window.ctpt_widgetRunned&&ie){let e=!1;for(let t in a.shippingRates[0].shipping_rates)a.shippingRates[0].shipping_rates[t].method_id==d&&a.shippingRates[0].shipping_rates[t].selected&&(e=!0);e&&(window.ctpt_widgetRunned=!0,window.CatapultoWidget.show())}};(0,r.useEffect)((()=>{O&&O&&(ue>0&&clearTimeout(ue),ge(setTimeout(_e,3e3)))}),[T,u]);const me=e=>{void 0!==e.results&&e.results.forEach((e=>{void 0===e.price_orig&&(e.price_orig=e.price)}))},he=e=>{window.CatapultoWidget.hide();const t=window.CatapultoWidget.getData().getVariant();e.dadata=t,e.rate_param=window.CatapultoWidget.getData().RateParams,e.ctpt_params.order_id=wc.wcSettings.getSetting("checkoutData").order_id,e.ctpt_params.isEmpty=!1,e.ctpt_params.insurance=Q,e.ctpt_params.ps=document.querySelector("#payment-method .wc-block-components-radio-control input:checked").value,V(d,"ctpt_ratedata",JSON.stringify(e)),V(d,"ctpt_paychanged","false"),wc.blocksCheckout.extensionCartUpdate({namespace:d,data:e}).then((()=>{let t={isSelected:!0,isPVZ:"pvz"===e.ctpt_params.rate_type,operator:e.variant.operator,operatorLogo:"",tarif:e.variant.rate,pvz:"pvz"===e.ctpt_params.rate_type?e.Terminal.address+"#"+e.Terminal.code:"",dlvTime:""};void 0!==se[t.operator]&&(t.operatorLogo=se[t.operator]),l(t),le(),window.ctptData.isFirstSended||(window.ctptData.isFirstSended=!0,setTimeout((()=>{wc.blocksCheckout.extensionCartUpdate({namespace:d,data:e})}),200))}))},ye=e=>{e&&void 0!==e.variant.id&&(e.ctpt_params={rate_type:"courier",order_id:0},he(e))},we=e=>{e&&void 0!==e.Variant&&(e.ctpt_params={rate_type:"pvz",order_id:0},void 0!==e.Variant&&(e.variant=e.Variant,delete e.Variant),he(e))};return(0,s.jsxs)("div",{className:"wp-block-shipping-catapulto",style:{display:"block"},children:[(0,s.jsx)("input",{type:"hidden",name:"ctpt_hid_cityname"}),u&&(0,s.jsxs)(s.Fragment,{children:[c.isSelected&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("p",{style:{margin:"0"},children:"Способ доставки:"}),(0,s.jsxs)("p",{style:{display:"flex",alignItems:"center",margin:"0"},children:[(0,s.jsx)("b",{style:{paddingRight:"5px"},children:"Оператор: "})," ",c.operator," ",""!=c.operatorLogo&&(0,s.jsx)("img",{style:{width:"60px",marginLeft:"5px"},src:c.operatorLogo})]}),(0,s.jsxs)("p",{style:{margin:"0"},children:[(0,s.jsx)("b",{children:"Тариф: "})," ",c.tarif]}),c.isPVZ&&(0,s.jsxs)("p",{style:{margin:"0"},children:[(0,s.jsx)("b",{children:"ПВЗ: "})," ",c.pvz]})]}),_&&(0,s.jsx)("button",{onClick:e=>{e.preventDefault(),window.CatapultoWidget&&window.CatapultoWidget.show()},style:{height:"40px",width:"220px",background:"#01bd6c",border:"1px solid #01bd6c",borderRadius:"6px",color:"#fff",cursor:"pointer",fontWeight:"700",transition:".5s"},children:"Выбрать способ доставки"})]})]})}})})();1 (()=>{"use strict";var e={20:(e,t,a)=>{var i=a(609),o=Symbol.for("react.element"),r=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,n=i.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,d={key:!0,ref:!0,__self:!0,__source:!0};function p(e,t,a){var i,r={},p=null,c=null;for(i in void 0!==a&&(p=""+a),void 0!==t.key&&(p=""+t.key),void 0!==t.ref&&(c=t.ref),t)s.call(t,i)&&!d.hasOwnProperty(i)&&(r[i]=t[i]);if(e&&e.defaultProps)for(i in t=e.defaultProps)void 0===r[i]&&(r[i]=t[i]);return{$$typeof:o,type:e,key:p,ref:c,props:r,_owner:n.current}}t.Fragment=r,t.jsx=p,t.jsxs=p},848:(e,t,a)=>{e.exports=a(20)},609:e=>{e.exports=window.React}},t={};const a=window.wc.blocksCheckout,i=window.wp.element,o=window.lodash,r=window.wc.wcSettings;window.wp.data,window.jQuery;var s=function a(i){var o=t[i];if(void 0!==o)return o.exports;var r=t[i]={exports:{}};return e[i](r,r.exports,a),r.exports}(848);const n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"catapultodelivery/catapulto-checkout-block","version":"1.0.0","title":"Catapulto Widget","category":"widgets","description":"Adds a Catapulto widget on checkout to allow user select delivery variant.","supports":{"html":false,"align":false,"multiple":false,"reusable":false},"parent":["woocommerce/checkout-shipping-methods-block"],"attributes":{"lock":{"type":"object","default":{"remove":true,"move":true}},"text":{"type":"string","default":""}},"textdomain":"catapultodelivery"}');(0,a.registerCheckoutBlock)({metadata:n,component:({checkoutExtensionData:e,extensions:t,cart:a,validation:n})=>{const d="catapultodelivery",p={isFirstSended:!1,isWidgetRun:!1},[c,l]=(0,i.useState)({isSelected:!1,isPVZ:!1,operator:"",operatorLogo:"",tarif:"",pvz:"",dlvTime:""}),[u,g]=(0,i.useState)(!1),[m,_]=(0,i.useState)(!1),[h,w]=(0,i.useState)(""),[y,f]=(0,i.useState)(!0),[v,S]=(0,i.useState)(0),[k,b]=(0,i.useState)(""),[C,x]=(0,i.useState)(""),[W,R]=(0,i.useState)(""),E={popup_mode:!0,service_path:"",sender_contact_params:{locality_id:"",zip:"",cityFrom:""},dadata_token:"",only_delivery_type:"",startTabMap:!1,delivery_type:"door",day_shift:0,inverse_delivery_type_for_operators:[],location:{address:""},cargo:{weight:0,height:0,length:0,width:0,quantity:1},need_insurance:!1,insured_value:0},[j,D]=(0,i.useState)({services_filter:"",filter_cash:!1,filter_card:!1}),[O,P]=(0,i.useState)(!1),[T,L]=(0,i.useState)(E),{setExtensionData:V}=e,{isTestMode:A,customWss:z,servicePath:F,senderLocalityId:M,senderZip:q,senderCityFrom:I,dadataToken:N,cargoHeight:Z,cargoLength:U,cargoWidth:J,cargoWeight:$,cargoComment:B,insuredValue:H,needInsurance:Q,PSCard:Y,PSCash:G,widgetDeliveryTypes:K,deliveryType:X,dayShift:ee,mapOpenMode:te,inverseOperators:ae,freeDeliveryOperators:ie,operatorsSettings:oe,runOnStart:re,opIcons:se,geoEmptyMessage:ne,freeDlvMinCourier:de,freeDlvMinPVZ:pe,isFitting:ce,fittingDefaultEnabled:le,partialRedemptionEnabled:ue}=(0,r.getSetting)(d+"_data"),ge=(0,i.useCallback)((0,o.debounce)((e=>{if(V(d,"ctpt_ratedata",""),V(d,"ctpt_paychanged","true"),!a.cartNeedsShipping)return;const t=e.flatMap((e=>e.shipping_rates)).find((e=>e.selected));if(t&&Object.prototype.hasOwnProperty.call(t,"method_id")&&t.method_id===d){if(S(wc.wcSettings.getSetting("checkoutData").order_id),t.meta_data.length>0){let e={},a={isSelected:!1,isPVZ:!1,operator:"",operatorLogo:"",tarif:"",pvz:"",dlvTime:""},i="";for(let o in t.meta_data)switch(t.meta_data[o].key){case"ctpt_params":a.isPVZ="pvz"===t.meta_data[o].value.rate_type,e.ctpt_params=t.meta_data[o].value;break;case"variant":a.isSelected=!0,a.operator=t.meta_data[o].value.operator,void 0!==se[a.operator]&&(a.operatorLogo=se[a.operator]),a.tarif=t.meta_data[o].value.rate,e.variant=t.meta_data[o].value;break;case"selected":e.selected=t.meta_data[o].value;break;case"Terminal":i=t.meta_data[o].value.address+"#"+t.meta_data[o].value.code,e.Terminal=t.meta_data[o].value;break;case"dadata":e.dadata=t.meta_data[o].value;break;case"rate_param":e.rate_param=t.meta_data[o].value}a.isPVZ&&(a.pvz=i),l(a),V(d,"ctpt_ratedata",JSON.stringify(e)),V(d,"ctpt_paychanged","false")}w(t.method_id),g(!0)}else g(!1)}),1e3),[]),me=()=>{void 0===window.ctptData&&(window.ctptData=p)};(0,i.useEffect)((()=>{me()}),[]),(0,i.useEffect)((()=>{me(),a.isLoading||a.isLoadingRates||ge(a.shippingRates)}),[a.isLoading,a.isLoadingRates,a.shippingRates,a.shippingAddress]),(0,i.useEffect)((()=>{let e="";"string"==typeof a.shippingAddress.state&&a.shippingAddress.state.length>2&&(e+=a.shippingAddress.state+", "),"string"==typeof a.shippingAddress.city&&a.shippingAddress.city.length<=2||b(e+a.shippingAddress.city)}),[a.shippingAddress.city,a.shippingAddress.state]),(0,i.useEffect)((()=>{const e=document.querySelector("#payment-method .wc-block-components-radio-control"),t=document.querySelectorAll("input[name=radio-control-wc-payment-method-options]");if(null==t||null==e)return;const a=e=>{R(e.target.value)};t.forEach((e=>{e.checked&&R(e.value),e.onchange=a})),document.querySelector("#payment-method .wc-block-components-radio-control").addEventListener("DOMSubtreeModified",(()=>{document.querySelectorAll("input[name=radio-control-wc-payment-method-options]").forEach((e=>{e.checked&&R(e.value),e.onchange=a}))}))}),[document.querySelector("input[name=radio-control-wc-payment-method-options]"),document.querySelector("#payment-method .wc-block-components-radio-control")]),(0,i.useEffect)((()=>{let e=Y.includes(W),t=G.includes(W);V(d,"ctpt_paychanged","true"),D(e||t?{services_filter:"NP,COD",filter_cash:t,filter_card:e}:{services_filter:"",filter_cash:!1,filter_card:!1})}),[W]),(0,i.useEffect)((()=>{let e={...E,...j,location:{address:k},service_path:F,sender_contact_params:{locality_id:M,zip:q,cityFrom:I},isMultiWarehouse:!0,dadata_token:N,only_delivery_type:K,day_shift:ee,cargo:{weight:$,height:Z,width:J,length:U,cargo_comment:B,quantity:1},need_insurance:Q,insured_value:H,startTabMap:te,is_fitting:ce,fitting_default:le,is_partial_redemption:ue,onSelectPvzItem:Se,onSelectCourierItem:ve,onRateResponse:ye,onPopupClose:()=>{"function"==typeof window.CatapultoWidget.destroy&&window.CatapultoWidget.destroy(),delete window.CatapultoWidget,we()}};(null!=A?A:"string"==typeof z)&&(e.ws_api_domain=z),ne.length>2&&(e.geo_data_empty_message=ne),L(e),P(!0)}),[j,k]);const[_e,he]=(0,i.useState)(0),we=()=>{if(he(0),window.CatapultoWidget?("function"==typeof window.CatapultoWidget.destroy&&window.CatapultoWidget.destroy(),delete window.CatapultoWidget,window.CatapultoWidget=new CatapultoWidget2(T)):window.CatapultoWidget=new CatapultoWidget2(T),m||_(!0),void 0===window.ctpt_widgetRunned&&(window.ctpt_widgetRunned=!1),!1===window.ctpt_widgetRunned&&re){let e=!1;for(let t in a.shippingRates[0].shipping_rates)a.shippingRates[0].shipping_rates[t].method_id==d&&a.shippingRates[0].shipping_rates[t].selected&&(e=!0);e&&(window.ctpt_widgetRunned=!0,window.CatapultoWidget.show())}};(0,i.useEffect)((()=>{O&&O&&(_e>0&&clearTimeout(_e),he(setTimeout(we,3e3)))}),[T,u]);const ye=e=>{void 0!==e.results&&e.results.forEach((e=>{void 0===e.price_orig&&(e.price_orig=e.price)}))},fe=e=>{window.CatapultoWidget.hide();const t=window.CatapultoWidget.getData().getVariant();e.dadata=t,e.rate_param=window.CatapultoWidget.getData().RateParams,e.ctpt_params.order_id=wc.wcSettings.getSetting("checkoutData").order_id,e.ctpt_params.isEmpty=!1,e.ctpt_params.insurance=Q,e.ctpt_params.ps=document.querySelector("#payment-method .wc-block-components-radio-control input:checked").value,e.ctpt_params.pr=ue,V(d,"ctpt_ratedata",JSON.stringify(e)),V(d,"ctpt_paychanged","false"),wc.blocksCheckout.extensionCartUpdate({namespace:d,data:e}).then((()=>{let t={isSelected:!0,isPVZ:"pvz"===e.ctpt_params.rate_type,operator:e.variant.operator,operatorLogo:"",tarif:e.variant.rate,pvz:"pvz"===e.ctpt_params.rate_type?e.Terminal.address+"#"+e.Terminal.code:"",dlvTime:""};void 0!==se[t.operator]&&(t.operatorLogo=se[t.operator]),l(t),me(),window.ctptData.isFirstSended||(window.ctptData.isFirstSended=!0,setTimeout((()=>{wc.blocksCheckout.extensionCartUpdate({namespace:d,data:e})}),200))}))},ve=e=>{e&&void 0!==e.variant.id&&(e.ctpt_params={rate_type:"courier",order_id:0},fe(e))},Se=e=>{e&&void 0!==e.Variant&&(e.ctpt_params={rate_type:"pvz",order_id:0},void 0!==e.Variant&&(e.variant=e.Variant,delete e.Variant),fe(e))};return(0,s.jsxs)("div",{className:"wp-block-shipping-catapulto",style:{display:"block"},children:[(0,s.jsx)("input",{type:"hidden",name:"ctpt_hid_cityname"}),u&&(0,s.jsxs)(s.Fragment,{children:[c.isSelected&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("p",{style:{margin:"0"},children:"Способ доставки:"}),(0,s.jsxs)("p",{style:{display:"flex",alignItems:"center",margin:"0"},children:[(0,s.jsx)("b",{style:{paddingRight:"5px"},children:"Оператор: "})," ",c.operator," ",""!=c.operatorLogo&&(0,s.jsx)("img",{style:{width:"60px",marginLeft:"5px"},src:c.operatorLogo})]}),(0,s.jsxs)("p",{style:{margin:"0"},children:[(0,s.jsx)("b",{children:"Тариф: "})," ",c.tarif]}),c.isPVZ&&(0,s.jsxs)("p",{style:{margin:"0"},children:[(0,s.jsx)("b",{children:"ПВЗ: "})," ",c.pvz]})]}),m&&(0,s.jsx)("button",{onClick:e=>{e.preventDefault(),window.CatapultoWidget&&window.CatapultoWidget.show()},style:{height:"40px",width:"220px",background:"#01bd6c",border:"1px solid #01bd6c",borderRadius:"6px",color:"#fff",cursor:"pointer",fontWeight:"700",transition:".5s"},children:"Выбрать способ доставки"})]})]})}})})(); -
catapultodelivery/trunk/catapultodelivery.php
r3417476 r3444321 4 4 * Plugin URI: https://catapulto.ru 5 5 * Description: Catapulto delivery service 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 5.9 8 8 * Text Domain: catapultodelivery -
catapultodelivery/trunk/languages/ipol_catapultodelivery-ru_RU.po
r3417476 r3444321 131 131 msgstr "Основные" 132 132 133 msgid "Terminals "134 msgstr "Терминалы "133 msgid "Terminals and warehouses" 134 msgstr "Терминалы и склады" 135 135 136 136 msgid "Dimensions and delivery settings" … … 245 245 msgstr "Город отправителя" 246 246 247 msgid "The city from which you send orders. For example, \"Moscow\"(without quotes)"248 msgstr "Город из которого вы отправляете заказы. Например, \"Москва\"(без кавычек)"247 msgid "The city from which you send orders. For example, «Moscow» (without quotes)" 248 msgstr "Город из которого вы отправляете заказы. Например, «Москва» (без кавычек)" 249 249 250 250 msgid "Default Sender ID" … … 257 257 msgstr "Уточнить нужное значение для этой настройки можно у менеджера Catapulto" 258 258 259 msgid "Enable sending by proxy (for \"Business Lines\")"260 msgstr "Включить отправку по доверенности (для \"Деловые линии\")"259 msgid "Enable sending by proxy (for «Business Lines»)" 260 msgstr "Включить отправку по доверенности (для «Деловые линии»)" 261 261 262 262 msgid "Full name of contact person" … … 434 434 msgstr "Возврат документов" 435 435 436 msgid "Ready to pickup" 437 msgstr "Готов к выдаче" 438 436 439 msgid "First page" 437 440 msgstr "Первая страница" … … 482 485 msgstr "Вашему отправлению присвоен трек-номер" 483 486 487 msgid "Enable local version of widget" 488 msgstr "Использовать локальную версию виджета" 489 490 msgid "Do not use this option" 491 msgstr "Не используйте эту опцию" 492 493 msgid "The dispatch warehouse was not found. You must select a warehouse and a new rate for the shipment" 494 msgstr "Склад отправления не найден, необходимо выбрать склад и новый тариф для отправления" 495 496 msgid "I cant read the cargo details for this order" 497 msgstr "Не могу прочитать данные грузомест этого заказа" 498 499 msgid "The weight of the product is not specified" 500 msgstr "Не задан вес у товара" 501 502 msgid "The height of the product is not set" 503 msgstr "Не задана высота у товара" 504 505 msgid "The product length is not specified" 506 msgstr "Не задана длина у товара" 507 508 msgid "The width of the product is not set" 509 msgstr "Не задана ширина у товара" 510 511 msgid "A mismatch of cargo units was detected. Please reselect the delivery option" 512 msgstr "Обнаружено несовпадение грузомест. Необходимо повторно выбрать вариант доставки" 513 514 msgid "A discrepancy was detected between the order basket and the package contents. You must delete the packages, recreate them, and select a new shipping calculation" 515 msgstr "Обнаружено несовпадение корзины заказа и состава грузомест. Необходимо удалить грузоместа, составить их заново и выбрать новый расчет доставки" 516 517 msgid "The Fitting service is included, but the billing was made without this service. A new billing is required" 518 msgstr "Включена услуга \"Примерка\", но расчет сделан без учета этой услуги. Необходимо выполнить новый расчет" 519 520 msgid "Add warehouse" 521 msgstr "Добавить склад" 522 523 msgid "Default warehouse" 524 msgstr "Склад по умолчанию" 525 526 msgid "Warehouse title" 527 msgstr "Название склада" 528 529 msgid "Settlement" 530 msgstr "Населенный пункт" 531 532 msgid "Coordinates (latitude, longitude)" 533 msgstr "Координаты (широта, долгота)" 534 535 msgid "Latitude" 536 msgstr "Широта" 537 538 msgid "Longitude" 539 msgstr "Долгота" 540 541 msgid "Not selected" 542 msgstr "Не выбрано" 543 544 msgid "Senders city ID" 545 msgstr "ID города отправителя" 546 547 msgid "The city ID from which you ship orders. Please confirm this information with your Catapulto manager" 548 msgstr "ID города из которого вы отправляете заказы. Уточните данную информацию у менеджера Catapulto" 549 550 msgid "The city postcode from which you ship orders. Please contact your Catapulto manager for this information" 551 msgstr "Индекс города из которого вы отправляете заказы. Уточните данную информацию у менеджера Catapulto" 552 553 msgid "Warehouse enabled" 554 msgstr "Склад включен" 555 556 msgid "Delete warehouse" 557 msgstr "Удалить склад" 558 559 msgid "Delivery operators" 560 msgstr "Операторы доставки" 561 562 msgid "Free delivery" 563 msgstr "Бесплатная доставка" 564 565 msgid "Default sending method" 566 msgstr "Способ отправки" 567 568 msgid "Default terminal code" 569 msgstr "Код терминала по умолчанию" 570 571 msgid "Fitting available" 572 msgstr "Примерка доступна" 573 574 msgid "Enable try-on feature. When you select try-on, the widget will only display delivery rates with try-on available" 575 msgstr "Включить возможность примерки. При выборе примерки в виджете отобразятся только тарифы доставки с доступной примеркой" 576 577 msgid "Fitting enabled by default" 578 msgstr "Включать примерку по умолчанию" 579 580 msgid "By default, the try-on mode is enabled when the widget is launched" 581 msgstr "По умолчанию режим примерки включен при запуске виджета" 582 583 msgid "Enable partial buyback by default" 584 msgstr "Включать частичный выкуп по умолчанию" 585 586 msgid "Enable the partial buyback service by default" 587 msgstr "Включить услугу частичного выкупа по умолчанию" 588 -
catapultodelivery/trunk/libs/Api/Entity/Request/Part/ShipmentNpData/Item.php
r3417476 r3444321 10 10 protected $name; 11 11 12 /** @var int */12 /** @var float */ 13 13 protected $quantity; 14 14 … … 63 63 64 64 /** 65 * @return int66 */ 67 public function getQuantity(): int65 * @return float 66 */ 67 public function getQuantity(): float 68 68 { 69 69 return $this->quantity; … … 71 71 72 72 /** 73 * @param int $quantity73 * @param float $quantity 74 74 * 75 75 * @return Item 76 76 */ 77 public function setQuantity( int $quantity): Item77 public function setQuantity(float $quantity): Item 78 78 { 79 79 $this->quantity = $quantity; -
catapultodelivery/trunk/libs/Api/Entity/Request/Terminal.php
r3417476 r3444321 55 55 56 56 /** 57 * @var string|null 58 */ 59 protected $iso; 60 61 /** 57 62 * @return int 58 63 */ … … 276 281 } 277 282 283 public function getIso(): ?string 284 { 285 return $this->iso; 286 } 287 288 public function setIso(?string $iso): Terminal 289 { 290 $this->iso = $iso; 291 return $this; 292 } 293 278 294 } -
catapultodelivery/trunk/libs/Core/Delivery/Cargo.php
r3417476 r3444321 93 93 $this->reset(); 94 94 while ($item = $this->getNext()) { 95 $arGabs[] = array($item->getLength(), $item->getWidth(), $item->getHeight(), $item->getQuantity());95 $arGabs[] = array($item->getLength(), $item->getWidth(), $item->getHeight(), ceil($item->getQuantity())); 96 96 } 97 97 … … 133 133 while($obItem = $this->getNext()) 134 134 { 135 $arGabs[] = array($obItem->getLength(), $obItem->getWidth(), $obItem->getHeight(), $obItem->getQuantity());135 $arGabs[] = array($obItem->getLength(), $obItem->getWidth(), $obItem->getHeight(), ceil($obItem->getQuantity())); 136 136 } 137 137 -
catapultodelivery/trunk/libs/Core/Delivery/CargoItem.php
r3417476 r3444321 365 365 ->setHeight((int)$data['height']) 366 366 ->setWeight((int)$data['weight']) 367 ->setQuantity(( int)$data['quantity'])367 ->setQuantity((float)$data['quantity']) 368 368 ->setPrice(new Money((float)$data['price']['amount'], $data['price']['currency'])) 369 369 ->setCost(new Money((float)$data['price']['amount'], $data['price']['currency'])) -
catapultodelivery/trunk/libs/Core/Entity/Money.php
r3417476 r3444321 91 91 public function getAmount(): float 92 92 { 93 return floatval(number_format($this->amount / pow(10, self::$decimal), self::$decimal, '.', ''));93 return (float)number_format($this->amount / pow(10, self::$decimal), self::$decimal, '.', ''); 94 94 } 95 95 -
catapultodelivery/trunk/libs/Core/Order/Item.php
r3417476 r3444321 50 50 protected $price; 51 51 /** 52 * @var float 53 */ 54 protected $quantity; 55 /** 56 * @var string 57 */ 58 protected $barcode; 59 /** 60 * @var string 61 */ 62 protected $id; 63 /** 64 * @var string 65 */ 66 protected $articul; 67 /** 52 68 * @var int 53 69 */ 54 protected $quantity;55 /**56 * @var string57 */58 protected $barcode;59 /**60 * @var string61 */62 protected $id;63 /**64 * @var string65 */66 protected $articul;67 /**68 * @var int69 */70 70 protected $vatRate; 71 71 /** … … 265 265 266 266 /** 267 * @return int267 * @return floot 268 268 */ 269 269 public function getQuantity() … … 273 273 274 274 /** 275 * @param int $quantity275 * @param float $quantity 276 276 * @return $this 277 277 */ -
catapultodelivery/trunk/libs/Core/Order/Payment.php
r3417476 r3444321 60 60 */ 61 61 protected $isBeznal; 62 63 /** 64 * @var bool 65 * 1 for NP, 0 without NP 66 */ 67 protected $isNp; 68 69 /** 70 * @var bool 71 * 1 for COD, 0 without COD 72 */ 73 protected $isCod; 74 75 /** 76 * @var bool 77 * 1 for SMS, 0 without SMS service 78 */ 79 protected $isSmsAmount; 62 80 63 81 /** … … 107 125 return $this; 108 126 } 109 127 110 128 /** 111 129 * @return bool 112 130 */ 131 public function getIsNp(): bool 132 { 133 return $this->isNp; 134 } 135 136 /** 137 * @return bool 138 */ 139 public function getIsCod(): bool 140 { 141 return $this->isCod; 142 } 143 144 /** 145 * @return bool 146 */ 147 public function getIsSmsAmount(): bool 148 { 149 return $this->isSmsAmount; 150 } 151 152 /** 153 * @return bool 154 */ 113 155 public function getIsBeznal(): bool 114 156 { … … 126 168 return $this; 127 169 } 170 171 /** 172 * @param bool $isNp 173 * @return $this 174 */ 175 public function setIsNp(bool $isNp): Payment 176 { 177 $this->isNp = $isNp; 178 179 return $this; 180 } 181 182 /** 183 * @param bool $isCod 184 * @return $this 185 */ 186 public function setIsCod(bool $isCod): Payment 187 { 188 $this->isCod = $isCod; 189 190 return $this; 191 } 192 193 /** 194 * @param bool $isSmsAmount 195 * @return $this 196 */ 197 public function setIsSmsAmount(bool $isSmsAmount): Payment 198 { 199 $this->isSmsAmount = $isSmsAmount; 200 201 return $this; 202 } 128 203 129 204 /** -
catapultodelivery/trunk/libs/Wordpress/CatapultoPlugin.php
r3417476 r3444321 11 11 use Ipol\Catapulto\Wordpress\DB\DBTools; 12 12 use Ipol\Catapulto\Wordpress\DB\OrdersDB; 13 use Ipol\Catapulto\Wordpress\DB\WarehousesDB; 13 14 use Ipol\Catapulto\Wordpress\Frontend\CheckoutBlock; 14 15 use Ipol\Catapulto\Wordpress\Rest\RestHandler; … … 26 27 private static $mainPluginDir = ''; 27 28 private static $mainPluginUrl = ''; 29 private static $pluginVersion = ''; 28 30 private $pluginBaseName; 31 32 /** @var string Рассчитывать средние габариты для заказа */ 33 const DEFMODE_O = 'O'; 34 /** @var string Рассчитывать средние габариты для товара */ 35 const DEFMODE_G = 'G'; 36 37 public const ORDER_META_CARGO = 'ctpt_cargodata'; 38 public const ORDER_META_CARGOCOMMENT = 'ctpt_cargocomment'; 29 39 30 40 //OtherConsts … … 34 44 { 35 45 return self::$mainPluginDir; 46 } 47 48 public static function getPluginVersionCode():int 49 { 50 $version = self::$pluginVersion; 51 if (empty($version)) { 52 return 0; 53 } 54 $versionAr = explode('.', $version); 55 $i = 1; 56 return array_reduce(array_reverse($versionAr), function ($carry, $item) use (&$i) { 57 return $carry + (intval($item) * ($i *= 10)); 58 }, 0); 59 } 60 61 public static function isPluginActive():bool 62 { 63 if (empty(self::$mainPluginDir)) { 64 return false; 65 } 66 if (empty(self::$mainPluginFile)) { 67 return false; 68 } 69 $basePluginDir = dirname(self::$mainPluginDir) . '/'; 70 $pluginPath = str_replace($basePluginDir, '', self::$mainPluginFile); 71 return is_plugin_active($pluginPath); 36 72 } 37 73 … … 41 77 self::$mainPluginDir = dirname($mainPluginFile); 42 78 self::$mainPluginUrl = plugin_dir_url($mainPluginFile); 79 self::$pluginVersion = get_file_data($mainPluginFile, ['Version'])[0]; 43 80 $this->pluginBaseName = plugin_basename($mainPluginFile); 44 81 … … 47 84 ->setMainPluginFile(self::$mainPluginFile) 48 85 ->setMainPluginUrl(self::$mainPluginUrl) 49 ->setPliginVersion( get_file_data($mainPluginFile, ['Version'])[0]);86 ->setPliginVersion(self::$pluginVersion); 50 87 51 88 $this->wpInit(); … … 67 104 68 105 add_action('woocommerce_shipping_methods', static function($methods) { 106 if (self::isPluginActive()) { 107 CatapultoModuleUpdate::checkUpdate(self::getPluginVersionCode()); 108 } 69 109 $methods[CatapultoPlugin::PLUGIN_ID] = CatapultoShippingMethod::class; 70 110 return $methods; … … 73 113 add_action('wp_head', static function () { 74 114 if (function_exists('wp_enqueue_script_module') && class_exists(FeaturesUtil::class)) { 75 wp_enqueue_script_module('catapulto_widget', 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js',[]); 115 $shippingMethod = new CatapultoShippingMethod(); 116 $settings = $shippingMethod->getAllSettings(); 117 $widgetPath = 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js'; 118 if (($settings['enLocalWidget'] ?? 'no') === 'yes') $widgetPath = Variables::getMainPluginUrl() . 'assets/js/catapulto-widget.js'; 119 wp_enqueue_script_module('catapulto_widget', $widgetPath,[]); 76 120 } 77 121 }); … … 86 130 ); 87 131 wp_enqueue_style('ctpt_manage', self::$mainPluginUrl . 'assets/css/admin.css'); 88 wp_enqueue_script_module('widget', 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js'); 132 $shippingMethod = new CatapultoShippingMethod(); 133 $settings = $shippingMethod->getAllSettings(); 134 $widgetPath = 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js'; 135 if (($settings['enLocalWidget'] ?? 'no') === 'yes') $widgetPath = Variables::getMainPluginUrl() . 'assets/js/catapulto-widget.js'; 136 wp_enqueue_script_module('catapulto_widget', $widgetPath); 89 137 }); 90 138 … … 238 286 ]); 239 287 288 //Cargoes 289 register_rest_route(self::PLUGIN_ID, '/cargocalc', [ 290 'methods' => \WP_REST_Server::EDITABLE, 291 'callback' => [RestHandler::class, 'calcCargoDims'], 292 'permission_callback' => function() { 293 $currentUser = wp_get_current_user(); 294 return in_array('administrator',$currentUser->roles); 295 }, 296 'show_in_index' => true, 297 'args' => [], 298 ]); 299 300 register_rest_route(self::PLUGIN_ID, '/cargosave', [ 301 'methods' => \WP_REST_Server::EDITABLE, 302 'callback' => [RestHandler::class, 'cargoSave'], 303 'permission_callback' => function() { 304 $currentUser = wp_get_current_user(); 305 return in_array('administrator',$currentUser->roles); 306 }, 307 'show_in_index' => true, 308 'args' => [], 309 ]); 310 311 register_rest_route(self::PLUGIN_ID, '/cargoclear', [ 312 'methods' => \WP_REST_Server::EDITABLE, 313 'callback' => [RestHandler::class, 'cargoClear'], 314 'permission_callback' => function() { 315 $currentUser = wp_get_current_user(); 316 return in_array('administrator',$currentUser->roles); 317 }, 318 'show_in_index' => true, 319 'args' => [], 320 ]); 321 240 322 // For old version WP 241 323 register_rest_route(self::PLUGIN_ID, '/wpold_ctptsave', [ … … 491 573 add_action('wp_footer', static function () { 492 574 if (!is_checkout()) return; 493 wp_enqueue_script_module('widget', 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js'); 575 $shippingMethod = new CatapultoShippingMethod(); 576 $settings = $shippingMethod->getAllSettings(); 577 $widgetPath = 'https://widgetcdn.catapulto.ru/assets/js/catapulto-widget/v3/catapulto-widget.js'; 578 if (($settings['enLocalWidget'] ?? 'no') === 'yes') $widgetPath = Variables::getMainPluginUrl() . 'assets/js/catapulto-widget.js'; 579 wp_enqueue_script_module('catapulto_widget', $widgetPath); 494 580 wp_enqueue_script('ctpt_widget_handler', self::$mainPluginUrl . 'assets/js/widget_handler.js', ['jquery'], self::ASSETS_VERSION, true); 495 581 }); … … 509 595 $settings = $shippingMethod->getAllSettings(); 510 596 $cargo = Calculator::getCurrentCargoDataByCart(); 597 $cargoAmount = Calculator::getCartAmount(); 511 598 512 599 $mainController = new MainController( … … 519 606 ); 520 607 521 $widgetDeliveryFrom = $settings['widgetDeliveryFrom'];522 $operatorsSettings = [];523 $inverseOperators = [];524 $freeDeliveryOperators = [];525 608 $icons = []; 526 609 $companyIcons = $mainController->getCompanyIcons(); … … 529 612 while ($el = $elements->getNext()) { 530 613 $icons[$el->getOperatorId()] = $el->getIcon(); 531 532 $operatorSetting = [533 'operator' => $el->getOperatorId(),534 'inverse_delivery_type' => false,535 'free_delivery' => false,536 ];537 538 if ($settings['op_type_' . $el->getOperatorId()] != $widgetDeliveryFrom ) {539 $inverseOperators[] = $el->getOperatorId();540 $operatorSetting['inverse_delivery_type'] = true;541 }542 543 if ($settings['op_free_' . $el->getOperatorId()] === 'yes' ) {544 $freeDeliveryOperators[] = $el->getOperatorId();545 $operatorSetting['free_delivery'] = true;546 }547 $operatorsSettings[] = $operatorSetting;548 614 } 549 615 } … … 554 620 $customWSS = ''; 555 621 if ($settings['isTest'] === 'yes') $customWSS = "ws_api_domain: '{$settings['customWSUrl']}',"; 556 557 $inverseOperatorsStr = "'" . implode("', '", $inverseOperators) . "'";558 if (empty($inverseOperators)) $inverseOperatorsStr = '';559 560 $freeDeliveryOperatorsStr = "'" . implode("', '", $freeDeliveryOperators) . "'";561 if (empty($freeDeliveryOperators)) $freeDeliveryOperatorsStr = '';562 563 $freeDlvMinCourier = '';564 if (floatval($settings['freeDlvMinCourier']) > 0) $freeDlvMinCourier = 'free_delivery_min_courier: ' . floatval($settings['freeDlvMinCourier']) . ',';565 $freeDlvMinPVZ = '';566 if (floatval($settings['freeDlvMinPVZ']) > 0) $freeDlvMinPVZ = 'free_delivery_min_pvz: ' . floatval($settings['freeDlvMinPVZ']) . ',';567 568 // operators_settings569 $operatorSettingsStr = '';570 foreach ($operatorsSettings as $st) {571 if (!empty($operatorSettingsStr)) $operatorSettingsStr .= ',';572 $operatorSettingsStr .= '{"operator":"'.$st['operator'].'", "inverse_delivery_type": '.($st['inverse_delivery_type']?'true':'false').', "free_delivery": '.($st['free_delivery']?'true':'false').'}';573 }574 622 575 623 $isCard = false; … … 590 638 } 591 639 640 $localityId = 0; 641 $zip = ''; 642 $cityFrom = ''; 643 $selectedWH = $shippingMethod->getSenderWarehouse(); 644 if (is_array($selectedWH)) { 645 $localityId = $selectedWH['city_id']; 646 $zip = $selectedWH['city_index']; 647 $cityFrom = $selectedWH['city_name']; 648 } 649 592 650 $script = "window.Ctpt_widgetParams = { 593 651 popup_mode: true, 594 652 service_path: '/?rest_route=/catapultodelivery/widgethandler', 595 653 sender_contact_params: { 596 locality_id: '{$ settings['senderLocalityId']}',597 zip: '{$ settings['senderZip']}',598 cityFrom: '{$ settings['senderCity']}',654 locality_id: '{$localityId}', 655 zip: '{$zip}', 656 cityFrom: '{$cityFrom}', 599 657 }, 658 isMultiWarehouse: true, 659 warehouseId: 0, 600 660 dadata_token: '{$settings['dadataApikey']}', 601 661 {$widgetDeliveryTypes} … … 603 663 delivery_type: '{$settings['widgetDeliveryFrom']}', 604 664 day_shift: ".intval($settings['termIncrease']).", 605 inverse_delivery_type_for_operators: [{$inverseOperatorsStr}],606 free_delivery_operators: [{$freeDeliveryOperatorsStr}],607 operators_settings: [{$operatorSettingsStr}],608 665 location: { 609 666 address: '', … … 612 669 }, 613 670 cargo: { 614 weight: {$cargo ['WEI']},615 height: {$cargo ['H']},616 length: {$cargo ['L']},617 width: {$cargo ['W']},671 weight: {$cargo->getWeight()}, 672 height: {$cargo->getHeight()}, 673 length: {$cargo->getLength()}, 674 width: {$cargo->getWidth()}, 618 675 quantity: 1, 619 676 }, 620 677 need_insurance: ".(($settings['mindEnsurance'] === 'yes')?'true':'false').", 621 insured_value: {$cargo ['TOTAL']},678 insured_value: {$cargoAmount}, 622 679 {$customWSS} 623 680 … … 627 684 628 685 {$geoEmptyMessage} 629 {$freeDlvMinCourier} 630 {$freeDlvMinPVZ} 686 687 is_fitting: ".(($settings['isFitting'] === 'yes')?'true':'false').", 688 fitting_default: ".(($settings['fittingDefaultEnabled'] === 'yes')?'true':'false').", 689 is_partial_redemption: ".(($settings['partialRedemptionEnabled'] === 'yes')?'true':'false').", 631 690 632 691 }; -
catapultodelivery/trunk/libs/Wordpress/CatapultoShippingMethod.php
r3417476 r3444321 6 6 use Ipol\Catapulto\Wordpress\DB\CartVariantsDB; 7 7 use Ipol\Catapulto\Wordpress\DB\OperatorsDB; 8 use Ipol\Catapulto\Wordpress\DB\WarehousesDB; 8 9 use Ipol\Catapulto\Wordpress\Tools\Variables; 9 10 use Ipol\Catapulto\Wordpress\Tools\VariantStore; … … 11 12 class CatapultoShippingMethod extends \WC_Shipping_Method 12 13 { 14 public const CTPT_SENDDLVTYPE_DOOR = 'door'; 15 public const CTPT_SENDDLVTYPE_WAREHOUSE = 'warehouse'; 16 17 public const CTPT_SERVICE_POD = 'pod_amount'; //Наложенный платеж (NP) 18 public const CTPT_SERVICE_COD = 'cod_amount'; //Оплата получателем за доставку (COD) 19 public const CTPT_SERVICE_FITTING = 'fitting_amount'; //Название услуги "Примерка" 20 public const CTPT_SERVICE_PR = 'partial_redemption_amount'; //Название услуги "Частичный выкуп" 21 public const CTPT_SERVICE_PR_RETURN = 'partial_redemption_return_amount'; //Название услуги "Частичный возврат товаров" 13 22 14 23 private $operators = []; 24 private $warehouses = []; 25 26 private $isWarehouseTabSelect = false; 15 27 16 28 public function __construct($instance_id = 0) … … 31 43 $operatorsDB = new OperatorsDB(); 32 44 $this->operators = $operatorsDB->getAllByColumn('op_enabled','Y'); 45 46 $warehosesDb = new WarehousesDB(); 47 $this->warehouses = $warehosesDb->getAll(); 33 48 34 49 $this->init_settings(); … … 147 162 'type' => [], 148 163 'value' => [], 164 'wh_id' => [], 149 165 ], 150 166 'tr' => [ 167 'class' => [], 151 168 'valign' => [], 152 169 ], … … 157 174 'td' => [ 158 175 'class' => [], 176 'colspan' => [], 159 177 ], 160 178 'label' => [ 161 179 'for' => [], 162 180 ], 163 'fieldset' => [], 181 'fieldset' => [ 182 'class' => [], 183 ], 164 184 'legend' => [ 165 185 'class' => [], … … 191 211 'type' => [], 192 212 'name' => [], 213 'placeholder' => [], 193 214 ], 194 215 … … 216 237 } 217 238 218 $operators = '219 <tr><th scope="row" class="titledesc"></th><td class="forminp">220 <h3>Операторы доставки, способ отправки, код терминала по умолчанию</h3>221 <div class="ctpt_operators_h">222 <p class="free_dlv">Бесплатная доставка</p>223 <p class="dlv_type">Способ отправки</p>224 <p class="term_code">Код терминала по умолчанию</p>225 </div>226 </td></tr>227 ';228 239 $operatorsHidden = ''; 229 foreach ($this->operators as $operator) {230 $code = $operator['operator_id'];231 232 $operators .= '<tr valign="top">233 <th scope="row" class="titledesc">234 <label for="ctpt_op_'.$code.'">'.$operator['operator_display'].'</label>235 </th>236 <td class="forminp ctpt_op_element">237 <fieldset>238 '239 . '<div class="ctpt_check_wr">' . $this->generateCheckboxOnly('op_free_'.$code, $form_fields['op_free_'.$code]) . '</div>'240 . $this->generateSelectOnly('op_type_'.$code, $form_fields['op_type_'.$code])241 . $this->generateTextOnly('op_code_'.$code, $form_fields['op_code_'.$code])242 . '243 </fieldset>244 </td>245 </tr>';246 $operatorsHidden .=247 $this->generateHiddenCheckbox('op_free_'.$code, $form_fields['op_free_'.$code]) .248 $this->generateHiddenSelect('op_type_'.$code, $form_fields['op_type_'.$code]) .249 $this->generateHiddenInput('op_code_'.$code, $form_fields['op_code_'.$code])250 ;251 }252 240 253 241 if ( … … 257 245 $this->renderSettingsSection('auth') . 258 246 $statusesFieldsHidden . 259 $operatorsHidden .247 //$operatorsHidden . 260 248 $this->renderHiddenSection('main') . 261 249 $this->renderHiddenSection('terminals') . … … 270 258 '</table>'; 271 259 272 $operators .= '273 <tr valign="top">274 <th scope="row" class="titledesc">275 <label for="ctpt_op_btns">' . __('Set up shipping for all courier services', 'catapultodelivery') . ':</label>276 </th>277 <td class="forminp ctpt_op_element">278 <fieldset>279 <button id="ctpt_op_setalldoors" class="components-button is-primary">' . __('From door', 'catapultodelivery') . '</button>280 <button id="ctpt_op_setallwh" class="components-button is-primary">' . __('To warehouse', 'catapultodelivery') . '</button>281 </fieldset>282 </td>283 </tr>284 ';285 286 260 $nonce = wp_create_nonce('wp_rest'); 287 261 288 $html = '262 $html = $this->renderHiddenSection('auth') . ' 289 263 <nav class="nav-tab-wrapper woo-nav-tab-wrapper" data-tabs-content-level="2"> 290 <a href="#" class="nav-tab ctpt-tab nav-tab-active" data-tab-content-id="ctpt_settings_main">' . __('Main', 'catapultodelivery') . '</a>291 <a href="#" class="nav-tab ctpt-tab " data-tab-content-id="ctpt_settings_terminals">' . __('Terminals', 'catapultodelivery') . '</a>264 <a href="#" class="nav-tab ctpt-tab' . (!$this->isWarehouseTabSelect ? ' nav-tab-active' : '') . '" data-tab-content-id="ctpt_settings_main">' . __('Main', 'catapultodelivery') . '</a> 265 <a href="#" class="nav-tab ctpt-tab' . ($this->isWarehouseTabSelect ? ' nav-tab-active' : '') . '" data-tab-content-id="ctpt_settings_terminals">' . __('Terminals and warehouses', 'catapultodelivery') . '</a> 292 266 <a href="#" class="nav-tab ctpt-tab" data-tab-content-id="ctpt_settings_gabs">' . __('Dimensions and delivery settings', 'catapultodelivery') . '</a> 293 267 <a href="#" class="nav-tab ctpt-tab" data-tab-content-id="ctpt_settings_statuses">' . __('Synchronization of statuses', 'catapultodelivery') . '</a> … … 297 271 </nav> 298 272 <div class="tab-wrapper"> 299 <div class="ctpt-tab-content-2" id="ctpt_settings_main"> 273 <input type="hidden" name="is_new_wh" value="N" /> 274 <input type="hidden" name="is_wh_del" value="N" /> 275 <div class="ctpt-tab-content-2' . ($this->isWarehouseTabSelect ? ' ctpt_tab_hidden' : '') . '" id="ctpt_settings_main"> 300 276 <div class="ctpt_tbl"> 301 277 <p style="font-size: 20px"><b>' . __('Api key', 'catapultodelivery') . ': </b>' . \mb_substr($this->settings['apikey'], 0, 30) . '...</p> … … 310 286 </table> 311 287 </div> 312 <div class="ctpt-tab-content-2 " id="ctpt_settings_terminals" style="display:none;">288 <div class="ctpt-tab-content-2' . ($this->isWarehouseTabSelect ? '' : ' ctpt_tab_hidden') . '" id="ctpt_settings_terminals"> 313 289 <h3>' . __('Default sending method and sending terminals', 'catapultodelivery') . '</h3> 314 290 <table class="form-table"> 315 ' .$this->renderSettingsSection('terminals') . $operators. '291 ' . $this->renderWarehousesSettings() . ' 316 292 </table> 317 293 </div> 318 <div class="ctpt-tab-content-2 " id="ctpt_settings_gabs" style="display:none;">294 <div class="ctpt-tab-content-2 ctpt_tab_hidden" id="ctpt_settings_gabs"> 319 295 <h3>' . __('Default dimensions', 'catapultodelivery') . '</h3> 320 296 <table class="form-table">'.$this->renderSettingsSection('gabs').'</table> … … 323 299 <table class="form-table">'.$this->renderSettingsSection('dlvsettings').'</table> 324 300 </div> 325 <div class="ctpt-tab-content-2 " id="ctpt_settings_statuses" style="display:none;">301 <div class="ctpt-tab-content-2 ctpt_tab_hidden" id="ctpt_settings_statuses"> 326 302 <h3>' . __('Synchronization of statuses', 'catapultodelivery') . '</h3> 327 303 <table class="form-table">' … … 330 306 .'</table> 331 307 </div> 332 <div class="ctpt-tab-content-2 " id="ctpt_settings_widget" style="display:none;">308 <div class="ctpt-tab-content-2 ctpt_tab_hidden" id="ctpt_settings_widget"> 333 309 <h3>' . __('Widget settings', 'catapultodelivery') . '</h3> 334 310 <table class="form-table">'.$this->renderSettingsSection('widget').'</table> 335 311 </div> 336 <div class="ctpt-tab-content-2 " id="ctpt_settings_paysystems" style="display:none;">312 <div class="ctpt-tab-content-2 ctpt_tab_hidden" id="ctpt_settings_paysystems"> 337 313 <h3>' . __('Payment system compliance settings', 'catapultodelivery') . '</h3> 338 314 <h4>' . __('Explanation of payment systems', 'catapultodelivery') . '</h4> … … 346 322 . '</table> 347 323 </div> 348 <div class="ctpt-tab-content-2 " id="ctpt_settings_service" style="display:none;">324 <div class="ctpt-tab-content-2 ctpt_tab_hidden" id="ctpt_settings_service"> 349 325 <h3>' . __('Service properties', 'catapultodelivery') . '</h3> 350 326 <table class="form-table">'.$this->renderSettingsSection('service').'</table> … … 354 330 355 331 return $html; 332 } 333 334 private function renderWarehousesSettings():string 335 { 336 $out = '<tr><td class="forminp ctpt_wh_actions" colspan="2"> 337 <fieldset> 338 <p>' . __('Default warehouse', 'catapultodelivery') . ':</p> 339 ' . $this->generateSelectOnly('wh_default_selected', $this->form_fields['wh_default_selected']) . ' 340 <button id="ctpt_new_wh" class="components-button is-primary">' . __('Add warehouse', 'catapultodelivery') . '</button> 341 </fieldset> 342 </td></tr>'; 343 344 foreach ($this->warehouses as $wh) { 345 $out .= $this->renderWarehouseBlock($wh); 346 } 347 348 return $out; 349 } 350 351 private function renderWarehouseBlock(array $warehouseData) 352 { 353 $pf = '_chwh_' . $warehouseData['id']; 354 $operatorsData = json_decode($warehouseData['operators'], true); 355 if (!$operatorsData) $operatorsData = []; 356 357 $operators = ''; 358 foreach ($this->operators as $operator) { 359 $code = $operator['operator_id']; 360 361 $opdata = $operatorsData[$code] ?? [ 362 'f' => false, //isfree 363 't' => self::CTPT_SENDDLVTYPE_DOOR,//from door/warehouse 364 'c' => '', //pvz_code 365 ]; 366 367 $operators .= ' 368 <fieldset> 369 <div class="ctpt_bl_d4"> 370 <p>'.$operator['operator_display'].'</p> 371 </div> 372 <div class="ctpt_bl_d4"> 373 '.$this->generateCheckboxOnly('op_free_' . $code . $pf, [ 374 'title' => '', 375 'description' => '', 376 'desc_tip' => false, 377 'type' => 'checkbox', 378 'default' => $opdata['f'] ? '1' : '0', 379 ], $opdata['f']).' 380 </div> 381 <div class="ctpt_bl_d4 ctpt_wh_select_dlv_type"> 382 '.$this->generateSelectOnly('op_type_' . $code . $pf, [ 383 'title' => '', 384 'type' => 'select', 385 'default' => $opdata['t'], 386 'description' => '', 387 'desc_tip' => false, 388 'options'=> [ 389 self::CTPT_SENDDLVTYPE_DOOR => __('From door', 'catapultodelivery'), 390 self::CTPT_SENDDLVTYPE_WAREHOUSE => __('To warehouse', 'catapultodelivery'), 391 ] 392 ], $opdata['t']).' 393 </div> 394 <div class="ctpt_bl_d4 ctpt_wh_select_dlv_code hid"> 395 '.$this->generateTextOnly('op_code_' . $code . $pf, [ 396 'title' => '', 397 'description' => '', 398 'desc_tip' => false, 399 'type' => 'text', 400 'default' => $opdata['c'], 401 ]).' 402 </div> 403 </fieldset> 404 '; 405 } 406 407 $out = ' 408 <tr class="ctpt_warehouse"> 409 <input type="hidden" name="id' . $pf . '" value="' . $warehouseData['id'] . '" /> 410 <td class="ctpt_sender"> 411 <fieldset class="wh_name_fs"> 412 <label>' . __('Warehouse title', 'catapultodelivery') . ':</label> 413 ' . $this->generateTextOnly('name' . $pf, [ 414 'title' => __('Warehouse title', 'catapultodelivery'), 415 'description' => '', 416 'desc_tip' => false, 417 'type' => 'text', 418 'default' => $warehouseData['name'], 419 ]) . '</fieldset> 420 421 <fieldset class="wh_name_fs"> 422 <label>' . __('Settlement', 'catapultodelivery') . ':</label> 423 ' . $this->generateTextOnly('cityname' . $pf, [ 424 'title' => __('Settlement', 'catapultodelivery'), 425 'description' => '', 426 'desc_tip' => false, 427 'type' => 'text', 428 'default' => $warehouseData['city_name'], 429 ]) . '</fieldset> 430 431 <fieldset class="wh_coords"> 432 <label>' . __('Coordinates (latitude, longitude)', 'catapultodelivery') . ':</label> 433 <fieldset> 434 ' . $this->generateTextOnly('lat' . $pf, [ 435 'title' => __('Latitude', 'catapultodelivery'), 436 'description' => '', 437 'desc_tip' => false, 438 'type' => 'text', 439 'default' => $warehouseData['lat'], 440 ]) . ' 441 ' . $this->generateTextOnly('lon' . $pf, [ 442 'title' => __('Longitude', 'catapultodelivery'), 443 'description' => '', 444 'desc_tip' => false, 445 'type' => 'text', 446 'default' => $warehouseData['lon'], 447 ]) . ' 448 </fieldset> 449 </fieldset> 450 451 <fieldset class="wh_digits wh_cityid"> 452 <label>' . __('Senders city ID', 'catapultodelivery') . ':</label> 453 ' . $this->generateTextOnly('city_id' . $pf, [ 454 'title' => __('Senders city ID', 'catapultodelivery'), 455 'description' => __('The city ID from which you ship orders. Please confirm this information with your Catapulto manager', 'catapultodelivery'), 456 'desc_tip' => true, 457 'type' => 'text', 458 'default' => intval($warehouseData['city_id']) > 0 ? $warehouseData['city_id'] : '', 459 ]) . ' 460 </fieldset> 461 462 <fieldset class="wh_digits wh_cityzip"> 463 <label>' . __('Sender zip', 'catapultodelivery') . ':</label> 464 ' . $this->generateTextOnly('city_index' . $pf, [ 465 'title' => __('Sender zip', 'catapultodelivery'), 466 'description' => __('The city postcode from which you ship orders. Please contact your Catapulto manager for this information', 'catapultodelivery'), 467 'desc_tip' => true, 468 'type' => 'text', 469 'default' => intval($warehouseData['city_index']) > 0 ? $warehouseData['city_index'] : '', 470 ]) . ' 471 </fieldset> 472 473 <fieldset class="wh_digits wh_senderid"> 474 <label>' . __('Default Sender ID', 'catapultodelivery') . ':</label> 475 ' . $this->generateTextOnly('contact_id' . $pf, [ 476 'title' => __('Default Sender ID', 'catapultodelivery'), 477 'description' => __('The contact ID from the address book in your Catapulto account, which will be selected by the sender in the module', 'catapultodelivery'), 478 'desc_tip' => true, 479 'type' => 'text', 480 'default' => intval($warehouseData['contact_id']) > 0 ? $warehouseData['contact_id'] : '', 481 ]) . ' 482 </fieldset> 483 484 <fieldset class="wh_amount"> 485 <label>' . __('Free courier delivery from, RUB', 'catapultodelivery') . ':</label> 486 ' . $this->generateTextOnly('free_courier_from' . $pf, [ 487 'title' => __('Free courier delivery from, RUB', 'catapultodelivery'), 488 'description' => '', 489 'desc_tip' => true, 490 'type' => 'text', 491 'default' => $warehouseData['free_courier_from'], 492 ]) . ' 493 </fieldset> 494 495 <fieldset class="wh_amount"> 496 <label>' . __('Free delivery to pick-up points from, RUB', 'catapultodelivery') . ':</label> 497 ' . $this->generateTextOnly('free_pickup_from' . $pf, [ 498 'title' => __('Free delivery to pick-up points from, RUB', 'catapultodelivery'), 499 'description' => '', 500 'desc_tip' => true, 501 'type' => 'text', 502 'default' => $warehouseData['free_pickup_from'], 503 ]) . ' 504 </fieldset> 505 506 <fieldset class="wh_poa_enable"> 507 <label>' . __('Enable sending by proxy (for «Business Lines»)', 'catapultodelivery') . ':</label> 508 ' . $this->generateCheckboxOnly('poa_enabled' . $pf, [ 509 'title' => __('Enable sending by proxy (for «Business Lines»)', 'catapultodelivery'), 510 'description' => '', 511 'desc_tip' => false, 512 'type' => 'checkbox', 513 'default' => 'no', 514 ], $warehouseData['poa_enabled'] === 'Y') . ' 515 </fieldset> 516 517 <fieldset class="wh_poa_fio"> 518 <label>' . __('Full name of contact person', 'catapultodelivery') . ':</label> 519 ' . $this->generateTextOnly('poa_fio' . $pf, [ 520 'title' => __('Full name of contact person', 'catapultodelivery'), 521 'description' => '', 522 'desc_tip' => true, 523 'type' => 'text', 524 'default' => $warehouseData['poa_from_fio'], 525 ]) . ' 526 </fieldset> 527 528 <fieldset class="wh_poa_p_ser"> 529 <label>' . __('Passport series (4 digits)', 'catapultodelivery') . ':</label> 530 ' . $this->generateTextOnly('poa_series' . $pf, [ 531 'title' => __('Passport series (4 digits)', 'catapultodelivery'), 532 'description' => '', 533 'desc_tip' => true, 534 'type' => 'text', 535 'default' => $warehouseData['poa_from_p_series'], 536 ]) . ' 537 </fieldset> 538 539 <fieldset class="wh_poa_p_num"> 540 <label>' . __('Passport number (6 digits)', 'catapultodelivery') . ':</label> 541 ' . $this->generateTextOnly('poa_number' . $pf, [ 542 'title' => __('Passport number (6 digits)', 'catapultodelivery'), 543 'description' => '', 544 'desc_tip' => true, 545 'type' => 'text', 546 'default' => $warehouseData['poa_from_p_number'], 547 ]) . ' 548 </fieldset> 549 550 <fieldset class="wh_poa_p_date"> 551 <label>' . __('Date of issue (dd.mm.yyyy)', 'catapultodelivery') . ':</label> 552 ' . $this->generateTextOnly('poa_date' . $pf, [ 553 'title' => __('Date of issue (dd.mm.yyyy)', 'catapultodelivery'), 554 'description' => '', 555 'desc_tip' => true, 556 'type' => 'text', 557 'default' => $warehouseData['poa_from_p_date'], 558 ]) . ' 559 </fieldset> 560 561 <fieldset class="wh_poa_p_mail"> 562 <label>' . __('Email for sending power of attorney (optional)', 'catapultodelivery') . ':</label> 563 ' . $this->generateTextOnly('poa_email' . $pf, [ 564 'title' => __('Email for sending power of attorney (optional)', 'catapultodelivery'), 565 'description' => '', 566 'desc_tip' => true, 567 'type' => 'text', 568 'default' => $warehouseData['poa_from_email'], 569 ]) . ' 570 </fieldset> 571 572 </td> 573 <td class="ctpt_operators"> 574 <fieldset class="ctpt_wh_active"> 575 <label>' . __('Warehouse enabled', 'catapultodelivery') . '</label> 576 ' . $this->generateCheckboxOnly('enabled' . $pf, [ 577 'title' => '', 578 'description' => '', 579 'desc_tip' => false, 580 'type' => 'checkbox', 581 'default' => 'no', 582 ], $warehouseData['active'] === 'Y') . ' 583 584 <div class="ctpt_wh_delete_wr"> 585 <button id="ctpt_wh_delete" wh_id="'.$warehouseData['id'].'" class="components-button is-primary">' . __('Delete warehouse', 'catapultodelivery') . '</button> 586 </div> 587 </fieldset> 588 589 <fieldset> 590 <label>' . __('Default method for sending shipments', 'catapultodelivery') . ':</label> 591 ' . $this->generateSelectOnly('dlv_default_from' . $pf, [ 592 'title' => '', 593 'type' => 'select', 594 'default' => $warehouseData['delivery_from'], 595 'description' => '', 596 'desc_tip' => false, 597 'options'=> [ 598 self::CTPT_SENDDLVTYPE_DOOR => __('From door', 'catapultodelivery'), 599 self::CTPT_SENDDLVTYPE_WAREHOUSE => __('To warehouse', 'catapultodelivery'), 600 ] 601 ], $warehouseData['delivery_from']) . ' 602 </fieldset> 603 604 <fieldset> 605 <div class="ctpt_bl_d4"> 606 <p><b>' . __('Delivery operators', 'catapultodelivery') . '</b></p> 607 </div> 608 <div class="ctpt_bl_d4"> 609 <p><b>' . __('Free delivery', 'catapultodelivery') . '</b></p> 610 </div> 611 <div class="ctpt_bl_d4"> 612 <p><b>' . __('Default sending method', 'catapultodelivery') . '</b></p> 613 </div> 614 <div class="ctpt_bl_d4"> 615 <p><b>' . __('Default terminal code', 'catapultodelivery') . '</b></p> 616 </div> 617 </fieldset> 618 619 '.$operators.' 620 </td> 621 </tr> 622 <tr class="ctpt_warehouse_after"><td colspan="2"></td></tr> 623 '; 624 625 return $out; 356 626 } 357 627 … … 501 771 502 772 return ' 503 <textarea rows="3" cols="20" type="'.$inputType.'" name="'.$idEl.'" id="'.$idEl.'" style="display:none !important;">'.$currentValue.'</textarea>773 <textarea rows="3" cols="20" type="'.$inputType.'" name="'.$idEl.'" id="'.$idEl.'" class="ctpt_inputhidden">'.$currentValue.'</textarea> 504 774 '; 505 775 } … … 541 811 { 542 812 $field_key = $this->get_field_key( $key ); 813 $savedValue = $this->get_option( $key ); 543 814 $defaults = [ 544 815 'title' => '', … … 551 822 'description' => '', 552 823 'custom_attributes' => [], 824 'value' => empty($savedValue) ? $data['default'] : $savedValue, 553 825 ]; 554 826 555 827 $data = wp_parse_args( $data, $defaults ); 556 828 557 return '<input class="input-text regular-input '.esc_attr( $data['class'] ).'" type="'.esc_attr( $data['type'] ).'" name="'.esc_attr( $field_key ).'" id="'.esc_attr( $field_key ).'" style="'.esc_attr( $data['css'] ).'" value="'.esc_attr( $ this->get_option( $key )).'" placeholder="'.esc_attr( $data['placeholder'] ).'" '.disabled( $data['disabled'], true ).' '.$this->get_custom_attribute_html( $data ).' />';829 return '<input class="input-text regular-input '.esc_attr( $data['class'] ).'" type="'.esc_attr( $data['type'] ).'" name="'.esc_attr( $field_key ).'" id="'.esc_attr( $field_key ).'" style="'.esc_attr( $data['css'] ).'" value="'.esc_attr( $data['value'] ).'" placeholder="'.esc_attr( $data['placeholder'] ).'" '.disabled( $data['disabled'], true ).' '.$this->get_custom_attribute_html( $data ).' />'; 558 830 } 559 831 … … 592 864 </tr>'; 593 865 } 594 private function generateCheckboxOnly( $key, $data ) {866 private function generateCheckboxOnly( $key, $data, $isForseChecked = false ) { 595 867 $field_key = $this->get_field_key( $key ); 596 868 $defaults = [ … … 611 883 $data['label'] = $data['title']; 612 884 } 613 614 return '<input class="'.esc_attr( $data['class'] ).'" type="checkbox" name="'.esc_attr( $field_key ).'" id="'.esc_attr( $field_key ).'" value="1" '.checked( $this->get_option( $key ), 'yes', false ).' '.$this->get_custom_attribute_html( $data ).' />'; 885 $value = $this->get_option( $key ); 886 if ($isForseChecked) $value = 'yes'; 887 888 return '<input class="'.esc_attr( $data['class'] ).'" type="checkbox" name="'.esc_attr( $field_key ).'" id="'.esc_attr( $field_key ).'" value="1" '.checked( $value, 'yes', false ).' '.$this->get_custom_attribute_html( $data ).' />'; 615 889 } 616 890 … … 659 933 </tr>'; 660 934 } 661 private function generateSelectOnly( $key, $data ) {935 private function generateSelectOnly( $key, $data, $forseValue = '' ) { 662 936 $field_key = $this->get_field_key( $key ); 663 937 $defaults = [ … … 676 950 $data = wp_parse_args( $data, $defaults ); 677 951 $value = $this->get_option( $key ); 952 if (!empty($forseValue)) $value = $forseValue; 678 953 679 954 $optionsHtml = ''; … … 810 1085 'title' => '', 811 1086 'type' => 'select', 812 'default' => 'door',1087 'default' => self::CTPT_SENDDLVTYPE_DOOR, 813 1088 'description' => '', 814 1089 'desc_tip' => false, 815 1090 'options'=> [ 816 'door'=> __('From door', 'catapultodelivery'),817 'warehouse'=> __('To warehouse', 'catapultodelivery'),1091 self::CTPT_SENDDLVTYPE_DOOR => __('From door', 'catapultodelivery'), 1092 self::CTPT_SENDDLVTYPE_WAREHOUSE => __('To warehouse', 'catapultodelivery'), 818 1093 ] 819 1094 ]; … … 833 1108 ]; 834 1109 } 1110 1111 //warehouses.... 1112 $defaultWHValue = [ 1113 '0' => __('Not selected', 'catapultodelivery'), 1114 ]; 1115 foreach ($this->warehouses as $wh) { 1116 if ($wh['active'] != 'Y') continue; 1117 $defaultWHValue[$wh['id']] = $wh['name'] . ' ('.$wh['id'].')'; 1118 } 1119 $this->form_fields['wh_default_selected'] = [ 1120 'title' => '', 1121 'type' => 'select', 1122 'default' => '0', 1123 'description' => '', 1124 'desc_tip' => false, 1125 'options'=> $defaultWHValue 1126 ]; 1127 835 1128 } 836 1129 837 1130 public function validate_text_field($key, $value) 838 1131 { 1132 static $whNewSaved; 1133 839 1134 $postData = $this->get_post_data(); 840 1135 $isAuthMode = isset($postData['ctptIsAuth']) && ($postData['ctptIsAuth'] === 'Y'); 1136 1137 // save warehouses 1138 $warehosesDb = new WarehousesDB(); 1139 //new warehouse 1140 if ($postData['is_new_wh'] == 'Y' && $whNewSaved === null) { 1141 $this->isWarehouseTabSelect = true; 1142 $isAddPermitted = true; 1143 foreach ($this->warehouses as $wh) { 1144 if (empty($wh['name'])) $isAddPermitted = false; 1145 } 1146 1147 if ($isAddPermitted) { 1148 $newWHData = [ 1149 'city_id' => 0, 1150 'city_index' => 0, 1151 'contact_id' => 0, 1152 'name' => '', 1153 'city_name' => '', 1154 'delivery_from' => '', 1155 'free_courier_from' => '', 1156 'free_pickup_from' => '', 1157 'poa_enabled' => 'N', 1158 'poa_from_fio' => '', 1159 'poa_from_p_series' => '', 1160 'poa_from_p_number' => '', 1161 'poa_from_p_date' => '', 1162 'poa_from_email' => '', 1163 'lat' => '', 1164 'lon' => '', 1165 'operators' => '', 1166 'active' => 'N', 1167 ]; 1168 $warehosesDb->saveOrUpdate($newWHData); 1169 $newWHData['id'] = $warehosesDb->getLastRecordId(); 1170 $this->warehouses[] = $newWHData; 1171 } 1172 1173 $whNewSaved = true; 1174 } 1175 if ($postData['is_wh_del'] != 'N' && $whNewSaved === null) { 1176 $this->isWarehouseTabSelect = true; 1177 $delWHId = intval($postData['is_wh_del']); 1178 if ($delWHId > 0) { 1179 $warehosesDb->deleteById($delWHId); 1180 foreach ($this->warehouses as $whKey => $wh) { 1181 if (intval($wh['id']) == $delWHId) { 1182 unset($this->warehouses[$whKey]); 1183 break; 1184 } 1185 } 1186 } 1187 $whNewSaved = true; 1188 } 1189 1190 //save current warehouses... 1191 if ($whNewSaved === null) { 1192 foreach ($this->warehouses as $whKey => $currentWH) { 1193 $currentId = intval($currentWH['id']); 1194 1195 $currentWH['city_id'] = intval($postData['woocommerce_catapultodelivery_city_id_chwh_' . $currentId]); 1196 $currentWH['city_index'] = intval($postData['woocommerce_catapultodelivery_city_index_chwh_' . $currentId]); 1197 $currentWH['contact_id'] = intval($postData['woocommerce_catapultodelivery_contact_id_chwh_' . $currentId]); 1198 $currentWH['city_name'] = $postData['woocommerce_catapultodelivery_cityname_chwh_' . $currentId]; 1199 $currentWH['name'] = $postData['woocommerce_catapultodelivery_name_chwh_' . $currentId]; 1200 $currentWH['delivery_from'] = $postData['woocommerce_catapultodelivery_dlv_default_from_chwh_' . $currentId]; 1201 $currentWH['free_courier_from'] = $postData['woocommerce_catapultodelivery_free_courier_from_chwh_' . $currentId]; 1202 $currentWH['free_pickup_from'] = $postData['woocommerce_catapultodelivery_free_pickup_from_chwh_' . $currentId]; 1203 $currentWH['poa_enabled'] = ( ($postData['woocommerce_catapultodelivery_poa_enabled_chwh_' . $currentId] ?? '0') === '1' ) ? 'Y' : 'N'; 1204 $currentWH['poa_from_fio'] = $postData['woocommerce_catapultodelivery_poa_fio_chwh_' . $currentId]; 1205 $currentWH['poa_from_p_series'] = $postData['woocommerce_catapultodelivery_poa_series_chwh_' . $currentId]; 1206 $currentWH['poa_from_p_number'] = $postData['woocommerce_catapultodelivery_poa_number_chwh_' . $currentId]; 1207 $currentWH['poa_from_p_date'] = $postData['woocommerce_catapultodelivery_poa_date_chwh_' . $currentId]; 1208 $currentWH['poa_from_email'] = $postData['woocommerce_catapultodelivery_poa_email_chwh_' . $currentId]; 1209 $currentWH['lat'] = $postData['woocommerce_catapultodelivery_lat_chwh_' . $currentId]; 1210 $currentWH['lon'] = $postData['woocommerce_catapultodelivery_lon_chwh_' . $currentId]; 1211 $currentWH['active'] = ( ($postData['woocommerce_catapultodelivery_enabled_chwh_' . $currentId] ?? '0') === '1' ) ? 'Y' : 'N'; 1212 1213 // Operators... 1214 $whOpData = []; 1215 foreach ($this->operators as $operator) { 1216 $code = $operator['operator_id']; 1217 $whOpData[$code] = [ 1218 'f' => ($postData["woocommerce_catapultodelivery_op_free_{$code}_chwh_{$currentId}"] ?? '0') === '1', 1219 't' => $postData["woocommerce_catapultodelivery_op_type_{$code}_chwh_{$currentId}"], 1220 'c' => ($postData["woocommerce_catapultodelivery_op_type_{$code}_chwh_{$currentId}"] === self::CTPT_SENDDLVTYPE_WAREHOUSE) ? $postData["woocommerce_catapultodelivery_op_code_{$code}_chwh_{$currentId}"] : '', 1221 ]; 1222 } 1223 $currentWH['operators'] = json_encode($whOpData); 1224 // /Operators... 1225 1226 //save to db 1227 $warehosesDb->saveOrUpdate($currentWH, 'id'); 1228 1229 $this->warehouses[$whKey] = $currentWH; 1230 $this->form_fields['wh_default_selected']['options'][$currentId] = $currentWH['name'] . ' ('.$currentId.')'; 1231 } 1232 $whNewSaved = true; 1233 } 841 1234 842 1235 $value = parent::validate_text_field($key, $value); … … 975 1368 'type' => 'title', 976 1369 ], 977 'senderLocalityId' => [978 'title' => __('Sender city ID', 'catapultodelivery'),979 'description' => __('ID of the city from which you send orders. Check this information with the Catapulto manager', 'catapultodelivery') . '.',980 'desc_tip' => true,981 'type' => 'text',982 'default' => '',983 ],984 'senderZip' => [985 'title' => __('Sender zip', 'catapultodelivery'),986 'description' => __('The city index from which you send orders. Check this information with the Catapulto manager', 'catapultodelivery') . '.',987 'desc_tip' => true,988 'type' => 'text',989 'default' => '',990 ],991 'senderCity' => [992 'title' => __('Sender`s city', 'catapultodelivery'),993 'description' => __("The city from which you send orders. For example, \"Moscow\" (without quotes)", 'catapultodelivery'),994 'desc_tip' => true,995 'type' => 'text',996 'default' => '',997 ],998 'senderId' => [999 'title' => __('Default Sender ID', 'catapultodelivery'),1000 'description' => __('The contact ID from the address book in your Catapulto account, which will be selected by the sender in the module', 'catapultodelivery') . '.<br/> ' . __('You can check the required value for this setting with the Catapulto manager', 'catapultodelivery'),1001 'desc_tip' => true,1002 'type' => 'text',1003 'default' => '',1004 ],1005 'poaEnabled' => [1006 'title' => __("Enable sending by proxy (for \"Business Lines\")", 'catapultodelivery'),1007 'type' => 'checkbox',1008 'default' => ''1009 ],1010 'poaFromName' => [1011 'title' => __('Full name of contact person', 'catapultodelivery'),1012 'description' => '',1013 'desc_tip' => false,1014 'type' => 'text',1015 'default' => '',1016 ],1017 'poaFromPassportSeries' => [1018 'title' => __('Passport series (4 digits)', 'catapultodelivery'),1019 'description' => '',1020 'desc_tip' => false,1021 'type' => 'text',1022 'default' => '',1023 ],1024 'poaFromPassportNumber' => [1025 'title' => __('Passport number (6 digits)', 'catapultodelivery'),1026 'description' => '',1027 'desc_tip' => false,1028 'type' => 'text',1029 'default' => '',1030 ],1031 'poaFromPassportDate' => [1032 'title' => __('Date of issue (dd.mm.yyyy)', 'catapultodelivery'),1033 'description' => '',1034 'desc_tip' => false,1035 'type' => 'text',1036 'default' => '',1037 ],1038 'poaSendReceiverEmail' => [1039 'title' => __('Email for sending power of attorney (optional)', 'catapultodelivery'),1040 'description' => '',1041 'desc_tip' => false,1042 'type' => 'text',1043 'default' => '',1044 ],1045 1370 ], 1046 1371 'terminals'=>[ 1047 'widgetDeliveryFrom' => [1048 'title' => __('Default method for sending shipments', 'catapultodelivery'),1049 'type' => 'select',1050 'default' => 'door',1051 'description' => '',1052 'desc_tip' => false,1053 'options'=> [1054 'door' => __('From door', 'catapultodelivery'),1055 'warehouse' => __('From warehouse', 'catapultodelivery'),1056 ]1057 ],1058 //Terminals....1059 'freeDlvMinCourier' => [1060 'title' => __('Free courier delivery from, RUB', 'catapultodelivery') . '.',1061 'description' => '',1062 'desc_tip' => false,1063 'type' => 'text',1064 'default' => '0',1065 ],1066 'freeDlvMinPVZ' => [1067 'title' => __('Free delivery to pick-up points from, RUB', 'catapultodelivery') . '.',1068 'description' => '',1069 'desc_tip' => false,1070 'type' => 'text',1071 'default' => '0',1072 ],1073 1372 ], 1074 1373 'gabs'=>[ … … 1148 1447 'type' => 'checkbox', 1149 1448 'default' => 'yes' 1449 ], 1450 'isFitting'=>[ 1451 'title' => __('Fitting available', 'catapultodelivery'), 1452 'description' => __('Enable try-on feature. When you select try-on, the widget will only display delivery rates with try-on available', 'catapultodelivery'), 1453 'desc_tip' => true, 1454 'type' => 'checkbox', 1455 'default' => 'no' 1456 ], 1457 'fittingDefaultEnabled'=>[ 1458 'title' => __('Fitting enabled by default', 'catapultodelivery'), 1459 'description' => __('By default, the try-on mode is enabled when the widget is launched', 'catapultodelivery'), 1460 'desc_tip' => true, 1461 'type' => 'checkbox', 1462 'default' => 'no' 1463 ], 1464 'partialRedemptionEnabled'=>[ 1465 'title' => __('Enable partial buyback by default', 'catapultodelivery'), 1466 'description' => __('Enable the partial buyback service by default', 'catapultodelivery'), 1467 'desc_tip' => true, 1468 'type' => 'checkbox', 1469 'default' => 'no' 1150 1470 ], 1151 1471 ], … … 1225 1545 'type' => 'checkbox', 1226 1546 'default' => 'yes' 1547 ], 1548 'enLocalWidget' => [ 1549 'title' => __('Enable local version of widget', 'catapultodelivery'), 1550 'description' => __('Do not use this option', 'catapultodelivery') . '.', 1551 'desc_tip' => true, 1552 'type' => 'checkbox', 1553 'default' => 'no' 1227 1554 ], 1228 1555 … … 1356 1683 } 1357 1684 1685 public function isFitting():bool 1686 { 1687 return ($this->settings['isFitting'] ?? false) === 'yes'; 1688 } 1689 1690 public function isFittingDefaultEnabled():bool 1691 { 1692 return ($this->settings['fittingDefaultEnabled'] ?? false) === 'yes'; 1693 } 1694 1695 public function isPartialRedemptionEnabled():bool 1696 { 1697 return ($this->settings['partialRedemptionEnabled'] ?? false) === 'yes'; 1698 } 1699 1358 1700 public function getOrderMapping():array 1359 1701 { … … 1365 1707 } 1366 1708 1709 public function getWarehouses():array 1710 { 1711 return $this->warehouses; 1712 } 1713 1714 public function getDefaultWarehouseId():int 1715 { 1716 return intval($this->settings['wh_default_selected']); 1717 } 1718 1719 public function getSenderWarehouse() 1720 { 1721 $defaultWhId = $this->getDefaultWarehouseId(); 1722 $selectedWH = null; 1723 if ($defaultWhId > 0) { 1724 foreach ($this->warehouses as $warehouse) { 1725 if (intval($warehouse['id']) == $defaultWhId) { 1726 $selectedWH = $warehouse; 1727 break; 1728 } 1729 } 1730 } 1731 if ($defaultWhId == 0 || $selectedWH === null) { 1732 //первый активный склад... 1733 foreach ($this->warehouses as $warehouse) { 1734 if ($warehouse['active'] === 'Y') { 1735 $selectedWH = $warehouse; 1736 break; 1737 } 1738 } 1739 } 1740 return $selectedWH; 1741 } 1742 1367 1743 } -
catapultodelivery/trunk/libs/Wordpress/Controller/AbstractController.php
r3417476 r3444321 39 39 while ($error = $errorsCollections->getNext()) $errors[] = 'R' . $error->getCode() . ': ' . $error->getMessage(); 40 40 41 $errors[] = 'R' . $response->getError()->getCode() . ': ' . $response->getError()->getMessage(); 41 if ($response->getError()) { 42 $errors[] = 'R' . $response->getError()->getCode() . ': ' . $response->getError()->getMessage(); 43 } 42 44 $this->errors = $errors; 43 45 return true; -
catapultodelivery/trunk/libs/Wordpress/Controller/MainController.php
r3417476 r3444321 4 4 5 5 use Ipol\Catapulto\Api\Entity\Response\ShipmentId; 6 use Ipol\Catapulto\Core\Order\Item; 6 7 use Ipol\Catapulto\Core\Order\Order; 7 8 use Ipol\Catapulto\Wordpress\CatapultoPlugin; … … 42 43 { 43 44 $response = $this->app->cargoCreate($order); 45 if ($this->isResponseError($response)) return false; 46 return $response->getResponse(); 47 } 48 49 public function createCargoByItem(Item $item) 50 { 51 $response = $this->app->cargoCreateByItem($item); 44 52 if ($this->isResponseError($response)) return false; 45 53 return $response->getResponse(); -
catapultodelivery/trunk/libs/Wordpress/Controller/OrderController.php
r3417476 r3444321 14 14 use Ipol\Catapulto\Core\Order\Order; 15 15 use Ipol\Catapulto\Core\Order\Payment; 16 use Ipol\Catapulto\Wordpress\CatapultoPlugin; 16 17 use Ipol\Catapulto\Wordpress\CatapultoShippingMethod; 17 18 use Ipol\Catapulto\Wordpress\DB\OrdersDB; … … 29 30 $shippingMethod = new CatapultoShippingMethod(); 30 31 $moduleSettings = $shippingMethod->getAllSettings(); 32 $additionalServices = []; 31 33 32 34 $cOrder = new Order(); … … 68 70 $cOrder->getAddressTo()->setCode($contactResponse->getResponse()->getId()); 69 71 70 //Sender 72 //Sender && selected warehouse... 73 $allWareHouses = $shippingMethod->getWarehouses(); 74 $selectedWarehouseId = intval($rateResultData['rate_param']['sender_warehouse_id'] ?? '0'); 75 $selectedWarehouse = null; 76 foreach ($allWareHouses as $warehouse) { 77 if (intval($warehouse['id']) == $selectedWarehouseId) { 78 $selectedWarehouse = $warehouse; 79 break; 80 } 81 } 82 if ($selectedWarehouse === null) { 83 $this->errors = [__('The dispatch warehouse was not found. You must select a warehouse and a new rate for the shipment', 'catapultodelivery')]; 84 return null; 85 } 71 86 $senderAddress = (new Address()) 72 ->setCode( $shippingMethod->getSenderId())73 ->setField('senderId', $shippingMethod->getSenderId())74 ->setField('senderCity', $shippingMethod->getSenderCity());87 ->setCode((string)$selectedWarehouse['contact_id']) 88 ->setField('senderId', (string)$selectedWarehouse['contact_id']) 89 ->setField('senderCity', (string)$selectedWarehouse['city_id']); 75 90 76 91 //Basket 92 $cargoesIds = []; 93 $rateCargoIds = $rateResultData['rate_param']['cargoes']; 94 foreach ($rateCargoIds as $cargoId) { 95 $cargoesIds[$cargoId] = false; //checked 96 } 97 98 $customCargoData = unserialize($order->get_meta(CatapultoPlugin::ORDER_META_CARGO)); 99 if (!$customCargoData) { 100 $this->errors = [__('I cant read the cargo details for this order', 'catapultodelivery')]; 101 return null; 102 } 103 //check cargoes... 104 $errorMsg = ''; 105 foreach ($customCargoData as $crgData) { 106 $cargoId = intval($crgData['ccargo_id']); 107 $cargoesIds[$cargoId] = true; 108 109 foreach ($crgData['items'] as $itm) { 110 $wei = intval($itm['weight']); 111 $h = intval($itm['height']); 112 $l = intval($itm['length']); 113 $w = intval($itm['width']); 114 if ($wei == 0) { 115 $errorMsg .= __('The weight of the product is not specified', 'catapultodelivery') . ' ['.$itm['id'].'] ' . $itm['name'] . PHP_EOL; 116 } 117 if ($h == 0) { 118 $errorMsg .= __('The height of the product is not set', 'catapultodelivery') . ' ['.$itm['id'].'] ' . $itm['name'] . PHP_EOL; 119 } 120 if ($l == 0) { 121 $errorMsg .= __('The product length is not specified.', 'catapultodelivery') . ' ['.$itm['id'].'] ' . $itm['name'] . PHP_EOL; 122 } 123 if ($w == 0) { 124 $errorMsg .= __('The width of the product is not set', 'catapultodelivery') . ' ['.$itm['id'].'] ' . $itm['name'] . PHP_EOL; 125 } 126 } 127 128 } 129 $isCargoChecked = true; 130 foreach ($cargoesIds as $checked) if (!$checked) $isCargoChecked = false; 131 if (!$isCargoChecked) $errorMsg .= __('A mismatch of cargo units was detected. Please reselect the delivery option', 'catapultodelivery') . PHP_EOL; 132 133 $isValidCargoData = Calculator::validateCargoData($customCargoData, null, $order); 134 if (!$isValidCargoData) $errorMsg .= __('A discrepancy was detected between the order basket and the package contents. You must delete the packages, recreate them, and select a new shipping calculation', 'catapultodelivery') . PHP_EOL; 135 if ( $requestData['ctpt_is_fitting'] == 'Y' ) { 136 $additionalServices[] = CatapultoShippingMethod::CTPT_SERVICE_FITTING; 137 if (!($rateResultData['variant']['_isFitting'] ?? false)) $errorMsg .= __('The Fitting service is included, but the billing was made without this service. A new billing is required', '') . PHP_EOL; 138 } 139 if ($requestData['ctpt_is_pr'] == 'Y') { 140 $additionalServices[] = CatapultoShippingMethod::CTPT_SERVICE_PR; 141 } 142 143 if (!empty($errorMsg)) { 144 $this->errors = [$errorMsg]; 145 return null; 146 } 147 77 148 $itemCollections = new ItemCollection(); 78 $cargoResult = Calculator::getCurrentCargoDataByOrder($order); 79 /** @var Cargo $cargo */ 80 $cargo = $cargoResult['CARGO']; 149 $cargo = Calculator::getCurrentCargoDataByOrder($order); 150 $cargoComment = Calculator::getCargoComment(); 81 151 $cargo->reset(); 82 152 while ($el = $cargo->getNext()) { 83 153 $item = (new Item()) 154 ->setId($el->getId()) 84 155 ->setName($el->getField('name')) 85 156 ->setQuantity($el->getQuantity()) … … 97 168 $goods = new Goods(); 98 169 $goods 99 ->setWeight($cargo Result['WEI'])100 ->setWidth($cargo Result['W'])101 ->setLength($cargo Result['L'])102 ->setHeight($cargo Result['H'])170 ->setWeight($cargo->getWeight()) 171 ->setWidth($cargo->getWidth()) 172 ->setLength($cargo->getLength()) 173 ->setHeight($cargo->getHeight()) 103 174 ; 175 176 $customCargo = []; 177 foreach ($customCargoData as $crgData) { 178 $cargoId = intval($crgData['ccargo_id']); 179 if ($cargoId == 0) continue; 180 $customCargo[$cargoId] = [ 181 'id' => $cargoId, 182 'items' => [], 183 ]; 184 foreach ($crgData['items'] as $itm) { 185 $customCargo[$cargoId]['items'][] = [ 186 'id' => intval($itm['id']), 187 'name' => $itm['name'], 188 'qty' => floatval($itm['quantity']), 189 'articul' => $itm['articul'], 190 'weight' => intval($itm['weight']), 191 'height' => intval($itm['height']), 192 'width' => intval($itm['width']), 193 'length' => intval($itm['length']), 194 ]; 195 } 196 } 104 197 105 198 //Payment … … 139 232 ->setField('deliveryPaySide','sender') 140 233 ->setField('additional_services', []) 234 ->setField('cargoes_ids', $rateCargoIds) 235 ->setField('customCargoData', $customCargo) 141 236 ; 142 237 143 238 if ( 144 ($moduleSettings['poaEnabled'] == 'yes')145 && ($rateResultData['variant']['operator'] == 'dellin')239 $selectedWarehouse['poa_enabled'] === 'Y' 240 && $rateResultData['variant']['operator'] === 'dellin' 146 241 ) { 147 242 $cOrder 148 243 ->setField('sender_poa', true) 149 ->setField('from_name', $ moduleSettings['poaFromName'])150 ->setField('from_passport_series', $ moduleSettings['poaFromPassportSeries'])151 ->setField('from_passport_number', $ moduleSettings['poaFromPassportNumber'])152 ->setField('from_passport_date', $ moduleSettings['poaFromPassportDate'])153 ->setField('send_receiver_poa_email', $ moduleSettings['poaSendReceiverEmail'])244 ->setField('from_name', $selectedWarehouse['poa_from_fio']) 245 ->setField('from_passport_series', $selectedWarehouse['poa_from_p_series']) 246 ->setField('from_passport_number', $selectedWarehouse['poa_from_p_number']) 247 ->setField('from_passport_date', $selectedWarehouse['poa_from_p_date']) 248 ->setField('send_receiver_poa_email', $selectedWarehouse['poa_from_email']) 154 249 ; 155 250 } … … 158 253 if ($isPod) { 159 254 if ($requestData['ctpt_deliveryPaySide'] == 'Y') { 160 $cOrder 161 ->setField('additional_services', ['pod_amount','cod_amount'])162 ->setField('deliveryPaySide', 'receiver')163 ;164 } else $cOrder->setField('additional_services', ['pod_amount']);165 }255 $cOrder->setField('deliveryPaySide', 'receiver'); 256 $additionalServices[] = CatapultoShippingMethod::CTPT_SERVICE_COD; 257 } 258 $additionalServices[] = CatapultoShippingMethod::CTPT_SERVICE_POD; 259 } 260 $cOrder->setField('additional_services', $additionalServices); 166 261 167 262 // for w2* tarifs 168 $operatorSendType = $moduleSettings['widgetDeliveryFrom']; 169 if (isset($moduleSettings['op_type_' . $rateResultData['variant']['operator'] ])) $operatorSendType = $moduleSettings['op_type_' . $rateResultData['variant']['operator'] ]; 170 171 if ($operatorSendType == 'warehouse') $cOrder->setField('sender_terminal_code', $moduleSettings['op_code_' . $rateResultData['variant']['operator'] ] ); 263 //$operatorSendType = $selectedWarehouse['delivery_from']; 264 $whOperators = json_decode($selectedWarehouse['operators'], true); 265 if (!$whOperators) $whOperators = []; 266 if (isset($whOperators[$rateResultData['variant']['operator']])) { 267 $operatorSendType = $whOperators[$rateResultData['variant']['operator']]['t']; 268 if ($operatorSendType === CatapultoShippingMethod::CTPT_SENDDLVTYPE_WAREHOUSE) 269 $cOrder->setField('sender_terminal_code', $whOperators[$rateResultData['variant']['operator']]['c'] ); 270 } 271 272 //goodsData 273 $goodsDataResult = $this->app->shipmentGoodsCreate($cOrder); 274 if ($this->isResponseError($goodsDataResult)) return null; 172 275 173 276 if ($isPod) { … … 189 292 'main_status' => '', 190 293 'main_status_display' => '', 191 'weight' => $cargo Result['WEI'],294 'weight' => $cargo->getWeight(), 192 295 'price' => $goodsAmount, 193 296 'operator' => $rateResultData['variant']['operator'], … … 203 306 'receiver_house' => $receiverAddress->getHouse() ?? '', 204 307 'receiver_flat' => $receiverAddress->getFlat() ?? '', 205 'description' => $cargo Result['COMMENT'],308 'description' => $cargoComment, 206 309 'with_insurance' => $needInsurance, 207 310 'insurance_cost' => $insuranceValue, -
catapultodelivery/trunk/libs/Wordpress/DB/AbstractDB.php
r3417476 r3444321 48 48 $sql = $this->db->prepare("SELECT * FROM %i WHERE `id` = %d;", $this->fullTableName, $recId); 49 49 return $this->db->get_row($sql, 'ARRAY_A'); 50 } 51 52 public function getLastRecord(): ?array 53 { 54 $sql = $this->db->prepare("SELECT * FROM %i ORDER BY `id` DESC LIMIT 1", $this->fullTableName); 55 return $this->db->get_row($sql, 'ARRAY_A'); 56 } 57 58 public function getLastRecordId(): int 59 { 60 $sql = $this->db->prepare("SELECT `id` FROM %i ORDER BY `id` DESC LIMIT 1", $this->fullTableName); 61 $record = $this->db->get_row($sql, 'ARRAY_A'); 62 if (!$record) return 0; 63 return intval($record['id']); 50 64 } 51 65 … … 113 127 } 114 128 129 public function deleteById(int $recId):void 130 { 131 $sql = $this->db->prepare("DELETE FROM %i WHERE `id` = %d", $this->fullTableName, $recId); 132 $this->db->query($sql); 133 } 134 115 135 } -
catapultodelivery/trunk/libs/Wordpress/DB/DBTools.php
r3417476 r3444321 62 62 `receiver_phone` VARCHAR(150), 63 63 `receiver_email` VARCHAR(150), 64 64 65 65 `receiver_street` VARCHAR(255), 66 66 `receiver_house` varchar(50), 67 67 `receiver_flat` varchar(50), 68 68 69 69 `description` TEXT, 70 70 `with_insurance` BOOL, … … 80 80 `rate_result_id` INT(11) NOT NULL, 81 81 `terminal_code` VARCHAR(100), 82 82 83 83 `comment` TEXT, 84 84 `dlv_pay_side` tinyint(1) unsigned NOT NULL DEFAULT '0', 85 85 86 86 `updated` datetime, 87 87 PRIMARY KEY (`id`), … … 92 92 ) DEFAULT CHARSET={$this->db->charset};"); 93 93 94 $this->db->query("CREATE TABLE IF NOT EXISTS `{$this->db->get_blog_prefix()}catapulto_warehouses` ( 95 `id` int(11) unsigned NOT NULL auto_increment, 96 `city_id` int(11) unsigned NOT NULL, 97 `city_index` int(11) unsigned NOT NULL, 98 `contact_id` int(11) unsigned NOT NULL, 99 `city_name` varchar(250), 100 `name` varchar(250), 101 `delivery_from` varchar(30), 102 `free_courier_from` varchar(30), 103 `free_pickup_from` varchar(30), 104 `poa_enabled` varchar(1) NOT NULL DEFAULT 'N', 105 `poa_from_fio` varchar(200), 106 `poa_from_p_series` varchar(20), 107 `poa_from_p_number` varchar(20), 108 `poa_from_p_date` varchar(20), 109 `poa_from_email` varchar(100), 110 `lat` varchar(12), 111 `lon` varchar(12), 112 `operators` text, 113 `active` varchar(1) NOT NULL DEFAULT 'N', 114 115 `updated` datetime, 116 PRIMARY KEY (`id`) 117 ) DEFAULT CHARSET={$this->db->charset};"); 118 94 119 } 95 120 -
catapultodelivery/trunk/libs/Wordpress/DB/OrdersDB.php
r3417476 r3444321 48 48 $finalStatuses = CatapultoShippingMethod::getFinalStatuses(); 49 49 $mask = implode( ', ', array_fill( 0, count( $finalStatuses ), '%s' ) ); 50 $sql = $this->db->prepare("SELECT * FROM %i WHERE (`tracking_status` IS NULL) OR (`tracking_status` NOT IN ({$mask}) );", $this->fullTableName, $finalStatuses); 50 array_unshift($finalStatuses, $this->fullTableName); 51 $sql = $this->db->prepare("SELECT * FROM %i WHERE (`tracking_status` IS NULL) OR (`tracking_status` NOT IN ({$mask}) );", ...$finalStatuses); 51 52 return $this->db->get_results($sql, 'ARRAY_A'); 52 53 } … … 55 56 { 56 57 $mask = implode( ', ', array_fill( 0, count( $ids ), '%d' ) ); 57 $sql = $this->db->prepare("SELECT * FROM %i WHERE (`id` IN ({$mask}) )", $this->fullTableName, $ids); 58 array_unshift($ids, $this->fullTableName); 59 $sql = $this->db->prepare("SELECT * FROM %i WHERE (`id` IN ({$mask}) )", ...$ids); 58 60 return $this->db->get_results($sql, 'ARRAY_A'); 59 61 } -
catapultodelivery/trunk/libs/Wordpress/Frontend/AdminPages.php
r3417476 r3444321 3 3 namespace Ipol\Catapulto\Wordpress\Frontend; 4 4 5 use Ipol\Catapulto\Core\Delivery\Cargo; 5 6 use Ipol\Catapulto\Wordpress\CatapultoPlugin; 6 7 use Ipol\Catapulto\Wordpress\CatapultoShippingMethod; … … 16 17 private static $moduleSettings = []; 17 18 private static $rateResultData = []; 19 private static $warehouses = []; 20 private static $selectedWarehouseId = 0; 21 private static $senderWarehouse = []; 18 22 19 23 public static function renderOrderMetaBox() … … 23 27 $shippingMethod = self::$shippingMethod; 24 28 self::$moduleSettings = $shippingMethod->getAllSettings(); 29 self::$warehouses = $shippingMethod->getWarehouses(); 30 self::$selectedWarehouseId = $shippingMethod->getDefaultWarehouseId(); 31 self::$senderWarehouse = $shippingMethod->getSenderWarehouse(); 25 32 $order = wc_get_order(); 26 33 … … 40 47 private static function renderOrderSendMetabox(\WC_Order $order) 41 48 { 42 $orderDefaultGabs = Calculator::getCurrentCargoDataByOrder($order); 49 //Работа с грузоместами - здесь 50 $customCargoData = unserialize($order->get_meta(CatapultoPlugin::ORDER_META_CARGO)); 51 $cargoComment = $order->get_meta(CatapultoPlugin::ORDER_META_CARGOCOMMENT); 52 $isSingleProduct = true; 53 $isCargoValid = true; 54 if (!$customCargoData) { 55 //create default cargo data... 56 $cargoId = 0; 57 if ( 58 isset(self::$rateResultData['rate_param']) 59 && isset(self::$rateResultData['rate_param']['cargoes']) 60 && is_array(self::$rateResultData['rate_param']['cargoes']) 61 && count(self::$rateResultData['rate_param']['cargoes']) == 1 62 ) $cargoId = self::$rateResultData['rate_param']['cargoes'][0]; 63 64 $cargo = Calculator::getCurrentCargoDataByOrder($order); 65 $cargoComment = Calculator::getCargoComment(); 66 $cargo 67 ->setId((new \DateTime())->getTimestamp()) 68 ->setOrd($order->get_id()) 69 ->setCargoId($cargoId) 70 ; 71 72 $order->update_meta_data(CatapultoPlugin::ORDER_META_CARGO, serialize([$cargo->toArray()])); 73 $order->update_meta_data(CatapultoPlugin::ORDER_META_CARGOCOMMENT, $cargoComment); 74 $order->save(); 75 76 $isSingleProduct = $cargo->isSingleProduct(); 77 78 $customCargoData = [$cargo]; 79 } else { 80 //load CustomCargoData 81 $cargoesData = $customCargoData; 82 $customCargoData = []; 83 $isCargoValid = Calculator::validateCargoData($cargoesData, null, $order); 84 foreach ($cargoesData as $cargo) { 85 $crg = new Cargo(); 86 $crg->fromArray($cargo); 87 $crg 88 ->setCargoId(intval($cargo['ccargo_id'])) 89 ->setId($cargo['id']) 90 ->setOrd($cargo['ord']) 91 ; 92 $customCargoData[] = $crg; 93 if (!$crg->isSingleProduct()) $isSingleProduct = false; 94 } 95 if (count($customCargoData) > 1) $isSingleProduct = false; 96 } 97 $cargoesData = []; 98 foreach ($customCargoData as $crg) $cargoesData[] = $crg->toArray(); 43 99 44 100 $orderData = $order->get_data(); … … 54 110 $isCod = true; 55 111 $serviceFilter = 'NP,COD'; 56 foreach (self::$rateResultData['variant']['additional_services'] as $service) { 57 if ($service['name'] == 'cod_amount') { 58 $codAmount = $service['cost']; 59 break; 112 if (isset(self::$rateResultData['variant']['additional_services'])) 113 foreach (self::$rateResultData['variant']['additional_services'] as $service) { 114 if ($service['name'] == 'cod_amount') { 115 $codAmount = $service['cost']; 116 break; 117 } 60 118 } 61 } 62 } 63 64 $defaultDeliveryFrom = self::$moduleSettings['widgetDeliveryFrom']; 65 $inverceDeliveryTypes = []; 66 $operatorsDB = new OperatorsDB(); 67 $allOperators = $operatorsDB->getAllByColumn('op_enabled','Y'); 68 foreach ($allOperators as $operator) { 69 if (self::$moduleSettings['op_type_' . $operator['operator_id']] != $defaultDeliveryFrom) $inverceDeliveryTypes[] = $operator['operator_id']; 70 } 71 $inverceDeliveryTypesStr = implode("','",$inverceDeliveryTypes); 72 if (empty($inverceDeliveryTypesStr)) $inverceDeliveryTypesStr = '[]'; 73 else $inverceDeliveryTypesStr = "['" . $inverceDeliveryTypesStr . "']"; 119 } 74 120 75 121 //get Order Meta Data … … 83 129 84 130 $pvzSender = ''; 85 if ( (self::$moduleSettings[ 'op_type_' . self::$rateResultData['variant']['operator'] ] ?? '') == 'warehouse' ) $pvzSender = '<p><b>' . __('Sender`s pickup point code', 'catapultodelivery') . '</b></p><p>' . self::$moduleSettings[ 'op_code_' . self::$rateResultData['variant']['operator'] ] . '</p>';131 if ( isset(self::$rateResultData['variant']['operator']) && (self::$moduleSettings[ 'op_type_' . self::$rateResultData['variant']['operator'] ] ?? '') == 'warehouse' ) $pvzSender = '<p><b>' . __('Sender`s pickup point code', 'catapultodelivery') . '</b></p><p>' . self::$moduleSettings[ 'op_code_' . self::$rateResultData['variant']['operator'] ] . '</p>'; 86 132 $pvzReceiver = ''; 87 133 if (isset(self::$rateResultData['Terminal']) && !empty(self::$rateResultData['Terminal'])) { … … 130 176 } 131 177 132 $emptyRateData = [ 133 'dadata' => [ 134 'data' => [], 135 ], 136 'variant' => [ 137 'additional_services' => [], 138 'operator' => 'NotSet', 139 ], 140 'ctpt_params' => [ 141 'isEmpty' => true, 142 ], 143 ]; 144 $str = json_encode($emptyRateData); 178 $cargoLen = 0; 179 $cargoHei = 0; 180 $cargoWid = 0; 181 $cargoWei = 0; 182 if (count($customCargoData) > 0) { 183 $cargoLen = $customCargoData[0]->getLength(); 184 $cargoHei = $customCargoData[0]->getHeight(); 185 $cargoWid = $customCargoData[0]->getWidth(); 186 $cargoWei = $customCargoData[0]->getWeight(); 187 } 188 189 //if rate empty... 190 if (empty($receiverPostalCode)) { 191 $receiverPostalCode = $order->get_shipping_postcode(); 192 if (empty($receiverPostalCode)) $receiverPostalCode = $order->get_billing_postcode(); 193 } 194 if (empty($receiverCity)) { 195 $receiverCity = $order->get_shipping_city(); 196 if (empty($receiverCity)) $receiverCity = $order->get_billing_city(); 197 } 198 199 $ctptServices = []; 200 foreach ( (self::$rateResultData['variant']['additional_services'] ?? []) as $service ) { 201 $ctptServices[] = [ 202 'name' => $service['name'], 203 'cost' => $service['cost'], 204 ]; 205 } 206 $ctptServicesJs = json_encode($ctptServices, JSON_UNESCAPED_UNICODE); 207 208 $senderId = 0; 209 $senderLocId = 0; 210 $senderZip = 0; 211 $senderCity = ''; 212 $selectedWhId = 0; 213 $warehousesForAdm = []; 214 if (!empty(self::$senderWarehouse)) { 215 $senderId = intval(self::$senderWarehouse['contact_id']); 216 $senderLocId = intval(self::$senderWarehouse['city_id']); 217 $senderZip = self::$senderWarehouse['city_index']; 218 $senderCity = self::$senderWarehouse['city_name']; 219 $selectedWhId = intval(self::$senderWarehouse['id']); 220 } 221 if ( 222 isset(self::$rateResultData['rate_param']) 223 ) { 224 $savedWarehouseId = intval(self::$rateResultData['rate_param']['sender_warehouse_id'] ?? '0'); 225 if ($savedWarehouseId > 0) { 226 $selectedWhId = $savedWarehouseId; 227 foreach (self::$warehouses as $warehouse) { 228 if (intval($warehouse['id']) == $savedWarehouseId) { 229 $senderId = $warehouse['contact_id']; 230 $senderLocId = $warehouse['city_id']; 231 $senderZip = $warehouse['city_index']; 232 $senderCity = $warehouse['city_name']; 233 } 234 $warehousesForAdm[] = [ 235 'id'=>intval($warehouse['id']), 236 'sid'=>intval($warehouse['contact_id']), 237 'lid'=>intval($warehouse['city_id']), 238 'zip'=>$warehouse['city_index'], 239 'city'=>$warehouse['city_name'], 240 'whname'=>$warehouse['name'], 241 ]; 242 } 243 } 244 } 145 245 146 246 $orderData = [ … … 152 252 'phone' => Tools::phoneValidator($order->get_billing_phone()), 153 253 'email' => $order->get_billing_email(), 154 'wei' => $orderDefaultGabs['WEI'], 155 'wid' => $orderDefaultGabs['W'], 156 'len' => $orderDefaultGabs['L'], 157 'hei' => $orderDefaultGabs['H'], 158 'cargoComment' => $orderDefaultGabs['COMMENT'], 254 'wei' => $cargoWei, 255 'wid' => $cargoWid, 256 'len' => $cargoLen, 257 'hei' => $cargoHei, 258 'cargoComment' => $cargoComment, 259 'customCargo' => json_encode($cargoesData), 260 'customCargoValid' => $isCargoValid ? 'true' : 'false', 159 261 'receiverZip' => $receiverPostalCode, 160 262 'receiverCity' => $receiverCity, … … 163 265 'receiverFlat' => $receiverFlat, 164 266 165 'senderId' => self::$moduleSettings['senderId'],166 'senderLocId' => self::$moduleSettings['senderLocalityId'],167 'senderZip' => self::$moduleSettings['senderZip'],168 'senderCity' => self::$moduleSettings['senderCity'],267 'senderId' => $senderId, 268 'senderLocId' => $senderLocId, 269 'senderZip' => $senderZip, 270 'senderCity' => $senderCity, 169 271 170 272 'variantId' => self::$rateResultData['variant']['id'] ?? '', … … 186 288 'widgetDeliveryFrom' => self::$moduleSettings['widgetDeliveryFrom'], 187 289 'widgetMapMode' => (self::$moduleSettings['enMapOpenMode'] === 'courier') ? 'false' : 'true', 188 'inverseOperators' => $inverceDeliveryTypesStr,189 290 'isCard' => $isCard ? 'true' : 'false', 190 291 'isCash' => $isCash ? 'true' : 'false', … … 198 299 199 300 'isInsurance' => (self::$rateResultData['ctpt_params']['insurance'] ?? false) ? 'true' : 'false', 301 'insuranceConfig' => floatval(self::$rateResultData['variant']['insurance_config'] ?? 0), 302 303 'isFitting' => (self::$rateResultData['variant']['_isFitting'] ?? false) ? 'true' : 'false', 304 'isPR' => (self::$rateResultData['ctpt_params']['pr'] ?? false) ? 'true' : 'false', 305 'basePrice' => floatval(self::$rateResultData['variant']['_priceWithoutAdditionalServices'] ?? 0), 306 'isProdSingle' => $isSingleProduct ? 'true' : 'false', 307 308 'ctpt_services' => $ctptServicesJs, 309 310 //widget settings... 311 'w_geo_data_empty_message' => self::$moduleSettings['geoEmptyMessage'] ?? '', 312 'w_ws_api_domain' => ( (self::$moduleSettings['isTest'] ?? '') === 'yes' ) ? (self::$moduleSettings['customWSUrl'] ?? '') : '', 313 314 'warehouses' => json_encode($warehousesForAdm, JSON_UNESCAPED_UNICODE), 315 'selectedwh' => $selectedWhId, 200 316 201 317 ]; -
catapultodelivery/trunk/libs/Wordpress/Frontend/CheckoutBlock.php
r3417476 r3444321 8 8 use Ipol\Catapulto\Wordpress\Controller\MainController; 9 9 use Ipol\Catapulto\Wordpress\DB\CartVariantsDB; 10 use Ipol\Catapulto\Wordpress\DB\WarehousesDB; 10 11 use Ipol\Catapulto\Wordpress\Shipping\Calculator; 11 12 use Ipol\Catapulto\Wordpress\Tools\Tools; … … 40 41 $settings = $shippingMethod->getAllSettings(); 41 42 $cargo = Calculator::getCurrentCargoDataByCart(); 42 if (empty($cargo)) return []; 43 if (!$cargo) return []; 44 $cargoComment = Calculator::getCargoComment(); 45 $cargoAmount = Calculator::getCartAmount(); 43 46 44 47 //get cart && delete current variant id … … 57 60 ); 58 61 59 $widgetDeliveryFrom = $settings['widgetDeliveryFrom'];60 $operatorsSettings = [];61 $inverseOperators = [];62 $freeDeliveryOperators = [];63 62 $icons = []; 64 63 $companyIcons = $mainController->getCompanyIcons(); … … 67 66 while ($el = $elements->getNext()) { 68 67 $icons[$el->getOperatorId()] = $el->getIcon(); 69 70 $operatorSetting = [71 'operator' => $el->getOperatorId(),72 'inverse_delivery_type' => false,73 'free_delivery' => false,74 ];75 76 if ($settings['op_type_' . $el->getOperatorId()] != $widgetDeliveryFrom ) {77 $inverseOperators[] = $el->getOperatorId();78 $operatorSetting['inverse_delivery_type'] = true;79 }80 81 if ($settings['op_free_' . $el->getOperatorId()] === 'yes' ) {82 $freeDeliveryOperators[] = $el->getOperatorId();83 $operatorSetting['free_delivery'] = true;84 }85 $operatorsSettings[] = $operatorSetting;86 68 } 87 69 } … … 90 72 if ($widgetDeliveryTypes == 'All') $widgetDeliveryTypes = false; 91 73 74 //getWarehouseData 75 $localityId = 0; 76 $zip = ''; 77 $cityFrom = ''; 78 $selectedWH = $shippingMethod->getSenderWarehouse(); 79 if (is_array($selectedWH)) { 80 $localityId = $selectedWH['city_id']; 81 $zip = $selectedWH['city_index']; 82 $cityFrom = $selectedWH['city_name']; 83 } 84 92 85 $params = [ 93 86 'isTestMode' => $settings['isTest'] === 'yes', 94 87 'servicePath' => '/?rest_route=/catapultodelivery/widgethandler', 95 'senderLocalityId' => $ settings['senderLocalityId'],96 'senderZip' => $ settings['senderZip'],97 'senderCityFrom' => $ settings['senderCity'],88 'senderLocalityId' => $localityId, 89 'senderZip' => $zip, 90 'senderCityFrom' => $cityFrom, 98 91 'dadataToken' => $settings['dadataApikey'], 99 'cargoHeight' => $cargo ['H'],100 'cargoLength' => $cargo ['L'],101 'cargoWidth' => $cargo ['W'],102 'cargoWeight' => $cargo ['WEI'],103 'cargoComment' => $cargo ['COMMENT'],104 'insuredValue' => $cargo ['CARGO']->getTotalPrice()->getAmount(),92 'cargoHeight' => $cargo->getHeight(), 93 'cargoLength' => $cargo->getLength(), 94 'cargoWidth' => $cargo->getWidth(), 95 'cargoWeight' => $cargo->getWeight(), 96 'cargoComment' => $cargoComment, 97 'insuredValue' => $cargoAmount, 105 98 'needInsurance' => $settings['mindEnsurance'] === 'yes', 106 99 … … 109 102 110 103 'widgetDeliveryTypes' => $widgetDeliveryTypes, 111 'deliveryType' => $settings['widgetDeliveryFrom'],112 'inverseOperators' => $inverseOperators,113 'freeDeliveryOperators' => $freeDeliveryOperators,114 'operatorsSettings' => $operatorsSettings,115 104 'dayShift' => intval($settings['termIncrease']), 116 105 'mapOpenMode' => $settings['enMapOpenMode'] === 'map', … … 124 113 // 125 114 'geoEmptyMessage' => $settings['geoEmptyMessage'] ?? '', 126 'freeDlvMinCourier' => floatval($settings['freeDlvMinCourier']) ?? 0, 127 'freeDlvMinPVZ' => floatval($settings['freeDlvMinPVZ']) ?? 0, 115 116 //fitting 117 'isFitting' => $settings['isFitting'] === 'yes', 118 'fittingDefaultEnabled' => $settings['fittingDefaultEnabled'] === 'yes', 119 'partialRedemptionEnabled' => $settings['partialRedemptionEnabled'] === 'yes', 128 120 129 121 ]; -
catapultodelivery/trunk/libs/Wordpress/Rest/RestHandler.php
r3417476 r3444321 3 3 namespace Ipol\Catapulto\Wordpress\Rest; 4 4 5 use Ipol\Catapulto\Api\BadResponseException; 6 use Ipol\Catapulto\Core\Delivery\Cargo; 7 use Ipol\Catapulto\Core\Delivery\CargoItem; 8 use Ipol\Catapulto\Core\Entity\Money; 5 9 use Ipol\Catapulto\Core\Order\Address; 6 10 use Ipol\Catapulto\Core\Order\Item; … … 9 13 use Ipol\Catapulto\Wordpress\CatapultoPlugin; 10 14 use Ipol\Catapulto\Wordpress\CatapultoShippingMethod; 15 use Ipol\Catapulto\Wordpress\Controller\AbstractController; 11 16 use Ipol\Catapulto\Wordpress\Controller\MainController; 12 17 use Ipol\Catapulto\Wordpress\DB\CartVariantsDB; 13 18 use Ipol\Catapulto\Wordpress\DB\OperatorsDB; 14 19 use Ipol\Catapulto\Wordpress\DB\OrdersDB; 20 use Ipol\Catapulto\Wordpress\DB\WarehousesDB; 15 21 use Ipol\Catapulto\Wordpress\Factory\ControllerFactory; 16 22 use Ipol\Catapulto\Wordpress\Tools\Variables; … … 18 24 class RestHandler 19 25 { 26 27 private static $errors = []; 20 28 21 29 public static function widgetHandler($request) … … 42 50 if (empty($requestData)) return new \WP_REST_Response(['error'=>'CreateRate: DATA_CORRUPTED'], 200); 43 51 52 $selectedWHIdForce = intval($requestData['warehouseId'] ?? 0); 53 $selectedWh = null; 54 $allWarehouses = $shippingMethod->getWarehouses(); 55 if ($selectedWHIdForce > 0) { 56 foreach ($allWarehouses as $warehouse) { 57 if (intval($warehouse['id']) == $selectedWHIdForce) { 58 $selectedWh = $warehouse; 59 break; 60 } 61 } 62 } else { 63 $defaultWH = null; 64 65 $geoLat = floatval($requestData['dadata_selected_choice']['geo_lat'] ?? '0'); 66 $geoLon = floatval($requestData['dadata_selected_choice']['geo_lon'] ?? '0'); 67 $distance = 0; 68 foreach ($allWarehouses as $warehouse) { 69 if ($warehouse['active'] != 'Y') continue; //склад не активен 70 $whLat = floatval($warehouse['lat']); 71 $whLon = floatval($warehouse['lon']); 72 if ($whLat == 0 || $whLon == 0) continue; //Отсутствуют координаты склада 73 if (intval($warehouse['id']) == $shippingMethod->getDefaultWarehouseId()) $defaultWH = $warehouse; 74 75 //Определяем ближайший склад 76 if ($geoLat > 0 && $geoLon > 0) { 77 $a1 = deg2rad($geoLat); 78 $b1 = deg2rad($geoLon); 79 $a2 = deg2rad($whLat); 80 $b2 = deg2rad($whLon); 81 $calculatedDistance = 12742016 * asin(sqrt(pow(sin(($a2 - $a1) / 2), 2) + cos($a2) * cos($a1) * pow(sin(($b2 - $b1) / 2), 2))); 82 if (($calculatedDistance < $distance) || ($distance === 0)) { 83 $selectedWh = $warehouse; 84 $distance = $calculatedDistance; 85 } 86 } 87 } 88 if ($selectedWh === null) $selectedWh = $defaultWH; 89 if ($selectedWh === null) { 90 //error - WH for tarif not selected.... 91 return new \WP_REST_Response(['error'=>'CreateRate: CANT SELECT WH'], 200); 92 } 93 } 94 95 $invSendType = []; 96 $freeDeliveryOperators = []; 97 $operatorsData = json_decode($selectedWh['operators'], true); 98 if (!$operatorsData) $operatorsData = []; 99 foreach ($operatorsData as $code => $operator) { 100 if ($operator['f']) $freeDeliveryOperators[] = $code; 101 if ($operator['t'] != $selectedWh['delivery_from']) $invSendType[] = $code; 102 } 103 104 $whParams = [ 105 'delivery_type' => $selectedWh['delivery_from'], 106 'free_delivery_min_courier' => intval($selectedWh['free_courier_from']), 107 'free_delivery_min_pvz' => intval($selectedWh['free_pickup_from']), 108 'free_delivery_operators' => $freeDeliveryOperators, 109 'inverse_delivery_type_for_operators' => $invSendType, 110 'warehouseCustom' => false, 111 ]; 112 44 113 $ignoredSettlementTypes = Variables::getIgnoredSettlementTypes(); 45 114 $receiverCity = $requestData['dadata_selected_choice']['settlement'] ?? ''; … … 74 143 75 144 $sender = (new Address()) 76 ->setZip($s hippingMethod->getSenderZip())77 ->setField('cityFrom', $s hippingMethod->getSenderCity())78 ->setField('locality_id', $s hippingMethod->getSenderLocId());79 80 $itemCollection = new ItemCollection();145 ->setZip($selectedWh['city_index']) 146 ->setField('cityFrom', $selectedWh['city_name']) 147 ->setField('locality_id', $selectedWh['city_id']); 148 149 self::$errors = []; 81 150 if (!empty($requestData['cargo_data'])) { 82 $item = (new Item()) 83 ->setField('comment', $requestData['cargo_data']['cargo_comment'] ?? 'empty') 84 ->setField('type', $requestData['delivery_type'] ?? 'parcel'); 85 ; 86 if (isset($requestData['cargo_data']['width']) && !empty($requestData['cargo_data']['width'])) $item->setWidth( intval($requestData['cargo_data']['width']) ); 87 if (isset($requestData['cargo_data']['height']) && !empty($requestData['cargo_data']['height'])) $item->setHeight( intval($requestData['cargo_data']['height']) ); 88 if (isset($requestData['cargo_data']['length']) && !empty($requestData['cargo_data']['length'])) $item->setLength( intval($requestData['cargo_data']['length']) ); 89 if (isset($requestData['cargo_data']['weight']) && !empty($requestData['cargo_data']['weight'])) $item->setWeight( intval($requestData['cargo_data']['weight']) ); 90 if (isset($requestData['cargo_data']['quantity']) && !empty($requestData['cargo_data']['quantity'])) $item->setQuantity( intval($requestData['cargo_data']['quantity']) ); 91 $itemCollection->add($item); 151 $cargoSubDataNames = ['cargo_comment', 'height', 'length', 'width', 'quantity', 'weight']; 152 $cargoRequestArrayData = $requestData['cargo_data']; 153 $isSingle = false; 154 foreach ($cargoSubDataNames as $name) if (isset($cargoRequestArrayData[$name])) $isSingle = true; 155 $cargoIds = []; 156 if ( 157 is_array($cargoRequestArrayData) 158 && (count($cargoRequestArrayData) > 0) 159 && !$isSingle 160 ) { 161 //Если это существующий заказ - смотрим - есть ли данные по сохраненным грузоместам, т.к. если это многоместный заказ - скорее всего есть. 162 $orderId = intval($cargoRequestArrayData[0]['ord']); 163 $savedCargoData = []; 164 try { 165 $wcOrder = new \WC_Order($orderId); 166 $savedCargoData = unserialize($wcOrder->get_meta(CatapultoPlugin::ORDER_META_CARGO)); 167 if (!$savedCargoData) $savedCargoData = []; 168 } catch (\Exception $e) { 169 170 } 171 172 foreach ($cargoRequestArrayData as $cCata) { 173 $cargoId = self::createCatapultoCargo($mainController, $cCata, $data['delivery_type'] ?? 'parcel'); 174 if (!$cargoId && !empty(self::$errors)) return new \WP_REST_Response(['error'=>self::$errors[0]], 200); 175 if ($cargoId !== false) $cargoIds[] = $cargoId; 176 177 //save to custom cargo data... 178 foreach ($savedCargoData as $key => $crg) { 179 if ($crg['id'] == $cCata['crg_id']) { 180 $savedCargoData[$key]['ccargo_id'] = $cargoId; 181 break; 182 } 183 } 184 } 185 186 //save info 187 if ($wcOrder) { 188 $wcOrder->update_meta_data(CatapultoPlugin::ORDER_META_CARGO, serialize($savedCargoData)); 189 $wcOrder->save(); 190 } 191 } else { 192 $cargoId = self::createCatapultoCargo($mainController, $cargoRequestArrayData, $data['delivery_type'] ?? 'parcel'); 193 if (!$cargoId && !empty(self::$errors)) return new \WP_REST_Response(['error'=>self::$errors[0]], 200); 194 $cargoIds = [$cargoId]; 195 //$cargoItem = self::createCargoItem($cargoRequestArrayData, $data['delivery_type'] ?? 'parcel'); 196 //if ($cargoItem) $itemCollection->add($cargoItem); 197 } 198 199 92 200 } 93 201 94 202 $order = (new Order()) 95 203 ->setAddressFrom($sender) 96 ->setAddressTo($receiver) 97 ->setItems($itemCollection); 98 99 $cargoData = $mainController->createCargo($order); 100 if (!$cargoData) return new \WP_REST_Response(['error'=>$mainController->getFirstError()], 200); 101 if (empty($cargoData->getId())) return new \WP_REST_Response(['error'=>'Cargo: empty data'], 200); 102 $order->setField('cargoes',[$cargoData->getId()]); 204 ->setAddressTo($receiver); 205 206 $order->setField('cargoes',$cargoIds); 103 207 104 208 $iconData = []; … … 111 215 112 216 $order->setField('dadata_variant', $requestData['dadata_selected_choice']); 113 if ( $shippingMethod->getSenderId() > 0) $order->setField('sender_contact_id', $shippingMethod->getSenderId());217 if (intval($selectedWh['contact_id']) > 0) $order->setField('sender_contact_id', intval($selectedWh['contact_id'])); 114 218 if (isset($requestData['pickup_days_shift'])) $order->setField('pickup_days_shift', $requestData['pickup_days_shift']); 115 219 … … 122 226 'locations' => [ 123 227 'sender' => [ 124 'locality_id' => $shippingMethod->getSenderLocId(), 125 'zip' => $shippingMethod->getSenderZip(), 228 'locality_id' => $selectedWh['city_id'], 229 'contact_id' => intval($selectedWh['contact_id']), 230 'zip' => $selectedWh['city_index'], 231 'warehouse_id'=> $selectedWh['id'], 126 232 ], 127 233 'contact' => [ … … 130 236 ], 131 237 ], 238 'multiWarehouse' => $whParams, 132 239 'params' => [ 133 240 'sender_locality_id' => $shippingMethod->getSenderLocId(), 241 'sender_warehouse_id' => $selectedWh['id'], 242 'sender_contact_id' => $selectedWh['contact_id'], 134 243 'receiver_locality_id' => $order->getAddressTo()->getField('locality_id'), 135 'cargoes' => [$cargoData->getId()]244 'cargoes' => $cargoIds 136 245 ], 137 246 'icons' => $iconData … … 429 538 } 430 539 540 //Cargoes 541 public static function calcCargoDims($request) 542 { 543 $requestData = $request->get_params(); 544 $cargoData = json_decode($requestData['crg'], true); 545 if (!$cargoData) return new \WP_REST_Response(['res'=>false], 200); 546 547 $coreCargo = new Cargo(); 548 $coreCargo->fromArray($cargoData)->calculateDimensions(true); 549 550 return new \WP_REST_Response([ 551 'res'=>true, 552 'l' => $coreCargo->getLength(), 553 'w' => $coreCargo->getWidth(), 554 'h' => $coreCargo->getHeight(), 555 ], 200); 556 } 557 558 public static function cargoSave($request) 559 { 560 $requestData = $request->get_params(); 561 $orderId = intval($requestData['order_id']); 562 if ($orderId == 0) return new \WP_REST_Response(['res'=>false, 'e'=>'NoOrder'], 200); 563 try { 564 $order = new \WC_Order($orderId); 565 } catch (\Exception $e) { 566 return new \WP_REST_Response(['res'=>false, 'e'=>'NoOrder'], 200); 567 } 568 569 $crgData = json_decode($requestData['crg'], true); 570 if (!$crgData) return new \WP_REST_Response(['res'=>false, 'e'=>'corrupted'], 200); 571 572 $customCargoData = []; 573 foreach ($crgData as $cData) { 574 $cargo = (new Cargo()) 575 ->setId($cData['id']) 576 ->setCargoId(intval($cData['cargoId'])) 577 ->setOrd($orderId) 578 ->setLength(intval($cData['length'])) 579 ->setHeight(intval($cData['height'])) 580 ->setWidth(intval($cData['width'])) 581 ->setWeight(intval($cData['weight'])) 582 ; 583 584 foreach ($cData['items'] as $itemdata) { 585 $itm = (new CargoItem()) 586 ->setId($itemdata['id']) 587 ->setName($itemdata['name']) 588 ->setArticul($itemdata['articul']) 589 590 ->setHeight(intval(floatval($itemdata['height']))) 591 ->setWidth(intval(floatval($itemdata['width']))) 592 ->setLength(intval(floatval($itemdata['length']))) 593 ->setWeight(floatval($itemdata['weight'])) 594 ->setQuantity(floatval($itemdata['quantity'])) 595 596 ->setCost(new Money( floatval($itemdata['price']['amount']) )) 597 ->setPrice(new Money( floatval($itemdata['price']['amount']) )) 598 ->setField('name', $itemdata['name']) 599 ->setField('sku', $itemdata['variantId']) 600 ->setField('dimEmpty', false) 601 ; 602 $cargo->add($itm); 603 } 604 $customCargoData[] = $cargo; 605 } 606 607 $cargoesData = []; 608 foreach ($customCargoData as $crg) $cargoesData[] = $crg->toArray(); 609 610 $order->update_meta_data(CatapultoPlugin::ORDER_META_CARGO, serialize($cargoesData)); 611 $order->update_meta_data('ctpt_ratedata', serialize([])); 612 $order->save(); 613 614 return new \WP_REST_Response(['res'=>true], 200); 615 } 616 617 public static function cargoClear($request) 618 { 619 $requestData = $request->get_params(); 620 $orderId = intval($requestData['order_id']); 621 if ($orderId == 0) return new \WP_REST_Response(['res' => false, 'e' => 'NoOrder'], 200); 622 try { 623 $order = new \WC_Order($orderId); 624 } catch (\Exception $e) { 625 return new \WP_REST_Response(['res' => false, 'e' => 'NoOrder'], 200); 626 } 627 628 $order->update_meta_data(CatapultoPlugin::ORDER_META_CARGO, ''); 629 $order->update_meta_data('ctpt_ratedata', serialize([])); 630 $order->save(); 631 632 return new \WP_REST_Response(['res'=>true], 200); 633 } 634 431 635 /////// For old WP versions 432 636 //save ctpt rate result from checkout page … … 453 657 454 658 659 660 private static function createCatapultoCargo( 661 $controler, 662 $cargoData, 663 $deliveryType = 'parcel' 664 ) { 665 $cargoSubDataNames = [/*'cargo_comment',*/ 'height', 'length', 'width', 'quantity', 'weight']; 666 foreach ($cargoSubDataNames as $name) { 667 if (!isset($cargoData[$name])) return false; //not valid! 668 if (empty($cargoData[$name])) return false; 669 } 670 $cargoItem = (new Item()) 671 ->setWeight((int)$cargoData['weight']) //граммы 672 ->setWidth((int)$cargoData['width']) //мм 673 ->setLength((int)$cargoData['length']) //мм 674 ->setHeight((int)$cargoData['height']) //мм 675 ->setQuantity((int)$cargoData['quantity']) //мм 676 ->setField('comment', $cargoData['cargo_comment'] ?? 'empty') 677 ->setField('type', $deliveryType)// тип отправления ['docs', 'parcel'] 678 ; 679 680 $cargoResult = $controler->createCargoByItem($cargoItem); 681 if (!$cargoResult) { 682 self::$errors[] = $controler->getFirstError(); 683 return null; 684 } 685 if (empty($cargoResult->getId())) { 686 self::$errors[] = 'Cargo: empty data'; 687 return null; 688 } 689 690 return $cargoResult->getId(); 691 } 692 455 693 } -
catapultodelivery/trunk/libs/Wordpress/Shipping/Calculator.php
r3417476 r3444321 6 6 use Ipol\Catapulto\Core\Delivery\CargoItem; 7 7 use Ipol\Catapulto\Core\Entity\Money; 8 use Ipol\Catapulto\Wordpress\CatapultoPlugin; 8 9 use Ipol\Catapulto\Wordpress\CatapultoShippingMethod; 9 10 … … 12 13 const API_DIMENSION_UNIT = 'mm'; 13 14 const API_WEIGHT_UNIT = 'g'; 15 16 private static $cargoComment = ''; 17 private static $cartAmount = 0; 14 18 15 19 public static function getDefaultGabs():array … … 35 39 * Для расчета доставки виджетом Катапульто - подготовка данных расчета - параметров грузоместа 36 40 */ 37 public static function getCurrentCargoDataByCart():array 38 { 39 if (!WC()->cart) return []; 40 $cargoData = self::getCargo( WC()->cart->get_cart() ); 41 $cargo = $cargoData['cargo']; 42 $cargoComment = $cargoData['comment']; 43 44 $dims = $cargo->getDimensions(); 45 $wei = $cargo->getWeight(); 46 47 return array_merge($dims,[ 48 'CARGO' => $cargo, 49 'WEI'=>$wei, 50 'TOTAL' => floatval(WC()->cart->get_subtotal()), 51 'COMMENT' => $cargoComment 52 ]); 53 } 54 55 public static function getCurrentCargoDataByOrder(\WC_Order $order):array 56 { 57 $cargoData = self::getCargo( $order->get_items() ); 58 $cargo = $cargoData['cargo']; 59 $cargoComment = $cargoData['comment']; 60 61 $dims = $cargo->getDimensions(); 62 $wei = $cargo->getWeight(); 63 64 return array_merge($dims,[ 65 'CARGO' => $cargo, 66 'WEI'=>$wei, 67 'COMMENT' => $cargoComment 68 ]); 69 } 70 71 private static function getCargo($items) 41 public static function getCurrentCargoDataByCart():?Cargo 42 { 43 if (!WC()->cart) return null; 44 self::$cartAmount = WC()->cart->get_subtotal(); 45 return self::getCargo( WC()->cart->get_cart() ); 46 } 47 48 public static function getCurrentCargoDataByOrder(\WC_Order $order):Cargo 49 { 50 self::$cartAmount = $order->get_subtotal(); 51 return self::getCargo( $order->get_items() ); 52 } 53 54 private static function getCargo($items): Cargo 72 55 { 73 56 … … 77 60 $cargoComment = ''; 78 61 79 if ($gabsSettings['MODE'] == 'O') {80 $itemsPrices = 0;62 if ($gabsSettings['MODE'] == CatapultoPlugin::DEFMODE_O) { 63 //$itemsPrices = 0; 81 64 $hasEmpty = false; 82 $orderCargo = new Cargo();65 //$orderCargo = new Cargo(); 83 66 foreach ( $items as $item ) { 84 67 $product = null; … … 99 82 || ($len == 0) 100 83 ) $isEmpty = true; 101 if (!$isEmpty) { 102 $cargoItem = (new CargoItem()) 103 ->setHeight($hei) 104 ->setWidth($wid) 105 ->setLength($len) 106 ->setWeight($wei) 107 ->setQuantity($qty) 108 ->setPrice(new Money( floatval($product->get_price()) )) 109 ->setField('name', $product->get_name()) 110 ->setField('sku', empty($product->get_sku()) ? '' : $product->get_sku()); 111 $orderCargo->add($cargoItem); 112 } else $hasEmpty = true; 113 114 $itemsPrices += floatval($product->get_price()) * floatval($item['quantity']); 84 if ($isEmpty) $hasEmpty = true; 85 86 $cargoItem = (new CargoItem()) 87 ->setId($product->get_id()) 88 ->setHeight($hei) 89 ->setWidth($wid) 90 ->setLength($len) 91 ->setWeight($wei) 92 ->setQuantity($qty) 93 ->setName($product->get_name()) 94 ->setCost(new Money( floatval($product->get_price()) )) 95 ->setPrice(new Money( floatval($product->get_price()) )) 96 ->setField('name', $product->get_name()) 97 ->setArticul('') 98 ->setField('sku', empty($product->get_sku()) ? '' : $product->get_sku()) 99 ->setField('dimEmpty', $isEmpty) 100 ; 101 $cargo->add($cargoItem); 102 115 103 $cargoComment .= $product->get_name() . '('.floatval($item['quantity']).');'; 116 104 } 117 105 118 106 if ($hasEmpty) { 119 $dims = $ orderCargo->getDimensions();120 $wei = $ orderCargo->getWeight();121 122 $cargo Item = (new CargoItem())123 ->set Height( max($gabsSettings['HEI'], $dims['H']))107 $dims = $cargo->getDimensions(); 108 $wei = $cargo->getWeight(); 109 110 $cargo 111 ->setWeight(max($gabsSettings['WEI'], $wei)) 124 112 ->setWidth( max($gabsSettings['WID'], $dims['W']) ) 125 113 ->setLength( max($gabsSettings['LEN'], $dims['L']) ) 126 ->setWeight( max($gabsSettings['WEI'], $wei) ) 127 ->setQuantity(1) 128 ->setPrice(new Money( $itemsPrices )) 129 ->setField('name', 'order_calculated_gabs') 130 ->setField('sku', ''); 131 $cargo->add($cargoItem); 132 133 } else $cargo = $orderCargo; 114 ->setHeight( max($gabsSettings['HEI'], $dims['H']) ) 115 ; 116 } else { 117 $cargo->calculateDimensions(true); 118 $cargo->setWeight($cargo->getWeight()); 119 } 134 120 135 121 } else { … … 155 141 ) $isEmpty = true; 156 142 157 if ($isEmpty && ($gabsSettings['MODE'] == 'G')) {143 if ($isEmpty && ($gabsSettings['MODE'] == CatapultoPlugin::DEFMODE_G)) { 158 144 $wei = $gabsSettings['WEI']; 159 145 $len = $gabsSettings['LEN']; … … 164 150 $cargoComment .= $product->get_name()."(${qty});"; 165 151 $cargoItem = (new CargoItem()) 152 ->setId($product->get_id()) 166 153 ->setHeight($hei) 167 154 ->setWidth($wid) … … 169 156 ->setWeight($wei) 170 157 ->setQuantity($qty) 158 ->setName($product->get_name()) 159 ->setCost(new Money( floatval($product->get_price()) )) 171 160 ->setPrice(new Money( floatval($product->get_price()) )) 172 161 ->setField('name', $product->get_name()) 173 ->setField('sku', empty($product->get_sku()) ? '' : $product->get_sku()); 162 ->setArticul('') 163 ->setField('sku', empty($product->get_sku()) ? '' : $product->get_sku()) 164 ->setField('dimEmpty', $isEmpty) 165 ; 174 166 $cargo->add($cargoItem); 175 167 } 176 } 177 178 return [ 179 'cargo' => $cargo, 180 'comment' => $cargoComment, 181 ]; 168 $cargo->calculateDimensions(true); 169 $cargo->setWeight($cargo->getWeight()); 170 } 171 172 self::$cargoComment = $cargoComment; 173 174 return $cargo; 175 } 176 177 public static function getCargoComment(): string 178 { 179 return self::$cargoComment; 180 } 181 182 public static function getCartAmount(): int 183 { 184 return self::$cartAmount; 185 } 186 187 public static function validateCargoData(array $customCargoData, Cargo $cargo = null, \WC_Order $order = null): bool 188 { 189 if (!$cargo && !$order) throw new \Exception('Cant validate CargoData, Cargo or WCOrder is missing'); 190 if (!$cargo) $cargo = self::getCurrentCargoDataByOrder($order); 191 192 $orderItems = []; 193 $cargo->reset(); 194 while ($itm = $cargo->getNext()) { 195 $orderItems[] = [ 196 'id' => intval($itm->getId()), 197 'sku' => $itm->getField('sku') ?? '', 198 'qty' => floatval($itm->getQuantity()), 199 'cqty' => 0, 200 ]; 201 } 202 203 foreach ($customCargoData as $customCargoItem) { 204 foreach ($customCargoItem['items'] as $item) { 205 $itemSku = $item['fields']['sku'] ?? ''; 206 $itemId = intval($item['id']); 207 $itemQty = floatval($item['quantity']); 208 $isExist = false; 209 foreach ($orderItems as &$orderItem) { 210 if ( 211 $orderItem['id'] == $itemId 212 && ($orderItem['sku'] == $itemSku) 213 ) { 214 $orderItem['cqty'] += $itemQty; 215 $isExist = true; 216 } 217 } 218 unset($orderItem); 219 if (!$isExist) $orderItems[] = [ 220 'id' => $itemId, 221 'sku' => $itemQty, 222 'qty' => 0, 223 'cqty' => $itemQty, 224 ]; 225 } 226 227 } 228 229 $isValid = true; 230 foreach ($orderItems as $orderItem) { 231 if ($orderItem['qty'] != $orderItem['cqty']) $isValid = false; 232 } 233 234 return $isValid; 182 235 } 183 236 -
catapultodelivery/trunk/libs/Wordpress/Tools/TemplateRender.php
r3417476 r3444321 20 20 { 21 21 echo wp_kses($content, [ 22 'div'=>[ 'class'=>[], 'style'=>[] ],22 'div'=>[ 'class'=>[], 'style'=>[], 'id'=>[], ], 23 23 'label' => [ 'for' => [], 'class' => [], 'style' => [], ], 24 24 'form' => [ 'action' => [], ], … … 34 34 'li'=>[ 'class'=>[], 'style'=>[], ], 35 35 'h3'=>[ ], 36 'h4'=>[ ],36 'h4'=>[ 'class' => [], ], 37 37 'b'=>[ ], 38 38 'hr'=>[ ], -
catapultodelivery/trunk/readme.txt
r3420063 r3444321 5 5 Requires at least: 5.9 6 6 Tested up to: 6.8 7 Stable tag: 1.0. 07 Stable tag: 1.0.1 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 23 23 * Отображение нескольких вариантов (тарифов) доставки в каждой службе доставки; 24 24 * Возможность указать желаемую дату получения заказа; 25 * И многое многое другое. Подробнее можно посмотреть на официальном сайте Catapulto (https://catapulto.ru /modul-dostavki-dlya-internet-magazinov/).25 * И многое многое другое. Подробнее можно посмотреть на официальном сайте Catapulto (https://catapulto.ru). 26 26 27 27 Ознакомьтесь со всеми возможностями модуля в настройках. 28 28 29 ***Внимание!*** Для работы этого платежного модуля необходимо заключить договор с Catapulto ,а также выпустить бесплатный ключ сервиса Dadata.29 ***Внимание!*** Для работы этого платежного модуля необходимо заключить договор с Catapulto а также выпустить бесплатный ключ сервиса Dadata. 30 30 31 31 == External services == 32 32 33 Этот плагин подключается в API службы доставки Catapulto (https://eshop.catapulto.ru/) для расчета возможных вариантов доставки. Для этого передается информация о составе заказа и местоположении пользователя. Без этой информации рассчитать доставку невозможно. 33 Этот плагин подключается в API службы доставки Catapulto (https://eshop.catapulto.ru/) для расчета возможных вариантов доставки. Для этого передается информация о составе заказа и местоположении пользователя. Без этой информации рассчитать доставку невозможно. 34 34 Сервис предоставляется на основе публичной оферты (https://catapulto.ru/media/public_offer/public_offer.pdf) и политики обработки персональных данных (https://catapulto.ru/privacy/). Используя этот модуль Вы принимаете условия, указанные в этих документах. 35 35 Также для более точного определения адреса используется сервис Dadata (https://suggestions.dadata.ru/) в том числе в виде подсказок адреса при вводе. Сервис предоставляется на основе политики конфиденциальности (https://dadata.ru/privacy/) и прочих документов (https://dadata.ru/offer/). … … 41 41 == Installation == 42 42 43 1. Установите модуль со страницы в каталоге плагинов WordPress (https://wordpress.org/plugins/catapultodelivery/). 44 1. Активируйте плагин на странице «Плагины» WordPress. 45 1. Перейдите на страницу «WooCommerce / Настройки / Доставка», нажмите ссылку в главной меню «Курьером или в пункт выдачи» и произведите настройку плагина. 43 1. Свяжитесь с Catapulto и получите архив с модулем, распакуйте его. 44 1. Его содержимое скопируйте в директорию /wp-content/plugins/catapultodelivery/ Вашего сайта 45 1. Активируйте плагин на странице "Плагины" WordPress 46 1. Перейдите на страницу "WooCommerce / Настройки / Доставка, нажмите ссылку в главной меню "Курьером или в пункт выдачи" и произведите настройку плагина. 46 47 1. Активируйте ключ доступа, установите остальные настройки при помощи консультации с менеджером Catapulto. 47 48 … … 52 53 == Frequently Asked Questions == 53 54 54 По всем возникающим вопросам обращайтесь в Catapulto по электронной почте im@catapulto.ru или по номеру телефона 8-800-555-22-41.55 По всем возникающим вопросам обращайтесь в Catapulto (support@catapulto.ru). 55 56 56 57 == Screenshots == -
catapultodelivery/trunk/templates/admin/orderPanel.tpl
r3417476 r3444321 1 <div class="ctpt_cargowinbg"></div> 2 <div class="ctpt_cargowin"> 3 <div class="ctpt_cargowin_close"></div> 4 <div class="ctpt_cargowin_content"> 5 6 <div class="ctpt_alert ctpt_danger rate_update_errors"></div> 7 <div class="ctpt_alert ctpt_success rate_update_success"> 8 Данные грузомест и габариты успешно сохранены для этого заказа.<br/><br/> 9 Текущий результат расчета был удален. Необходимо заново выбрать новый расчет доставки.<br/><br/> 10 </div> 11 <div class="ctpt_alert ctpt_default"> 12 Внимание! В случае сохранения необходимо будет повторно выбрать вариант доставки.<br/> 13 До выбора нового варианта доставки отправление заявки в Catapulto невозможно. 14 </div> 15 16 <div class="ctpt_move_win"> 17 <div class="close"></div> 18 <p>Выберите место <br/>и количество <br/>перемещаемого <br/>в него товара</p> 19 <select class="form-select"> 20 21 </select> 22 <div class="place"> 23 <p>10 /</p> 24 <input type="text"> 25 </div> 26 <div class="ctpt_btn ctpt_btn_green">Переместить</div> 27 </div> 28 29 <div class="ctpt_cargo_table"> 30 <h3>Управление грузоместами и товарами</h3> 31 32 <div class="cargoes"></div> 33 34 <div class="ctpt_btn add_new_cargo">Добавить место</div> 35 36 <div class="btm_buttons"> 37 <div class="ctpt_btn ctpt_btn_green ctpt_gdsdata_save">Сохранить</div> 38 <div class="ctpt_btn ctpt_btn_yellow ctpt_gdsdata_reset">Сбросить</div> 39 </div> 40 </div> 41 42 </div> 43 </div> 44 45 <style> 46 .ctpt_cargowin, 47 .ctpt_cargowinbg { 48 position: fixed; 49 left: 0; 50 top: 0; 51 width: 100%; 52 height: 100%; 53 display: none; 54 } 55 .ctpt_cargowinbg { 56 background: #fff; 57 z-index: 10000; 58 opacity: 0.8; 59 } 60 .ctpt_cargowinbg.sh { 61 display: block; 62 } 63 .ctpt_cargowin { 64 z-index: 10001; 65 justify-content: center; 66 overflow-y: scroll; 67 } 68 .ctpt_cargowin.sh { 69 display: flex; 70 } 71 72 .ctpt_btn { 73 display: inline-block; 74 padding: 0.375rem 0.75rem; 75 color: #fff; 76 text-align: center; 77 text-decoration: none; 78 vertical-align: middle; 79 cursor: pointer; 80 -webkit-user-select: none; 81 -moz-user-select: none; 82 user-select: none; 83 border: 1px solid #0d6efd; 84 border-radius: 4px; 85 background-color: #0d6efd; 86 transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; 87 } 88 89 .ctpt_btn.ctpt_btn_green { 90 border-color: #198754; 91 background-color: #198754; 92 } 93 .ctpt_btn.ctpt_btn_yellow { 94 color: #000; 95 border-color: #ffc107; 96 background-color: #ffc107; 97 } 98 99 .ctpt_calc_cargo_gabs { 100 margin-bottom: 10px; 101 } 102 103 .ctpt_alert { 104 position: relative; 105 padding: 20px; 106 margin-bottom: 20px; 107 color: #664d03; 108 background-color: #fff3cd; 109 border: 1px solid #ffe69c; 110 border-radius: 0.375rem; 111 112 font-size: 13px; 113 } 114 .ctpt_alert.ctpt_success { 115 background-color: #d1e7dd; 116 border-color: #a3cfbb; 117 color:#0a3622; 118 } 119 .ctpt_alert.ctpt_danger { 120 background-color: #f8d7da; 121 border-color: #f1aeb5; 122 color: #58151c; 123 } 124 .ctpt_alert.ctpt_default { 125 margin-top: 100px; 126 } 127 128 #ctpt_cargoes { 129 margin-top: 20px; 130 } 131 132 </style> 133 1 134 <div class="ctpt_order_panel"> 2 135 <h3>Создать отправление</h3> 3 136 4 <h4>Габариты заказа</h4> 5 <p><b>Размеры (мм)</b></p> 6 <p>#len# x #wid# x #hei#</p> 7 <p><b>Вес (г)</b></p> 8 <p>#wei#</p> 137 <h4 class="cargo_gabs_block">Габариты грузомест</h4> 138 <div class="cargo_gabs_block_content"> 139 </div> 9 140 10 141 <hr> … … 14 145 <p><b>Город отправителя</b></p> 15 146 <p>#senderCity#</p> 147 <div class="ctpt_tbl" style="padding: 10px 0;"> 148 <p style="float:left;cursor:pointer"><b><label for="ctpt_is_custom_wh">Выбрать другой склад</label></b></p> 149 <input id="ctpt_is_custom_wh" type="checkbox" name="ctpt_is_custom_wh" checked style="float:left;margin-top:5px;margin-left: 10px" /> 150 </div> 151 <p><b>Склад отправителя</b></p> 152 <select id="ctpt_adm_selected_wh" style="width:98%;"></select> 16 153 17 154 <hr/> … … 72 209 <input id="ctpt_needInsurance" type="checkbox" name="ctpt_needInsurance" style="float:left;margin-top:5px;margin-left: 10px" /> 73 210 </div> 74 75 <p><b>Страховая стоимость</b></p> 211 <div class="ctpt_tbl" style="padding: 0 0 10px 0"> 212 <p style="float:left;cursor:pointer"><b><label for="ctpt_is_fitting">Примерка</label></b></p> 213 <input id="ctpt_is_fitting" type="checkbox" name="ctpt_is_fitting" style="float:left;margin-top:5px;margin-left: 10px" /> 214 </div> 215 <div class="ctpt_tbl" style="padding: 0 0 10px 0"> 216 <p style="float:left;cursor:pointer"><b><label for="ctpt_is_pr">Частичный выкуп</label></b></p> 217 <input id="ctpt_is_pr" type="checkbox" name="ctpt_is_pr" style="float:left;margin-top:5px;margin-left: 10px" /> 218 </div> 219 220 <div class="ctpt_hint_block"> 221 <span class="ctpt_hintlbl"></span> 222 <div class="ctpt_hint_content"> 223 <p class="ctpt_hint_content">В случае утраты груза возмещение возможно в размере объявленной ценности, но не больше действительной документально подтвержденной стоимости груза. Также для возмещения будет необходимо предоставить документы, подтверждающие стоимость и основание законного владения грузом.</p> 224 </div> 225 <p><b>Объявленная ценность</b></p> 226 </div> 76 227 <input type="text" id="ctpt_insuranceValue" name="ctpt_insuranceValue" value="#goodsPrice#" /> 77 228 … … 94 245 </div> 95 246 247 <p class="ctpt_custom_cargo_valid" style="color: #f00; margin-bottom: 15px">Обнаружено несовпадение корзины заказа и состава грузомест. Необходимо удалить грузоместа, составить их заново и выбрать новый расчет доставки.</p> 248 96 249 <div class="ctpt_buttons"> 97 250 <button id="ctpt_sendorder" class="button button-primary">Отправить</button> 98 251 </div> 99 252 </div> 253 254 <button id="ctpt_cargoes" class="button button-primary">Управление грузоместами</button> 255 <button id="ctpt_cargoer_del" class="button button-primary" style="margin-bottom: 20px;">Очистить грузоместа</button> 256 100 257 </div> 101 258 … … 109 266 goodsPrice: #goodsPrice#, 110 267 shippingPrice: #shippingPrice#, 268 ratePrice: #deliveryPrice#, 111 269 isCod: #isCod#, 112 270 codAmount: #codAmount#, 113 271 isEnsurance: #isInsurance#, 272 cargoData: #customCargo#, 273 basePrce: #basePrice#, 274 isFitting: #isFitting#, 275 isPR: #isPR#, 276 isProductSingle: #isProdSingle#, 277 services: '#ctpt_services#', 278 std_wei: '#wei#', 279 std_len: '#len#', 280 std_wid: '#wid#', 281 std_hei: '#hei#', 282 cargo_valid: #customCargoValid#, 283 w_geo_data_empty_message: '#w_geo_data_empty_message#', 284 w_ws_api_domain: '#w_ws_api_domain#', 285 insurance_cost: '#insuranceConfig#', 286 warehouses: #warehouses#, 287 selectedwh: #selectedwh#, 114 288 }; 289 window.ctptData.insurance_cost = Number(window.ctptData.insurance_cost); 290 if (isNaN(window.ctptData.insurance_cost)) window.ctptData.insurance_cost = 0; 115 291 116 292 if (isEmpty) { 117 293 document.querySelector('.ctpt_datablock').style.display = 'none'; 118 294 document.querySelector('.ctpt_warnempty').style.display = 'block'; 295 } 296 297 document.querySelector('#ctpt_is_custom_wh').checked = false; 298 for (let i in window.ctptData.warehouses) { 299 const el = document.createElement('option'); 300 el.setAttribute('value', window.ctptData.warehouses[i].id); 301 if (window.ctptData.warehouses[i].id == window.ctptData.selectedwh) 302 el.setAttribute('selected','selected'); 303 el.innerHTML = '(' + window.ctptData.warehouses[i].id + ') ' + window.ctptData.warehouses[i].whname; 304 document.querySelector('#ctpt_adm_selected_wh').appendChild(el); 305 } 306 document.getElementById('ctpt_adm_selected_wh').setAttribute('disabled','disabled'); 307 document.getElementById('ctpt_is_custom_wh').onchange = function(e) { 308 if (e.target.checked) { 309 document.getElementById('ctpt_adm_selected_wh').removeAttribute('disabled'); 310 } else { 311 document.getElementById('ctpt_adm_selected_wh').setAttribute('disabled','disabled'); 312 } 119 313 } 120 314 … … 127 321 cityFrom: '#senderCity#', 128 322 }, 323 isMultiWarehouse: true, 129 324 startTabMap: #widgetMapMode#, 130 325 dadata_token: '#dadataToken#', 131 cargo: {132 height: #hei#,133 length: #len#,134 quantity: 1,135 width: #wid#,136 weight: #wei#,137 cargo_comment:'#cargoComment#',138 },139 326 services_filter: '#serviceFilter#', 140 327 filter_card: #isCard#, … … 146 333 delivery_type: '#widgetDeliveryFrom#', 147 334 day_shift: #day_shift#, 148 inverse_delivery_type_for_operators: #inverseOperators#,149 335 150 336 need_insurance: #needInsurance#, 151 337 insured_value: 0, 338 warehouseId: 0, 152 339 }; 153 340
Note: See TracChangeset
for help on using the changeset viewer.