1/** 2 * @ai:claude Sends the browser to the login form when an XHR comes back 401, carrying the page the 3 * user was on so they land back on it after logging in. 4 * 5 * MY_Controller::redirectToLoginForm() cannot redirect an XHR - a 302 on an ajax call is followed by 6 * jQuery and the login page arrives as the response body - so it answers 401 and leaves it to the 7 * browser. Nothing was listening: utils/global.js has a handler, but it is only loaded by the 8 * `vendor_new_js` and `frontpage_js` groups, and it opens a jQuery-UI dialog inside a try/catch that 9 * swallows the failure when the page has no #dialog element - and then never runs the redirect 10 * anyway, because showPromptDialog() ignores the callback it is passed. On omat_tiedot the result 11 * was an expired session that looked like nothing happening at all. 12 * 13 * Deliberately its own file rather than pulling global.js into more templates: that file also 14 * defines the `global` object, jQuery-UI dialogs and a placeholder shim, none of which these pages 15 * want. 16 * 17 * The returnUrl is the current page, not the failed endpoint. The endpoint is a POST that saves 18 * something; sending the user back to it after login would either 404 or repeat a write. 19 */ 20(function($) { 21 'use strict'; 22 23 if (!$ || window.ivSessionExpiry) { 24 return; 25 } 26 27 var LOGIN_PATH = '/auth/login'; 28 29 var ivSessionExpiry = { 30 // One redirect per page, however many requests fail at once 31 redirecting: false, 32 33 loginUrl: function() { 34 return LOGIN_PATH + '?returnUrl=' + encodeURIComponent(window.location.pathname + window.location.search); 35 }, 36 37 /** 38 * Never from the login form itself or the rest of /auth - the session is expected to be absent 39 * there, and redirecting would loop. 40 */ 41 shouldRedirect: function() { 42 return !this.redirecting && window.location.pathname.indexOf('/auth/') !== 0; 43 }, 44 45 handle: function(status) { 46 if (status !== 401 || !this.shouldRedirect()) { 47 return; 48 } 49 50 this.redirecting = true; 51 // replace() so Back does not return to a page whose session is gone 52 window.location.replace(this.loginUrl()); 53 }, 54 }; 55 56 window.ivSessionExpiry = ivSessionExpiry; 57 58 $(document).ajaxError(function(event, jqXHR) { 59 ivSessionExpiry.handle(jqXHR && jqXHR.status); 60 }); 61})(window.jQuery); 62 63; 64var CustomerCardDialogVm = function() { 65 'use strict'; 66 var self = this; 67 68 // Reference to jQuery ui dialog 69 self.inited = ko.observable(false); 70 self.dialog = null; 71 self.saving = ko.observable(false); 72 self.saved = ko.observable(false); 73 74 self.customer = { 75 id: ko.observable(null), 76 identifier: ko.observable(''), 77 type: ko.observable(), 78 ssn: ko.observable(''), 79 firstName: ko.observable(''), 80 lastName: ko.observable(''), 81 companyName: ko.observable(''), 82 businessId: ko.observable(''), 83 contactPerson: ko.observable(''), 84 contactPersonEmail: ko.observable(''), 85 extraInfo: ko.observable(''), 86 additionalInfo:ko.observable(''), 87 co: ko.observable(''), 88 address: ko.observable(''), 89 zipcode: ko.observable(''), 90 city: ko.observable(''), 91 email: ko.observable(''), 92 phone: ko.observable(''), 93 eInvoiceAddress: ko.observable(''), 94 eInvoiceOperator: ko.observable(''), 95 paymentTerms: ko.observable('14'), 96 deliveryMethod: ko.observable('mail'), 97 notificationMethod: ko.observable(null) 98 }; 99 100 self.customerCardTitle = ko.computed(function(){ 101 102 return 'Asiakaskortti' 103 }) 104 105 self.availableDeliveryMethods = ko.computed(function() { 106 107 if (self.customer.type() === 'person') { 108 return [ 109 { value: 'mail', text: 'Postitse' }, 110 { value: 'sms', text: 'Tekstiviesti' }, 111 { value: 'email', text: 'Sähköpostitse' }, 112 ]; 113 } 114 115 if (self.customer.type() === 'company') { 116 return [ 117 { value: 'mail', text: 'Postitse' }, 118 { value: 'email', text: 'Sähköpostitse' }, 119 { value: 'e_invoice', text: 'Verkkolasku' }, 120 ]; 121 } 122 123 return []; 124 }); 125 126 127 self.availableTermsOfPayment = ko.computed(function() { 128 var availableTermsOfPayment = [ 129 { value: 7, type: 'net', text: '7 pv netto' }, 130 { value: 10, type: 'net', text: '10 pv netto' }, 131 { value: 14, type: 'net', text: '14 pv netto' }, 132 { value: 21, type: 'net', text: '21 pv netto' }, 133 { value: 30, type: 'net', text: '30 pv netto' }, 134 { value: 45, type: 'net', text: '45 pv netto' }, 135 { value: 60, type: 'net', text: '60 pv netto' }, 136 { value: 90, type: 'net', text: '90 pv netto' }, 137 ]; 138 139 if (self.customer.type() === 'person') { 140 availableTermsOfPayment = $.grep(availableTermsOfPayment, function(elem) { 141 return ( 142 (elem.type === 'net' && elem.value >= 14 && elem.value !== 45) || elem.type !== 'net' 143 ); 144 }); 145 } 146 147 return availableTermsOfPayment; 148 }); 149 150 self.eInvoiceOperators = ko.observableArray([]); 151 152 self.init = function() { 153 154 if(self.inited()) 155 return; 156 157 // console.log('CustomerCardDialogVm::init'); 158 // self.initJQueryElements(); 159 self.applyKoBindings($('#customer-card-dialog')[0]); 160 self.inited(true); 161 }; 162 163 self.applyKoBindings = function(elem){ 164 ko.applyBindings(this, elem); 165 }; 166 167 self.fetchAndUpdateData = function(customerId) { 168 jQuery 169 .ajax({ 170 url: '/asiakasrekisteri/customer/'.concat(customerId), 171 dataType: 'json', 172 }) 173 .done(self.setData) 174 .fail(function(response) { 175 }); 176 }; 177 178 self.show = function(customerId) { 179 180 // If jQuery UI dialog has not been inited yet 181 if (self.dialog === null) { 182 self.dialog = $('#customer-card-dialog').dialog({ 183 width: 800, 184 height: 600, 185 autoOpen: false, 186 modal: true, 187 resizable: true, 188 draggable: true, 189 beforeclose: function(event) { 190 $('link#extrabs').remove(); 191 $('script#bsjs').remove(); 192 event.stopPropagation(); 193 }, 194 title: self.customerCardTitle(), 195 buttons: [ 196 { 197 text: 'Sulje', 198 class: 'close-btn btn btn-default', 199 click: function() { 200 self.close(); 201 }, 202 }, 203 { 204 text: 'Tallenna', 205 class: 'save-btn btn btn-default', 206 click: function() { 207 //self.dialog.find('#account_card_form').submit(); 208 self.saveCustomer(); 209 }, 210 }, 211 ], 212 }); 213 } 214 215 self.dialog.dialog('open'); 216 217 self.fetchAndUpdateData(customerId); 218 }; 219 220 self.close = function() { 221 self.dialog.dialog('close'); 222 }; 223 224 self.setData = function(data) { 225 226 if (data.eInvoiceOperators) { 227 // console.log('CustomerCardDialog::setData, eInvoiceOperators: ', data.eInvoiceOperators); 228 ko.mapping.fromJS(data.eInvoiceOperators, {}, self.eInvoiceOperators); 229 } 230 self.setCustomerData(data.customer); 231 }; 232 233 self.setCustomerData = function(customerData){ 234 235 // console.log('CustomerCardDialog::setCustomerData, customer: ', customerData); 236 237 ko.mapping.fromJS(customerData, {}, self.customer); 238 239 //console.log(ko.toJSON(self.customer)); 240 }; 241 242 self.deleteCustomer = function (){ 243 244 // console.log('CustomerCardDialog::deleteCustomer'); 245 246 self.saving(true); 247 global.showLoadingDialog('Poistetaan asiakasta...'); 248 249 jQuery 250 .ajax({ 251 type: 'post', 252 dataType: 'json', 253 url: '/asiakasrekisteri/trashCustomer', 254 data: { id: self.customer.id() }, 255 }) 256 .done(function(responseJSON) { 257 self.saved(true); 258 global.show_message(responseJSON); 259 global.close_loading_dialog(); 260 self.setData(responseJSON.data); 261 }) 262 .fail(function(data) { 263 global.show_message($.parseJSON(data.responseText)); 264 global.close_loading_dialog(); 265 console.error('.ajax.fail:', data); 266 }) 267 .then(function() {
268 // Set the saved observable back to false, so we can, 269 // listen for new saved events outside this obj 270 self.saving(false); 271 self.saved(false); 272 }); 273 } 274 275 self.saveCustomer = function() { 276 277 var data = { 278 customer: ko.mapping.toJSON(self.customer), 279 }; 280 281 self.saving(true); 282 global.showLoadingDialog('Tallennetaan...'); 283 284 jQuery 285 .ajax({ 286 type: 'post', 287 dataType: 'json', 288 url: '/asiakasrekisteri/save', 289 data: data, 290 }) 291 .done(function(responseJSON) { 292 self.saved(true); 293 global.show_message(responseJSON); 294 global.close_loading_dialog(); 295 self.setData(responseJSON.data); 296 }) 297 .fail(function(data) { 298 global.show_message($.parseJSON(data.responseText)); 299 global.close_loading_dialog(); 300 // console.error('.ajax.fail:', data); 301 }) 302 .then(function() {
303 // Set the saved observable back to false, so we can, 304 // listen for new saved events outside this obj 305 self.saving(false); 306 self.saved(false); 307 }); 308 309 return false; 310 }; 311 312} 313 314;/** 315 * humane.js 316 * Humanized Messages for Notifications 317 * @author Marc Harter (@wavded) 318 * @example 319 * humane.log('hello world'); 320 * See more usage examples at: http://wavded.github.com/humane-js/ 321 */ 322 323;!function (name, context, definition) { 324 if (typeof module !== 'undefined') module.exports = definition(name, context) 325 else if (typeof define === 'function' && typeof define.amd === 'object') define(definition) 326 else context[name] = definition(name, context) 327}('humane', this, function (name, context) { 328 var win = window 329 var doc = document 330 331 var ENV = { 332 on: function (el, type, cb) { 333 'addEventListener' in win ? el.addEventListener(type,cb,false) : el.attachEvent('on'+type,cb) 334 }, 335 off: function (el, type, cb) { 336 'removeEventListener' in win ? el.removeEventListener(type,cb,false) : el.detachEvent('on'+type,cb) 337 }, 338 bind: function (fn, ctx) { 339 return function () { fn.apply(ctx,arguments) } 340 }, 341 isArray: Array.isArray || function (obj) { return Object.prototype.toString.call(obj) === '[object Array]' }, 342 config: function (preferred, fallback) { 343 return preferred != null ? preferred : fallback 344 }, 345 transSupport: false, 346 useFilter: /msie [678]/i.test(navigator.userAgent), // sniff, sniff 347 _checkTransition: function () { 348 var el = doc.createElement('div') 349 var vendors = { webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' } 350 351 for (var vendor in vendors) 352 if (vendor + 'Transition' in el.style) { 353 this.vendorPrefix = vendors[vendor] 354 this.transSupport = true 355 } 356 } 357 } 358 ENV._checkTransition() 359 360 var Humane = function (o) { 361 o || (o = {}) 362 this.queue = [] 363 this.baseCls = o.baseCls || 'humane' 364 this.addnCls = o.addnCls || '' 365 this.timeout = 'timeout' in o ? o.timeout : 2500 366 this.waitForMove = o.waitForMove || false 367 this.clickToClose = o.clickToClose || false 368 this.timeoutAfterMove = o.timeoutAfterMove || false 369 this.container = o.container 370 371 try { this._setupEl() } // attempt to setup elements 372 catch (e) { 373 ENV.on(win,'load',ENV.bind(this._setupEl, this)) // dom wasn't ready, wait till ready 374 } 375 } 376 377 Humane.prototype = { 378 constructor: Humane, 379 _setupEl: function () { 380 var el = doc.createElement('div') 381 el.style.display = 'none' 382 if (!this.container){ 383 if(doc.body) this.container = doc.body; 384 else throw 'document.body is null' 385 } 386 this.container.appendChild(el) 387 this.el = el 388 this.removeEvent = ENV.bind(function(){ if (!this.timeoutAfterMove){this.remove()} else {setTimeout(ENV.bind(this.remove,this),this.timeout);}},this) 389 this.transEvent = ENV.bind(this._afterAnimation,this) 390 this._run() 391 }, 392 _afterTimeout: function () { 393 if (!ENV.config(this.currentMsg.waitForMove,this.waitForMove)) this.remove() 394 395 else if (!this.removeEventsSet) { 396 ENV.on(doc.body,'mousemove',this.removeEvent) 397 ENV.on(doc.body,'click',this.removeEvent) 398 ENV.on(doc.body,'keypress',this.removeEvent) 399 ENV.on(doc.body,'touchstart',this.removeEvent) 400 this.removeEventsSet = true 401 } 402 }, 403 _run: function () { 404 if (this._animating || !this.queue.length || !this.el) return 405 406 this._animating = true 407 if (this.currentTimer) { 408 clearTimeout(this.currentTimer) 409 this.currentTimer = null 410 } 411 412 var msg = this.queue.shift() 413 var clickToClose = ENV.config(msg.clickToClose,this.clickToClose) 414 415 if (clickToClose) { 416 ENV.on(this.el,'click',this.removeEvent) 417 ENV.on(this.el,'touchstart',this.removeEvent) 418 } 419 420 var timeout = ENV.config(msg.timeout,this.timeout) 421 422 if (timeout > 0) 423 this.currentTimer = setTimeout(ENV.bind(this._afterTimeout,this), timeout) 424 425 if (ENV.isArray(msg.html)) msg.html = '<ul><li>'+msg.html.join('<li>')+'</ul>' 426 427 this.el.innerHTML = msg.html 428 this.currentMsg = msg 429 this.el.className = this.baseCls 430 if (ENV.transSupport) { 431 this.el.style.display = 'block' 432 setTimeout(ENV.bind(this._showMsg,this),50) 433 } else { 434 this._showMsg() 435 } 436 437 }, 438 _setOpacity: function (opacity) { 439 if (ENV.useFilter){ 440 try{ 441 this.el.filters.item('DXImageTransform.Microsoft.Alpha').Opacity = opacity*100 442 } catch(err){} 443 } else { 444 this.el.style.opacity = String(opacity) 445 } 446 }, 447 _showMsg: function () { 448 var addnCls = ENV.config(this.currentMsg.addnCls,this.addnCls) 449 if (ENV.transSupport) { 450 this.el.className = this.baseCls+' '+addnCls+' '+this.baseCls+'-animate' 451 } 452 else { 453 var opacity = 0 454 this.el.className = this.baseCls+' '+addnCls+' '+this.baseCls+'-js-animate' 455 this._setOpacity(0) // reset value so hover states work 456 this.el.style.display = 'block' 457 458 var self = this 459 var interval = setInterval(function(){ 460 if (opacity < 1) { 461 opacity += 0.1 462 if (opacity > 1) opacity = 1 463 self._setOpacity(opacity) 464 } 465 else clearInterval(interval) 466 }, 30) 467 } 468 }, 469 _hideMsg: function () { 470 var addnCls = ENV.config(this.currentMsg.addnCls,this.addnCls) 471 if (ENV.transSupport) { 472 this.el.className = this.baseCls+' '+addnCls 473 ENV.on(this.el,ENV.vendorPrefix ? ENV.vendorPrefix+'TransitionEnd' : 'transitionend',this.transEvent) 474 } 475 else { 476 var opacity = 1 477 var self = this 478 var interval = setInterval(function(){ 479 if(opacity > 0) { 480 opacity -= 0.1 481 if (opacity < 0) opacity = 0 482 self._setOpacity(opacity); 483 } 484 else { 485 self.el.className = self.baseCls+' '+addnCls 486 clearInterval(interval) 487 self._afterAnimation() 488 } 489 }, 30) 490 } 491 }, 492 _afterAnimation: function () { 493 if (ENV.transSupport) ENV.off(this.el,ENV.vendorPrefix ? ENV.vendorPrefix+'TransitionEnd' : 'transitionend',this.transEvent) 494 495 if (this.currentMsg.cb) this.currentMsg.cb() 496 this.el.style.display = 'none' 497 498 this._animating = false 499 this._run() 500 }, 501 remove: function (e) { 502 var cb = typeof e == 'function' ? e : null 503 504 ENV.off(doc.body,'mousemove',this.removeEvent) 505 ENV.off(doc.body,'click',this.removeEvent) 506 ENV.off(doc.body,'keypress',this.removeEvent) 507 ENV.off(doc.body,'touchstart',this.removeEvent) 508 ENV.off(this.el,'click',this.removeEvent) 509 ENV.off(this.el,'touchstart',this.removeEvent) 510 this.removeEventsSet = false 511 512 if (cb && this.currentMsg) this.currentMsg.cb = cb 513 if (this._animating) this._hideMsg() 514 else if (cb) cb() 515 }, 516 log: function (html, o, cb, defaults) { 517 var msg = {} 518 if (defaults) 519 for (var opt in defaults) 520 msg[opt] = defaults[opt] 521 522 if (typeof o == 'function') cb = o 523 else if (o) 524 for (var opt in o) msg[opt] = o[opt] 525 526 msg.html = html 527 if (cb) msg.cb = cb 528 this.queue.push(msg) 529 this._run() 530 return this 531 }, 532 spawn: function (defaults) { 533 var self = this 534 return function (html, o, cb) { 535 self.log.call(self,html,o,cb,defaults) 536 return self 537 } 538 }, 539 create: function (o) { return new Humane(o) } 540 } 541 return new Humane() 542}) 543 544;
544/** 545 * @ai:claude Procountor accounting settings - the tab in omat_tiedot and the same editor embedded 546 * in the admin account card. 547 * 548 * Deliberately NOT a webpack module: omat_tiedot has no webpack entry and is not gaining one, so 549 * this is plain ES5 in the same style as the ~40 other view models in this directory, loaded through 550 * the `site_js` minify group. 551 * 552 * It is never bound on its own. ko.applyBindings(VM, $('#omat_tiedot_tabs')[0]) already binds the 553 * whole tab container, and a second applyBindings inside an already-bound element throws, so this 554 * hangs off its host view model instead - UserSettingsVm.accounting on the settings page, 555 * AccountCardDialogVm.accounting on the account card - and the markup reaches it with a `with:` 556 * binding. For the same reason nothing in here calls applyBindings. 557 * 558 * Every row object carries its own save/remove functions, closed over the view model, so the markup 559 * never has to reach out of a nested foreach with $root or $parent. That is what lets the identical 560 * body partial render under two different roots. 561 * 562 * Server state is the only state: each write posts one row and the endpoint replies with the whole 563 * page payload, which is fed straight back into setData(). Nothing here predicts what the server 564 * did with a save. 565 */ 566 567var AccountingSettingsVm = function(opts) { 568 'use strict'; 569 var self = this; 570 571 // Nothing renders until setData() has run - a company without Procountor never gets a payload 572 self.available = ko.observable(false); 573 self.canEdit = ko.observable(false); 574 self.busy = ko.observable(false); 575 576 self.companyId = ko.observable(null); 577 self.companyName = ko.observable(''); 578 579 // Read-only: until the company is flipped, everything configured here is stored but not used 580 self.useConfigResolver = ko.observable(false); 581 582 self.accountDefaults = ko.observableArray([]); 583 584 /** [{key, label}] - the card's block headings, in render order */ 585 self.accountDefaultGroupLabels = ko.observableArray([]); 586 587 /** 588 * @ai:claude The Täsmäytys ja rajoitukset card - four preferences_procountor flags, not account 589 * configuration, which is why they are their own block and their own endpoint. 590 */ 591 self.preferences = { 592 automaticReconciliation: ko.observable(false), 593 maxReconciliationAmount: ko.observable(''), 594 bankStatement: ko.observable(false), 595 blockEuSales: ko.observable(false), 596 }; 597 598 self.types = ko.observableArray([]); 599 // @ai:claude Static display rows, not configuration. Every vähennys posts NO_VAT to the 600 // Vähennystili with its debit taken from the carrying transaction, so there is nothing per-kind to 601 // edit and nothing per-company to load - these come straight from the catalogue. 602 self.deductionKinds = ko.observableArray([]); 603 self.itemGlAccounts = ko.observableArray([]); 604 self.customerGlAccounts = ko.observableArray([]); 605 self.dimensionLinks = ko.observableArray([]); 606 self.stations = ko.observableArray([]); 607 // @ai:claude The dimensions card asks for the entity type first, and only 'station' resolves in 608 // the factory today. The list is here rather than in the view so adding the customer type later 609 // is one entry, not a markup change. 610 self.entityTypeOptions = ko.observableArray([{ value: 'station', name: 'Toimipiste' }]); 611 612 self.dimensionOptions = ko.observableArray([]); 613 614 // Which type panels the user has open. Kept outside the row objects so a save, which replaces 615 // every row with a fresh one from the server, does not collapse the panel being edited. 616 self.openTypes = {}; 617 618 // '/omat_tiedot' on the settings page, '/asiakkuudet' on the account card. The account card also 619 // appends the company id, because there the company being configured is not the session company. 620 self.baseUrl = '/omat_tiedot'; 621 self.adminMode = ko.observable(false); 622 623 self.lookups = { 624 dimensions: new AccountingSettingsVm.Lookup(self, 'dimensions', 'Dimensiot'), 625 }; 626 627 self.lookupList = ko.observableArray([ 628 self.lookups.dimensions, 629 ]); 630 631 self.dimensionsAreFreeText = ko.computed(function() { 632 return self.lookups.dimensions.fallback(); 633 }); 634 635 self.editableRows = ko.computed(function() { 636 return self.canEdit() && !self.busy(); 637 }); 638 639 /** 640 * @ai:claude Replaces the whole page from a server payload. Every endpoint returns one, so this 641 * runs after each write as well as at page load - the browser never patches its own copy of the 642 * configuration, because a partial save that the server rejected would otherwise look applied. 643 */ 644 self.setData = function(data) { 645 if (!data) { 646 self.available(false); 647 return; 648 } 649 650 self.available(true); 651 self.canEdit(!!data.canEdit); 652 self.companyId(data.companyId || null);
653 self.companyName(data.companyName || ''); 654 self.useConfigResolver(!!data.useConfigResolver); 655 656 self.setLookupData(data.lookups || {}); 657 658 self.setPreferences(data.preferences || {}); 659 // @ai:claude Not sorted here. AccountDefaults::KEYS is already in group order, and the previous 660 // comparator was not a valid one - it returned -1 for payments_in_transit regardless of which 661 // side of the comparison it was on, so the order it produced depended on the sort algorithm. 662 self.accountDefaultGroupLabels(data.accountDefaultGroups || []); 663 self.accountDefaults( 664 (data.accountDefaults || []).map(function(row) { 665 return new AccountingSettingsVm.AccountDefault(self, row); 666 }) 667 ); 668 669 self.types(self.buildTypes(data.types || [], 'types')); 670 671 self.deductionKinds(data.deductionKinds || []); 672 673 self.itemGlAccounts(data.itemGlAccounts || []); 674 self.customerGlAccounts(data.customerGlAccounts || []); 675 // Same reason as the option lists below: an explicit empty entry, never an optionsCaption 676 self.stations([{ id: '', name: 'Valitse toimipiste' }].concat(data.stations || [])); 677 self.dimensionLinks(self.buildDimensionLinks(data.dimensionLinks || [])); 678 679 self.rebuildOptions(); 680 }; 681 682 /** Kept separate from setData() only because every write re-reads the whole payload back */ 683 self.setPreferences = function(preferences) { 684 self.preferences.automaticReconciliation(!!preferences.automaticReconciliation); 685 self.preferences.maxReconciliationAmount( 686 typeof preferences.maxReconciliationAmount === 'undefined' ? '' : preferences.maxReconciliationAmount 687 ); 688 self.preferences.bankStatement(!!preferences.bankStatement); 689 self.preferences.blockEuSales(!!preferences.blockEuSales); 690 }; 691 692 self.setLookupData = function(lookups) { 693 self.lookups.dimensions.setData(lookups.dimensions); 694 }; 695 696 self.buildTypes = function(types, section) { 697 return types.map(function(type) { 698 return new AccountingSettingsVm.Type(self, type, section); 699 }); 700 }; 701 702 self.buildDimensionLinks = function(links) { 703 return links.map(function(link) { 704 return new AccountingSettingsVm.DimensionLink(self, link); 705 }); 706 }; 707 708 /** 709 * @ai:claude Account-default inputs are plain text fields now, not dropdowns - accounts, 710 * vat_statuses and vat_rates lookups are gone with procountor_lookup_cache. The only option list 711 * left is dimensions, for the dimension-link picker. 712 */ 713 self.rebuildOptions = function() { 714 self.dimensionOptions( 715 [{ id: '', name: 'Valitse dimensio', items: [] }].concat(self.lookups.dimensions.items()) 716 ); 717 }; 718 719 self.url = function(path) { 720 var url = self.baseUrl + '/' + path; 721 722 if (self.adminMode() && self.companyId()) { 723 url += '/' + self.companyId(); 724 } 725 726 return url; 727 }; 728 729 /** 730 * @ai:claude One POST, one refresh. Serialised through `busy` so two saves cannot race and leave 731 * the page showing the losing one's payload. 732 */ 733 self.post = function(path, data, successText) { 734 if (self.busy()) { 735 self.notify('Edellinen tallennus on vielä kesken', 'warning'); 736 return; 737 } 738 739 self.busy(true); 740 741 return $.ajax({ url: self.url(path), type: 'POST', data: data }) 742 .done(function(response) { 743 if (response && response.data) { 744 self.setData(response.data); 745 } 746 747 self.notify(successText || (response && response.text) || 'Tallennettu', 'success'); 748 }) 749 .fail(function(xhr) { 750 self.notify(self.errorText(xhr), 'danger'); 751 }) 752 .always(function() { 753 self.busy(false); 754 }); 755 }; 756 757 self.errorText = function(xhr) { 758 try { 759 var parsed = JSON.parse(xhr.responseText); 760 return parsed.text || 'Toimintoa ei voitu suorittaa'; 761 } catch (e) { 762 return 'Toimintoa ei voitu suorittaa'; 763 } 764 }; 765 766 // bootstrap alert class -> humane.js theme class (jackedup.css only styles these three) 767 var HUMANE_CLASS_BY_TYPE = { 768 success: 'humane-jackedup-success', 769 info: 'humane-jackedup-info', 770 danger: 'humane-jackedup-error', 771 warning: 'humane-jackedup-error', 772 }; 773 774 /** 775 * @ai:claude Replaces the old top-of-page alert box, which on the omat_tiedot tab's long page made 776 * a failed save three cards down easy to miss. humane.js is bundled into site_js specifically for 777 * this (see groupsConfig.php) so it is always present wherever this view model runs; the existence 778 * check is just the usual defensive habit around a global, not a real "might be missing" case. 779 */ 780 self.notify = function(text, type) { 781 if (text && typeof humane !== 'undefined') { 782 humane.log(text, { 783 addnCls: HUMANE_CLASS_BY_TYPE[type] || 'humane-jackedup-info', 784 timeout: type === 'danger' || type === 'warning' ? 6000 : 3000, 785 clickToClose: true, 786 }); 787 } 788 }; 789 790 791 /**
792 * @ai:claude The whole "Oletus tilit" card in one post. There is nothing to propagate any more - 793 * the transaction config table below is generated live from these accounts on every read - so the 794 * reply is just the refreshed page, which already shows what the new accounts generate. 795 * 796 * Every field is submitted rather than only the dirty ones, so the server validates the card as 797 * the user left it. It skips the unchanged ones itself; see AccountingSettingsWriter. 798 */ 799 self.saveAccountDefaults = function() { 800 if (self.missingAccountDefaults().length) { 801 self.notify(self.missingAccountDefaultsText(), 'danger'); 802 return; 803 } 804 805 var accounts = {}; 806 807 self.accountDefaults().forEach(function(row) { 808 accounts[row.key] = row.account(); 809 }); 810 811 self.post('saveAccountingDefaults', { accounts: accounts }, null); 812 }; 813 814 /** 815 * @ai:claude The Oletus tilit card as blocks: [{key, label, rows}], empty blocks dropped. 816 * 817 * Presentation only - dirtyAccountDefaults, missingAccountDefaults and saveAccountDefaults all 818 * keep walking the flat accountDefaults array, so the save still posts every key regardless of 819 * how the card is carved up. A block can come out empty when every default in it is a VAT variant 820 * the company's Procountor cannot post, which the server has already filtered out. 821 */ 822 self.accountDefaultGroups = ko.computed(function() { 823 var rowsByGroup = {}; 824 825 self.accountDefaults().forEach(function(row) { 826 (rowsByGroup[row.group] = rowsByGroup[row.group] || []).push(row); 827 }); 828 829 return self.accountDefaultGroupLabels() 830 .filter(function(group) { 831 return (rowsByGroup[group.key] || []).length > 0; 832 }) 833 .map(function(group) { 834 return { key: group.key, label: group.label, rows: rowsByGroup[group.key] }; 835 }); 836 }); 837 838 self.dirtyAccountDefaults = ko.computed(function() { 839 return self.accountDefaults().filter(function(row) { 840 return row.isDirty(); 841 }); 842 }); 843 844 // @ai:claude Required fields left blank. A blank here is not "unset" downstream - it generates a 845 // NULL account, which TransactionAdapter turns into the literal '1700' without reporting anything. 846 // The server rejects the save either way; the card names them first so it is not a round trip. 847 self.missingAccountDefaults = ko.computed(function() { 848 return self.accountDefaults().filter(function(row) { 849 return row.isMissing(); 850 }); 851 }); 852 853 self.missingAccountDefaultsText = ko.computed(function() { 854 var labels = self.missingAccountDefaults().map(function(row) { 855 return row.label; 856 }); 857 858 if (!labels.length) { 859 return ''; 860 } 861 862 return 'Nämä tilit ovat pakollisia eikä niitä voi jättää tyhjäksi: ' + labels.join(', '); 863 }); 864 865 self.canSaveAccountDefaults = ko.computed(function() { 866 return self.editableRows() && self.dirtyAccountDefaults().length > 0; 867 }); 868 869 //@ai:claude canRegenerate/regenerateBlockedText/regenerateConfigs are gone with the "Luo 870 //transaktiokohtaiset asetukset" button - there is no materialized table to rebuild, the 871 //transaction config table always shows what the saved accounts currently generate. 872 873 /** 874 * @ai:claude All four are submitted every time, so an unticked checkbox is a value rather than an 875 * omission - the writer reads them that way. 876 */ 877 self.savePreferences = function() { 878 self.post( 879 'saveAccountingPreferences', 880 { 881 automatic_reconciliation: self.preferences.automaticReconciliation() ? 1 : 0, 882 max_reconciliation_amount: self.preferences.maxReconciliationAmount(), 883 bank_statement: self.preferences.bankStatement() ? 1 : 0, 884 block_eu_sales: self.preferences.blockEuSales() ? 1 : 0, 885 }, 886 null 887 ); 888 }; 889 890 self.saveDimensionLink = function(link) { 891 self.post('saveAccountingDimensionLink', link.toPayload(), 'Dimensio tallennettu'); 892 }; 893 894 self.deleteDimensionLink = function(link) { 895 if (!link.id()) { 896 self.dimensionLinks.remove(link); 897 return; 898 } 899 900 self.post('deleteAccountingDimensionLink', { id: link.id() }, 'Dimensio poistettu'); 901 }; 902 903 self.addDimensionLink = function() { 904 self.dimensionLinks.push(new AccountingSettingsVm.DimensionLink(self, {})); 905 }; 906 907 self.refreshLookup = function(lookupType) { 908 self.post('refreshAccountingLookup', { lookup_type: lookupType }, 'Lista haettu Procountorista'); 909 }; 910 911 // @ai:claude Two call shapes. omat_tiedot passes the server payload straight in, because there the 912 // company is always the session one and the endpoints live on this controller. The account card 913 // passes { baseUrl, adminMode, data } instead, because there the company being configured is not 914 // the session company and the endpoints have to carry its id. 915 if (opts) { 916 var payload = opts; 917 918 if (opts.baseUrl || opts.adminMode || Object.prototype.hasOwnProperty.call(opts, 'data')) { 919 if (opts.baseUrl) { 920 self.baseUrl = opts.baseUrl; 921 } 922 923 self.adminMode(!!opts.adminMode); 924 payload = opts.data; 925 } 926 927 self.setData(payload); 928 } 929}; 930 931/** 932 * @ai:claude One row of the "Oletus tilit" card. 933 * 934 * ## Why this no longer saves on its own `change` event (2026-09-15) 935 * 936 * It used to. Picking a value - including the "Ei asetettu" entry - posted immediately, which made 937 * blanking an account a single click with no confirmation and no undo. Blanking Myyntisaamiset on 938 * company 521 that way propagated NULL into 35 generated cells, and nothing downstream then 939 * complained: a NULL account reaches TransactionAdapter, which quietly substitutes '1700'. The card 940 * is saved as a whole now, behind "Tallenna muutokset", so there is something to not press. 941 * 942 * `savedAccount` is the server's copy and `account` the edited one; the difference is what makes the 943 * row dirty. Nothing is patched locally on save - the server replies with the whole page and 944 * setData() rebuilds these rows, which is what puts the two back in step. 945 */ 946AccountingSettingsVm.AccountDefault = function(vm, data) { 947 var self = this; 948 949 self.key = data.key; 950 self.label = data.label; 951 self.side = data.side || null; 952 self.group = data.group || null; 953 self.description = data.description || ''; 954 self.inheritsFromLabel = data.inheritsFromLabel || null; 955 // Blank is a complete answer for a field that inherits, and for the selvittelytili. For everything 956 // else it generates a NULL cell, so the card marks it and the save button refuses to submit it. 957 self.required = data.required !== false; 958 959 self.account = ko.observable(data.account === null ? '' : data.account || ''); 960 self.savedAccount = self.account(); 961 962 // What generation would actually write. For a blank inheriting field that is the parent's account, 963 // which is why the row can show "peritään 3021" next to an empty input rather than looking unset. 964 self.effectiveAccount = ko.observable(data.effectiveAccount || ''); 965 self.isInheriting = ko.observable(!!data.isInheriting); 966 967 self.editable = vm.editableRows; 968 969 self.isDirty = ko.computed(function() { 970 return self.account() !== self.savedAccount; 971 }); 972 973 self.isMissing = ko.computed(function() { 974 return self.required && self.account() === ''; 975 }); 976}; 977 978//@ai:claude AccountingSettingsVm.DeductionVariant is gone. It carried the editable ALV-käsittely 979//and the "do the eight rows agree?" reporting for one deduction variant; there are no deduction 980//config rows to disagree and no status to choose, so section 3 renders vm.deductionKinds - plain 981//objects from the catalogue - as static text. 982 983/** 984 * @ai:claude One pick-list - just dimensions today. Nothing is cached server-side any more: every 985 * page load starts as `fallback: true, items: []`, and only pressing "Päivitä" (refresh()) fills it 986 * in for this view, unsaved. 987 */ 988AccountingSettingsVm.Lookup = function(vm, type, label) { 989 var self = this; 990 991 self.type = type; 992 self.label = ko.observable(label); 993 self.items = ko.observableArray([]); 994 self.fetchedAt = ko.observable(null); 995 self.fetchable = ko.observable(false); 996 self.fallback = ko.observable(true); 997 self.warning = ko.observable(null); 998 999 /** 1000 * @ai:claude Nothing is cached server-side any more (see ProcountorLookups) - every write posts 1001 * one row and reads the whole page back, and every type but the one refreshAccountingLookup() just 1002 * fetched comes back in that reply as "never fetched". Without a client-side copy, saving a single
1003 * dimension link would wipe the fetched list back to free text on every save. Keyed by company so 1004 * two companies sharing a browser never see each other's cached list. 1005 * 1006 * sessionStorage rather than localStorage: dimension names/items may carry personal data, and this 1007 * bounds how long it sits in the browser to the current tab's lifetime instead of indefinitely. 1008 */ 1009 self.storageKey = function() { 1010 return 'iv.accountingLookup.' + vm.companyId() + '.' + type; 1011 }; 1012 1013 self.cacheItems = function(items, fetchedAt) { 1014 try { 1015 sessionStorage.setItem(self.storageKey(), JSON.stringify({ items: items, fetchedAt: fetchedAt })); 1016 } catch (e) { 1017 // Private browsing or storage disabled - the fetched list just won't survive a save 1018 } 1019 }; 1020 1021 self.loadCachedItems = function() { 1022 try { 1023 var raw = sessionStorage.getItem(self.storageKey()); 1024 return raw ? JSON.parse(raw) : null; 1025 } catch (e) { 1026 return null; 1027 } 1028 }; 1029 1030 self.setData = function(data) { 1031 if (!data) { 1032 return; 1033 } 1034 1035 self.label(data.label || label); 1036 self.fetchable(!!data.fetchable); 1037 1038 // A real fetch (the refresh button's own response) - cache it so the next unrelated save can 1039 // restore it. Anything else that comes back with items is already a restore, not a new fetch. 1040 if (!data.fallback && (data.items || []).length) { 1041 self.cacheItems(data.items, data.fetchedAt); 1042 self.items(data.items); 1043 self.fetchedAt(data.fetchedAt || null); 1044 self.fallback(false); 1045 self.warning(null); 1046 return; 1047 } 1048 1049 var cached = data.fallback ? self.loadCachedItems() : null; 1050 1051 if (cached) { 1052 self.items(cached.items || []); 1053 self.fetchedAt(cached.fetchedAt || null); 1054 self.fallback(false); 1055 self.warning(null); 1056 return; 1057 } 1058 1059 self.items(data.items || []); 1060 self.fetchedAt(data.fetchedAt || null); 1061 self.fallback(!!data.fallback); 1062 self.warning(data.warning || null); 1063 }; 1064 1065 // @ai:claude Three states, not two. A list with no endpoint behind it reads as "kiinteä lista" 1066 // rather than "ei haettu kertaakaan", because the latter invites the reader to go and fetch it - 1067 // and there is nothing to press. 1068 self.fetchedAtText = ko.computed(function() { 1069 if (self.fetchedAt()) { 1070 return 'Haettu ' + self.fetchedAt(); 1071 } 1072 1073 return self.fetchable() ? 'Ei haettu kertaakaan' : 'Kiinteä lista'; 1074 }); 1075 1076 self.canRefresh = ko.computed(function() { 1077 return self.fetchable() && vm.canEdit() && !vm.busy(); 1078 }); 1079 1080 self.refresh = function() { 1081 vm.refreshLookup(self.type); 1082 }; 1083}; 1084 1085/** One transaction type and its variants. Always fully generated - there is no disabled state. */ 1086AccountingSettingsVm.Type = function(vm, data, section) { 1087 var self = this; 1088 1089 self.type = data.type; 1090 self.openKey = section + ':' + data.type; 1091 self.label = data.label; 1092 self.ledgerType = data.ledgerType; 1093 self.deprecated = !!data.deprecated; 1094 self.carriesVatStatus = data.carriesVatStatus !== false; 1095 1096 self.variants = ko.observableArray( 1097 (data.variants || []).map(function(variant) { 1098 return new AccountingSettingsVm.ConfigRow(vm, self, variant); 1099 }) 1100 ); 1101 1102 self.defaultRow = ko.computed(function() { 1103 var rows = self.variants().filter(function(row) { 1104 return row.isDefault; 1105 }); 1106 1107 return rows.length ? rows[0] : null; 1108 }); 1109 1110 // Nothing is configured at all - the required default it needs is blank - worth calling out on 1111 // the collapsed header instead of only inside the panel 1112 self.isUnconfigured = ko.computed(function() { 1113 var row = self.defaultRow(); 1114 1115 return !row || !row.debitAccount() || !row.creditAccount(); 1116 }); 1117 1118 self.editable = vm.editableRows; 1119 1120 self.isOpen = ko.observable(!!vm.openTypes[self.openKey]); 1121 1122 self.toggle = function() { 1123 self.isOpen(!self.isOpen()); 1124 vm.openTypes[self.openKey] = self.isOpen(); 1125 }; 1126}; 1127 1128/** One (transaction type, variant) row: the two accounts and the VAT status posted with them */ 1129AccountingSettingsVm.ConfigRow = function(vm, type, data) { 1130 var self = this; 1131 1132 self.type = type; 1133 self.transactionType = data.transactionType; 1134 self.variant = data.variant; 1135 self.label = data.label; 1136 self.isDefault = data.variant === 'default'; 1137 // reconciliation_row posts through ReconciliationAdapter, which has no vatStatus at all 1138 self.carriesVatStatus = type.carriesVatStatus; 1139 1140 self.debitAccount = ko.observable(data.debitAccount === null ? '' : data.debitAccount || ''); 1141 self.creditAccount = ko.observable(data.creditAccount === null ? '' : data.creditAccount || ''); 1142 self.vatStatus = ko.observable( 1143 data.vatStatus === null || typeof data.vatStatus === 'undefined' ? '' : String(data.vatStatus) 1144 ); 1145 1146 /** 1147 * @ai:claude The three cells as text. The row is display only - it is generated from the Oletus 1148 * tilit card, and the way to change it is to change a default and save the card. There is no
1149 * chart-of-accounts lookup any more to turn a code into "code - name", so this is just the bare 1150 * value, or "Ei asetettu" when the row has none. 1151 */ 1152 self.debitAccountText = ko.computed(function() { 1153 return self.debitAccount() || 'Ei asetettu'; 1154 }); 1155 1156 self.creditAccountText = ko.computed(function() { 1157 return self.creditAccount() || 'Ei asetettu'; 1158 }); 1159 1160 self.vatStatusText = ko.computed(function() { 1161 return self.vatStatus() || 'Ei asetettu'; 1162 }); 1163}; 1164 1165/** 1166 * One entity-to-dimension-item mapping. `isDefault` additionally makes its item the one used when a 1167 * ledger row's entity cannot be resolved - a flag on the mapping, which keeps resolving its entity. 1168 */ 1169AccountingSettingsVm.DimensionLink = function(vm, data) { 1170 var self = this; 1171 1172 self.id = ko.observable(data.id || null); 1173 self.entityType = ko.observable(data.entityType || 'station'); 1174 self.entityId = ko.observable(data.entityId === null ? '' : data.entityId || ''); 1175 self.entityName = ko.observable(data.entityName || null); 1176 // @ai:claude Left as the numbers the payload carries rather than stringified. Knockout matches a 1177 // select's value against the option object's own value with ===, and the dimension and item ids 1178 // come back from json_encode as numbers - a string here would match nothing, select the empty 1179 // placeholder and write the id away. 1180 self.dimensionId = ko.observable(data.dimensionId ? data.dimensionId : ''); 1181 self.dimensionName = ko.observable(data.dimensionName || ''); 1182 self.itemId = ko.observable(data.itemId ? data.itemId : ''); 1183 self.itemCodeName = ko.observable(data.itemCodeName || ''); 1184 self.itemDescription = ko.observable(data.itemDescription || ''); 1185 self.isDefault = ko.observable(!!data.isDefault); 1186 1187 self.isNew = ko.computed(function() { 1188 return !self.id(); 1189 }); 1190 1191 // @ai:claude A saved row opens locked - every field disabled - so an accidental click in a filled 1192 // table does not nudge a working mapping. "Muokkaa" is the only way in; a successful save rebuilds 1193 // every row from scratch (setData()), which drops this back to locked on its own. 1194 self.editingSaved = ko.observable(false); 1195 1196 self.entityTypeOptions = vm.entityTypeOptions; 1197 self.dimensionOptions = vm.dimensionOptions; 1198 self.dimensionsAreFreeText = vm.dimensionsAreFreeText; 1199 1200 // The page-level permission, for buttons whose availability must not depend on this row's own 1201 // lock state - Poista and Muokkaa both need to work on a row that is currently locked 1202 self.canEditRows = vm.editableRows; 1203 1204 // Field-level: a new row is editable outright, a saved one only once Muokkaa has been pressed 1205 self.editable = ko.computed(function() { 1206 return vm.editableRows() && (self.isNew() || self.editingSaved()); 1207 }); 1208 1209 self.showEditButton = ko.computed(function() { 1210 return !self.isNew() && !self.editingSaved(); 1211 }); 1212 1213 self.edit = function() { 1214 self.editingSaved(true); 1215 }; 1216 1217 /** 1218 * @ai:claude The entities this row can point at, for its own entity type. Only stations exist as 1219 * a list today; an unknown type gets the empty entry alone rather than a station list that would 1220 * mean something else. 1221 * 1222 * A row whose entity is no longer in the list - a deleted station - has it appended, because 1223 * Knockout's value binding writes the first option back into the observable when the current one 1224 * matches nothing, which would silently repoint the mapping at another station on save. 1225 * 1226 * entityId is peeked, not read: this list is the option source for the very select that writes it, 1227 * so subscribing to it would rebuild the options on every pick. Peeking leaves the appended entry 1228 * in place after the user moves off it, which costs one stale option and no correctness. 1229 */ 1230 self.entityOptions = ko.computed(function() { 1231 if (self.entityType() !== 'station') { 1232 return [{ id: '', name: 'Valitse kohde' }]; 1233 } 1234 1235 var options = vm.stations(); 1236 var entityId = self.entityId.peek(); 1237 1238 var known = options.some(function(station) { 1239 return String(station.id) === String(entityId); 1240 }); 1241 1242 if (!entityId || known) { 1243 return options; 1244 } 1245 1246 return options.concat([ 1247 { id: entityId, name: (self.entityName() || 'Toimipiste #' + entityId) + ' (poistettu)' }, 1248 ]); 1249 }); 1250 1251 // Only an oletusarvo row is allowed to map nothing, so the card says so where the choice is made 1252 self.entityIsUnset = ko.computed(function() { 1253 return !self.entityId(); 1254 }); 1255 1256 /** The items of the currently selected dimension, empty when the list has never been fetched */ 1257 self.itemOptions = ko.computed(function() { 1258 var dimensionId = self.dimensionId(); 1259 1260 var matching = vm.dimensionOptions().filter(function(dimension) { 1261 return String(dimension.id) === String(dimensionId); 1262 }); 1263 1264 return [{ itemId: '', name: 'Valitse dimensioarvo' }].concat( 1265 matching.length ? matching[0].items : [] 1266 ); 1267 }); 1268 1269 // Only the placeholder entry: the dimension list has never been fetched, or the chosen dimension 1270 // carries no items, so the id and name are typed in by hand 1271 self.itemsAreFreeText = ko.computed(function() { 1272 return self.itemOptions().length <= 1; 1273 }); 1274 1275 /** 1276 * @ai:claude A saved link shows its plain id/name fields always, fetched list or not - the same 1277 * shape whether or not anyone has pressed "Päivitä" this page view, and with no risk of the select 1278 * silently overwriting a saved id that is not in whatever the list happens to hold right now (a 1279 * renamed or deleted dimension/item, or simply a page view where the list was never fetched). Only 1280 * a row still being created gets the picker, and only once the list actually has something to pick 1281 * from. 1282 */ 1283 self.showDimensionDropdown = ko.computed(function() { 1284 return self.isNew() && !self.dimensionsAreFreeText(); 1285 }); 1286 1287 self.showItemDropdown = ko.computed(function() { 1288 return self.isNew() && !self.itemsAreFreeText(); 1289 }); 1290 1291 // @ai:claude Keeps the denormalised names in step with the ids whenever the user picks from a 1292 // fetched list. They are stored on the row so a mapping still reads sensibly after the dimension 1293 // is renamed or the lookup goes unavailable, which means something has to maintain them. 1294 self.dimensionId.subscribe(function(dimensionId) { 1295 // The empty id is the placeholder option, which names nothing worth copying over 1296 if (!dimensionId) { 1297 return; 1298 } 1299 1300 var matching = vm.dimensionOptions().filter(function(dimension) { 1301 return String(dimension.id) === String(dimensionId); 1302 }); 1303 1304 if (matching.length) { 1305 self.dimensionName(matching[0].name); 1306 } 1307 }); 1308 1309 self.itemId.subscribe(function(itemId) { 1310 if (!itemId) { 1311 return; 1312 } 1313 1314 var matching = self.itemOptions().filter(function(item) { 1315 return String(item.itemId) === String(itemId); 1316 }); 1317 1318 if (matching.length) { 1319 self.itemCodeName(matching[0].name); 1320 self.itemDescription(matching[0].description || ''); 1321 } 1322 }); 1323 1324 self.toPayload = function() { 1325 return { 1326 id: self.id() || '', 1327 entity_type: self.entityType(), 1328 entity_id: self.entityId(), 1329 dimension_id: self.dimensionId(), 1330 dimension_name: self.dimensionName(), 1331 item_id: self.itemId(), 1332 item_code_name: self.itemCodeName(), 1333 item_description: self.itemDescription(), 1334 is_default: self.isDefault() ? 1 : 0, 1335 }; 1336 }; 1337 1338 self.save = function() { 1339 vm.saveDimensionLink(self); 1340 }; 1341 1342 self.remove = function() { 1343 vm.deleteDimensionLink(self); 1344 }; 1345}; 1346 1347;var UserSettingsVm = function (opts) { 1348 'use strict'; 1349 var self = this; 1350 self.isPartner = opts.isPartner; 1351 self.userGroups = ko.observableArray(opts.userGroups); 1352 self.users = ko.observableArray(opts.users); 1353 1354 self.workers = ko.observableArray(opts.workers); 1355 self.supervisors = ko.observableArray(opts.supervisors); 1356 self.editUserId = ko.observable(null); 1357 self.userCompanies = ko.observableArray([]); 1358 self.relatedCompanies = ko.observableArray([]); 1359 self.relatedCompaniesFilter = ko.observable(''); 1360 self.selectedCompaniesFilter = ko.observable(''); 1361 self.currentUserId = opts.currentUserId; 1362 1363 // @ai:claude The Procountor accounting settings tab. It hangs off this view model rather than 1364 // being bound on its own because ko.applyBindings(VM, $('#omat_tiedot_tabs')[0]) already binds the 1365 // whole tab container, and a second applyBindings inside an already-bound element throws. 1366 // opts.accounting is null whenever the tab is not shown, which AccountingSettingsVm handles. 1367 self.accounting = new AccountingSettingsVm(opts.accounting); 1368 1369 self.inactiveShowActiveText = 'Näytä vain aktiiviset käyttäjät'; 1370 self.inactiveShowAllText = 'Näytä kaikki käyttäjät' 1371 self.hideInactiveUsers = ko.observable(false); 1372 self.hideInactiveUsersText = ko.observable(self.inactiveShowActiveText); 1373 self.hideInactiveSupervisors = ko.observable(false); 1374 self.hideInactiveSupervisorsText = ko.observable(self.inactiveShowActiveText); 1375 self.hideInactiveWorkers = ko.observable(false); 1376 self.hideInactiveWorkersText = ko.observable(self.inactiveShowActiveText); 1377 1378 self.toggleInactiveUsers = function () { 1379 if (self.hideInactiveUsers()) { 1380 self.hideInactiveUsers(false); 1381 self.hideInactiveUsersText(self.inactiveShowActiveText); 1382 } else { 1383 self.hideInactiveUsers(true); 1384 self.hideInactiveUsersText(self.inactiveShowAllText); 1385 } 1386 }; 1387 1388 self.toggleInactiveSupervisors = function () { 1389 if (self.hideInactiveSupervisors()) { 1390 self.hideInactiveSupervisors(false); 1391 self.hideInactiveSupervisorsText(self.inactiveShowActiveText); 1392 } else { 1393 self.hideInactiveSupervisors(true); 1394 self.hideInactiveSupervisorsText(self.inactiveShowAllText); 1395 } 1396 }; 1397 1398 self.toggleInactiveWorkers = function () { 1399 if (self.hideInactiveWorkers()) { 1400 self.hideInactiveWorkers(false); 1401 self.hideInactiveWorkersText(self.inactiveShowActiveText); 1402 } else { 1403 self.hideInactiveWorkers(true); 1404 self.hideInactiveWorkersText(self.inactiveShowAllText); 1405 } 1406 }; 1407 1408 self.userGroupEditable = function (groupId) { 1409 if (!groupId) return true; 1410 return ( 1411 self.userGroups().filter(function (v) { 1412 return v.id === parseInt(groupId); 1413 }).length > 0 1414 ); 1415 }; 1416 1417 self.canEditDisable = function (user) { 1418 return user.user_id === self.currentUserId; 1419 }; 1420 1421 self.hideUser = function (el, user, type) { 1422 1423 var userId = type === 'user' && user.user_id ? user.user_id : user.id; 1424 1425 var isChecked = $(el).prop("checked"); 1426 var salesName = user.sales_name; 1427 var url = '/omat_tiedot/hideUser'; 1428 var isLoading = false;
1429 1430 $('#disableText').html( 1431 `Vahvista käyttäjän <strong>${salesName}</strong> ${isChecked ? 'sulku' : 'aktivointi'}` 1432 ); 1433 1434 $('#disableUserDialog').dialog({ 1435 resizable: false, 1436 height: 'auto', 1437 closeOnEscape: false, 1438 width: 400, 1439 modal: true, 1440 open: function () { 1441 $('.ui-icon-closethick').parent('a').hide(); 1442 }, 1443 close: function(){ 1444 console.log('Close function ran'); 1445 $(this).dialog("close"); 1446 isChecked = $(el).prop("checked"); 1447 $(el).prop('checked', ! isChecked); 1448 }, 1449 buttons: { 1450 Vahvista: function () { 1451 1452 if(isLoading){ 1453 return false; 1454 } 1455 1456 jQuery 1457 .ajax({ 1458 type: 'post', 1459 url: url, 1460 data: { userId: userId, hidden: (+ isChecked) }, 1461 beforeSend(jqXHR, settings) { 1462 isLoading = true; 1463 } 1464 }) 1465 .then(function (response) { 1466 1467 var msg = response.text || 'Käyttäjä muokattu'; 1468 var action = msg.action || 'muokattu'; 1469 var isHidden = msg.hidden; 1470 1471 $('#disableText').text(msg.sales_name + ' ' + action); 1472 1473 var updatedUser = Object.assign({}, user, { hidden: isHidden }); 1474 1475 console.log('action:', action); 1476 console.log('isHidden:', isHidden); 1477 // console.log('user:', user); 1478 // console.log('updateUser:', updatedUser); 1479 1480 $('#disableUserDialog').dialog("option", "buttons", { 1481 "Sulje": function(){ 1482 $('#disableUserDialog').dialog('destroy'); 1483 } 1484 }); 1485 1486 self.replaceUserData(type, user, updatedUser); 1487 1488 }) 1489 .fail(function (response) { 1490 1491 var msg = response.text || 'Toimintoa ei voitu suorittaa'; 1492 $('#disableText').text(msg); 1493 }); 1494 }, 1495 Peruuta: function () { 1496 1497 if(isLoading) 1498 return false; 1499 1500 $(this).dialog("close"); 1501 }, 1502 }, 1503 }); 1504 }; 1505 1506 1507 self.disableUser = function (el, user, type) { 1508 1509 var userId = type === 'user' && user.user_id ? user.user_id : user.id; 1510 1511 var isChecked = $(el).prop("checked"); 1512 var salesName = user.sales_name; 1513 var disabled = isChecked; 1514 var isLoading = false; 1515 1516 var url = '/omat_tiedot/disableUser'; 1517 1518 $('#disableText').html( 1519 `Vahvista käyttäjän <strong>${salesName}</strong> ${isChecked ? 'sulku' : 'aktivointi'}` 1520 ); 1521 1522 $('#disableUserDialog').dialog({ 1523 resizable: false, 1524 height: 'auto', 1525 closeOnEscape: false, 1526 width: 400, 1527 modal: true, 1528 open: function () { 1529 $('.ui-icon-closethick').parent('a').hide(); 1530 }, 1531 close: function(){ 1532 console.log('Close function ran'); 1533 $(this).dialog("close"); 1534 isChecked = $(el).prop("checked"); 1535 $(el).prop('checked', ! isChecked); 1536 }, 1537 buttons: { 1538 Vahvista: function () { 1539 1540 if(isLoading){ 1541 return false; 1542 } 1543 1544 jQuery 1545 .ajax({ 1546 type: 'post', 1547 url: url, 1548 data: { userId: userId, disabled: (+ disabled)}, 1549 1550 }) 1551 .then(function (response) { 1552 1553 var msg = response.text || 'Käyttäjä muokattu'; 1554 var action = msg.action || 'muokattu'; 1555 var isDisabled = msg.disabled; 1556 $('#disableText').text(msg.sales_name + ' ' + action); 1557 1558 var updateUser = Object.assign({}, user, { disabled: isDisabled }); 1559 1560 $('#disableUserDialog').dialog("option", "buttons", { 1561 "Sulje": function(){ 1562 $('#disableUserDialog').dialog('destroy'); 1563 } 1564 }); 1565 1566 self.replaceUserData(type, user, updateUser); 1567 1568 }) 1569 .fail(function (response) { 1570 var msg = response.text || 'Toimintoa ei voitu suorittaa'; 1571 $('#disableText').text(msg); 1572 }); 1573 }, 1574 Peruuta: function () { 1575 1576 if(isLoading) 1577 return false;
1578 1579 $(this).dialog("close"); 1580 }, 1581 }, 1582 }); 1583 }; 1584 1585 self.newWorker = { 1586 name: ko.observable(''), 1587 extId: ko.observable(''), 1588 }; 1589 1590 self.resetNewWorker = function () { 1591 self.newWorker.name(''); 1592 self.newWorker.extId(''); 1593 }; 1594 1595 self.newSupervisor = { 1596 userName: ko.observable(''), 1597 email: ko.observable(''), 1598 name: ko.observable(''), 1599 extId: ko.observable(''), 1600 }; 1601 1602 self.resetNewSupervisor = function () { 1603 self.newSupervisor.userName(''); 1604 self.newSupervisor.email(''); 1605 self.newSupervisor.name(''); 1606 self.newSupervisor.extId(''); 1607 }; 1608 1609 self.newUser = { 1610 username: ko.observable(''), 1611 email: ko.observable(''), 1612 usergroup_id: ko.observable(''), 1613 sales_name: ko.observable(''), 1614 }; 1615 1616 self.resetNewUser = function () { 1617 self.newUser.username(''); 1618 self.newUser.email(''); 1619 self.newUser.usergroup_id(''); 1620 self.newUser.sales_name(''); 1621 }; 1622 1623 self.showAddUserModal = function () { 1624 $('#addUserModal').modal('show'); 1625 }; 1626 1627 self.showAddWorkerModal = function () { 1628 global.showLoadingDialog('Haetaan toimipaikkoja...'); 1629 jQuery 1630 .ajax({ 1631 url: '/omat_tiedot/getRelatedCompanies/', 1632 dataType: 'json', 1633 }) 1634 .done(function (response) { 1635 global.close_loading_dialog(); 1636 self.setCompanySelectModalData(response.data); 1637 $('#addWorkerModal').modal('show'); 1638 }) 1639 .fail(function (response) { 1640 global.close_loading_dialog(); 1641 global.show_message(response.responseJSON); 1642 }); 1643 }; 1644 1645 self.showAddSupervisorModal = function () { 1646 global.showLoadingDialog('Haetaan toimipaikkoja...'); 1647 jQuery 1648 .ajax({ 1649 url: '/omat_tiedot/getRelatedCompanies/', 1650 dataType: 'json', 1651 }) 1652 .done(function (response) { 1653 global.close_loading_dialog(); 1654 self.setCompanySelectModalData(response.data); 1655 $('#addSupervisorModal').modal('show'); 1656 }) 1657 .fail(function (response) { 1658 global.close_loading_dialog(); 1659 global.show_message(response.responseJSON); 1660 }); 1661 }; 1662 1663 self.showUserRelatedCompaniesModal = function (userId) { 1664 global.showLoadingDialog('Haetaan toimipaikkoja...'); 1665 jQuery 1666 .ajax({ 1667 url: '/omat_tiedot/getRelatedCompanies/'.concat(userId), 1668 dataType: 'json', 1669 }) 1670 .done(function (response) { 1671 global.close_loading_dialog(); 1672 self.setCompanySelectModalData(response.data); 1673 self.editUserId(userId); 1674 $('#companySelectModal').modal('show'); 1675 }) 1676 .fail(function (response) { 1677 global.close_loading_dialog(); 1678 global.show_message(response.responseJSON); 1679 }); 1680 }; 1681 1682 $('#companySelectModal, #addUserModal, #addSupervisorModal, #addWorkerModal').on('hidden.bs.modal', function () { 1683 self.editUserId(null); 1684 self.relatedCompaniesFilter(''); 1685 self.selectedCompaniesFilter(''); 1686 self.resetNewWorker(); 1687 self.resetNewSupervisor(); 1688 self.resetNewUser(); 1689 }); 1690 1691 self.setCompanySelectModalData = function (data) { 1692 self.userCompanies(data.userCompanies); 1693 self.relatedCompanies(data.relatedCompanies); 1694 }; 1695 self.removeCompany = function (company) { 1696 self.userCompanies.remove(company); 1697 self.relatedCompanies.push(company); 1698 }; 1699 1700 self.addCompany = function (company) { 1701 self.relatedCompanies.remove(company); 1702 self.userCompanies.push(company); 1703 }; 1704 1705 self.relatedCompaniesFilter.subscribe(function () { 1706 var filterText = self.relatedCompaniesFilter(); 1707 $('#related_companies button').show(); 1708 if (filterText != '') { 1709 $('#related_companies button').filter(function () { 1710 var btn = $(this).text(); 1711 if (!btn.includes(filterText)) { 1712 $(this).hide(); 1713 } 1714 }); 1715 } 1716 }); 1717 1718 self.selectedCompaniesFilter.subscribe(function () { 1719 var filterText = self.selectedCompaniesFilter(); 1720 $('#user_companies button').show(); 1721 if (filterText != '') { 1722 $('#user_companies button').filter(function () { 1723 var btn = $(this).text(); 1724 if (!btn.includes(filterText)) { 1725 $(this).hide(); 1726 } 1727 }); 1728 } 1729 }); 1730 1731 self.saveUserCompanies = function () { 1732 if (!self.editUserId()) { 1733 JSON = { 1734 type: 'error', 1735 title: 'Virhe', 1736 text: 'Virheellinen käyttäjä', 1737 }; 1738 global.show_message(JSON); 1739 return; 1740 } 1741 if (self.userCompanies().length === 0) { 1742 JSON = { 1743 type: 'error', 1744 title: 'Virhe', 1745 text: 'Käyttäjän pitää kuulua vähintään yhteen toimipaikkaan', 1746 }; 1747 global.show_message(JSON); 1748 return; 1749 } 1750 var data = { 1751 userCompanies: ko.toJS(self.userCompanies), 1752 relatedCompanies: ko.toJS(self.relatedCompanies), 1753 }; 1754 global.showLoadingDialog('Tallennetaan...'); 1755 jQuery 1756 .ajax({ 1757 type: 'post', 1758 url: '/omat_tiedot/saveRelatedCompanies/'.concat(self.editUserId()), 1759 dataType: 'json', 1760 data: data, 1761 }) 1762 .done(function (response) { 1763 global.close_loading_dialog(); 1764 self.setCompanySelectModalData(response.data); 1765 self.showSuccessMessage('Tallennettu', 'Käyttäjän toimipaikat tallennettu'); 1766 }) 1767 .fail(function (response) { 1768 global.close_loading_dialog(); 1769 global.show_message(response.responseJSON); 1770 }); 1771 }; 1772 1773 self.saveNewUser = function () { 1774 if (!self.newUser.username() || self.newUser.username().trim == '') { 1775 self.showErrorMessage('Virheellinen käyttäjätunnus'); 1776 return; 1777 } 1778 if (!self.newUser.email() || self.newUser.email().trim == '') { 1779 self.showErrorMessage('Virheellinen käyttäjän sähköposti'); 1780 return; 1781 } 1782 if (!self.newUser.usergroup_id() || self.newUser.usergroup_id().trim == '') { 1783 self.showErrorMessage('Virheellinen käyttäjätaso'); 1784 return; 1785 } 1786 if (!self.newUser.sales_name() || self.newUser.sales_name().trim == '') { 1787 self.showErrorMessage('Virheellinen käyttäjän nimi'); 1788 return; 1789 } 1790 1791 var data = { 1792 newUser: ko.toJS(self.newUser), 1793 }; 1794 global.showLoadingDialog('Tallennetaan...'); 1795 jQuery 1796 .ajax({ 1797 type: 'post', 1798 url: '/omat_tiedot/saveNewUser/', 1799 dataType: 'json', 1800 data: data, 1801 }) 1802 .done(function (response) { 1803 global.close_loading_dialog(); 1804 self.users(response.data.users); 1805 $('#addUserModal').modal('hide'); 1806 self.showSuccessMessage('Käyttäjä tallennettu', 'Uuden käyttäjän lisäys onnistui'); 1807 }) 1808 .fail(function (response) { 1809 global.close_loading_dialog(); 1810 global.show_message(response.responseJSON); 1811 }); 1812 }; 1813 1814 self.saveNewWorker = function () { 1815 if (!self.newWorker.name() || self.newWorker.name().trim == '') { 1816 self.showErrorMessage('Virheellinen käyttäjän nimi'); 1817 return; 1818 } 1819 if (!self.newWorker.extId() || self.newWorker.extId().trim == '') { 1820 self.showErrorMessage('Virheellinen käyttäjän Mepco-ID'); 1821 return; 1822 } 1823 if (self.userCompanies().length === 0 && !self.isPartner) { 1824 self.showErrorMessage('Käyttäjän pitää kuulua vähintään yhteen toimipaikkaan'); 1825 return; 1826 } 1827 var url = self.isPartner ? '/omat_tiedot/newWorkerForCompany/' : '/omat_tiedot/newWorkerForCompanyGroup/'; 1828 var data = { 1829 userCompanies: ko.toJS(self.userCompanies), 1830 newWorker: ko.toJS(self.newWorker), 1831 }; 1832 global.showLoadingDialog('Tallennetaan...'); 1833 jQuery 1834 .ajax({ 1835 type: 'post', 1836 url: url, 1837 dataType: 'json', 1838 data: data, 1839 }) 1840 .done(function (response) { 1841 global.close_loading_dialog(); 1842 self.workers(response.data.workers); 1843 $('#addWorkerModal').modal('hide'); 1844 self.showSuccessMessage('Käyttäjä tallennettu', 'Uuden käyttäjän lisäys onnistui'); 1845 }) 1846 .fail(function (response) { 1847 var errorResponse = response.responseJSON ? response.responseJSON : JSON.parse(response.responseText); 1848 global.close_loading_dialog(); 1849 global.show_message(errorResponse); 1850 }); 1851 }; 1852 1853 self.saveNewSupervisor = function () { 1854 if (!self.newSupervisor.userName() || self.newSupervisor.userName().trim == '') { 1855 self.showErrorMessage('Virheellinen käyttäjän käyttäjätunnus'); 1856 return; 1857 } 1858 if (!self.newSupervisor.email() || self.newSupervisor.email().trim == '') { 1859 self.showErrorMessage('Virheellinen käyttäjän sähköpostiosoite'); 1860 return; 1861 } 1862 if (!self.newSupervisor.name() || self.newSupervisor.name().trim == '') { 1863 self.showErrorMessage('Virheellinen käyttäjän nimi'); 1864 return; 1865 } 1866 if (!self.newSupervisor.extId() || self.newSupervisor.extId().trim == '') { 1867 self.showErrorMessage('Virheellinen käyttäjän Mepco-ID'); 1868 return; 1869 } 1870 if (self.userCompanies().length === 0 && !self.isPartner) { 1871 self.showErrorMessage('Käyttäjän pitää kuulua vähintään yhteen toimipaikkaan'); 1872 return; 1873 } 1874 1875 var url = self.isPartner ? '/omat_tiedot/newSupervisorForCompany/' : '/omat_tiedot/newSupervisorForCompanyGroup/'; 1876 var data = { 1877 userCompanies: ko.toJS(self.userCompanies), 1878 newSupervisor: ko.toJS(self.newSupervisor), 1879 }; 1880 global.showLoadingDialog('Tallennetaan...'); 1881 jQuery 1882 .ajax({ 1883 type: 'post', 1884 url: url, 1885 dataType: 'json', 1886 data: data, 1887 }) 1888 .done(function (response) { 1889 global.close_loading_dialog(); 1890 self.supervisors(response.data.supervisors); 1891 $('#addSupervisorModal').modal('hide'); 1892 self.showSuccessMessage('Käyttäjä tallennettu', 'Uuden käyttäjän lisäys onnistui'); 1893 }) 1894 .fail(function (response) { 1895 var errorResponse = response.responseJSON ? response.responseJSON : JSON.parse(response.responseText); 1896 global.close_loading_dialog(); 1897 global.show_message(errorResponse); 1898 }); 1899 }; 1900 1901 self.updateUsers = function () { 1902 self.updateCompanyUsers(ko.toJS(self.users), 'users'); 1903 }; 1904 1905 self.updateWorkers = function () { 1906 var workersData = self.workers().map(function (row) { 1907 row.user_id = row.id; 1908 return row; 1909 }); 1910 self.updateCompanyUsers(workersData, 'workers'); 1911 }; 1912 1913 self.updateSupervisors = function () { 1914 var supervisorsData = self.supervisors().map(function (row) { 1915 row.user_id = row.id; 1916 return row; 1917 }); 1918 self.updateCompanyUsers(supervisorsData, 'supervisors'); 1919 }; 1920 1921 self.updateCompanyUsers = function (usersData, userType) { 1922 1923 var data = { users: usersData, type: userType }; 1924 global.showLoadingDialog('Tallennetaan...'); 1925 jQuery 1926 .ajax({ 1927 type: 'post', 1928 url: '/omat_tiedot/updateUsers/', 1929 dataType: 'json', 1930 data: data, 1931 }) 1932 .done(function (response) { 1933 global.close_loading_dialog(); 1934 if (userType === 'supervisors') self.supervisors(response.data.users); 1935 if (userType === 'workers') self.workers(response.data.users); 1936 if (userType === 'users') self.users(response.data.users); 1937 1938 self.showSuccessMessage('Käyttäjät tallennettu', 'Käyttäjien tiedot päivitetty'); 1939 }) 1940 .fail(function (response) { 1941 global.close_loading_dialog(); 1942 global.show_message(response.responseJSON); 1943 }); 1944 }; 1945 1946 self.resetPassword = function (user) { 1947 $('#resetText').text('Vahvista salasanan resetointi'); 1948 $('#passwordResetModal').dialog({ 1949 resizable: false, 1950 height: 'auto', 1951 width: 400, 1952 modal: true, 1953 buttons: { 1954 Resetoi: function () { 1955 jQuery 1956 .ajax({ 1957 url: '/omat_tiedot/resetPassword', 1958 data: { userId: user.user_id ? user.user_id : user.id }, 1959 }) 1960 .then(function (response) { 1961 var msg = response.text || 'Salasana muutettu, ja lähettty sähköpostitse käyttäjälle';
1962 $('#resetText').text(msg); 1963 setTimeout(() => $('#passwordResetModal').dialog('close'), 2000); 1964 }) 1965 .fail(function (response) { 1966 var msg = response.text || 'Salasanaa ei voitu resetoida'; 1967 $('#resetText').text(msg); 1968 }); 1969 }, 1970 Peruuta: function () { 1971 $(this).dialog('close'); 1972 }, 1973 }, 1974 }); 1975 }; 1976 1977 self.showSuccessMessage = function (title, txt) { 1978 JSON = { 1979 type: 'success', 1980 title: title, 1981 text: txt, 1982 }; 1983 global.show_message(JSON); 1984 }; 1985 1986 self.showErrorMessage = function (txt) { 1987 JSON = { 1988 type: 'error', 1989 title: 'Virhe', 1990 text: txt, 1991 }; 1992 global.show_message(JSON); 1993 }; 1994 1995 self.replaceUserData = function (type, oldVal, newVal) { 1996 switch (type) { 1997 case 'user': 1998 self.users.replace(oldVal, newVal); 1999 break; 2000 case 'worker': 2001 self.workers.replace(oldVal, newVal); 2002 break; 2003 case 'supervisor': 2004 self.supervisors.replace(oldVal, newVal); 2005 break; 2006 } 2007 }; 2008}; 2009 2010;/* global ko, $ */ 2011const SSN_REGEX = /^(0[1-9]|[12]\d|3[01])(0[1-9]|1[0-2])([5-9]\d\+|\d\d-|[012]\dA)\d{3}[\dA-Z]$/ 2012 2013const DEFAULT_CAR_TOW_USER_ACCESS_LEVEL = 3 2014const DEFAULT_USER_ACCESS_LEVEL = 2 2015const DEFAULT_CONNECTION_FEE = 139 2016 2017var selectpicker = { 2018 preprocess: function (value, name, addBindingCallback) { 2019 // add optionsCaption to the bindings against a "caption" sub-observable 2020 addBindingCallback('optionsCaption', value + '.caption'); 2021 // just return the original value to allow this binding to remain as-is 2022 return value; 2023 }, 2024 init: function (element, valueAccessor, allBindings) { 2025 var options = valueAccessor(); 2026 var hasDisable = allBindings.get('disable'); 2027 var notificationSettings = 2028 $(element).hasClass('notifications-stations-select') || 2029 $(element).hasClass('notifications-types-select'); 2030 2031 if (ko.isObservable(hasDisable)) { 2032 hasDisable.subscribe((isDisabled) => { 2033 $(element).prop('disabled', isDisabled); 2034 $(element).selectpicker('refresh'); 2035 }); 2036 } 2037 // create an observable to track the caption 2038 if (options && !ko.isObservable(options.caption)) { 2039 options.caption = ko.observable(); 2040 } 2041 var opts = { 2042 liveSearch: true, 2043 size: 5, 2044 noneResultsText: 'Haku {0} ei tuottanut tuloksia', 2045 noneSelectedText: notificationSettings ? 'Kaikki' : 'Ei valintoja', 2046 liveSearchPlaceholder: 'Etsi nimellä', 2047 }; 2048 2049 $(element).selectpicker(opts); 2050 2051 $('[data-toggle="automatic_reconciliation_tooltip"]').popover({ 2052 trigger: 'hover', 2053 'placement': 'top' 2054 }); 2055 $('[data-toggle="bank_statement_tooltip"]').popover({ 2056 trigger: 'hover', 2057 'placement': 'top' 2058 }); 2059 $('[data-toggle="service_charge_to_payment_account_tooltip"]').popover({ 2060 trigger: 'hover', 2061 'placement': 'top' 2062 }); 2063 $('[data-toggle="block_eu_sales_tooltip"]').popover({ 2064 trigger: 'hover', 2065 'placement': 'top' 2066 }); 2067 2068 return ko.bindingHandlers.options.init.apply(this, arguments); 2069 }, 2070 update: function (element, valueAccessor, allBindings) { 2071 ko.bindingHandlers.options.update.apply(this, arguments); 2072 var value = allBindings.get('value'); 2073 $(element).selectpicker('val', ko.unwrap(value)); 2074 $(element).selectpicker('refresh'); 2075 }, 2076}; 2077 2078ko.bindingHandlers.selectpicker = selectpicker; 2079 2080ko.extenders.uppercase = function(target, option) { 2081 target.subscribe(function(newValue) { 2082 if(newValue){ 2083 target(newValue.toUpperCase()); 2084 } 2085 }); 2086 return target; 2087}; 2088 2089function createNewShiftSettingGroup(data) { 2090 return { 2091 id: ko.observable(data.id || null), 2092 company_id: ko.observable(data.company_id || null), 2093 tes: ko.observable(data.tes || null), 2094 group_name: ko.observable(data.group_name || null), 2095 job_type: ko.observable(data.job_type || 'period'), 2096 period_start_date: ko.observable(data.period_start_date || null), 2097 period_length: ko.observable(data.period_length || 14), 2098 evening_start: ko.observable(data.evening_start || null), 2099 evening_end: ko.observable(data.evening_end || null), 2100 night_start: ko.observable(data.night_start || null), 2101 night_end: ko.observable(data.night_end || null), 2102 enable_wait: ko.observable(data.enable_wait), 2103 enable_standby: ko.observable(data.enable_standby), 2104 enable_evening: ko.observable(data.enable_evening), 2105 enable_night: ko.observable(data.enable_night), 2106 enable_overtime: ko.observable(data.enable_overtime), 2107 }; 2108} 2109 2110function isValidSsn(ssn){ 2111 return typeof ssn === 'string' ? /^\d{6}[+-Aa]\d{3}[a-zA-Z0-9]$/.test(ssn.trim()) : false;
2112} 2113 2114function maskedSsn(param){ 2115 var ssn = ko.isObservable(param) ? param() : param; 2116 //return typeof ssn === 'string' ? ssn.substr(0, 7)+'****' : ssn; 2117 return isValidSsn(ssn) ? ssn.substr(0, 7)+'****' : ssn; 2118} 2119 2120function getUserLastLoggedLabel(param){ 2121 var date = ko.isObservable(param) ? param() : param; 2122 var dateObj = new Date(date); 2123 2124 return dateObj != 'Invalid Date' ? 'Kirjautunut: ' + dateObj.toLocaleString('fi') : 'Käyttäjä ei ole kirjautunut palveluun'; 2125} 2126 2127var AccountCardDialogVm = function () { 2128 'use strict'; 2129 var self = this; 2130 2131 // Reference to jQuery ui dialog 2132 self.dialog = null; 2133 self.saving = ko.observable(false); 2134 self.saved = ko.observable(false); 2135 self.reactivatingTrial = ko.observable(false); 2136 self.toggleReactivatingTrial = function () { 2137 self.reactivatingTrial(!self.reactivatingTrial()); 2138 }; 2139 self.contactPersonSaved = { 2140 name: ko.observable(false), 2141 phone: ko.observable(false), 2142 ssn: ko.observable(false), 2143 email: ko.observable(false), 2144 }; 2145 2146 // Static data 2147 self.autoklinikkaBranches = []; 2148 self.accountManagers = []; 2149 self.usergroups = []; 2150 self.eInvoiceOperators = []; 2151 self.workingFields = []; 2152 self.routeTypes = [ 2153 { type: false, label: '4 Aikaleimaa' }, 2154 { type: true, label: '6 Aikaleimaa' } 2155 ]; 2156 2157 // @ai:claude Safe default so the view binding doesn't throw before account data is loaded. 2158 // bindComputedObservables() replaces this with a live ko.pureComputed once account exists. 2159 self.trialStatusBadge = ko.observable({ text: '', cls: 'label-default' }); 2160 2161 // @ai:claude Trial status options matching Company::TRIAL_STATUS_* PHP constants (0â5). 2162 self.trialStatuses = [ 2163 { value: 0, text: 'Luonnos' }, 2164 { value: 1, text: 'Aktiivinen' }, 2165 { value: 2, text: 'Vanhentunut' }, 2166 { value: 3, text: 'Muuttumassa asiakkaaksi' }, 2167 { value: 4, text: 'Muutettu asiakkaaksi' }, 2168 { value: 5, text: 'Peruutettu' }, 2169 ]; 2170 2171 // @ai:claude Signals that the next saveAccount call should also convert the trial to a real customer. 2172 self.convertingTrialToCustomer = ko.observable(false); 2173 2174 // @ai:claude Promotes a trial company to a real paying customer. The company must be 2175 // aktiivinen (ACTIVE) â the backend accepts ACTIVE or CONVERTING and handles conversion. 2176 self.convertTrialToCustomer = function () { 2177 if (!self.account.company.contact_person_ssn()) { 2178 return global.show_message({ type: 'error', text: 'Muuttaminen vaatii sopimusyhteyshenkilön hetun' }); 2179 } 2180 2181 var message = 'Muutetaanko kokeiluasiakkuus oikeaksi asiakkuudeksi? Tämä toimenpidettä ei voi perua.'; 2182 2183 var $confirmDialog = $('<div />') 2184 .html('<p style="margin:0;">' + message + '</p>') 2185 .prepend( 2186 $( 2187 '<span />', 2188 { 2189 class: 'ui-icon ui-icon-alert', 2190 style: 'float:left; margin:0 7px 50px 0;', 2191 } 2192 ) 2193 ); 2194 2195 $confirmDialog.dialog({ 2196 title: 'Vahvista muutos', 2197 modal: true, 2198 buttons: { 2199 Peruuta: function () { 2200 $confirmDialog.dialog('close'); 2201 }, 2202 Muuta: function () { 2203 $confirmDialog.dialog('close'); 2204 self.convertingTrialToCustomer(true); 2205 self.saveAccount(); 2206 }, 2207 }, 2208 close: function () { 2209 $confirmDialog.dialog('destroy'); 2210 $confirmDialog.remove(); 2211 }, 2212 }); 2213 2214 // Make sure the dialog appears above the account card. 2215 $confirmDialog.parents('.ui-dialog').css('z-index', 9999); 2216 }; 2217 2218 // @ai:claude Cancels the trial â sets trial_status = 5 (CANCELLED). 2219 self.cancelTrialCustomer = function () { 2220 var $d = $('<div />').html('<p style="margin:0;">Haluatko varmasti peruuttaa kokeiluasiakkuuden?</p>') 2221 .prepend($('<span />', { class: 'ui-icon ui-icon-alert', style: 'float:left; margin:0 7px 50px 0;' })); 2222 2223 $d.dialog({ 2224 title: 'Peruuta kokeiluasiakkuus', 2225 modal: true, 2226 buttons: { 2227 'Kyllä, peruuta': function () { 2228 $d.dialog('close'); 2229 global.show_loading_dialog('Peruutetaan...'); 2230 $.ajax({ 2231 url: '/asiakkuudet/cancelTrialCustomer', 2232 type: 'POST', 2233 dataType: 'json', 2234 data: { company_id: self.account.company.id() }, 2235 success: function (response) { 2236 global.close_loading_dialog(); 2237 global.show_message(response); 2238 self.fetchAndUpdateData(self.account.company.id()); 2239 self.saved(true); 2240 self.saved(false); 2241 }, 2242 error: function (xhr) { 2243 global.close_loading_dialog(); 2244 global.show_message($.parseJSON(xhr.responseText)); 2245 }, 2246 }); 2247 }, 2248 'Takaisin': function () { $d.dialog('close'); }, 2249 }, 2250 close: function () { $d.dialog('destroy'); $d.remove(); }, 2251 }).parents('.ui-dialog').css('z-index', 9999); 2252 }; 2253 2254 self.selectedCompanyGroups = ko.observableArray([]); 2255 self.companyGroupSelected = ko.observable(null); 2256 self.companyGroupSelected.subscribe(function(g) { 2257 var found = self.selectedCompanyGroups().find(id => id === g.id) 2258 if (found) { 2259 self.selectedCompanyGroups(self.selectedCompanyGroups().filter(id => id !== g.id)) 2260 } else { 2261 self.selectedCompanyGroups.push(Number(g.id)) 2262 } 2263 }); 2264 2265 // Settings 2266 self.settings = { 2267 stationTypeOptions: [ 2268 { type: 0, label: 'Asemapaikka' }, 2269 { type: 1, label: 'Toimipiste' }, 2270 { type: 2, label: 'Asemapaikka + Toimipiste' } 2271 ], 2272 stations: ko.observableArray([]), 2273 agreements: ko.observableArray([]), 2274 agreements_innokorjaamo: ko.observableArray([]), 2275 sms_templates: ko.observableArray([]), 2276 agreementToAdd: ko.observable(), 2277 resourceToAdd: { 2278 resource: ko.observable(null), 2279 ext_id: ko.observable(null), 2280 }, 2281 roles: ko.observableArray([]), 2282 towingRecordTypes: ko.observableArray([]), 2283 typeToAdd: ko.observable(), 2284 freightTypes: ko.observableArray([]), 2285 jobOrderTypes: ko.observableArray([]), 2286 companyGroups: ko.observableArray([]), 2287 freightTypeToAdd: ko.observable(), 2288 jobOrderTypeToAdd: ko.observable(), 2289 depots: ko.observableArray([]), 2290 categories: ko.observableArray([]), 2291 glAccounts: ko.observableArray([]), 2292 resources: ko.observableArray([]), 2293 spare_parts: ko.observableArray([]), 2294 depotToAdd: ko.observable(), 2295 categoryToAdd: ko.observable(), 2296 subCategoryToAdd: ko.observable(), 2297 glAccountToAdd: { 2298 gl_account: ko.observable(null), 2299 desc: ko.observable(null), 2300 }, 2301 shiftGroupSettings: ko.observableArray(), 2302 isHidden: function (type) { 2303 return typeof type.deleted_at === 'string'; 2304 }, 2305 }; 2306 2307 self.apiKeys = ko.observableArray([]); 2308 2309 self.subcontractingCompanies = ko.observableArray([]); 2310 self.subcontractingSearch = ko.observable(''); 2311 self.subcontractingSearchResults = ko.observableArray([]); 2312 self.subcontractingSearchLoading = ko.observable(false); 2313 self.subcontractingSearchNoResults = ko.observable(false); 2314 self._subcontractingDebounceTimer = null; 2315 2316 self.smsMessageTriggers = ko.observableArray([]); 2317 self.smsMessageTimings = ko.observableArray([]); 2318 self.onSmsTriggerChange = function(a) { 2319 // var used = self.smsMessageTriggers().find(function(t) { 2320 // return t.type == ko.unwrap(a.trigger) 2321 // }) 2322 // if (!used) { return; } 2323 ko.tasks.schedule(function() { 2324 if (ko.unwrap(a.id) == null) { 2325 switch (ko.unwrap(a.trigger)) { 2326 case 'reservation_confirmation': 2327 a.template('Hei! \n\nAjoneuvollesi {{REKNO}} on varattu huoltoaika {{ALOITUSPVM}} klo {{ALOITUSKLO}}.'); 2328 a.timing('+0 day') 2329 a.title('Varausvahvistus'); 2330 break; 2331 case 'reservation_reminder': 2332 a.template('Hei! \n\nMuistutus ajoneuvollesi {{REKNO}} varatusta huoltoajasta huomenna {{ALOITUSPVM}} klo {{ALOITUSKLO}}.'); 2333 a.timing('-1 day') 2334 a.title('Varausvahvistus, muistutus'); 2335 break; 2336 case 'work_started': 2337 a.template('Hei! \n\nAjoneuvosi {{REKNO}} on nyt otettu työn alle. Arvioitu valmistumisaika on {{VALMISPVM}} klo {{VALMISKLO}}. Ilmoitamme erikseen kun ajoneuvo on valmis noudettavaksi.'); 2338 a.timing('+0 day') 2339 a.title('Ajoneuvo otettu työn alle'); 2340 break; 2341 case 'work_done': 2342 a.template('Hei! \n\nAjoneuvosi {{REKNO}} on valmis noudettavaksi. Aukioloaikamme 09-17. Ota yhteyttä mikäli et pääse noutamaan ajoneuvoasi aukioloaikoaikojen puitteissa'); 2343 a.timing('+0 day') 2344 a.title('Ajoneuvo valmis noudettavaksi'); 2345 break; 2346 case 'job_finished': 2347 a.template('Hei! \n\nEsim. Muista kiristää ruuvit tmv.'); 2348 a.timing('+0 day')
2349 a.title('Jälkiviesti'); 2350 break; 2351 } 2352 } 2353 }); 2354 } 2355 2356 self.kycIsDraft = ko.observable(false); 2357 self.kycDeclineReasonsRaw = [ 2358 { 2359 selected: ko.observable(false), 2360 description: 'Kuuluu ALV-rekisteriin, mutta ilmoittanut että ei kuulu', 2361 }, 2362 { 2363 selected: ko.observable(false), 2364 description: 'Liikevaihto yli 20k mutta ei ole ALV-rekisterissä', 2365 }, 2366 { 2367 selected: ko.observable(false), 2368 description: 'Ei kuulu ennakkoperintärekisteriin', 2369 }, 2370 { 2371 selected: ko.observable(false), 2372 description: 'Ilmoitetut vastuuhenkilöt ei täsmää rekisteröityihin', 2373 }, 2374 { 2375 selected: ko.observable(false), 2376 description: 'Ilmoitetut nimenkirjoitusoikeudet ei täsmää rekisteröityihin', 2377 }, 2378 { 2379 selected: ko.observable(false), 2380 description: 'Kuuluu ennakkoperintärekisteriin, mutta ilmoittanut että ei kuulu', 2381 }, 2382 { 2383 selected: ko.observable(false), 2384 description: 'Ulkomainen tilinumero', 2385 }, 2386 { 2387 selected: ko.observable(false), 2388 description: 'Epäyhtenäisyys pankkiyhteystiedoissa', 2389 }, 2390 { 2391 selected: ko.observable(false), 2392 description: 'Epäyhtenäisyys pankkiyhteystiedoissa - Asiakasyritys ei ole tilinomistaja', 2393 }, 2394 { 2395 selected: ko.observable(false), 2396 description: 'Asiakastiedoissa yhteys black-list maahan', 2397 }, 2398 { 2399 selected: ko.observable(false), 2400 description: 'Pakotetarkastus tuottanut tuloksen', 2401 }, 2402 { 2403 selected: ko.observable(false), 2404 description: 'Allekirjoittajalle ei nimenkirjoitusoikeutta', 2405 }, 2406 { 2407 selected: ko.observable(false), 2408 description: 'Prokuraa ei rekisteröity tai tiedoissa epäyhtenäisyys', 2409 }, 2410 ] 2411 2412 self.kycDeclineReasons = ko.observableArray(self.kycDeclineReasonsRaw.sort(function(a, b){return a.description > b.description ? 1 : -1})) 2413 2414 self.kycDeclineReasonOther = ko.observable(''); 2415 2416 self.declineKycReason = ko.computed(function(){ 2417 let reasons = []; 2418 self.kycDeclineReasons().forEach(function(item){ 2419 if(item.selected()){ 2420 reasons.push(item.description); 2421 } 2422 }) 2423 if(self.kycDeclineReasonOther()){ 2424 reasons.push(self.kycDeclineReasonOther()); 2425 } 2426 return reasons.join(', '); 2427 }); 2428 2429 self.clearKycDeclineReasons = function(){ 2430 self.kycDeclineReasons().forEach(function(item){ 2431 item.selected(false); 2432 }) 2433 self.kycDeclineReasonOther(''); 2434 } 2435 2436 self.setKycManualAcceptanceRequired = ko.observable(false); 2437 self.continueInterval = ko.observable(false); 2438 2439 function SubCategory(data) { 2440 this.id = ko.observable(data.id); 2441 this.sub_category = ko.observable(data.sub_category); 2442 this.deleted_at = ko.observable(data.deleted_at); 2443 } 2444 2445 function Category(data) { 2446 this.id = ko.observable(data.id); 2447 this.category = ko.observable(data.category); 2448 this.deleted_at = ko.observable(data.deleted_at); 2449 this.sub_categories = ko.observableArray(data.sub_categories.map((s) => new SubCategory(s))); 2450 } 2451 2452 self.handleUpdateMFAServiceState = function(context, toggleMFA) { 2453 const accessLevel = self.account.company.field_of_work() === 'car_tow' ? DEFAULT_CAR_TOW_USER_ACCESS_LEVEL : DEFAULT_USER_ACCESS_LEVEL; 2454 self.account.preferences.min_access_level_required_to_use_mfa(toggleMFA ? accessLevel : null) 2455 2456 //If creating new company don't send request 2457 if( ! self.account.company.id()) { 2458 return 2459 } 2460 2461 self.updateServiceState(context, toggleMFA) 2462 } 2463 2464 self.updateServiceState = function (context, value) 2465 { 2466 var value = value ? 1 : 0; 2467 2468 if (context === 'mod_sms' && value === 1) { 2469 self.account.preferences.mobile_sales_vat(13.5); 2470 } 2471 2472 if(value && self.companyRestrictions.restrictionExists(context) ){ 2473 window.alert('HUOM! Palvelu on yrityken palveluesto listalla. Mikäli sinulle ei ole hyvää syytä ottaa palvelua käyttöön, klikkaa palvelu pois päältä!'); 2474 return; 2475 } 2476 2477 global.showLoadingDialog('Ladataan...'); 2478 2479 $.ajax({ 2480 url: '/asiakkuudet/updateModStatus', 2481 method: 'post', 2482 data: { 2483 company_id: self.account.company.id(), 2484 context, 2485 value, 2486 }, 2487 }) 2488 .then(function (success) { 2489 if (context === 'mod_company_group' && Number(value) === 0) { 2490 var reset = self.settings.companyGroups().map(g => { g.active = false; return g}) 2491 self.settings.companyGroups.removeAll(); 2492 self.settings.companyGroups(reset) 2493 self.selectedCompanyGroups([]); 2494 self.account.company.company_group_admin(false); 2495 self.account.company.ak_partner(false); 2496 } 2497 if (value === 0) { 2498 global.show_message(success); 2499 } 2500 2501 self.account.logs.unshift(success.data.logItem); 2502 2503 if (value === 1) { 2504 global.close_loading_dialog() 2505 var dia = $('#dialog') 2506 .dialog({ 2507 resizable: false, 2508 title: 'Aktivointiviesti', 2509 height: 'auto', 2510 width: 400, 2511 modal: true, 2512 buttons: { 2513 'Lähetä': function () { 2514 $.ajax({ 2515 url: '/asiakkuudet/sendActivationMail', 2516 method: 'post', 2517 data: { 2518 company_id: self.account.company.id(), 2519 context, 2520 value, 2521 }, 2522 }) 2523 .then(function (resp) { 2524 console.log(resp) 2525 var msg = resp.msg || 'Toiminto suoritettu, mutta palvelin ei vastannut'; 2526 dia.dialog('option', 'title', 'Valmis'); 2527 dia.dialog('option', 'buttons', {}); 2528 dia.html('<p>' + msg + '</p>') 2529 setTimeout(function() { dia.dialog('close') }, 3500); 2530 }) 2531 .fail(function (resp) { 2532 var msg = resp.responseJSON.error || 'Palvelinvirhe'; 2533 dia.dialog('option', 'title', 'Virhe'); 2534 dia.dialog('option', 'buttons', {}); 2535 dia.html('<p>' + msg + '</p>') }) 2536 setTimeout(function() { dia.dialog('close') }, 3500); 2537 }, 2538 'Ei viestiä': function () { 2539 dia.dialog('close'); 2540 }, 2541 }, 2542 }) 2543 .html('<p>Haluatko lähetetää sopimusyhteyshenkilölle palvelun aktivointiviestin?</p>'); 2544 } 2545 }) 2546 .fail(function (error) { 2547 global.show_message(error.responseJSON); 2548 }) 2549 .always(function () { 2550 global.close_loading_dialog(); 2551 }); 2552 }; 2553 2554 self.kredinorSubscriptionCount = ko.observable(0); 2555 self.companyDocuments = new CompanyDocumentsVM(); 2556 self.companyRestrictions = new CompanyRestrictionsVM(); 2557 2558 // @ai:claude The Procountor accounting settings editor, the same view model and the same markup 2559 // the company's own omat_tiedot tab uses, so the two editors cannot show different c
2559onfiguration. 2560 // adminMode makes its endpoints carry the company id, because the card configures a company other 2561 // than the admin's own session company. Filled by setData() when a card is opened. 2562 self.accounting = new AccountingSettingsVm({ 2563 baseUrl: '/asiakkuudet', 2564 adminMode: true, 2565 data: null, 2566 }); 2567 2568 2569 self.canSelectRiverty = function() { 2570 if (!self.account.company.id()) { 2571 return false; 2572 } 2573 2574 var currentLedgerService = self.account.company.ledger_service(); 2575 return currentLedgerService === 'riverty'; 2576 }; 2577 2578 self.companyMessagingDetails = new CompanyMessagingDetailsVM(); 2579 self.companyMessagingDetailOptions = ko.observableArray([]); 2580 // START OF SERVICE SUBSCRIPTIONS 2581 2582 self.serviceSubscriptions = { 2583 //add subscriptions here 2584 review: { 2585 type: 'review', 2586 subscriptions: ko.observableArray([]), 2587 }, 2588 paymentTerminal: { 2589 type: 'paymentTerminal', 2590 subscriptions: ko.observableArray([]), 2591 }, 2592 accountingService: { 2593 type: 'accountingService', 2594 subscriptions: ko.observableArray([]), 2595 }, 2596 workShiftService: { 2597 type: 'workShiftService', 2598 subscriptions: ko.observableArray([]), 2599 }, 2600 trackingLink: { 2601 type: 'trackingLink', 2602 subscriptions: ko.observableArray([]), 2603 }, 2604 paymentLink: { 2605 type: 'paymentLink', 2606 subscriptions: ko.observableArray([]), 2607 }, 2608 }; 2609 2610 self.serviceSubscriptions.review.isActive = ko.computed(function () { 2611 var isActive = false; 2612 self.serviceSubscriptions.review.subscriptions().forEach(function (subscription) { 2613 if (subscription.isActive()) { 2614 isActive = true; 2615 } 2616 }); 2617 return isActive; 2618 }); 2619 2620 self.serviceSubscriptions.paymentTerminal.isActive = ko.computed(function () { 2621 var isActive = false; 2622 self.serviceSubscriptions.paymentTerminal.subscriptions().forEach(function (subscription) { 2623 if (subscription.isActive()) { 2624 isActive = true; 2625 } 2626 }); 2627 return isActive; 2628 }); 2629 2630 self.serviceSubscriptions.accountingService.isActive = ko.computed(function () { 2631 var isActive = false; 2632 self.serviceSubscriptions.accountingService.subscriptions().forEach(function (subscription) { 2633 if (subscription.isActive()) { 2634 isActive = true; 2635 } 2636 }); 2637 return isActive; 2638 }); 2639 2640 self.serviceSubscriptions.workShiftService.isActive = ko.computed(function () { 2641 var isActive = false; 2642 self.serviceSubscriptions.workShiftService.subscriptions().forEach(function (subscription) { 2643 if (subscription.isActive()) { 2644 isActive = true; 2645 } 2646 }); 2647 return isActive; 2648 }); 2649 2650 self.serviceSubscriptions.trackingLink.isActive = ko.computed(function () { 2651 var isActive = false; 2652 self.serviceSubscriptions.trackingLink.subscriptions().forEach(function (subscription) { 2653 if (subscription.isActive()) { 2654 isActive = true; 2655 } 2656 }); 2657 return isActive; 2658 }); 2659 2660 self.companyForms = [ 2661 { value: 'asoy', text: 'Asunto-osakeyhtö' }, 2662 { value: 'ay', text: 'Avoin yhtiö' }, 2663 { value: 'ky', text: 'Kommandiittiyhtiö' }, 2664 { value: 'oy', text: 'Osakeyhtiö' }, 2665 { value: 'sr', text: 'Säätiö' }, 2666 { value: 'tmi', text: 'Toiminimi' }, 2667 { value: 'ry', text: 'Yhdistys' }, 2668 { value: 'other', text: 'Muu' }, 2669 ]; 2670 self.kycAddressOptions = [ 2671 { value: 'same', text: 'Sama kuin postiosoite' }, 2672 { value: 'different', text: 'Erillinen käyntiosoite' }, 2673 ]; 2674 self.kycRepresentationOptions = [ 2675 { value: 'ceo', text: 'Toimitusjohtaja, yksin' }, 2676 { value: 'ceo_substitute', text: 'Toimitusjohtajan sijainen, yksin' }, 2677 { value: 'ceo_and_cabinet_member', text: 'Hallituksen jäsen ja toimitusjohtaja yhdessä' }, 2678 { value: 'chairman', text: 'Hallituksen puheenjohtaja, yksin' }, 2679 { value: 'cabinet_member', text: 'Hallituksen jäsen, yksin' }, 2680 { value: 'cabinet_members', text: 'Hallituksen jäsen, kaksi yhdessä' }, 2681 { value: 'deputy_member', text: 'Hallituksen varajäsen, yksin' }, 2682 { value: 'deputy_members', text: 'Hallituksen varajäsen, kaksi yhdessä' }, 2683 { value: 'full_cabinet', text: 'Hallitus, kokonaisuudessaan' }, 2684 { value: 'sole_proprietor', text: 'Elinkeinonharjoittaja' }, 2685 { value: 'partner', text: 'Yhtiömies yksin' }, 2686 { value: 'partners', text: 'Yhtiömies kaksin' }, 2687 ]; 2688 self.kycProcuration = [ 2689 { value: true, text: 'Kyllä' }, 2690 { value: false, text: 'Ei' }, 2691 ]; 2692 self.kycInterval = [ 2693 { value: 12, text: '1 vuosi' }, 2694 { value: 24, text: '2 vuotta' }, 2695 ]; 2696 self.kycOwner = [ 2697 { value: true, text: 'Kyllä' }, 2698 { value: false, text: 'Ei' }, 2699 ]; 2700 self.kycProcurationsRepresentation = [ 2701 { value: 'one', text: 'Yksin' }, 2702 { value: 'two', text: 'Kaksin' }, 2703 { value: 'other', text: 'Muu, mikä?' }, 2704 ]; 2705 self.kycCommissions = [ 2706 { value: 'ceo', text: 'Toimitusjohtaja' }, 2707 { value: 'ceo_substitute', text: 'Toimitusjohtajan sijainen' }, 2708 { value: 'chairman', text: 'Hallituksen puheenjohtaja' }, 2709 { value: 'cabinet_member', text: 'Hallituksen jäsen' }, 2710 { value: 'cabinet_member2', text: 'Hallituksen varajäsen' }, 2711 { value: 'partner', text: 'Yhtiömies (Ay)' }, 2712 { value: 'liable_partner', text: 'Vastuunalainen yhtiömies (Ky)' }, 2713 { value: 'sole_proprietor', text: 'Elinkeinonharjoittaja' }, 2714 ]; 2715 2716 self.pendingKycInformation = { 2717 contactPerson: ko.observable(), 2718 contactPersonSSN: ko.observable(),
2719 contactPersonEmail: ko.observable(), 2720 contactPersonPhone: ko.observable(), 2721 }; 2722 2723 self.enableBankAccountInfo = ko.observable(false); 2724 self.toggleBankAccountInput = function() { 2725 self.enableBankAccountInfo(!self.enableBankAccountInfo()); 2726 }; 2727 2728 self.enableKycBaseInformation = ko.observable(true); 2729 self.enableKycContactPersonInformation = ko.observable(true); 2730 self.enableKycBankAccountInformation = ko.observable(true); 2731 self.enableKycRepresentationInformation = ko.observable(true); 2732 self.enableKycPersonInChargeInformation = ko.observable(true); 2733 self.enableKycOwnersInformation = ko.observable(true); 2734 self.enableKycPoliticallyInfluentialPersonsInformation = ko.observable(true); 2735 2736 self.toggleEnableKycBaseInformation = function () { 2737 self.enableKycBaseInformation(!self.enableKycBaseInformation()); 2738 }; 2739 2740 self.toggleEnableKycContactPersonInformation = function () { 2741 self.enableKycContactPersonInformation(!self.enableKycContactPersonInformation()); 2742 }; 2743 2744 self.toggleEnableKycBankAccountInformation = function () { 2745 self.enableKycBankAccountInformation(!self.enableKycBankAccountInformation()); 2746 }; 2747 2748 self.toggleKycRepresentationInformation = function () { 2749 self.enableKycRepresentationInformation(!self.enableKycRepresentationInformation()); 2750 }; 2751 2752 self.toggleKycPersonInChargeInformation = function () { 2753 self.enableKycPersonInChargeInformation(!self.enableKycPersonInChargeInformation()); 2754 }; 2755 2756 self.toggleKycOwnersInformation = function () { 2757 self.enableKycOwnersInformation(!self.enableKycOwnersInformation()); 2758 }; 2759 2760 self.addKycRepresentationInformation = function (value) { 2761 self.account.kyc.procurations.push(kycProcuration()); 2762 }; 2763 2764 self.removeKycProcuration = function(value) { 2765 self.account.kyc.procurations.remove(value); 2766 }; 2767 2768 self.addKycPersonInCharge = function () { 2769 $('#add-person-in-charge').removeClass('error'); 2770 self.account.kyc.personsInCharge.push(kycPersonInCharge()); 2771 self.initDatepicker(); 2772 }; 2773 2774 self.removeKycPersonInCharge = function(value) { 2775 self.account.kyc.personsInCharge.remove(value); 2776 }; 2777 2778 self.toggleKycPoliticallyInfluentialPersonsInformation = function () { 2779 self.enableKycPoliticallyInfluentialPersonsInformation( 2780 !self.enableKycPoliticallyInfluentialPersonsInformation() 2781 ); 2782 }; 2783 2784 self.addKycPoliticallyInfluentialPerson = function (type) { 2785 switch (type) { 2786 case 'pip': 2787 self.account.kyc.politicallyInfluentialPersons.push(kycPoliticallyInfluentialPerson(type)); 2788 break; 2789 case 'family_member': 2790 self.account.kyc.politicallyInfluentialFamilyMembers.push(kycPoliticallyInfluentialPerson(type)); 2791 break; 2792 } 2793 }; 2794 2795 self.removeKycPIP = function (value) { 2796 switch (ko.toJS(value).type) { 2797 case 'pip': 2798 self.account.kyc.politicallyInfluentialPersons.remove(value); 2799 break; 2800 case 'family_member': 2801 self.account.kyc.politicallyInfluentialFamilyMembers.remove(value); 2802 break; 2803 } 2804 }; 2805 2806 self.removeKycOwner = function (value) { 2807 switch (ko.toJS(value).type) { 2808 case 'person': 2809 self.account.kyc.personOwners.remove(value); 2810 break; 2811 case 'oy': 2812 self.account.kyc.oyOwners.remove(value); 2813 break; 2814 case 'ky': 2815 self.account.kyc.kyOwners.remove(value); 2816 break; 2817 } 2818 }; 2819 2820 self.addKycPersonOwner = function() { 2821 self.account.kyc.personOwners.push(kycOwner('person')); 2822 }; 2823 2824 self.addKycOyOwner = function() { 2825 self.account.kyc.oyOwners.push(kycOwner('oy')); 2826 }; 2827 2828 self.addKycKyOwner = function() { 2829 self.account.kyc.kyOwners.push(kycOwner('ky')); 2830 }; 2831 2832 self.searchCompanyRegister = function() { 2833 window.open('https://tietopalvelu.ytj.fi/yritys/' + self.account.company.business_id(), '_blank'); 2834 }; 2835 2836 self.acceptKYCChanges = function() { 2837 2838 try { 2839 global.showLoadingDialog('Hyväksytään muutoksia...'); 2840 2841 jQuery 2842 .ajax({ 2843 type: 'post', 2844 dataType: 'json', 2845 url: '/asiakkuudet/acceptKYCChanges', 2846 data: { id: self.account.kyc.id(), companyId: self.account.company.id() }, 2847 }) 2848 .done(function (responseJSON) { 2849 global.show_message({ 2850 title: 'KYC muutokset tallennettu', 2851 text: 'KYC lomake tallennettu onnistuneesti.', 2852 type: 'success', 2853 }); 2854 global.close_loading_dialog(); 2855 //ko.mapping.fromJS(responseJSON.data, {}, self.account.kyc); 2856 self.setData(responseJSON); 2857 }) 2858 .fail(function (data) { 2859 global.show_message($.parseJSON(data.responseText)); 2860 global.close_loading_dialog(); 2861 console.error('.ajax.fail:', data); 2862 }); 2863 } catch (e) { 2864 console.error(e.message); 2865 global.show_message({type: 'error', text: e.message}); 2866 } 2867 }; 2868 2869 self.discardKYCChanges = function(){ 2870 $dialog = $('#decline-kyc-dialog'); 2871 2872 $dialog.dialog({ 2873 width: 'auto', 2874 height: 'auto', 2875 modal: true, 2876 resizable: false, 2877 autoOpen: true, 2878 title: 'Hylkäyksen syy', 2879 close: function () { 2880 $(this).dialog('close'); 2881 }, 2882 buttons: { 2883 Hylkää: function(){ 2884 self.declineKYC(); 2885 $(this).dialog('close'); 2886 }, 2887 Sulje: function(){ 2888 $(this).dialog('close'); 2889 } 2890 } 2891 }) 2892 } 2893 2894 self.discardKYCChanges = function(){ 2895 $dialog = $('#decline-kyc-dialog'); 2896 2897 $dialog.dialog({ 2898 width: 'auto', 2899 height: 'auto', 2900 modal: true, 2901 resizable: false, 2902 autoOpen: true, 2903 title: 'Hylkäyksen syy', 2904 close: function () { 2905 $(this).dialog('close'); 2906 }, 2907 buttons: { 2908 Hylkää: function(){ 2909 self.declineKYC(); 2910 $(this).dialog('close'); 2911 }, 2912 Sulje: function(){ 2913 self.clearKycDeclineReasons(); 2914 $(this).dialog('close'); 2915 } 2916 } 2917 }) 2918 } 2919 2920 self.declineKYC = function() { 2921 try { 2922 let reason = self.declineKycReason(); 2923 self.clearKycDeclineReasons(); 2924 if(!reason){ 2925 window.alert('Et ole antanut syytä hylkäämiselle.'); 2926 return; 2927 } 2928 global.showLoadingDialog('Hylätään muutoksia...'); 2929 2930 jQuery 2931 .ajax({ 2932 type: 'post', 2933 dataType: 'json', 2934 url: '/asiakkuudet/discardKYCChanges', 2935 data: { id: self.account.kyc.id(), companyId: self.account.company.id(), reason: reason }, 2936 }) 2937 .done(function (responseJSON) { 2938 global.show_message({ 2939 title: 'KYC muutokset hylätty', 2940 text: 'KYC lomake hylätty onnistuneesti.', 2941 type: 'success', 2942 }); 2943 global.close_loading_dialog(); 2944 //ko.mapping.fromJS(responseJSON.data, {}, self.account.kyc); 2945 self.setData(responseJSON); 2946 }) 2947 .fail(function (data) { 2948 global.show_message($.parseJSON(data.responseText)); 2949 global.close_loading_dialog(); 2950 console.error('.ajax.fail:', data); 2951 }); 2952 } catch (e) { 2953 console.error(e.message); 2954 global.show_message({type: 'error', text: e.message}); 2955 } 2956 }; 2957 2958 self.createKycFormDialog = function(){ 2959 $dialog = $('#new-kyc-dialog'); 2960 2961 $dialog.dialog({ 2962 width: '400', 2963 height: 'auto', 2964 modal: true, 2965 resizable: false, 2966 autoOpen: true, 2967 title: 'Varmista lähetys', 2968 close: function () { 2969 $(this).dialog('close'); 2970 }, 2971 buttons: { 2972 "Luo ja lähetä": function(){ 2973 self.createAndSendKycForm(); 2974 $(this).dialog('close'); 2975 }, 2976 Sulje: function(){ 2977 self.setKycManualAcceptanceRequired(false); 2978 $(this).dialog('close'); 2979 } 2980 } 2981 }) 2982 } 2983 2984 self.sendKycForm = function () { 2985 try { 2986 if (!self.account.kyc.recipientEmail()) { 2987 throw Error('Vastaanottajan sposti puuttuu'); 2988 } 2989 2990 global.showLoadingDialog('Lähetetään...'); 2991 2992 var data = ko.toJS(self.account.kyc); 2993 delete data.__ko_mapping__; 2994 2995 jQuery 2996 .ajax({ 2997 type: 'post', 2998 dataType: 'json', 2999 url: '/asiakkuudet/updateReceiverAndSend', 3000 data: { formId: data.id, email: data.recipientEmail, companyId: self.account.company.id() }, 3001 }) 3002 .done(function (responseJSON) { 3003 global.show_message(responseJSON); 3004 global.close_loading_dialog(); 3005 }) 3006 .fail(function (data) { 3007 global.show_message($.parseJSON(data.responseText)); 3008 global.close_loading_dialog(); 3009 // console.error('.ajax.fail:', data); 3010 }); 3011 } catch (e) { 3012 console.error(e.message); 3013 global.show_message({type: 'error', text: e.message}); 3014 } 3015 }; 3016 3017 self.changeKycInterval = function () { 3018 try { 3019 global.showLoadingDialog('Lähetetään...'); 3020 3021 var data = ko.toJS(self.account.kyc); 3022 delete data.__ko_mapping__; 3023 3024 jQuery 3025 .ajax({ 3026 type: 'post', 3027 dataType: 'json', 3028 url: '/asiakkuudet/changeKycInterval', 3029 data: { formId: data.id, interval: data.interval, companyId: self.account.company.id()}, 3030 }) 3031 .done(function (responseJSON) { 3032 global.show_message(responseJSON); 3033 global.close_loading_dialog(); 3034 }) 3035 .fail(function (data) { 3036 global.show_message($.parseJSON(data.responseText)); 3037 global.close_loading_dialog(); 3038 // console.error('.ajax.fail:', data); 3039 }); 3040 } catch (e) { 3041 console.error(e.message); 3042 global.show_message({type: 'error', text: e.message}); 3043 } 3044 }; 3045 3046 self.createAndSendKycForm = function () { 3047 try {
3048 let forceManualAccept = self.setKycManualAcceptanceRequired() ? 1 : 0; 3049 let continueInterval = self.continueInterval() ? 1 : 0; 3050 self.setKycManualAcceptanceRequired(false); 3051 self.continueInterval(false); 3052 3053 if (!self.account.kyc.recipientEmail()) { 3054 throw Error('Vastaanottajan sposti puuttuu'); 3055 } 3056 3057 global.showLoadingDialog('Lähetetään...'); 3058 3059 var data = ko.toJS(self.account.kyc); 3060 delete data.__ko_mapping__; 3061 3062 jQuery 3063 .ajax({ 3064 type: 'post', 3065 dataType: 'json', 3066 url: '/asiakkuudet/createAndSendKycForm', 3067 data: { 3068 data: data, 3069 companyId: self.account.company.id(), 3070 forceManualAccept: forceManualAccept, 3071 continueInterval: continueInterval, 3072 sentAt: self.account.kyc.sentAt(), 3073 }, 3074 }) 3075 .done(function (responseJSON) { 3076 global.show_message({ 3077 title: 'KYC lomake lähetetty', 3078 text: 'KYC lomake lähetetty onnistuneesti.', 3079 type: 'success', 3080 }); 3081 global.close_loading_dialog(); 3082 //ko.mapping.fromJS(responseJSON.data, {}, self.account.kyc); 3083 self.setData(responseJSON); 3084 }) 3085 .fail(function (data) { 3086 global.show_message($.parseJSON(data.responseText)); 3087 global.close_loading_dialog(); 3088 console.error('.ajax.fail:', data); 3089 }); 3090 } catch (e) { 3091 console.error(e.message); 3092 global.show_message({type: 'error', text: e.message}); 3093 } 3094 }; 3095 3096 function kycProcuration() { 3097 return { 3098 id: ko.observable(null), 3099 representation: ko.observable(''), 3100 name: ko.observable(''), 3101 ssn: ko.observable(''), 3102 description: ko.observable(''), 3103 nationality: ko.observable('Suomi') 3104 }; 3105 } 3106 3107 function kycPersonInCharge() { 3108 return { 3109 id: ko.observable(null), 3110 commission: ko.observable(''), 3111 name: ko.observable(''), 3112 ssn: ko.observable(''), 3113 commissionStartDate: ko.observable(''), 3114 nationality: ko.observable('Suomi') 3115 }; 3116 } 3117 3118 function kycOwner(type = 'person') { 3119 return { 3120 id: ko.observable(null), 3121 type: ko.observable(type), 3122 name: ko.observable(''), 3123 companyName: ko.observable(''), 3124 ssn: ko.observable(''), 3125 businessId: ko.observable(''), 3126 nationality: ko.observable(''), 3127 stake: ko.observable(''), 3128 }; 3129 } 3130 3131 function kycPoliticallyInfluentialPerson(type = 'person') { 3132 return { 3133 id: ko.observable(null), 3134 type: ko.observable(type), 3135 name: ko.observable(''), 3136 description: ko.observable(''), 3137 }; 3138 } 3139 3140 self.getkycConfirmationLabel = function(date, addDays) { 3141 // date is in format d.m.Y or null and we want to return date + addDays in same format 3142 if (!date) { 3143 return 'Lähetyspvm puuttuu'; 3144 } 3145 3146 var parts = date.split('.'); 3147 var result = new Date(parts[2], parts[1] - 1, parts[0]); 3148 result.setDate(result.getDate() + addDays); 3149 // if result is in the past, return addDays from today 3150 var today = new Date(); 3151 if (result < today) { 3152 return 'pvm mennyt'; 3153 } 3154 return result.getDate() + '.' + (result.getMonth() + 1) + '.' + result.getFullYear(); 3155 } 3156 3157 self.addSubscription = function (type) { 3158 switch (type) { 3159 case 'review': 3160 var newSubscription = new ServiceSubscriptionVM(); 3161 newSubscription.data.company_id(self.account.company.id()); 3162 self.subscriptionDefaults.review && 3163 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.review)); 3164 self.serviceSubscriptions.review.subscriptions.push(newSubscription); 3165 break; 3166 case 'paymentTerminal': 3167 var newSubscription = new ServiceSubscriptionVM(); 3168 newSubscription.data.company_id(self.account.company.id()); 3169 self.subscriptionDefaults.payment_terminal && 3170 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.payment_terminal)); 3171 self.serviceSubscriptions.paymentTerminal.subscriptions.push(newSubscription); 3172 break; 3173 case 'accountingService': 3174 var newSubscription = new ServiceSubscriptionVM(); 3175 newSubscription.data.company_id(self.account.company.id()); 3176 self.subscriptionDefaults.accounting_service && 3177 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.accounting_service)); 3178 self.serviceSubscriptions.accountingService.subscriptions.push(newSubscription); 3179 break; 3180 case 'workShiftService': 3181 var newSubscription = new ServiceSubscriptionVM(); 3182 newSubscription.data.company_id(self.account.company.id()); 3183 self.subscriptionDefaults.work_shift_service && 3184 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.work_shift_service)); 3185 self.serviceSubscriptions.workShiftService.subscriptions.push(newSubscription); 3186 break; 3187 case 'trackingLink': 3188 var newSubscription = new ServiceSubscriptionVM(); 3189 newSubscription.data.company_id(self.account.company.id()); 3190 self.subscriptionDefaults.tracking_link && 3191 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.tracking_link)); 3192 self.serviceSubscriptions.trackingLink.subscriptions.push(newSubscription); 3193 break; 3194 case 'paymentLink': 3195 var newSubscription = new ServiceSubscriptionVM(); 3196 newSubscription.data.company_id(self.account.company.id()); 3197 self.subscriptionDefaults.payment_link && 3198 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.payment_link)); 3199 self.serviceSubscriptions.paymentLink.subscriptions.push(newSubscription); 3200 break; 3201 default: 3202 return; 3203 } 3204 }; 3205 3206 self.removeServiceSubscription = function (index, type) { 3207 self.serviceSubscriptions[type].subscriptions.splice(index, 1); 3208 }; 3209 3210 self.subscriptionDefaults = {}; 3211 3212 self.emptyServiceSubscriptions = function () { 3213 self.serviceSubscriptions.review.subscriptions([]); 3214 self.serviceSubscriptions.paymentTerminal.subscriptions([]); 3215 self.serviceSubscriptions.accountingService.subscriptions([]); 3216 self.serviceSubscriptions.workShiftService.subscriptions([]); 3217 self.serviceSubscriptions.trackingLink.subscriptions([]); 3218 self.serviceSubscriptions.paymentLink.subscriptions([]); 3219 }; 3220 3221 self.setSubscriptionData = function (subscriptions, companyId) { 3222 // first empty all models so we dont have any data from other companies 3223 self.emptyServiceSubscriptions(); 3224 3225 subscriptions.forEach(function (subscription) { 3226 //add subscriptions here 3227 switch (subscription.type) { 3228 case 'monthly_fee_sms_review': 3229 case 'monthly_fee_sms_review_nps': 3230 var newSubscription = new ServiceSubscriptionVM(); 3231 newSubscription.data.company_id(companyId); 3232 self.subscriptionDefaults.review && 3233 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.review)); 3234 newSubscription.setActiveSubscription(subscription); 3235 self.serviceSubscriptions.review.subscriptions.push(newSubscription); 3236 break; 3237 case 'monthly_fee_payment_terminal': 3238 var newSubscription = new ServiceSubscriptionVM(); 3239 newSubscription.data.company_id(companyId); 3240 self.subscriptionDefaults.payment_terminal && 3241 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.payment_terminal)); 3242 newSubscription.setActiveSubscription(subscription); 3243 self.serviceSubscriptions.paymentTerminal.subscriptions.push(newSubscription); 3244 break; 3245 case 'monthly_fee_accounting_service': 3246 var newSubscription = new ServiceSubscriptionVM(); 3247 newSubscription.data.company_id(companyId); 3248 self.subscriptionDefaults.accounting_service && 3249 newSubscription.setDefaults( 3250 Object.values(self.subscriptionDefaults.accounting_service) 3251 ); 3252 newSubscription.setActiveSubscription(subscription); 3253 self.serviceSubscriptions.accountingService.subscriptions.push(newSubscription); 3254 break; 3255 case 'monthly_fee_work_shift_service': 3256 var newSubscription = new ServiceSubscriptionVM(); 3257 newSubscription.data.company_id(companyId); 3258 self.subscriptionDefaults.work_shift_service && 3259 newSubscription.setDefaults( 3260 Object.values(self.subscriptionDefaults.work_shift_service) 3261 ); 3262 newSubscription.setActiveSubscription(subscription); 3263 self.serviceSubscriptions.workShiftService.subscriptions.push(newSubscription); 3264 break; 3265 case 'monthly_fee_tracking_link': 3266 var newSubscription = new ServiceSubscriptionVM(); 3267 newSubscription.data.company_id(companyId); 3268 self.subscriptionDefaults.tracking_link && 3269 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.tracking_link)); 3270 newSubscription.setActiveSubscription(subscription); 3271 self.serviceSubscriptions.trackingLink.subscriptions.push(newSubscription); 3272 break; 3273 case 'monthly_fee_payment_link': 3274 var newSubscription = new ServiceSubscriptionVM(); 3275 newSubscription.data.company_id(companyId); 3276 self.subscriptionDefaults.payment_link && 3277 newSubscription.setDefaults(Object.values(self.subscriptionDefaults.payment_link)); 3278 newSubscription.setActiveSubscription(subscription); 3279 self.serviceSubscriptions.paymentLink.subscriptions.push(newSubscription); 3280 break; 3281 default: 3282 return; 3283 } 3284 }); 3285 }; 3286 3287 // END OF SERVICE SUBSCRIPTIONS 3288 3289 self.openRegistryImport = function(){ 3290 var company_id = ko.toJS(self.account.company.id); 3291 var url = '/rekisterin_tuonti/' + company_id; 3292 window.open(url, '_blank'); 3293 } 3294 3295 self.getRegistryTemplate = async function(type){ 3296 var url = '/rekisterin_tuonti/getTemplate/' + type; 3297 3298 const data = await self.fetchTemplate(url); 3299 3300 if(data !== null){ 3301 self.downloadCSV(data); 3302 } 3303 } 3304 3305 self.downloadCSV = function(data) { 3306 const link = document.createElement('a'); 3307 link.href = window.URL.createObjectURL(data.blob); 3308 link.download = data.fileName; 3309 document.body.appendChild(link); 3310 link.click(); 3311 document.body.removeChild(link); 3312 } 3313 3314 self.fetchTemplate = async function(url) { 3315 3316 var $dialog = $('<div>Haetaan tietoja...</div>'); 3317 3318 $dialog.dialog({ 3319 width: 400, 3320 height: 200, 3321 title: 'Haku käynnissä', 3322 close: function (e) { 3323 e.stopPropagation(); 3324 $dialog.dialog('destroy').remove(); 3325 }, 3326 }); 3327 3328 try { 3329 const response = await fetch(url, { 3330 method: "GET" 3331 }); 3332 3333 const contentType = response.headers.get('content-type'); 3334 3335 $dialog.dialog('destroy').remove(); 3336 3337 if(contentType && contentType.includes('text/csv')){ 3338 3339 const blob = await response.blob(); 3340 const fileName = self.extractFileName(response.headers.get('Content-Disposition')); 3341 3342 return { 3343 blob: blob, 3344 fileName: fileName 3345 } 3346 } else { 3347 3348 self.errorDialog('Ei tuloksia'); 3349 return null; 3350 } 3351 3352 } catch (error) { 3353 $dialog.html('<p>Mallin luonti epäonnistui</p>'); 3354 console.log('Error!:', error); 3355 self.errorDialog(error); 3356 $dialog.dialog('close'); 3357 3358 return null; 3359 } 3360 } 3361 3362 self.errorDialog = function(error){ 3363 3364 const errorDialog = document.querySelector('.errorDialog'); 3365 3366 if(errorDialog !== null){ 3367 errorDialog.remove(); 3368 } 3369 3370 var $dialog = $('<div>' + error + '</div>'); 3371 3372 $dialog.dialog({ 3373 dialogClass: 'errorDialog', 3374 width: 200, 3375 height: 150, 3376 title: 'Haku', 3377 close: function (e) { 3378 e.stopPropagation(); 3379 $dialog.dialog('destroy').remove(); 3380 }, 3381 }); 3382 3383 } 3384 3385 self.extractFileName = function(contentDisposition) { 3386 const match = contentDisposition.match(/filename="([^"]+)"/); 3387 if (match && match[1]) { 3388 return match[1]; 3389 } 3390 return null; 3391 } 3392 3393
3394 self.selectedCategory = ko.observable(null); 3395 self.showSubcategories = (category) => self.selectedCategory(category.id()); 3396 3397 self.subCategories = ko.pureComputed(() => { 3398 return self.settings 3399 .categories() 3400 .filter((category) => category.id() === self.selectedCategory()) 3401 .map((category) => category.sub_categories()) 3402 .flat(); 3403 }); 3404 3405 self.showOrHideCategory = (category) => { 3406 jQuery 3407 .ajax({ 3408 url: 'asiakkuudet/hideOrShowCategory', 3409 method: 'post', 3410 data: { 3411 id: category.id, 3412 type: 'category', 3413 company_id: ko.toJS(self.account.company.id), 3414 }, 3415 }) 3416 .then(function (categories) { 3417 self.settings.categories.removeAll(); 3418 self.settings.categories(categories.map((c) => new Category(c))); 3419 }) 3420 .fail(function (error) { 3421 alert(error.responseJSON); 3422 }); 3423 }; 3424 3425 self.addGlAccount = () => { 3426 if (!self.settings.glAccountToAdd.gl_account()) { 3427 return alert('Tilikoodi-kenttä on tyhjä!'); 3428 } 3429 if (!self.settings.glAccountToAdd.desc()) { 3430 return alert('Selite-kenttä on tyhjä!'); 3431 } 3432 3433 var existing = self.settings.glAccounts().find((item) => { 3434 return item.gl_account == self.settings.glAccountToAdd.gl_account().trim(); 3435 }); 3436 3437 if (typeof existing !== 'undefined') { 3438 alert('Tili on jo olemassa!'); 3439 return; 3440 } 3441 3442 jQuery 3443 .ajax({ 3444 url: 'asiakkuudet/addGlAccount', 3445 method: 'post', 3446 data: { 3447 gl_account: self.settings.glAccountToAdd.gl_account(), 3448 desc: self.settings.glAccountToAdd.desc(), 3449 company_id: ko.toJS(self.account.company.id), 3450 }, 3451 }) 3452 .then(function (glAccounts) { 3453 self.settings.glAccounts(glAccounts); 3454 self.settings.glAccountToAdd.gl_account(null); 3455 self.settings.glAccountToAdd.desc(null); 3456 }) 3457 .fail(function (error) { 3458 alert(error.responseJSON); 3459 }); 3460 }; 3461 3462 self.addCategory = () => { 3463 jQuery 3464 .ajax({ 3465 url: 'asiakkuudet/addCategory', 3466 method: 'post', 3467 data: { 3468 category: self.settings.categoryToAdd(), 3469 type: 'category', 3470 company_id: ko.toJS(self.account.company.id), 3471 }, 3472 }) 3473 .then(function (categories) { 3474 self.settings.categories.removeAll(); 3475 self.settings.categories(categories.map((c) => new Category(c))); 3476 self.settings.categoryToAdd(null); 3477 }) 3478 .fail(function (error) { 3479 alert(error.responseJSON); 3480 }); 3481 }; 3482 3483 self.showOrHideSubCategory = (subCategory) => { 3484 jQuery 3485 .ajax({ 3486 url: 'asiakkuudet/hideOrShowCategory', 3487 method: 'post', 3488 data: { 3489 id: subCategory.id, 3490 type: 'sub_category', 3491 company_id: ko.toJS(self.account.company.id), 3492 }, 3493 }) 3494 .then(function (categories) { 3495 self.settings.categories.removeAll(); 3496 self.settings.categories(categories.map((c) => new Category(c))); 3497 }) 3498 .fail(function (error) { 3499 alert(error.responseJSON); 3500 }); 3501 }; 3502 3503 self.addSubCategory = () => { 3504 jQuery 3505 .ajax({ 3506 url: 'asiakkuudet/addCategory', 3507 method: 'post', 3508 data: { 3509 category: self.settings.subCategoryToAdd(), 3510 type: 'sub_category', 3511 company_id: ko.toJS(self.account.company.id), 3512 category_id: self.selectedCategory(), 3513 }, 3514 }) 3515 .then(function (categories) { 3516 self.settings.categories.removeAll(); 3517 self.settings.categories(categories.map((c) => new Category(c))); 3518 self.settings.subCategoryToAdd(null); 3519 }) 3520 .fail(function (error) { 3521 alert(error.responseJSON); 3522 }); 3523 }; 3524 3525 self.userShiftGroupSettings = ko.pureComputed(function () { 3526 return [ 3527 { 3528 id: null, 3529 group_name: 'Ei kytketty', 3530 }, 3531 ].concat(self.settings.shiftGroupSettings().filter((s) => Boolean(s.id()))); 3532 }); 3533 3534 self.isWorkerGroup = function (groupId) { 3535 groupId = groupId && !Number.isInteger(groupId) ? parseInt(groupId) : groupId; 3536 return ( 3537 self.usergroups.filter(function (group) { 3538 return group.id === groupId && group.role === 'worker'; 3539 }).length > 0 3540 ); 3541 }; 3542 3543 self.disableUserGroupChange = function(user){ 3544 3545 if( ! user.id()){ 3546 return false;
3547 } 3548 3549 //If user is related to many companies, a change in user group would change the group in all related companies 3550 //Prevent this from happening 3551 if( ko.toJS(user.related_company_ids).length > 1){ 3552 return true; 3553 } 3554 3555 if(self.isWorkerGroup(user.usergroup_id())){ 3556 return true; 3557 } 3558 3559 return false; 3560 } 3561 3562 self.getRole = function (groupId) { 3563 return self.usergroups 3564 .filter(function (group) { 3565 return group.id === groupId; 3566 }) 3567 .map(function (obj) { 3568 return obj.role; 3569 }); 3570 }; 3571 3572 self.smsInvoicingFeeOptions = [ 3573 { value: false, label: 'Ei käytössä' }, 3574 { value: true, label: 'Käytössä' }, 3575 ]; 3576 3577 self.notificationMethods = [ 3578 { value: 'disabled', label: 'Ãlä lähetä' }, 3579 { value: 'email', label: 'Sähköposti' }, 3580 { value: 'sms', label: 'SMS' }, 3581 ]; 3582 3583 self.towingNotifications = { 3584 stations: ko.observableArray([]), 3585 jobTypes: ko.observableArray([]), 3586 availableStations: ko.pureComputed(function () { 3587 return self.account.stations().filter(function (value) { 3588 return value.type() === 1 || value.type() === 2; 3589 }); 3590 }), 3591 availableJobTypes: ko.pureComputed(function () { 3592 var jobTypes = ko.toJS(self.settings.towingRecordTypes); 3593 jobTypes = jobTypes.filter((type) => type.deleted_at === null); 3594 jobTypes = jobTypes.map(function (type) { 3595 return { id: type.type, type: type.type }; 3596 }); 3597 3598 if (jobTypes.length === 0) { 3599 ['A', 'B', 'C'].forEach(function (type) { 3600 jobTypes.push({ id: type, type: type }); 3601 }); 3602 } 3603 3604 jobTypes.unshift({ id: null, type: 'Tyhjä' }); 3605 3606 if (self.account.company.mod_assistance()) { 3607 jobTypes.unshift({ id: 'AL', type: 'AL' }); 3608 } 3609 3610 return jobTypes; 3611 }), 3612 }; 3613 3614 // Dimension related observables 3615 self.dimensionIdToAdd = ko.observable(); 3616 self.dimensionTypeOptions = [ 3617 { type: 'station', label: 'Toimipiste (Station)' }, 3618 { type: 'customer', label: 'Asiakas (Customer)'} 3619 ]; 3620 3621 self.dimensionTypeToAdd = ko.observable('station'); 3622 self.dimensionNameToAdd = ko.observable(); 3623 self.dimensions = ko.observableArray(); 3624 self.addDimensionItem = ko.observable(false); 3625 self.addDimension = ko.observable(false); 3626 3627 self.setDimensions = function(dimensions){ 3628 3629 self.dimensions([]); 3630 3631 console.log('setDimensions:', dimensions); 3632 3633 if( ! dimensions){ 3634 console.log('No dimensions to set'); 3635 return; 3636 } 3637 3638 dimensions.forEach(function(dimension){ 3639 self.addProcountorDimension(dimension); 3640 }) 3641 }; 3642 3643 self.dimensions.subscribe(function (dimensions) { 3644 console.log('self.dimensions changed, dimensions:', dimensions); 3645 }); 3646 3647 self.dimensionItemIdToAdd = ko.observable(); 3648 self.dimensionItemNameToAdd = ko.observable(); 3649 self.dimensionItemIvIdToAdd = ko.observable(); 3650 3651 self.dimensionToEdit = ko.observable(); 3652 3653 self.newLogItem = ko.observable(); 3654 3655 // SMS review system related observables 3656 self.reviewData = { 3657 jobTypes: ko.observableArray([]), 3658 availableJobTypes: ko.observableArray([]), 3659 towingRecordJobTypes: ko.observableArray([]), 3660 freightJobTypes: ko.observableArray([]), 3661 jobOrderJobTypes: ko.observableArray([]), 3662 stationSetting: ko.observable(), 3663 messageType: ko.observable(), 3664 message: ko.observable(), 3665 userStatistics: ko.observable(), 3666 settings: ko.observableArray([]), 3667 npsMessage: ko.pureComputed(function () { 3668 return 'Kiitos kun käytit palveluitamme! Asteikolla 0-10, kuinka todennäköisesti suosittelisit meitä ystävälle tai työtoverille? T. '; 3669 }), 3670 ownMessage: ko.pureComputed(function () { 3671 return 'Kiitos kun käytit palveluitamme! Palautteesi on meille tärkeää. Asteikolla 0-10, kuinka tyytyväinen olit saamaasi palveluun? T. '; 3672 }), 3673 }; 3674 3675 self.addLogItem = function () { 3676 var companyId = ko.toJS(self.account.company.id), 3677 event = ko.toJS(self.newLogItem); 3678 3679 if (!event) return global.show_message({ type: 'error', text: 'Lokimerkintä on tyhjä' }); 3680 3681 jQuery 3682 .ajax({ 3683 url: '/asiakkuudet/add_log_item/' + companyId, 3684 dataType: 'json', 3685 data: { 3686 event: event, 3687 }, 3688 type: 'post', 3689 }) 3690 3691 .done(function (responseJSON) { 3692 self.account.logs.unshift(responseJSON.data.logItem); 3693 self.newLogItem(''); 3694 }) 3695 .fail(function (response) { 3696 global.show_message(response.responseJSON); 3697 }); 3698 }; 3699 3700 self.deleteLogItem = function (logItem) { 3701 if (window.confirm('Haluatko varmasti poistaa lokimerkinnän?')) { 3702 var id = ko.toJS(logItem.id); 3703 3704 $.ajax({ 3705 url: '/asiakkuudet/delete_log_item/' + id, 3706 type: 'POST', 3707 }) 3708 .done(function (responseJSON) { 3709 self.account.logs.remove(function (item) { 3710 return ko.toJS(item.id) == responseJSON.data.deletedLogItem.id; 3711 }); 3712 }) 3713 .fail(function (response) { 3714 global.show_message(response.responseJSON); 3715 }); 3716 } 3717 }; 3718 3719 self.removeCompanyRestriction = function(type){ 3720 self.companyRestrictions.deleteRestrictions(type, self.setData) 3721 } 3722 3723 self.unselectTag = function (tag) { 3724 self.account.tags.remove(tag); 3725 }; 3726 3727 self.showExtraUserSettings = function () { 3728 self.showUserExtraOptions(!self.showUserExtraOptions()); 3729 }; 3730 3731 self.selectTag = function (tag) { 3732 self.account.tags.push(tag); 3733 }; 3734 3735 self.station = function () { 3736 return { 3737 id: ko.observable(), 3738 name: ko.observable(), 3739 short_name: ko.observable(), 3740 type: ko.observable(), 3741 address: ko.observable(), 3742 zipcode: ko.observable(), 3743 city: ko.observable(), 3744 accept_autoliitto_orders: ko.observable(), 3745 autoliitto_id: ko.observable(), 3746 autoliitto_phone: ko.observable(), 3747 autoliitto_email: ko.observable(), 3748 accept_sos_orders: ko.observable(false), 3749 email_notifications: ko.observable(), 3750 lahitapiola_direct_contract: ko.observable(false), 3751 sos_phone: ko.observable(), 3752 sos_call_robot_open_order: ko.observable(false), 3753 sos_call_robot_order_cancelled: ko.observable(false), 3754 sos_call_robot_use_ivr: ko.observable(false), 3755 sos_call_robot_open_order_phone: ko.observable(), 3756 sos_email: ko.observable(), 3757 coords_lat: ko.observable(), 3758 coords_long: ko.observable(), 3759 telegram_notifications: ko.observable(false), 3760 telegram_chat_id: ko.observable(), 3761 telegram_notifications_order_pending_acceptance: ko.observable(false), 3762 telegram_notifications_open_order: ko.observable(false), 3763 telegram_notifications_order_cancelled: ko.observable(true), 3764 ava_integration: ko.observable(false), 3765 urent_phone: ko.observable(), 3766 urent_call_robot_open_order: ko.observable(), 3767 urent_call_robot_order_cancelled: ko.observable(), 3768 urent_call_robot_use_ivr: ko.observable(), 3769 // @ai:claude Which provider receives incoming Autoliitto replacement car orders for this station. 3770 replacement_car_provider: ko.observable() 3771 }; 3772 }; 3773 3774 self.sendAutoliittoTestJob = function(station, jobType) { 3775 var station = ko.toJS(station); 3776 3777 if (!station.autoliitto_id) 3778 return alert('Autoliitto ID:tä ei ole täytetty, testikeikkaa ei voida lähettää'); 3779 3780 self.confirmSendTestJob(station, 'autoliitto', jobType); 3781 }; 3782 3783 self.sendLahiTapiolaTestJob = function (station) { 3784 var station = ko.toJS(station); 3785 3786 if (!station.autoliitto_id) 3787 return alert('Autoliitto ID:tä ei ole täytetty, testikeikkaa ei voida lähettää'); 3788 3789 self.confirmSendTestJob(station, 'lahitapiola'); 3790 }; 3791 3792 self.sendSosTestJob = function (station) { 3793 var station = ko.toJS(station); 3794 3795 if (!station.accept_sos_orders) 3796 return alert( 3797 'Toimipistettä ei ole merkitty vastaanottamaan SOS-tilauksia, testikeikkaa ei voida lähettää' 3798 ); 3799 3800 self.confirmSendTestJob(station, 'sos'); 3801 }; 3802 3803 self.sendUrentTestJob = function (station) { 3804 var station = ko.toJS(station); 3805 self.confirmSendTestJob(station, 'urent'); 3806 } 3807 3808 self.sendStationTestMessage = function (station, notificationChannel) { 3809 var station = ko.toJS(station); 3810 3811 self.confirmSendTestMessage(station, notificationChannel); 3812 }; 3813 3814 self.addStation = function (data) { 3815 var station = self.station(); 3816 self.account.stations.push(station); 3817 }; 3818 3819 self.removeStation = function (station) { 3820 // If existing user, confirm the removal 3821 if (station.id()) { 3822 return self.confirmRemoveStation(station); 3823 } 3824 3825 self.account.stations.remove(station); 3826 }; 3827 3828 self.confirmSendTestJob = function(station, orderOrigin, jobType) { 3829 3830 var url; 3831 3832 if(orderOrigin === 'autoliitto') 3833 url = '/tilaukset/new_autoliitto_test_job'; 3834 3835 if(orderOrigin === 'sos') 3836 url = '/tilaukset/new_sos_test_job'; 3837 3838 if(orderOrigin === 'lahitapiola') 3839 url = '/tilaukset/new_lahitapiola_test_job'; 3840 3841 if(orderOrigin === 'urent') 3842 url = '/tilaukset/new_urent_test_job'; 3843 3844 var $dialog = $('<div />') 3845 .html( 3846 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti lähettää testikeikan asiakkaalle?</p>' 3847 ) 3848 .dialog({ 3849 resizable: false, 3850 height: 200, 3851 width: 400, 3852 title: 'Vahvista testikeikan lähetys', 3853 modal: true, 3854 buttons: { 3855 Ei: function() { 3856 $(this).dialog('close'); 3857 }, 3858 Kyllä: function() { 3859 3860 jQuery 3861 .ajax({ 3862 url: url, 3863 data: { 3864 stationId: station.id, 3865 jobType: jobType 3866 }, 3867 type: 'post', 3868 dataType: 'json', 3869 "beforeSend":function(request){ 3870 $dialog.dialog({ 3871 width:400, 3872 height:200, 3873 modal:true, 3874 resizable:false, 3875 title:'Lähetetään testikeikkaa', 3876 close: function(){ 3877 $dialog.dialog('destroy'); 3878 } 3879 }); 3880 3881 global.show_ajax_loader($dialog); 3882 }, 3883 }) 3884 .done(function (responseJSON) { 3885 $dialog.dialog('close'); 3886 global.show_message(responseJSON); 3887 }) 3888 .fail(function (response) { 3889 global.show_message(response.responseJSON); 3890 }) 3891 .always(function () { 3892 global.close_loading_dialog(); 3893 }); 3894 }, 3895 }, 3896 }); 3897 }; 3898 3899 self.confirmSendTestMessage = function (station, notificationChannel) { 3900 var $dialog = $('<div />') 3901 .html( 3902 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>
3902Haluatko varmasti lähettää testiviestin toimipisteelle?</p>' 3903 ) 3904 .dialog({ 3905 resizable: false, 3906 height: 200, 3907 width: 400, 3908 title: 'Vahvista testiviestin lähetys', 3909 modal: true, 3910 buttons: { 3911 Ei: function () { 3912 $(this).dialog('close'); 3913 }, 3914 Kyllä: function () { 3915 jQuery 3916 .ajax({ 3917 url: '/asiakkuudet/send_station_test_message', 3918 data: { 3919 stationId: station.id, 3920 notificationChannel: notificationChannel, 3921 }, 3922 type: 'post', 3923 dataType: 'json', 3924 beforeSend: function (request) { 3925 $dialog.dialog({ 3926 width: 400, 3927 height: 200, 3928 modal: true, 3929 resizable: false, 3930 title: 'Lähetetään testiviestiä', 3931 close: function () { 3932 $dialog.dialog('destroy'); 3933 }, 3934 }); 3935 3936 global.show_ajax_loader($dialog); 3937 }, 3938 }) 3939 .done(function (responseJSON) { 3940 global.show_message(responseJSON); 3941 }) 3942 .fail(function (response) { 3943 global.show_message(response.responseJSON); 3944 }) 3945 .always(function () { 3946 $dialog.dialog('close'); 3947 }); 3948 }, 3949 }, 3950 }); 3951 }; 3952 3953 self.getBlockMoneyTransferReason = function () { 3954 var checked = self.account.company.block_money_transfer(); 3955 var type = checked ? 'asetuksen' : 'poiston'; 3956 var kycText = checked ? 'KYC suorittamatta' : 'KYC suoritettu' 3957 var dialogInput = $('<input />', { 3958 type: 'text', 3959 name: 'transfer_block_reason', 3960 id: 'transfer_block_reason', 3961 class: 'text form-control medium', 3962 style: 'border-top-right-radius: 0; border-bottom-right-radius: 0;' 3963 }); 3964 var kycButton = $('<button />', { 3965 text: 'KYC', 3966 type: 'button', 3967 class: 'btn btn-default', 3968 click: function() { 3969 $('#transfer_block_reason').val(kycText); 3970 }, 3971 style: 'height: 34px; border-top-left-radius: 0; border-bottom-left-radius: 0;' 3972 }); 3973 3974 var $dialog = $('<div />') 3975 .html('<p style="font-weight:bold;">Tilitysten eston ' + type + ' syy:</p>') 3976 .append(dialogInput) 3977 .append(kycButton) 3978 .dialog({ 3979 resizable: false, 3980 height: 200, 3981 width: 400, 3982 title: 'Tilitysten esto', 3983 modal: true, 3984 buttons: { 3985 Peruuta: function () { 3986 $(this).dialog('close'); 3987 }, 3988 Lisää: function () { 3989 var reason = $(this).find('#transfer_block_reason').val(); 3990 if (reason && reason !== '') { 3991 var logMessage = checked 3992 ? 'Tilitysten eston asetus: ' + reason 3993 : 'Tilitysten eston poisto: ' + reason; 3994 self.moneyTransferBlockReason(logMessage); 3995 $(this).dialog('close'); 3996 } else { 3997 global.show_message({ 3998 type: 'error', 3999 text: 'Tilitysten eston ' + type + ' syy puuttuu', 4000 }); 4001 } 4002 }, 4003 }, 4004 close: function () { 4005 //var reason = $(this).find('#transfer_block_reason').val(); 4006 if ( 4007 self.moneyTransferBlockReason() === '' && 4008 self.account.company.block_money_transfer() != self.BlockMoneyTransferOld() 4009 ) { 4010 self.account.company.block_money_transfer(self.BlockMoneyTransferOld()); 4011 } 4012 $(this).dialog('destroy').remove(); 4013 }, 4014 }); 4015 }; 4016 4017 self.confirmRemoveStation = function (station) { 4018 var $dialog = $('<div />') 4019 .html( 4020 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen hinausyksikön?</p>' 4021 ) 4022 .dialog({ 4023 resizable: false, 4024 height: 200, 4025 width: 400, 4026 title: 'Poista hinausyksikkö', 4027 modal: true, 4028 buttons: { 4029 Ei: function () { 4030 $(this).dialog('close'); 4031 }, 4032 Kyllä: function () { 4033 jQuery 4034 .ajax({ 4035 url: '/asiakkuudet/delete_station/' + station.id(), 4036 type: 'post', 4037 dataType: 'json', 4038 }) 4039 .done(function (responseJSON) { 4040 self.account.stations.remove(station); 4041 $dialog.dialog('close'); 4042 global.show_message(responseJSON); 4043 4044 // If this company has reviews enabled and they're using own settings for each station, we should delete
4045 // those settings too 4046 if (self.account.company.mod_review() && self.reviewData.stationSetting() == 1) 4047 self.deleteStationSettings(station.id()); 4048 }) 4049 .fail(function (response) { 4050 global.show_message(response.responseJSON); 4051 global.close_loading_dialog(); 4052 }); 4053 }, 4054 }, 4055 }); 4056 }; 4057 4058 var modifyTypeDataOnServer = function (data) { 4059 var action = data.action; 4060 4061 jQuery 4062 .ajax({ 4063 url: 'asiakkuudet/modifyTypeData', 4064 data: data, 4065 }) 4066 .done(function (data) { 4067 self.settings.towingRecordTypes( 4068 self.settings.towingRecordTypes().map(function (type) { 4069 return type.id === data.id ? data : type; 4070 }) 4071 ); 4072 4073 if (action === 'disable') { 4074 self.reviewData.availableJobTypes.remove(function (item) { 4075 return item.id === 'kk' + data.id; 4076 }); 4077 self.reviewData.jobTypes.remove(function (item) { 4078 return item.id === 'kk' + data.id; 4079 }); 4080 } else { 4081 self.reviewData.availableJobTypes.push({ 4082 id: 'kk' + data.id, 4083 label: data.type + ' (IH)', 4084 }); 4085 } 4086 }); 4087 }; 4088 4089 var modifyFreightTypeDataOnServer = function (data) { 4090 var action = data.action; 4091 4092 jQuery 4093 .ajax({ 4094 url: 'asiakkuudet/modifyFreightTypeData', 4095 data: data, 4096 }) 4097 .done(function (data) { 4098 self.settings.freightTypes( 4099 self.settings.freightTypes().map(function (type) { 4100 return type.id === data.id ? data : type; 4101 }) 4102 ); 4103 4104 if (action === 'disable') { 4105 self.reviewData.availableJobTypes.remove(function (item) { 4106 return item.id === 'rk' + data.id; 4107 }); 4108 self.reviewData.jobTypes.remove(function (item) { 4109 return item.id === 'rk' + data.id; 4110 }); 4111 } else { 4112 self.reviewData.availableJobTypes.push({ 4113 id: 'rk' + data.id, 4114 label: data.type + ' (IR)', 4115 }); 4116 } 4117 }); 4118 }; 4119 4120 var modifyJobOrderTypeDataOnServer = function (data) { 4121 jQuery 4122 .ajax({ 4123 url: 'asiakkuudet/modifyJobOrderTypeData', 4124 data: data, 4125 }) 4126 .done(function (data) { 4127 self.settings.jobOrderTypes( 4128 self.settings.jobOrderTypes().map(function (name) { 4129 return name.id === data.id ? data : name; 4130 }) 4131 ); 4132 }); 4133 }; 4134 4135 var modifyResourceOnServer = function (data) { 4136 jQuery 4137 .ajax({ 4138 url: 'asiakkuudet/modifyResources', 4139 data: data, 4140 }) 4141 .done(function (data) { 4142 self.settings.resources( 4143 self.settings.resources().map(function (name) { 4144 return name.id === data.id ? data : name; 4145 }) 4146 ); 4147 }); 4148 }; 4149 4150 var modifyDepotsOnServer = function (data) { 4151 jQuery 4152 .ajax({ 4153 url: 'asiakkuudet/modifyDepots', 4154 data: data, 4155 }) 4156 .done(function (data) { 4157 self.settings.depots( 4158 self.settings.depots().map(function (name) { 4159 return name.id === data.id ? data : name; 4160 }) 4161 ); 4162 }); 4163 }; 4164 4165 var modifyAgreementOnServer = function (data) { 4166 jQuery 4167 .ajax({ 4168 url: 'asiakkuudet/modifyAgreement', 4169 data: data, 4170 }) 4171 .done(function (data) { 4172 if (data.type === 'default') { 4173 self.settings.agreements( 4174 self.settings.agreements().map(function (agreement) { 4175 return agreement.id === data.id ? data : agreement; 4176 }) 4177 ); 4178 } 4179 if (data.type === 'innokorjaamo') { 4180 self.settings.agreements_innokorjaamo( 4181 self.settings.agreements_innokorjaamo().map(function (agreement) { 4182 return agreement.id === data.id ? data : agreement; 4183 }) 4184 ); 4185 } 4186 }); 4187 }; 4188 4189 self.insertTypeData = function () { 4190 var data = ko.toJS(self.account.company); 4191 data.typeToAdd = self.settings.typeToAdd(); 4192 4193 jQuery 4194 .ajax({ 4195 url: 'asiakkuudet/addTypeData', 4196 data: data, 4197 }) 4198 .done(function (data) { 4199 self.settings.towingRecordTypes.push(data); 4200 self.reviewData.availableJobTypes.push({ id: 'kk' + data.id, label: data.type + ' (IH)' }); 4201 self.settings.typeToAdd(''); 4202 }); 4203 }; 4204 4205 self.insertFreightTypeData = function () { 4206 var data = ko.toJS(self.account.company); 4207 data.freightTypeToAdd = self.settings.freightTypeToAdd(); 4208 4209 jQuery 4210 .ajax({ 4211 url: 'asiakkuudet/addFreightTypeData', 4212 data: data, 4213 }) 4214 .done(function (data) { 4215 self.settings.freightTypes.push(data); 4216 self.reviewData.availableJobTypes.push({ id: 'rk' + data.id, label: data.type + ' (IR)' }); 4217 self.settings.freightTypeToAdd(''); 4218 }); 4219 }; 4220 4221 self.insertJobOrderTypeData = function () { 4222 var data = ko.toJS(self.account.company); 4223 data.jobOrderTypeToAdd = self.settings.jobOrderTypeToAdd(); 4224 4225 jQuery 4226 .ajax({ 4227 url: 'asiakkuudet/addJobOrderTypeData', 4228 data: data, 4229 }) 4230 .done(function (data) { 4231 self.settings.jobOrderTypes.push(data); 4232 self.settings.jobOrderTypeToAdd(''); 4233 }); 4234 }; 4235 4236 self.insertAgreement = function (type) { 4237 var data = ko.toJS(self.account.company); 4238 data.agreementToAdd = self.settings.agreementToAdd(); 4239 data.type = type 4240 jQuery 4241 .ajax({ 4242 url: 'asiakkuudet/addAgreeement', 4243 data: data, 4244 }) 4245 .done(function (data) { 4246 if (data.type === 'default') { 4247 self.settings.agreements.push(data); 4248 } 4249 if (data.type === 'innokorjaamo') { 4250 self.settings.agreements_innokorjaamo.push(data); 4251 } 4252 }).always(function() { 4253 self.settings.agreementToAdd(''); 4254 }); 4255 }; 4256 4257 self.insertResource = function () { 4258 var companyId = self.account.company.id(); 4259 var resource = self.settings.resourceToAdd.resource(); 4260 var extId = self.settings.resourceToAdd.ext_id(); 4261 4262 jQuery 4263 .ajax({ 4264 method: 'post', 4265 url: 'asiakkuudet/addResource', 4266 data: { 4267 company_id: companyId, 4268 resource: resource, 4269 ext_id: extId, 4270 }, 4271 }) 4272 .done(function (data) { 4273 self.settings.resources.push(data); 4274 self.settings.resourceToAdd.resource(null); 4275 self.settings.resourceToAdd.ext_id(null); 4276 }); 4277 }; 4278 4279 self.insertDepots = function () { 4280 var data = ko.toJS(self.account.company); 4281 data.depotToAdd = self.settings.depotToAdd(); 4282 jQuery 4283 .ajax({ 4284 url: 'asiakkuudet/addDepots', 4285 data: data, 4286 }) 4287 .done(function (data) { 4288 self.settings.depots.push(data); 4289 self.settings.depotToAdd(''); 4290 }); 4291 }; 4292 4293 self.addProcountorDimension = function (dimensionParam) { 4294 4295 console.log('addProcountorDimension:', dimensionParam); 4296 4297 if( ! dimensionParam){ 4298 dimensionParam = { 4299 id: '', 4300 name: '', 4301 type: 'station', 4302 isEditable: true 4303 }; 4304 } 4305 4306 var dimension = { 4307 type: ko.observable(dimensionParam.type), 4308 id: ko.observable(dimensionParam.id), 4309 name: ko.observable(dimensionParam.name), 4310 items: ko.observableArray( []), 4311 isEditable: ko.observable(dimensionParam.isEditable), 4312 showItems: ko.observable(true), 4313 4314 toggleShowItems: function(){ 4315 dimension.showItems( ! dimension.showItems()); 4316 }, 4317 edit: function(){ 4318 dimension.isEditable(true) 4319 }, 4320 delete: function(){ 4321 4322 console.log('dimension.delete called'); 4323 4324 if(dimension.id()){ 4325 dimension.confirmDelete(); 4326 }else { 4327 self.dimensions.remove(dimension); 4328 } 4329 }, 4330 confirmDelete: function () { 4331 4332 var $dialog = $('<div />') 4333 .html( 4334 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa dimension?</p>' 4335 ) 4336 .dialog({ 4337 resizable: false, 4338 height: 200, 4339 width: 400, 4340 title: 'Poista Dimensio', 4341 modal: true, 4342 buttons: { 4343 Ei: function () { 4344 $(this).dialog('close'); 4345 }, 4346 Kyllä: function () { 4347 self.dimensions.remove(dimension); 4348 $(this).dialog('close'); 4349 }, 4350 }, 4351 }); 4352 }, 4353 removeItem: function(item){ 4354 4355 console.log('removeItem:', item); 4356 4357 if (item.itemId) { 4358 return dimension.confirmRemoveDimensionItem(item); 4359 }else { 4360 dimension.items.remove(item); 4361 } 4362 }, 4363 confirmRemoveDimensionItem: function (item) { 4364 4365 console.log('confirmRemoveDimensionItem:', item); 4366 4367 var itemName = ko.toJS(item.itemName); 4368 4369 var $dialog = $('<div />') 4370 .html( 4371 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa dimensioarvon ' + 4372 itemName +
4373 '?</p>' 4374 ) 4375 .dialog({ 4376 resizable: false, 4377 height: 200, 4378 width: 400, 4379 title: 'Poista Dimensioarvo', 4380 modal: true, 4381 buttons: { 4382 Ei: function () { 4383 $(this).dialog('close'); 4384 }, 4385 Kyllä: function () { 4386 4387 dimension.items.remove(item); 4388 $(this).dialog('close'); 4389 }, 4390 }, 4391 }); 4392 }, 4393 accept: function(){ 4394 dimension.isEditable(false); 4395 self.addDimension(false); 4396 }, 4397 setItems: function (items) { 4398 4399 dimension.items([]); 4400 4401 console.log('setItems:', items); 4402 4403 if( ! items){ 4404 console.log('No items to set'); 4405 return; 4406 } 4407 4408 items.forEach(function(item){ 4409 dimension.addItem(item); 4410 }) 4411 }, 4412 addItem: function(item){ 4413 4414 var item = { 4415 itemIvId: ko.observable(ko.toJS(item.itemIvId) || ''), 4416 itemId: ko.observable(ko.toJS(item.itemId) || ''), 4417 itemName: ko.observable(ko.toJS(item.itemName) || '') 4418 } 4419 4420 dimension.items.push(item); 4421 } 4422 }; 4423 4424 if(dimensionParam){ 4425 dimension.setItems(dimensionParam.items); 4426 } 4427 4428 4429 console.log('before self.dimensions.push:', dimension); 4430 4431 self.dimensions.push(dimension); 4432 self.addDimension(true); 4433 } 4434 4435 self.incidentInpection = function () { 4436 var data = ko.toJS(self.account.company), 4437 companyId = data.id, 4438 controllerName = data.incident_inspection_controller_name, 4439 controllerIdentifier = data.incident_inspection_controller_identifier; 4440 4441 self.company.incident_inspection_controller_name = ko.observable(); 4442 self.company.incident_inspection_controller_identifier = ko.observable(); 4443 4444 controllerName = self.settings.incident_inspection_controller_name; 4445 controllerIdentifier = self.settings.incident_inspection_controller_identifier; 4446 4447 jQuery 4448 .ajax({ 4449 url: 'asiakkuudet/addIncidentInspection /' + companyId, 4450 data: { controller_name: controllerName, controller_identifier: controllerIdentifier }, 4451 }) 4452 .done(function (data) { 4453 self.settings.push(data); 4454 }); 4455 }; 4456 4457 self.deleteSmsTemplate = function (id) { 4458 if (!id) { 4459 return self.settings.sms_templates.remove(this); 4460 } 4461 var ok = window.confirm('Haluatko varmasti poistaa SMS viestipohjan?'); 4462 if (!ok) { 4463 return; 4464 } 4465 jQuery.ajax({ 4466 method: 'post', 4467 url: '/asiakkuudet/deleteSmsTemplate', 4468 data: { 4469 company_id: self.account.company.id(), 4470 id: id, 4471 } 4472 }).then((resp) => { 4473 self.settings.sms_templates.remove(this) 4474 }).fail((resp) => { 4475 var msg = resp.responseJSON || 'Palvelinvirhe: Viestipohjan poisto epäonnistui'; 4476 global.show_message({ type: 'error', text: msg }); 4477 }); 4478 }; 4479 4480 self.addSmsTemplate = function () { 4481 self.settings.sms_templates.push({ 4482 id: ko.observable(null), 4483 title: ko.observable(''), 4484 timing: ko.observable('+0 day'), 4485 trigger: ko.observable(null), 4486 template: ko.observable(''), 4487 }); 4488 }; 4489 4490 self.modifyAgreementData = function (action, agreement) { 4491 agreement.action = action; 4492 return modifyAgreementOnServer(agreement); 4493 }; 4494 4495 self.modifyTypeData = function (action, type) { 4496 type.action = action; 4497 return modifyTypeDataOnServer(type); 4498 }; 4499 4500 self.modifyFreightTypeData = function (action, type) { 4501 type.action = action; 4502 return modifyFreightTypeDataOnServer(type); 4503 }; 4504 4505 self.modifyJobOrderTypeData = function (action, type) { 4506 type.action = action; 4507 return modifyJobOrderTypeDataOnServer(type); 4508 }; 4509 4510 self.modifyDepots = function (action, name) { 4511 name.action = action; 4512 return modifyDepotsOnServer(name); 4513 }; 4514 4515 self.modifyResource = function (action, name) { 4516 name.action = action; 4517 4518 return modifyResourceOnServer(name); 4519 }; 4520 4521 self.companyGroupSettings = { 4522 companyGroupId: ko.observable(), 4523 }; 4524 4525 self.companyGroups = [ 4526 { value: null, text: 'Ei kuulu yritysryhmään' }, 4527 { value: 1, text: 'Autoklinikka' }, 4528 ]; 4529 4530 self.corporateChains = [ 4531 { value: '', text: 'Ei kuulu ketjuun' }, 4532 { value: 'Autoasi', text: 'Autoasi' }, 4533 { value: 'Autonomi', text: 'Autonomi' }, 4534 { value: 'Autoklinikka', text: 'Autoklinikka' }, 4535 { value: 'Autoklinikka partneri', text: 'Autoklinikka partneri' }, 4536 { value: 'Fixus', text: 'Fixus' }, 4537 { value: 'Awux', text: 'Awux' }, 4538 { value: 'KL', text: 'KL' }, 4539 { value: 'Motonet', text: 'Motonet' }, 4540 { value: 'Scandia Rent', text: 'Scandia Rent' }, 4541 { value: '123 Tuulilasi', text: '123 Tuulilasi' }, 4542 { value: 'Autoliitto', text: 'Autoliitto' }, 4543 { value: 'AL tiepalvelu', text: 'AL tiepalvelu' }, 4544 { value: 'Menevä', text: 'Menevä' }, 4545 { value: 'Vaurioturva', text: 'Vaurioturva' }, 4546 ]; 4547 4548 self.themes = [ 4549 { value: 'default', text: 'Innovoice' }, 4550 { value: 'tuulilasi', text: '123 Tuulilasi' }, 4551 { value: 'scandia', text: 'Scandia Rent' }, 4552 { value: 'fixus', text: 'Fixus' }, 4553 { value: 'awux', text: 'Awux' }, 4554 { value: 'motonet', text: 'Motonet' }, 4555 { value: 'vaurioturva', text: 'Vaurioturva' }, 4556 ]; 4557 4558 self.invoiceDeliveryMethods = [ 4559 { value: 'e_invoice', text: 'Verkkolasku' }, 4560 { value: 'email', text: 'Sähköpostitse' }, 4561 { value: 'mail', text: 'Postitse' }, 4562 ]; 4563 4564 self.vatBases = [0, 10, 13.5, 14, 25.5]; 4565 4566 self.companyFinancingPaymentTerms = [ 4567 { text: '14pv netto', value: '14_days_net' }, 4568 { text: '30pv netto', value: '30_days_net' }, 4569 ]; 4570 4571 self.consumerFinancingPaymentTerms = [ 4572 { text: '14pv netto', value: '14_days_net' }, 4573 { text: '30pv netto', value: '30_days_net' }, 4574 ]; 4575 4576 self.accountingServices = [ 4577 { value: '', text: 'Ei kirjanpitosovellusta' }, 4578 { value: 'procountor', text: 'Procountor' }, 4579 { value: 'netvisor', text: 'Netvisor' }, 4580 ]; 4581 4582 self.invoiceSendingFrequencies = [ 4583 { value: 'daily', text: 'Kerran päivässä' }, 4584 { value: 'weekly', text: 'Kerran viikossa' }, 4585 { value: 'monthly', text: 'Kerran kuukaudessa' }, 4586 ]; 4587 4588 self.account = null; 4589 self.logoBase64 = ko.observable(''); 4590 4591 self.copyValue = function (target, value) { 4592 // If the target field is empty, copy the value to it 4593 if (!target()) { 4594 target(value); 4595 } 4596 }; 4597 self.BlockMoneyTransferOld = ko.observable(); 4598 self.moneyTransferBlockReason = ko.observable(''); 4599 self.setBlockMoneyTransfer = function () { 4600 if (self.account.company.id()) { 4601 self.getBlockMoneyTransferReason(); 4602 } 4603 }; 4604 4605 self.setData = function (data) { 4606 self.setSettingsData(data); 4607 4608 if (typeof data.static !== 'undefined') { 4609 self.setStaticData(data.static); 4610 } 4611 self.setAccountData(data.account); 4612 if (typeof data.logItem !== 'undefined') { 4613 self.account.logs.unshift(data.logItem); 4614 } 4615 self.reviewData.settings([]); 4616 4617 if (data.account.company.mod_review === true) self.setReviewData(data); 4618 if (data.paymentTerminalDevices) { 4619 self.paymentTerminalDevices(data.paymentTerminalDevices); 4620 } 4621 4622 if(data.followUpSettings){ 4623 self.populateFollowUpSettings(data.followUpSettings); 4624 }else{ 4625 self.resetFollowUpSettings(); 4626 } 4627 4628 if(data.defaultFollowUpSmsTemplate){ 4629 self.defaultFollowUpSmsTemplate(data.defaultFollowUpSmsTemplate); 4630 } 4631 4632 if (typeof data.subscriptionDefaults !== 'undefined') { 4633 self.subscriptionDefaults = data.subscriptionDefaults; 4634 //self.setDefaultsToServiceSubscriptions(); 4635 } 4636 self.companyRestrictions.getRestrictions(self.account.company.id()); 4637 4638 self.companyDocuments.setData(data.companyDocuments, self.account.company.id()); 4639 self.companyDocuments.setUnsignedDocumentsData(data.unsignedDocuments, self.account.company.email()
4639); 4640 4641 self.companyMessagingDetailOptions(data.companyMessagingDetailOptions); 4642 self.companyMessagingDetails.setData(self.account.company.id(), data.companyMessagingDetails); 4643 4644 // Null for a company that is not on Procountor, which the sub view model renders as unavailable 4645 self.accounting.setData(data.accountingSettings || null); 4646 4647 self.setSubscriptionData(data.subscriptions, self.account.company.id()); 4648 self.initDatepicker(); 4649 4650 if (self.account.kyc && (self.account.kyc.history().length > 0 || self.account.kyc.actualStatus() != 'draft') ) { 4651 self.disableAllKycInputs(); 4652 } else { 4653 self.enableAllKycInputs(); 4654 } 4655 4656 if (data.apiKeys) { 4657 self.apiKeys(data.apiKeys); 4658 } 4659 4660 self.kycOyParentOwners = ko.computed(function() { 4661 return self.account && self.account.kyc && self.account.kyc.owners ? self.account.kyc.owners().filter(function(o) { 4662 return o.type() === 'oy' && o.stake() > 25; 4663 }) : []; 4664 }); 4665 4666 self.kycOtherParentOwners = ko.computed(function() { 4667 return self.account && self.account.kyc && self.account.kyc.owners ? self.account.kyc.owners().filter(function(o) { 4668 return (o.type() === 'ay' || o.type() === 'ko') && o.stake() > 25; 4669 }) : []; 4670 }); 4671 4672 self.setKycManualAcceptanceRequired(false); 4673 self.continueInterval(false); 4674 4675 self.kredinorSubscriptionCount(data.kredinorSubscriptionCount); 4676 4677 self.subcontractingCompanies([]); 4678 self.subcontractingSearch(''); 4679 self.subcontractingSearchResults([]); 4680 self.subcontractingSearchNoResults(false); 4681 self.subcontractingSearchLoading(false); 4682 4683 var companyId = self.account && self.account.company && self.account.company.id 4684 ? ko.unwrap(self.account.company.id) 4685 : null; 4686 if (companyId) { 4687 self.fetchSubcontractingCompanies(companyId); 4688 } 4689 }; 4690 4691 self.setSettingsData = function (data) { 4692 self.settings.shiftGroupSettings.removeAll(); 4693 self.settings.towingRecordTypes(data.towingRecordTypes); 4694 self.settings.roles(data.roles); 4695 data.shiftGroupSettings.forEach((s) => 4696 self.settings.shiftGroupSettings.push(createNewShiftSettingGroup(s)) 4697 ); 4698 self.settings.freightTypes(data.freigthTypes); 4699 self.settings.jobOrderTypes(data.jobOrderTypes); 4700 self.settings.companyGroups(data.companyGroups); 4701 self.settings.depots(data.depots); 4702 self.settings.resources(data.resources); 4703 self.settings.spare_parts(data.spare_parts); 4704 4705 // Preset to null, so that the state is npt preserved when editing multiple accounts in sequence 4706 self.selectedCategory(null); 4707 self.settings.subCategoryToAdd(null); 4708 self.settings.categoryToAdd(null); 4709 self.selectedCompanyGroups([]) 4710 self.noConnectionFee(false) 4711 4712 self.settings.glAccounts(data.gl_accounts || []); 4713 self.settings.glAccountToAdd.gl_account(null); 4714 self.settings.glAccountToAdd.desc(null); 4715 4716 self.settings.categories(data.categories.map((c) => new Category(c))); 4717 4718 if (data.messageTriggers) { 4719 self.smsMessageTriggers.removeAll(); 4720 data.messageTriggers.forEach(trigger => { 4721 self.smsMessageTriggers.push(trigger) 4722 }); 4723 } 4724 4725 if (data.messageTimings) { 4726 self.smsMessageTimings.removeAll(); 4727 data.messageTimings.forEach(timing => { 4728 self.smsMessageTimings.push(timing) 4729 }); 4730 } 4731 4732 if (data.account) { 4733 self.settings.agreements(data.account.agreements); 4734 self.settings.agreements_innokorjaamo(data.account.agreements_innokorjaamo); 4735 self.settings.sms_templates.removeAll();
4736 data.account.sms_templates.forEach(template => { 4737 self.settings.sms_templates.push({ 4738 id: ko.observable(template.id), 4739 title: ko.observable(template.title), 4740 template: ko.observable(template.template), 4741 trigger: ko.observable(template.trigger), 4742 timing: ko.observable(template.timing), 4743 }) 4744 }); 4745 } 4746 4747 if(data.companyGroups){ 4748 var active = data.companyGroups.filter(g => g.active === true).map(g => Number(g.id)) 4749 active.forEach(id => self.selectedCompanyGroups.push(id)) 4750 } 4751 }; 4752 4753 self.addEmptyShiftSetting = function () { 4754 self.settings.shiftGroupSettings.push( 4755 createNewShiftSettingGroup({ 4756 enable_evening: true, 4757 enable_overtime: true, 4758 enable_standby: true, 4759 enable_wait: true, 4760 enable_night: true, 4761 }) 4762 ); 4763 }; 4764 4765 self.deleteShiftSetting = function (shift) { 4766 self.settings.shiftGroupSettings.remove(shift); 4767 }; 4768 4769 self.setStaticData = function (staticData) { 4770 self.autoklinikkaBranches = staticData.akBranches; 4771 self.accountManagers = staticData.accountManagers; 4772 self.accountManagers.unshift({id: null, username: '', sales_name:'Ei asiakasvastaavaa'}); 4773 self.usergroups = staticData.usergroups; 4774 self.mfaUsergroups = JSON.parse(JSON.stringify(self.usergroups)); 4775 self.mfaUsergroups.unshift({access_level: null, group_name: '-- Ei vaadittu tunnistautumista --'}); 4776 self.usergroups.unshift({access_level: null, group_name: '-- Valitse --'}); 4777 self.eInvoiceOperators = staticData.eInvoiceOperators; 4778 self.workingFields = staticData.workingFields; 4779 }; 4780 4781 self.noConnectionFee = ko.observable(false); 4782 self.noConnectionFee.subscribe(function(newValue) { 4783 if(self.account && self.account.preferences && !self.account.company.id()) 4784 self.noConnectionFee(newValue); 4785 self.account.preferences.connection_fee(0); 4786 }); 4787 4788 self.setAccountData = function (accountData) { 4789 //Remove the logo from accountData and place it in own observable, so it wont be sent back to the server 4790 self.logoBase64(accountData.company.logo_base64); 4791 delete accountData.company.logo_base64; 4792 4793 if (self.account) { 4794 // @TEMP HACK. Remove after we allow sales persons to change 4795 // a users shift working group 4796 if (accountData.users) { 4797 accountData.users = accountData.users.map((u) => { 4798 u.hadPreviousShiftSettingId = u.shift_group_setting_id; 4799 return u; 4800 }); 4801 } 4802 ko.mapping.fromJS(accountData, {}, self.account); 4803 } else { 4804 self.account = ko.mapping.fromJS(accountData); 4805 self.bindExtenders(); 4806 self.bindComputedObservables(); 4807 self.bindSubscribers(); 4808 } 4809 4810 //self.dimensions([]); 4811 4812 if ( 4813 self.account.preferences_procountor && 4814 self.account.preferences_procountor.dimensions && 4815 self.account.preferences_procountor.dimensions() !== null 4816 ) { 4817 console.log(self.account.preferences_procountor.dimensions, JSON.parse(ko.toJS(self.account.preferences_procountor.dimensions))); 4818 self.setDimensions(JSON.parse(ko.toJS(self.account.preferences_procountor.dimensions))); 4819 } 4820 4821 if ( 4822 self.account.preferences_procountor && 4823 self.account.preferences_procountor.reminder_email && 4824 self.account.preferences_procountor.reminder_email() == '' 4825 ) { 4826 self.account.preferences_procountor.reminder_email(self.account.company.email()); 4827 } 4828 4829 //Block money transfers and enable sales monitoring for newly created accounts and enable MFA 4830 if (!self.account.company.id()) { 4831 self.account.company.block_money_transfer(true); 4832 self.account.company.sales_monitoring(true); 4833 self.account.company.mod_multifactor_authentication(1); 4834 self.account.preferences.min_access_level_required_to_use_mfa(DEFAULT_USER_ACCESS_LEVEL); 4835 self.account.preferences.connection_fee(DEFAULT_CONNECTION_FEE); 4836 self.account.company.is_trial(true); 4837 } else { 4838 self.BlockMoneyTransferOld(self.account.company.block_money_transfer()); 4839 } 4840 4841 var towingNotificationData = accountData.preferences.towing_customer_notification_settings; 4842 4843 if (towingNotificationData) { 4844 towingNotificationData = JSON.parse(towingNotificationData); 4845 self.towingNotifications.stations(towingNotificationData.stations); 4846 self.towingNotifications.jobTypes(towingNotificationData.jobTypes); 4847 4848 $('.notifications-stations-select').selectpicker('refresh'); 4849 $('.notifications-types-select').selectpicker('refresh'); 4850 } 4851 4852 if (accountData.preferences.towing_customer_notification_display_name == null) { 4853 self.account.preferences.towing_customer_notification_display_name( 4854 'T. ' + self.account.company.invoice_company_name() 4855 ); 4856 } 4857 4858 if (self.account.kyc && (self.account.kyc.history().length > 0 || self.account.kyc.actualStatus() != 'draft') ) { 4859 self.disableAllKycInputs(); 4860 self.kycIsDraft(false); 4861 } else { 4862 self.enableAllKycInputs(); 4863 self.kycIsDraft(true); 4864 } 4865 4866 if (self.account.kyc && !self.account.kyc.recipientEmail()) { 4867 self.account.kyc.recipientEmail(self.account.company.email()
4867); 4868 } 4869 4870 if (self.account && self.account.company) { 4871 if (self.account.company.contact_person() && self.account.company.contact_person() != '') { 4872 self.contactPersonSaved.name(true); 4873 } else { 4874 self.contactPersonSaved.name(false); 4875 } 4876 4877 if (self.account.company.phone() && self.account.company.phone() != '') { 4878 self.contactPersonSaved.phone(true); 4879 } else { 4880 self.contactPersonSaved.phone(false); 4881 } 4882 4883 if (self.account.company.contact_person_ssn() && self.account.company.contact_person_ssn() != '') { 4884 self.contactPersonSaved.ssn(true); 4885 } else { 4886 self.contactPersonSaved.ssn(false); 4887 } 4888 4889 if (self.account.company.email() && self.account.company.email() != '') { 4890 self.contactPersonSaved.email(true); 4891 } else { 4892 self.contactPersonSaved.email(false); 4893 } 4894 } 4895 }; 4896 4897 self.enableAllKycInputs = function(){ 4898 4899 self.enableKycBaseInformation(true); 4900 self.enableKycContactPersonInformation(false); // dont enable this becuase its not really editable (overridden from company data) 4901 self.enableKycBankAccountInformation(true); 4902 self.enableKycRepresentationInformation(true); 4903 self.enableKycPersonInChargeInformation(true); 4904 self.enableKycOwnersInformation(true); 4905 self.enableKycPoliticallyInfluentialPersonsInformation(true); 4906 }; 4907 4908 self.disableAllKycInputs = function(){ 4909 4910 self.enableKycBaseInformation(false); 4911 self.enableKycContactPersonInformation(false); 4912 self.enableKycBankAccountInformation(false); 4913 self.enableKycRepresentationInformation(false); 4914 self.enableKycPersonInChargeInformation(false); 4915 self.enableKycOwnersInformation(false); 4916 self.enableKycPoliticallyInfluentialPersonsInformation(false); 4917 }; 4918 4919 self.setReviewData = function (data, type = 0) { 4920 self.reviewData.availableJobTypes([ 4921 { id: 'all', label: 'Kaikki' }, 4922 // { id: 'kk0', label: 'Kuormakirja' }, 4923 // { id: 'tm0', label: 'Työmääräys' }, 4924 // { id: 'rk0', label: 'Rahtikirja' }, 4925 ]); 4926 4927 self.reviewData.towingRecordJobTypes([{ id: 'all', label: 'Kaikki' }]); 4928 4929 self.reviewData.freightJobTypes([{ id: 'all', label: 'Kaikki' }]); 4930 4931 self.reviewData.jobOrderJobTypes([{ id: 'all', label: 'Kaikki' }]); 4932 4933 if (self.account.company.mod_assistance() === true) { 4934 self.reviewData.availableJobTypes.push({ id: 'kk-1', label: 'Autoliitto' }); 4935 self.reviewData.towingRecordJobTypes.push({ id: 'kk-1', label: 'Autoliitto' }); 4936 } 4937 4938 if (self.account.company.mod_autoklinikka()) { 4939 [ 4940 { type: 'D', label: 'Vauriokorjaus' }, 4941 { type: 'W', label: 'Tuulilasin vaihto' }, 4942 { type: 'F', label: 'Tuulilasin korjaus' }, 4943 { type: 'R', label: 'PDR' }, 4944 { type: 'Partneri', label: 'Partneri' }, 4945 { type: 'O', label: 'Muu työ' }, 4946 ].forEach(function (value) { 4947 self.reviewData.jobOrderJobTypes.push({ id: `tm${value.type}`, label: `${value.label} (IK)` }); 4948 self.reviewData.availableJobTypes.push({ id: `tm${value.type}`, label: `${value.label} (IK)` }); 4949 }); 4950 } 4951 4952 if (type === 0) { 4953 data.towingRecordTypes.forEach(function (towingRecordType) { 4954 if (towingRecordType.deleted_at === null) { 4955 self.reviewData.availableJobTypes.push({ 4956 id: 'kk' + towingRecordType.id, 4957 label: towingRecordType.type + ' (IH)', 4958 }); 4959 4960 self.reviewData.towingRecordJobTypes.push({ 4961 id: 'kk' + towingRecordType.id, 4962 label: towingRecordType.type + ' (IH)', 4963 }); 4964 } 4965 }); 4966 4967 4968 if(data.jobOrderTypes){ 4969 4970 data.jobOrderTypes.forEach(function(type) { 4971 if (type.deleted_at === null) { 4972 self.reviewData.availableJobTypes.push({ 4973 id: 'tm' + type.id, 4974 label: type.type + ' (IK)', 4975 }); 4976 4977 self.reviewData.jobOrderJobTypes.push({ 4978 id: 'tm' + type.id, 4979 label: type.type + ' (IK)', 4980 }); 4981 } 4982 }); 4983 } 4984 4985 data.freigthTypes.forEach(function (freigthType) { 4986 if (freigthType.deleted_at === null) { 4987 self.reviewData.availableJobTypes.push({ 4988 id: 'rk' + freigthType.id, 4989 label: freigthType.type + ' (IR)', 4990 }); 4991 4992 self.reviewData.freightJobTypes.push({ 4993 id: 'rk' + freigthType.id, 4994 label: freigthType.type + ' (IR)', 4995 }); 4996 } 4997 }); 4998 4999 ko.mapping.fromJS(data.preferencesReviews, {}, self.reviewData.settings); 5000 } else { 5001 ko.mapping.fromJS(data, {}, self.reviewData.settings); 5002
5003 self.settings.towingRecordTypes().forEach(function (towingRecordType) { 5004 self.reviewData.availableJobTypes.push({ 5005 id: 'kk' + towingRecordType.id, 5006 label: towingRecordType.type + ' (IH)', 5007 }); 5008 }); 5009 5010 self.settings.jobOrderTypes().forEach(function(type) { 5011 if (type.deleted_at === null) { 5012 self.reviewData.availableJobTypes.push({ 5013 id: 'tm' + type.id, 5014 label: type.type + ' (IK)', 5015 }); 5016 } 5017 }); 5018 5019 self.settings.freightTypes().forEach(function (freightType) { 5020 self.reviewData.availableJobTypes.push({ 5021 id: 'rk' + freightType.id, 5022 label: freightType.type + ' (IR)', 5023 }); 5024 }); 5025 } 5026 5027 if (self.reviewData.settings()[0]) 5028 self.reviewData.stationSetting(self.reviewData.settings()[0].type()); 5029 5030 if (self.reviewData.settings()[0]) { 5031 self.reviewData.messageType(self.reviewData.settings()[0].message_type()); 5032 if (self.reviewData.settings()[0].send_reply() && !self.reviewData.messageType().includes('+')) 5033 self.reviewData.messageType(self.reviewData.settings()[0].message_type() + '+'); 5034 5035 self.reviewData.userStatistics(self.reviewData.settings()[0].user_statistics()); 5036 } 5037 5038 //self.reviewData.userStatistics(false); 5039 //self.setDefaultMessageType(); 5040 self.messageTypeChanged(); 5041 $('.job-types-select').selectpicker('refresh'); 5042 }; 5043 5044 self.accountExists = function () { 5045 if (!self.account) return false; 5046 5047 return !!self.account.company.id(); 5048 }; 5049 5050 self.bindExtenders = function () { 5051 // Add extenders to mapped properties 5052 self.account.company.phone = self.account.company.phone.extend({ formatPhone: 1 }); 5053 self.account.company.phone2 = self.account.company.phone2.extend({ formatPhone: 1 }); 5054 self.account.company.invoice_phone = self.account.company.invoice_phone.extend({ 5055 formatPhone: 1, 5056 }); 5057 self.account.preferences.insurance_company_financing_commission_fee = 5058 self.account.preferences.insurance_company_financing_commission_fee.extend({ 5059 commaNumeric: true, 5060 }); 5061 self.account.preferences.company_14_days_net_financing_commission_fee = 5062 self.account.preferences.company_14_days_net_financing_commission_fee.extend({ 5063 commaNumeric: true, 5064 }); 5065 self.account.preferences.company_30_days_net_financing_commission_fee = 5066 self.account.preferences.company_30_days_net_financing_commission_fee.extend({ 5067 commaNumeric: true, 5068 }); 5069 self.account.preferences.consumer_financing_commission_fee = 5070 self.account.preferences.consumer_financing_commission_fee.extend({ commaNumeric: true }); 5071 self.account.preferences.consumer_14_days_net_financing_commission_fee = 5072 self.account.preferences.consumer_14_days_net_financing_commission_fee.extend({ 5073 commaNumeric: true, 5074 }); 5075 self.account.preferences.consumer_30_days_net_financing_commission_fee = 5076 self.account.preferences.consumer_30_days_net_financing_commission_fee.extend({ 5077 commaNumeric: true, 5078 }); 5079 self.account.preferences.part_payment_transaction_fee = 5080 self.account.preferences.part_payment_transaction_fee.extend({ commaNumeric: true }); 5081 self.account.preferences.part_payment_financing_commission_fee = 5082 self.account.preferences.part_payment_financing_commission_fee.extend({ commaNumeric: true }); 5083 self.account.preferences.invoice_transaction_fee = 5084 self.account.preferences.invoice_transaction_fee.extend({ commaNumeric: true }); 5085 self.account.preferences.paper_invoice_transaction_fee = 5086 self.account.preferences.paper_invoice_transaction_fee.extend({ commaNumeric: true }); 5087 self.account.preferences.e_invoice_transaction_fee = 5088 self.account.preferences.e_invoice_transaction_fee.extend({ commaNumeric: true }); 5089 self.account.preferences.connection_fee = self.account.preferences.connection_fee.extend({ 5090 commaNumeric: true, 5091 }); 5092 self.account.preferences.consumer_financing_limit = 5093 self.account.preferences.consumer_financing_limit.extend({ commaNumeric: true }); 5094 self.account.preferences.company_financing_limit = 5095 self.account.preferences.company_financing_limit.extend({ commaNumeric: true }); 5096 self.account.preferences.insurance_company_financing_limit = 5097 self.account.preferences.insurance_company_financing_limit.extend({ commaNumeric: true }); 5098 self.account.preferences.part_payment_financing_limit = 5099 self.account.preferences.part_payment_financing_limit.extend({ commaNumeric: true }); 5100 self.account.preferences.service_charge_fee = 5101 self.account.preferences.service_charge_fee.extend({ 5102 commaNumeric: true, 5103 }); 5104 self.account.preferences.sms_review_fee = self.account.preferences.sms_review_fee.extend({ 5105 commaNumeric: true, 5106 }); 5107 self.account.preferences.invoicing_fee = self.account.preferences.invoicing_fee.extend({ 5108 commaNumeric: true, 5109 }); 5110 self.account.preferences.online_payment_link_fee = self.account.preferences.online_payment_link_fee.extend({ 5111 commaNumeric: true, 5112 }); 5113 }; 5114 5115 self.bindSubscribers = function () { 5116 // Add subscribers to some of properties to copy copy to anothers properties on change 5117 self.account.company.address.subscribe(function (value) { 5118 self.copyValue(self.account.company.invoice_address, value); 5119 self.copyValue(self.account.company.invoicing_address, value); 5120 }); 5121 5122 self.account.company.zipcode.subscribe(function (value) { 5123 self.copyValue(self.account.company.invoice_zipcode, value); 5124 self.copyValue(self.account.company.invoicing_zipcode, value); 5125 }); 5126 5127 self.account.company.city.subscribe(function (value) { 5128 self.copyValue(self.account.company.invoice_city, value); 5129 self.copyValue(self.account.company.invoicing_city, value); 5130 }); 5131 5132 self.account.company.company_name.subscribe(function (value) { 5133 self.copyValue(self.account.company.invoice_company_name, value); 5134 }); 5135 5136 self.account.company.email.subscribe(function (value) { 5137 self.copyValue(self.account.company.ticket_email, value); 5138 self.copyValue(self.account.company.sales_leads_email, value); 5139 self.copyValue(self.account.company.invoice_email, value); 5140 self.copyValue(self.account.company.invoicing_email, value); 5141 if (!self.account.kyc.recipientEmail()) { 5142 self.copyValue(self.account.kyc.recipientEmail, value); 5143 } 5144 }); 5145 5146 self.account.company.phone.subscribe(function (value) { 5147 self.copyValue(self.account.company.invoice_phone, value); 5148 if (!self.account.kyc.signerPhone()) { 5149 self.copyValue(self.account.kyc.signerPhone, value); 5150 } 5151 }); 5152 5153 self.account.company.business_id.subscribe(function (value) { 5154 self.copyValue(self.account.company.invoice_business_id, value); 5155 }); 5156 5157 self.account.company.contact_person_ssn.subscribe(function(value) { 5158 if (value) { 5159 self.account.company.contact_person_ssn(value.toUpperCase()); 5160 self.copyValue(self.account.kyc.signerSsn, value.toUpperCase()); 5161 } 5162 }); 5163 5164 self.account.company.contact_person.subscribe(function (value) { 5165 self.copyValue(self.account.kyc.signedBy, value); 5166 }); 5167 }; 5168 5169 self.bindComputedObservables = function() { 5170 5171 // @ai:claude Returns Bootstrap 3 label class and Finnish text for the current trial status, 5172 // used to render the colour-coded badge in the Kokeiluasiakkuuden tila panel header. 5173 self.trialStatusBadge = ko.pureComputed(function () { 5174 if (!self.account || !self.account.company) return { text: '', cls: 'label-default' }; 5175 switch (parseInt(self.account.company.trial_status(), 10)) { 5176 case 0: return { text: 'Luonnos', cls: 'label-default' }; 5177 case 1: return { text: 'Aktiivinen', cls: 'label-success' }; 5178 case 2: return { text: 'Vanhentunut', cls: 'label-danger' }; 5179 case 3: return { text: 'Muuttumassa asiakkaaksi', cls: 'label-warning' }; 5180 case 4: return { text: 'Muutettu asiakkaaksi', cls: 'label-primary' }; 5181 case 5: return { text: 'Peruutettu', cls: 'label-default' }; 5182 default: return { text: 'Tuntematon', cls: 'label-default' }; 5183 } 5184 }); 5185 5186 self.account.displayStations = ko.computed(function(){ 5187 5188 return self.account.company.id() && 5189 ( 5190 self.account.company.field_of_work() === "car_tow" 5191 || self.account.company.field_of_work() === "car_rental" 5192 || self.account.company.mod_autoklinikka() 5193 ) 5194 }); 5195 5196 // Add computed to calculated stats totals 5197 function sumStatsField(fieldName) { 5198 return ko.computed(function () { 5199 var total = 0; 5200 5201 for (var p = 0; p < self.account.stats().length; ++p) { 5202 total += +self.account.stats()[p][fieldName](); 5203 } 5204 5205 return total; 5206 }); 5207 } 5208 5209 self.account.statsTotal = sumStatsField("quantity"); 5210 self.account.statsTotalCurrentYear = sumStatsField("quantity_current_year"); 5211 self.account.statsTotalPreviousYear = sumStatsField("quantity_previous_year"); 5212 5213 self.settings.availableTags = ko.computed(function () { 5214 if (!self.account) { 5215 return []; 5216 } 5217 5218 return [ 5219 'fixus', 5220 'motonet', 5221 'webasto', 5222 'kaha', 5223 'autoasi', 5224 'scandia rent', 5225 'sos', 5226 'autoliitto', 5227 'autonomi', 5228 'awux', 5229 '123 tuulilasi', 5230 'kl', 5231 'terra gas', 5232 ].filter(function (tag) { 5233 return ko.toJS(self.account.tags).indexOf(tag) === -1; 5234 }); 5235 }); 5236 5237 self.kycEditButtonsVisible = ko.computed(function() { 5238 5239 if (!self.account) { 5240 return false;
5241 } 5242 var history = ko.toJS(self.account.kyc.history); 5243 5244 //If there is only one KYC form and it is still in draft status, allow it to be edited by Innovoice 5245 if (history.length === 1 && history[0].actualStatus === 'draft') { 5246 return true; 5247 } 5248 5249 return self.account.kyc.actualStatus() === 'declined'; 5250 }); 5251 5252 self.kycRepresentation = ko.computed(function() { 5253 var representation2 = self.account && self.account.kyc ? self.account.kyc.representation2() : null; 5254 var representation3 = self.account && self.account.kyc ? self.account.kyc.representation3() : null; 5255 5256 return self.kycRepresentationOptions.filter(value => value.value !== representation2 && value.value !== representation3); 5257 }); 5258 5259 self.kycRepresentation2 = ko.computed(function() { 5260 var representation = self.account && self.account.kyc ? self.account.kyc.representation() : null; 5261 var representation3 = self.account && self.account.kyc ? self.account.kyc.representation3() : null; 5262 5263 return self.kycRepresentationOptions.filter(value => value.value !== representation && value.value !== representation3); 5264 }); 5265 5266 self.kycRepresentation3 = ko.computed(function() { 5267 var representation = self.account && self.account.kyc ? self.account.kyc.representation() : null; 5268 var representation2 = self.account && self.account.kyc ? self.account.kyc.representation2() : null; 5269 5270 return self.kycRepresentationOptions.filter(value => value.value !== representation && value.value !== representation2); 5271 }); 5272 5273 self.noActiveMainUsers = ko.computed(function() { 5274 var users = self.account.users(); 5275 var hasMainUser = ko.toJS(users).find(function(user) { 5276 return (user.usergroup_id == '2' || user.usergroup_id == '14' || user.usergroup_id == '17') && (user.disabled === '0' || user.disabled === false) && user.deleted_at === null; 5277 }); 5278 5279 return typeof hasMainUser === 'undefined'; 5280 }); 5281 5282 self.canSendKycForm = ko.computed(function() { 5283 if (self.account.kyc && self.account.kyc.disabled()) { 5284 return false; 5285 } 5286 5287 if ((self.account.kyc && (self.account.kyc.history().length > 0 && self.account.kyc.actualStatus() == 'pending_acceptance'))) { 5288 return false; 5289 } 5290 5291 if (self.account.kyc && (self.account.kyc.actualStatus() == 'ok' || self.account.kyc.actualStatus() == 'declined')) { 5292 return false; 5293 } 5294 5295 return !self.noActiveMainUsers(); 5296 }); 5297 5298 self.canCreateKycForm = ko.computed(function() { 5299 if (self.account.kyc && self.account.kyc.disabled()) { 5300 return false; 5301 } 5302 if (self.account.kyc && !(self.account.kyc.actualStatus() == 'ok' || self.account.kyc.actualStatus() == 'declined' || self.account.kyc.actualStatus() == 'draft')) { 5303 return false; 5304 } 5305 5306 return !self.noActiveMainUsers(); 5307 }); 5308 }; 5309 5310 self.init = function () { 5311 self.initJQueryElements(); 5312 self.fetchInitialDataAndApplyKoBindings(); 5313 self.companyDocuments.addElementBinding(); 5314 }; 5315 5316 self.applyKoBindings = function (elem) { 5317 ko.applyBindings(this, elem); 5318 }; 5319 5320 self.initJQueryElements = function () { 5321 $('#account-card-tabs').tabs(); 5322 self.initDatepicker(); 5323 //$('.job-types-select').selectpicker('refresh'); 5324 }; 5325 5326 self.initDatepicker = function () { 5327 $('.datepicker').datepicker({startDate: '01.01.1900'}); 5328 }; 5329 5330 self.fetchSubcontractingCompanies = function (companyId) { 5331 if (!companyId) return; 5332 jQuery 5333 .ajax({ 5334 url: '/asiakkuudet/getSubcontractingCompanies/' + companyId, 5335 method: 'get', 5336 dataType: 'json', 5337 }) 5338 .done(function (response) { 5339 self.subcontractingCompanies( 5340 Array.isArray(response.data) ? response.data.map(function (c) { 5341 // @ai:claude collapsed by default so long subcontractor lists stay scannable 5342 var mapped = ko.mapping.fromJS(c); 5343 mapped.isCollapsed = ko.observable(true); 5344 return mapped; 5345 }) : [] 5346 ); 5347 }) 5348 .fail(function () { 5349 self.subcontractingCompanies([]); 5350 }); 5351 }; 5352 5353 self.onSubcontractingSearchInput = function () { 5354 5355 clearTimeout(self._subcontractingDebounceTimer); 5356 5357 self.subcontractingSearchResults([]); 5358 self.subcontractingSearchNoResults(false); 5359 5360 var query = self.subcontractingSearch(); 5361 if (!query || query.trim().length < 2) { 5362 self.subcontractingSearchLoading(false); 5363 return; 5364 } 5365 5366 self.subcontractingSearchLoading(true); 5367 5368 self._subcontractingDebounceTimer = setTimeout(function () { 5369 jQuery 5370 .ajax({ 5371 url: '/asiakkuudet/searchSubcontractingCompanies', 5372 method: 'post', 5373 dataType: 'json', 5374 data: { 5375 query: query.trim(), 5376 companyId: self.account.company.id(), 5377 }, 5378 }) 5379 .done(function (response) { 5380 self.subcontractingSearchResults(Array.isArray(response.data) ? response.data : []); 5381 self.subcontractingSearchNoResults(Array.isArray(response.data) && response.data.length === 0); 5382 }) 5383 .fail(function () { 5384 self.subcontractingSearchResults([]); 5385 self.subcontractingSearchNoResults(false); 5386 }) 5387 .always(function () { 5388 self.subcontractingSearchLoading(false); 5389 }); 5390 }, 400); 5391 }; 5392 5393 self.addSubcontractingCompany = function (company) { 5394 jQuery 5395 .ajax({ 5396 url: '/asiakkuudet/addSubcontractingCompany', 5397 method: 'post', 5398 dataType: 'json', 5399 data: { 5400 companyId: self.account.company.id(), 5401 contractorId: company.id, 5402 }, 5403 }) 5404 .done(function (response) { 5405 console.log(response.data); 5406 // @ai:claude newly added company starts expanded, as the user likely wants to configure it right away 5407 var mapped = ko.mapping.fromJS(response.data); 5408 mapped.isCollapsed = ko.observable(false); 5409 self.subcontractingCompanies.push(mapped); 5410 self.subcontractingSearch(''); 5411 self.subcontractingSearchResults([]); 5412 self.subcontractingSearchNoResults(false); 5413 if (!self.account.preferences.towing_subcontracts()) { 5414 self.account.preferences.towing_subcontracts(true); 5415 } 5416 }) 5417 .fail(function (err) { 5418 window.show_message && window.show_message(err.responseJSON); 5419 }); 5420 }; 5421 5422 self.removeSubcontractingCompany = function (company) { 5423 if (!window.confirm('Haluatko varmasti poistaa alihankkijayrityksen ' + ko.unwrap(company.name) + '?')) { 5424 return; 5425 } 5426 jQuery 5427 .ajax({ 5428 url: '/asiakkuudet/removeSubcontractingCompany', 5429 method: 'post', 5430 dataType: 'json', 5431 data: { 5432 companyId: self.account.company.id(), 5433 contractorId: ko.unwrap(company.id), 5434 }, 5435 }) 5436 .done(function () { 5437 self.subcontractingCompanies.remove(function (c) { 5438 return ko.unwrap(c.id) === ko.unwrap(company.id); 5439 }); 5440 }) 5441 .fail(function (err) { 5442 window.show_message && window.show_message(err.responseJSON); 5443 }); 5444 }; 5445 5446 // @ai:claude flips the per-company collapse state used to show/hide the settings panel body 5447 self.toggleSubcontractingCompany = function (company) { 5448 company.isCollapsed(!company.isCollapsed()); 5449 }; 5450 5451 self.updateSubcontractingCompanySettings = function (company) { 5452 jQuery.ajax({ 5453 url: '/asiakkuudet/updateSubcontractingCompanySettings', 5454 method: 'post', 5455 dataType: 'json', 5456 data: { 5457 companyId: self.account.company.id(), 5458 contractorId: ko.unwrap(company.id), 5459 client: ko.mapping.toJS(company.clientSettings), 5460 contractor: ko.mapping.toJS(company.contractorSettings), 5461 }, 5462 }).fail(function (err) { 5463 window.show_message && window.show_message(err.responseJSON); 5464 }); 5465 }; 5466 5467 self.fetchAndUpdateData = function (companyId) { 5468 jQuery 5469 .ajax({ 5470 url: '/asiakkuudet/asiakkuus/'.concat(companyId), 5471 dataType: 'json', 5472 }) 5473 .done(self.setData) 5474 .fail(function (response) {}); 5475 }; 5476 5477 self.fetchInitialDataAndApplyKoBindings = function () { 5478 jQuery 5479 .ajax({ 5480 url: '/asiakkuudet/asiakkuus/', 5481 dataType: 'json', 5482 }) 5483 .done(self.setData) 5484 .then(function () { 5485 self.applyKoBindings($('#account-card-dialog')[0]); 5486 }) 5487 .fail(function (response) {}); 5488 }; 5489 5490 self.includeDisabled = ko.observable(false); 5491 self.showUserExtraOptions = ko.observable(false); 5492 self.show = function (companyId) { 5493 // If jQuery UI dialog has not been inited yet 5494 if (self.dialog === null) { 5495 self.dialog = $('#account-card-dialog').dialog({ 5496 width: window.innerWidth >= 1280 ? 1280 : '90%', 5497 height: 800, 5498 autoOpen: false, 5499 modal: true, 5500 resizable: true, 5501 draggable: true, 5502 beforeclose: function (event) { 5503 $('link#extrabs').remove(); 5504 $('script#bsjs').remove(); 5505 event.stopPropagation(); 5506 }, 5507 title: 'Asiakkuuskortti', 5508 buttons: [ 5509 { 5510 text: 'Sulje', 5511 class: 'close-btn btn btn-default', 5512 click: function () { 5513 self.close(); 5514 }, 5515 }, 5516 { 5517 text: 'Tallenna', 5518 class: 'save-btn btn btn-default', 5519 click: function () { 5520 //self.dialog.find('#account_card_form').submit(); 5521 self.saveAccount(); 5522 }, 5523 }, 5524 ], 5525 }); 5526 } 5527 5528 self.dialog.dialog('open'); 5529 $('div#account-card-tabs').tabs('option', 'active', 0); 5530 self.fetchAndUpdateData(companyId); 5531 self.showUserExtraOptions(false); 5532 }; 5533 5534 self.close = function () { 5535 self.reviewData.availableJobTypes([]); 5536 self.reviewData.jobTypes([]); 5537 self.dialog.dialog('close'); 5538 }; 5539 5540 self.saveStations = function () { 5541 if (self.account.stations() && self.account.stations().length > 0) { 5542 var stationsNamesMissing = 5543 self.account.stations().filter(function (value) { 5544 return value.name() === '' && (value.type() === 1 || value.type() === 2); 5545 }).length > 0; 5546 var stationMissingCoords = 5547 self.account.stations().filter(function (value) { 5548 return isNaN(value.coords_lat()) || isNaN(value.coords_long()); 5549 }).length > 0; 5550 5551 if (stationsNamesMissing) 5552 return global.show_message({ type: 'error', text: 'Toimipisteen nimi ei saa olla tyhjä' }); 5553 if (stationMissingCoords) 5554 return global.show_message({ 5555 type: 'error', 5556 text: 'Toimipisteen kordinaatit virheelliset. Käytä pistettä erottimena (esim 61.14046433).', 5557 }); 5558 } 5559 5560 var stations = ko.mapping.toJSON(self.account.stations()); 5561 5562 var data = { 5563 companyId: ko.toJS(self.account.company.id), 5564 stations, 5565 }; 5566 global.showLoadingDialog('Tallennetaan...'); 5567 5568 $.ajax({ 5569 type: 'POST', 5570 url: 'asiakkuudet/saveStations/', 5571 data: data, 5572 }) 5573 .done(function (response) { 5574 global.close_loading_dialog(); 5575 global.show_message(response); 5576 if (response.data && response.data.stations) { 5577 ko.mapping.fromJS(response.data.stations, {}, self.account.stations); 5578 } 5579 if (self.account.company.mod_review() && response.data && response.data.reviews) { 5580 ko.mapping.fromJS(response.data.reviews, {}, self.reviewData.settings); 5581 } 5582 }) 5583 .fail(function (error) { 5584 global.close_loading_dialog(); 5585 global.show_message(error.responseJSON); 5586 }); 5587 }; 5588 5589 self.saveAccount = function () { 5590 if ( 5591 self.account.company.id() && 5592 !self.account.company.is_trial() &&
5593 !self.convertingTrialToCustomer() 5594 ) { 5595 var trialStatus = parseInt(self.account.company.trial_status(), 10); 5596 if (trialStatus === 1) { 5597 return global.show_message({ 5598 type: 'error', 5599 text: 'Kokeiluasiakkuutta ei voi poistaa ruksista. Muuta se oikeaksi asiakkuudeksi.', 5600 }); 5601 } 5602 if (trialStatus === 5) { 5603 return global.show_message({ 5604 type: 'error', 5605 text: 'Kokeiluasiakkuutta ei voi poistaa ruksista. Käytä reaktivointia kokeilun jatkamiseksi.', 5606 }); 5607 } 5608 } 5609 5610 // @ai:claude Guard: trial customers must have an expiry date before saving. 5611 if (self.account.company.is_trial() && !self.account.company.trial_expires_at()) { 5612 return global.show_message({ 5613 type: 'error', 5614 text: 'Aseta kokeilujakson päättymispäivä ennen tallennusta.', 5615 }); 5616 } 5617 5618 // Guard: if status is Vanhentunut and a future expiry is set, confirm reactivation first. 5619 if ( 5620 self.account.company.is_trial() && 5621 self.account.company.id() && 5622 parseInt(self.account.company.trial_status(), 10) === 2 && 5623 !self._confirmedTrialReactivation 5624 ) { 5625 var expiryRaw = self.account.company.trial_expires_at(); 5626 if (expiryRaw) { 5627 var parts = expiryRaw.split('.'); 5628 var expiryDate = parts.length === 3 5629 ? new Date(parts[2], parts[1] - 1, parts[0]) 5630 : new Date(expiryRaw); 5631 if (expiryDate > new Date()) { 5632 var $d = $('<div />').html('<p style="margin:0;">Haluatko uudelleenaktivoida kokeiluasiakkuuden asettamalla uusi päättymispäivä?</p>') 5633 .prepend($('<span />', { class: 'ui-icon ui-icon-alert', style: 'float:left; margin:0 7px 50px 0;' })); 5634 $d.dialog({ 5635 title: 'Uudelleenaktivoi kokeilu', 5636 modal: true, 5637 buttons: { 5638 'Kyllä, aktivoi uudelleen': function () { 5639 $d.dialog('close'); 5640 self._confirmedTrialReactivation = true; 5641 self.saveAccount(); 5642 }, 5643 'Peruuta': function () { $d.dialog('close'); }, 5644 }, 5645 close: function () { $d.dialog('destroy'); $d.remove(); }, 5646 }).parents('.ui-dialog').css('z-index', 9999); 5647 return; 5648 } 5649 } 5650 } 5651 5652 // @ai:claude Guard: if trial is Peruutettu and admin checked Reaktivoi, validate the 5653 // expiry date and confirm before saving. Mutates trial_status(1) and disabled(false) 5654 // so the normal save payload carries the updated values â no separate endpoint needed. 5655 if ( 5656 self.account.company.is_trial() && 5657 self.account.company.id() && 5658 parseInt(self.account.company.trial_status(), 10) === 5 && 5659 self.reactivatingTrial() && 5660 !self._confirmedTrialReactivation 5661 ) { 5662 var expiryRawCancelled = self.account.company.trial_expires_at(); 5663 if (!expiryRawCancelled) { 5664 global.show_message({ type: 'error', text: 'Aseta ensin uusi kokeilujakson päättymispäivä ennen reaktivointia.' }); 5665 return; 5666 } 5667 var cancelledParts = expiryRawCancelled.split('.'); 5668 var cancelledExpiry = new Date(cancelledParts[2], cancelledParts[1] - 1, cancelledParts[0]); 5669 cancelledExpiry.setHours(23, 59, 59, 0); 5670 if (cancelledExpiry <= new Date()) { 5671 global.show_message({ type: 'error', text: 'Aseta tuleva päättymispäivä ennen reaktivointia.' }); 5672 return; 5673 } 5674 var $dCancel = $('<div />').html('<p style="margin:0;">Haluatko reaktivoida kokeiluasiakkuuden?</p>') 5675 .prepend($('<span />', { class: 'ui-icon ui-icon-alert', style: 'float:left; margin:0 7px 50px 0;' })); 5676 $dCancel.dialog({ 5677 title: 'Reaktivoi kokeiluasiakkuus', 5678 modal: true, 5679 buttons: { 5680 'Kyllä, reaktivoi': function () { 5681 $dCancel.dialog('close'); 5682 self.account.company.trial_status(1); 5683 self.account.company.disabled(false); 5684 self._confirmedTrialReactivation = true; 5685 self.saveAccount(); 5686 }, 5687 'Peruuta': function () { $dCancel.dialog('close'); }, 5688 }, 5689 close: function () { $dCancel.dialog('destroy'); $dCancel.remove(); }, 5690 }).parents('.ui-dialog').css('z-index', 9999); 5691 return; 5692 } 5693 5694 self._confirmedTrialReactivation = false;
5695 self.reactivatingTrial(false); 5696 5697 if (self.account.stations() && self.account.stations().length > 0) { 5698 var stationsNamesMissing = 5699 self.account.stations().filter(function (value) { 5700 return value.name() === '' && (value.type() === 1 || value.type() === 2); 5701 }).length > 0; 5702 var stationMissingCoords = 5703 self.account.stations().filter(function (value) { 5704 return isNaN(value.coords_lat()) || isNaN(value.coords_long()); 5705 }).length > 0; 5706 5707 if (stationsNamesMissing) 5708 return global.show_message({ type: 'error', text: 'Toimipisteen nimi ei saa olla tyhjä' }); 5709 if (stationMissingCoords) 5710 return global.show_message({ 5711 type: 'error', 5712 text: 'Toimipisteen kordinaatit virheelliset. Käytä pistettä erottimena (esim 61.14046433).', 5713 }); 5714 } 5715 5716 var missingContactFields = !self.account.company.contact_person() 5717 || !self.account.company.email() 5718 || !self.account.company.phone(); 5719 5720 if (!self.account.company.is_trial()) { 5721 missingContactFields = missingContactFields || !self.account.company.contact_person_ssn(); 5722 } 5723 5724 if (!self.account.company.id() && missingContactFields) { 5725 return global.show_message({ type: 'error', text: 'Tarkasta yhteyshenkilön tiedot' }); 5726 } 5727 5728 if (self.account.company.contact_person_ssn() && !SSN_REGEX.test(self.account.company.contact_person_ssn())) { 5729 return global.show_message({ type: 'error', text: 'Yhteyshenkilön hetu on virheellinen' }); 5730 } 5731 5732 if (self.account.company.ext_service() === 'bildem' && !self.account.company.mod_bildem()) 5733 self.account.company.ext_service(''); 5734 5735 if (self.account.company.mod_bildem()) self.account.company.ext_service('bildem'); 5736 5737 self.account.preferences.drivers_may_accept_external_towing_orders( 5738 Number(self.account.preferences.drivers_may_accept_external_towing_orders()) 5739 ); 5740 5741 if (self.account.preferences_procountor && self.account.preferences_procountor.dimensions) 5742 self.account.preferences_procountor.dimensions(self.dimensions); 5743 5744 if (self.account.company.mod_review() === true) { 5745 self.setReviewMessage(); 5746 } 5747 5748 if (!self.account.kyc.signedBy()) { 5749 self.copyValue(self.account.kyc.signedBy, self.account.company.contact_person()); 5750 } 5751 5752 if (!self.account.kyc.recipientEmail()) { 5753 self.copyValue(self.account.kyc.recipientEmail, self.account.company.email()); 5754 } 5755 5756 if (!self.account.kyc.signerPhone()) { 5757 self.copyValue(self.account.kyc.signerPhone, self.account.company.phone()); 5758 } 5759 5760 if (!self.account.kyc.signerSsn()) { 5761 self.copyValue(self.account.kyc.signerSsn, self.account.company.contact_person_ssn()); 5762 } 5763 5764 if (self.account.company.mod_trafi() && self.account.company.trafi_innokorjaamo_service_enabled() && self.account.company.trafi_innohinaus_service_enabled() && ! self.account.company.trafi_default_service()) { 5765 5766 return global.show_message({ 5767 type: 'error', 5768 text: 'Ole hyvä ja valitse Traficom-haun ensisijainen palveluala', 5769 }); 5770 } 5771 5772 // if (self.reviewData.message()) {
5773 // self.reviewData.settings().forEach((settings) => { 5774 // settings.message(self.reviewData.message()); 5775 // }); 5776 // } 5777 5778 var account = ko.mapping.toJS(self.account); 5779 5780 if (self.convertingTrialToCustomer()) { 5781 account.company.convert_to_customer = true; 5782 self.convertingTrialToCustomer(false); 5783 } 5784 5785 var towingNotifications = ko.toJS(self.towingNotifications); 5786 var followUpSettings = self.account.company.mod_follow_up() === true ? ko.toJS(self.followUpSettings) : []; 5787 delete towingNotifications.availableJobTypes; 5788 delete towingNotifications.availableStations; 5789 5790 account.preferences.towing_customer_notification_settings = ko.toJSON(towingNotifications); 5791 account.companyGroupSettings = ko.toJS({ companyGroupIDs: self.selectedCompanyGroups() }); 5792 5793 //Dont send log items unnecessarily to the server 5794 delete account.logs; 5795 5796 // 5797 delete account.company.kredinor_password; 5798 delete account.company.kredinor_username; 5799 delete account.company.kredinor_active; 5800 5801 // Delete preferences_reviews and send them as their own parameter 5802 delete account.preferences_reviews; 5803 // if block_money_transfer changed and reason added, add reason to log 5804 var newLogItem = {}; 5805 if ( 5806 self.account.company.block_money_transfer() != self.BlockMoneyTransferOld() && 5807 self.moneyTransferBlockReason() != '' 5808 ) { 5809 newLogItem = ko.toJS(self.moneyTransferBlockReason); 5810 } 5811 var data = { 5812 account: ko.mapping.toJSON(account), 5813 preferencesReviews: ko.toJS(self.reviewData.settings), 5814 followUpSettings: followUpSettings, 5815 spareParts: ko.toJS(self.settings.spare_parts), 5816 sms_templates: ko.toJS(self.settings.sms_templates), 5817 selectedCompanyGroups: ko.toJS(self.selectedCompanyGroups), 5818 categories: ko.toJS(self.settings.categories).map((c) => ({ 5819 id: c.id, 5820 sub_categories: c.sub_categories.map((s) => ({ 5821 id: s.id, 5822 })), 5823 })), 5824 shiftGroupSettings: ko.toJS(self.settings.shiftGroupSettings).map((s) => { 5825 s.enable_evening = Number(s.enable_evening); 5826 s.enable_night = Number(s.enable_night); 5827 s.enable_overtime = Number(s.enable_overtime); 5828 s.enable_wait = Number(s.enable_wait); 5829 s.enable_standby = Number(s.enable_standby); 5830 return s; 5831 }), 5832 newLogItem: newLogItem, 5833 }; 5834 5835 $(`.error`).removeClass('error'); 5836 5837 self.saving(true); 5838 global.showLoadingDialog('Tallennetaan...'); 5839 5840 jQuery 5841 .ajax({ 5842 type: 'post', 5843 dataType: 'json', 5844 url: '/asiakkuudet/save', 5845 data: data, 5846 }) 5847 .done(function (responseJSON) { 5848 self.saved(true); 5849 global.show_message(responseJSON); 5850 global.close_loading_dialog(); 5851 self.setData(responseJSON.data); 5852 }) 5853 .fail(function (data) { 5854 global.show_message($.parseJSON(data.responseText)); 5855 global.close_loading_dialog(); 5856 console.error('.ajax.fail:', data); 5857 if (data.responseJSON && data.responseJSON.data && data.responseJSON.data.kyc) { 5858 var index = $('#account-card-tabs a[href="#kyc-forms"]').parent().index(); 5859 $('#account-card-tabs').tabs('option', 'active', index); 5860 var object = data.responseJSON.data.errors; 5861 console.log('object', object); 5862 self.setErrors(object); 5863 } 5864 }) 5865 .then(function () {
5866 // Set the saved observable back to false, so we can, 5867 // listen for new saved events outside this obj 5868 self.saving(false); 5869 self.saved(false); 5870 }); 5871 5872 return false; 5873 }; 5874 5875 self.user = function () { 5876 var roles = self.settings.roles().map((role) => ({ 5877 role_id: ko.observable(role.id), 5878 role_desc: role.role_desc, 5879 active: ko.observable(false), 5880 })); 5881 5882 var stations = self.account.stations().map((station) => ({ 5883 station_id: ko.observable(station.id), 5884 name: station.name, 5885 active: ko.observable(false), 5886 })); 5887 5888 const minAccessLevelForMFA = Number(self.account.preferences.min_access_level_required_to_use_mfa()); 5889 const matchingUserGroup = self.usergroups.find((group) => Number(group.access_level) === minAccessLevelForMFA); 5890 const defaultUserGroupIdForNewCompanyUser = matchingUserGroup ? matchingUserGroup.id : null; 5891 5892 return { 5893 id: ko.observable(), 5894 email: ko.observable(), 5895 username: ko.observable(), 5896 password: ko.observable(), 5897 roles: roles, 5898 stations: stations, 5899 usergroup_id: ko.observable(defaultUserGroupIdForNewCompanyUser), 5900 work_time_type: ko.observable('foo'), 5901 sales_name: ko.observable(''), 5902 disabled: ko.observable('0'), 5903 hidden: ko.observable('0'), 5904 user_authenticated: ko.observable('0'), 5905 firstname: ko.observable(''), 5906 lastname: ko.observable(''), 5907 msisdn_verified: ko.observable('0') 5908 }; 5909 }; 5910 5911 self.usergroupName = function (user) { 5912 var userGroupId = 5913 user.usergroup_id() && !Number.isInteger(user.usergroup_id()) 5914 ? parseInt(user.usergroup_id()) 5915 : user.usergroup_id(); 5916 const filtered = self.usergroups.filter((group) => group.id === userGroupId); 5917 return (filtered[0] || { group_name: 'Ei valittu' }).group_name; 5918 }; 5919 5920 self.addUser = function (data) { 5921 var user = self.user(); 5922 self.account.users.push(user); 5923 }; 5924 5925 self.removeUser = function (user) { 5926 // If existing user, confirm the removal 5927 if (user.id()) { 5928 return self.confirmRemoveUser(user); 5929 } 5930 self.account.users.remove(user); 5931 }; 5932 5933 self.confirmRemoveUser = function (user) { 5934 var $dialog = $('<div />') 5935 .html( 5936 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen käyttäjän?</p>' 5937 ) 5938 .dialog({ 5939 resizable: false, 5940 height: 200, 5941 width: 400, 5942 title: 'Poista käyttäjä', 5943 modal: true, 5944 buttons: { 5945 Ei: function () { 5946 $(this).dialog('close'); 5947 }, 5948 Kyllä: function () { 5949 jQuery 5950 .ajax({ 5951 url: '/asiakkuudet/delete_user/' + user.id(), 5952 type: 'post', 5953 dataType: 'json', 5954 }) 5955 .done(function (responseJSON) { 5956 if (user.usergroup_id() === '10') { 5957 // Remove autofutur user from client 5958 self.resetAutofuturUser(); 5959 } else { 5960 // Remove normal user from client 5961 self.account.users.remove(user); 5962 } 5963 $dialog.dialog('close'); 5964 global.show_message(responseJSON); 5965 }) 5966 .fail(function (response) { 5967 global.show_message(response.responseJSON); 5968 global.close_loading_dialog(); 5969 }); 5970 }, 5971 }, 5972 }); 5973 }; 5974 5975 self.removeCompanyLogo = function () { 5976 // If existing user, confirm the removal 5977 return self.confirmRemoveCompanyLogo(); 5978 }; 5979 5980 self.processCompanyLogo = function (_, event) { 5981 var logo = event.target.files[0]; 5982 5983 var data = new FormData(); 5984 data.append('file', logo); 5985 5986 $.ajax({ 5987 url: '/asiakkuudet/add_company_logo/' + ko.toJS(self.account.company.id), 5988 type: 'post', 5989 data: data, 5990 contentType: false, 5991 processData: false, 5992 }) 5993 .done(function (responseJSON) { 5994 global.show_message(responseJSON); 5995 self.account.company.logo(responseJSON.data.logo); 5996 self.logoBase64(responseJSON.data.logo_base64); 5997 event.target.val(null); 5998 }) 5999 .fail(function (error) { 6000 global.show_message(JSON.parse(error.responseText)); 6001 }); 6002 }; 6003 6004 self.addCompanyLogo = function () { 6005 $('#fileElem').click(); 6006 }; 6007 6008 self.confirmRemoveCompanyLogo = function () { 6009 var $dialog = $('<div />') 6010 .html( 6011 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa yrityksen logon laskuilta?</p>' 6012 ) 6013 .dialog({ 6014 resizable: false, 6015 height: 200, 6016 width: 400, 6017 title: 'Poista logo', 6018 modal: true, 6019 buttons: { 6020 Ei: function () { 6021 $(this).dialog('close'); 6022 }, 6023 Kyllä: function () { 6024 jQuery 6025 .ajax({ 6026 url: '/asiakkuudet/delete_company_logo/'.concat(self.account.company.id()), 6027 type: 'post', 6028 dataType: 'json', 6029 }) 6030 .done(function (responseJSON) { 6031 self.account.company.logo(''); 6032 self.logoBase64(false); 6033 6034 $dialog.dialog('close'); 6035 global.show_message(responseJSON); 6036 }) 6037 .fail(function (response) { 6038 global.show_message(response.responseJSON); 6039 global.close_loading_dialog(); 6040 }); 6041 }, 6042 }, 6043 }); 6044 }; 6045 6046 self.showCreateAutofuturUser = function () { 6047 self.account.autofuturUser.createNewUser(true); 6048 }; 6049 6050 self.hideCreateAutofuturUser = function () { 6051 self.account.autofuturUser.createNewUser(false); 6052 }; 6053 6054 self.changeUserPassword = function (user) { 6055 var $form = $('<form />', { 6056 method: 'POST', 6057 action: '/asiakkuudet/change_user_password/' + user.id(), 6058 }).append( 6059 $('<fieldset />').append( 6060 $('<ol />', {}).append( 6061 $('<li />', {}).append( 6062 $('<label />', {}).html('Uusi salasana'), 6063 $('<input />', { 6064 type: 'text', 6065 name: 'new_password', 6066 id: 'new_password', 6067 class: 'text form-control medium', 6068 }) 6069 ) 6070 ) 6071 ) 6072 ); 6073 6074 var $dialog = $('<div />', { style: 'text-align:left;' }) 6075 .append($form) 6076 .dialog({ 6077 width: 400, 6078 autoOpen: true, 6079 modal: true, 6080 resizable: false, 6081 draggable: false, 6082 beforeclose: function (event, ui) { 6083 event.stopPropagation(); 6084 }, 6085 title: 'Salasanan vaihto', 6086 buttons: { 6087 Peruuta: function () { 6088 $(this).dialog('close'); 6089 }, 6090 'Vaihda salasana': function () { 6091 $form.ajaxSubmit({ 6092 type: 'post', 6093 dataType: 'json', 6094 beforeSubmit: function () { 6095 global.showLoadingDialog('Vaihdetaan salasanaa...'); 6096 }, 6097 success: function (responseJSON) { 6098 global.show_message(responseJSON); 6099 global.close_loading_dialog(); 6100 $dialog.dialog('close'); 6101 }, 6102 error: function (data) { 6103 global.show_message($.parseJSON(data.responseText)); 6104 global.close_loading_dialog(); 6105 }, 6106 }); 6107 }, 6108 }, 6109 }); 6110 }; 6111 6112 self.enableUser = function (user) { 6113 user.disabled(false); 6114 }; 6115 6116 self.disableUser = function (user) { 6117 user.disabled(true); 6118 }; 6119 6120 self.createKredinorClient = function(){ 6121 6122 global.showLoadingDialog('Tallennetaan...'); 6123 jQuery 6124 .ajax({ 6125 url: '/asiakkuudet/createKredinorClientAndWebhookSubscriptions/' + self.account.company.id(), 6126 type: 'post', 6127 dataType: 'json', 6128 }) 6129 .done(function(responseJSON) { 6130 6131 if(responseJSON && responseJSON.data && responseJSON.data.username){ 6132 self.account.company.kredinor_username(responseJSON.data.username); 6133 } 6134 6135 if(responseJSON && responseJSON.data && responseJSON.data.subscriptionCount){ 6136 self.kredinorSubscriptionCount(responseJSON.data.subscriptionCount); 6137 } 6138 6139 global.close_loading_dialog(); 6140 global.show_message(responseJSON); 6141 6142 }) 6143 .fail(function(response) { 6144 global.close_loading_dialog(); 6145 global.show_message(response.responseJSON); 6146 }); 6147 } 6148 6149 self.createKredinorWebhookSubscriptions = function(){ 6150 6151 global.showLoadingDialog('Luodaan Webhook-tilauksia...'); 6152 jQuery 6153 .ajax({ 6154 url: '/asiakkuudet/createKredinorWebhookSubscriptions/' + self.account.company.id(), 6155 type: 'post', 6156 dataType: 'json', 6157 }) 6158 .done(function(responseJSON) { 6159 6160 if(responseJSON && responseJSON.data && responseJSON.data.subscriptionCount){ 6161 self.kredinorSubscriptionCount(responseJSON.data.subscriptionCount); 6162 } 6163 6164 global.close_loading_dialog(); 6165 global.show_message(responseJSON); 6166 }) 6167 .fail(function(response) { 6168 global.close_loading_dialog(); 6169 global.show_message(response.responseJSON); 6170 }); 6171 } 6172 6173 self.toggleKredinorClientActive = function(){ 6174 global.showLoadingDialog('Päivitetään...'); 6175 jQuery 6176 .ajax({ 6177 url: '/asiakkuudet/toggleKredinorClientActive/' + self.account.company.id(), 6178 type: 'post', 6179 dataType: 'json', 6180 }) 6181 .done(function(responseJSON) { 6182 global.close_loading_dialog(); 6183 global.show_message(responseJSON); 6184 self.account.company.kredinor_active(1); 6185 self.account.logs.unshift(responseJSON.data.logItem); 6186 }) 6187 .fail(function(response) { 6188 global.close_loading_dialog(); 6189 global.show_message(response.responseJSON); 6190 }); 6191 } 6192 6193 self.resetUserPassword = function(user) { 6194 $('<div />', { style: 'text-align:left;' }) 6195 .html('Haluatko varmasti resetoida käyttäjän salasanan?') 6196 .dialog({ 6197 autoOpen: true, 6198 modal: true, 6199 resizable: false, 6200 draggable: false,
6201 title: 'Resetoi käyttäjän salasana', 6202 beforeclose: function (event, ui) { 6203 event.stopPropagation(); 6204 }, 6205 buttons: { 6206 Peruuta: function () { 6207 $(this).dialog('close'); 6208 }, 6209 'Resetoi salasana': function () { 6210 jQuery 6211 .ajax({ 6212 url: '/asiakkuudet/reset_user_password/' + user.id() + '/', 6213 type: 'post', 6214 dataType: 'json', 6215 beforeSubmit: function () { 6216 global.showLoadingDialog('Resetoidaan salasanaa...'); 6217 }, 6218 }) 6219 .done(function (responseJSON) { 6220 global.show_message(responseJSON); 6221 }) 6222 .fail(function (response) { 6223 global.show_message(response.responseJSON); 6224 global.close_loading_dialog(); 6225 }); 6226 6227 $(this).dialog('close'); 6228 }, 6229 }, 6230 }); 6231 }; 6232 6233 self.resetUserMFA = function(user) { 6234 $('<div />', { style: 'text-align:left;' }) 6235 .html('Haluatko varmasti resetoida käyttäjän 2-vaiheisen tunnistautumisen?') 6236 .dialog({ 6237 autoOpen: true, 6238 modal: true, 6239 resizable: false, 6240 draggable: false, 6241 title: 'Resetoi käyttäjän 2-vaiheinen tunnistus', 6242 beforeclose: function (event, ui) { 6243 event.stopPropagation(); 6244 }, 6245 buttons: { 6246 Peruuta: function () { 6247 $(this).dialog('close'); 6248 }, 6249 'Resetoi': function () { 6250 jQuery 6251 .ajax({ 6252 url: '/asiakkuudet/reset_user_mfa/' + user.id() + '/', 6253 type: 'post', 6254 dataType: 'json', 6255 beforeSubmit: function () {
6256 global.showLoadingDialog('Resetoidaan 2-vaiheista tunnistusta...'); 6257 }, 6258 }) 6259 .done(function (responseJSON) { 6260 //console.log('reset callback user:', user); 6261 user.mfa_active(0); 6262 user.mfa_secret(null); 6263 global.show_message(responseJSON); 6264 }) 6265 .fail(function (response) { 6266 global.show_message(response.responseJSON); 6267 global.close_loading_dialog(); 6268 }); 6269 6270 $(this).dialog('close'); 6271 }, 6272 }, 6273 }); 6274 }; 6275 6276 self.resetAutofuturUser = function () { 6277 self.account.autofuturUser.id(null); 6278 self.account.autofuturUser.usergroup_id(null); 6279 self.account.autofuturUser.createNewUser(false); 6280 self.account.autofuturUser.existingUser(false); 6281 self.account.autofuturUser.registrationCode(''); 6282 self.account.autofuturUser.username('autofutur.'); 6283 self.account.autofuturUser.email(''); 6284 self.account.autofuturUser.connectionFee(99); 6285 self.account.autofuturUser.sendActivationEmailToInnovoice(false); 6286 }; 6287 6288 self.smsInterface = function () { 6289 return { 6290 id: ko.observable(), 6291 email: ko.observable(), 6292 username: ko.observable(), 6293 password: ko.observable(), 6294 usergroup_id: ko.observable(), 6295 sales_name: ko.observable(), 6296 disabled: ko.observable(false), 6297 }; 6298 }; 6299 6300 self.addSmsInterface = function () { 6301 var smsInterface = self.smsInterface(); 6302 self.account.smsInterfaces.push(smsInterface); 6303 }; 6304 6305 self.removeSmsInterface = function (smsInterface) { 6306 // If existing user, confirm the removal 6307 if (smsInterface.id()) { 6308 return self.confirmRemoveSmsInterface(smsInterface); 6309 } 6310 self.account.smsInterfaces.remove(smsInterface); 6311 }; 6312 6313 self.confirmRemoveSmsInterface = function (smsInterface) { 6314 var $dialog = $('<div />') 6315 .html( 6316 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen myyntipuhelimen?</p>' 6317 ) 6318 .dialog({ 6319 resizable: false, 6320 height: 200, 6321 width: 400, 6322 title: 'Poista myyntipuhelin', 6323 modal: true, 6324 buttons: { 6325 Ei: function () { 6326 $(this).dialog('close'); 6327 }, 6328 Kyllä: function () { 6329 jQuery 6330 .ajax({ 6331 url: '/asiakkuudet/delete_sms_interface/' + smsInterface.id(), 6332 type: 'post', 6333 dataType: 'json', 6334 }) 6335 .done(function (responseJSON) { 6336 self.account.smsInterfaces.remove(smsInterface); 6337 $dialog.dialog('close'); 6338 global.show_message(responseJSON); 6339 }) 6340 .fail(function (response) { 6341 global.show_message(response.responseJSON); 6342 global.close_loading_dialog(); 6343 }); 6344 }, 6345 }, 6346 }); 6347 }; 6348 6349 self.getDefaultReviewSettings = function () { 6350 // If user selected there to be only one settings for this customer, let's fetch default setting from DB 6351 6352 if (ko.toJS(self.account.company.id) === null) return; 6353 6354 global.showLoadingDialog('Ladataan...'); 6355 6356 $.ajax({ 6357 method: 'GET', 6358 url: 'asiakkuudet/getDefaultReviewSettings/' + ko.toJS(self.account.company.id), 6359 }) 6360 .done(function (response) { 6361 global.show_message(response); 6362 self.setReviewData(response.data, 1); 6363 }) 6364 .fail(function (response) { 6365 var errorText = JSON.parse(response.responseText); 6366 global.show_message(errorText); 6367 }) 6368 .always(function () { 6369 global.close_loading_dialog(); 6370 }); 6371 }; 6372 6373 self.getStationReviewSettings = function () { 6374 // If user selected that every station will have it's own settings, let's fetch them from DB (or create if they dont exist) 6375 6376 var data = { 6377 companyId: ko.toJS(self.account.company.id), 6378 stations: ko.toJS(self.account.stations), 6379 }; 6380 6381 global.showLoadingDialog('Ladataan...'); 6382 6383 $.ajax({ 6384 type: 'POST', 6385 url: 'asiakkuudet/getStationReviewSettings/', 6386 data: data, 6387 }) 6388 .done(function (response) { 6389 global.show_message(response); 6390 self.setReviewData(response.data, 1); 6391 }) 6392 .fail(function (response) { 6393 var errorText = JSON.parse(response.responseText); 6394 global.show_message(errorText); 6395 }) 6396 .always(function () { 6397 global.close_loading_dialog(); 6398 }); 6399 }; 6400 6401 self.changeMessageType = function (index) { 6402 //, obj, event 6403 6404 self.reviewData.settings()[index].message_type(self.reviewData.messageType()); 6405 6406 switch (self.reviewData.messageType()) { 6407 case 'nps': 6408 self.reviewData 6409 .settings() 6410 [index].message( 6411 self.reviewData.npsMessage() /* + self.reviewData.settings()[index].screen_name(),*/ 6412 ); 6413 self.reviewData.settings()[index].send_reply(false); 6414 self.reviewData.settings()[index].main_user_statistics(true); 6415 break; 6416 case 'nps+': 6417 case 'nps++': 6418 self.reviewData 6419 .settings() 6420 [index].message( 6421 self.reviewData.npsMessage() /* + self.reviewData.settings()[index].screen_name(),*/ 6422 ); 6423 self.reviewData.settings()[index].send_reply(true); 6424 self.reviewData.settings()[index].main_user_statistics(true); 6425 break; 6426 case 'own': 6427 self.reviewData 6428 .settings() 6429 [index].message( 6430 self.reviewData.ownMessage() /* + self.reviewData.settings()[index].screen_name(),*/ 6431 ); 6432 self.reviewData.settings()[index].send_reply(false); 6433 self.reviewData.settings()[index].main_user_statistics(true); 6434 break; 6435 case 'own+': 6436 self.reviewData 6437 .settings() 6438 [index].message( 6439 self.reviewData.ownMessage() /* + self.reviewData.settings()[index].screen_name(),*/ 6440 ); 6441 self.reviewData.settings()[index].send_reply(true); 6442 self.reviewData.settings()[index].main_user_statistics(true); 6443 break; 6444 case 'msg': 6445 self.reviewData 6446 .settings() 6447 [index].message( 6448 self.reviewData.message() /* + self.reviewData.settings()[index].screen_name()*/ 6449 ); 6450 self.reviewData.settings()[index].send_reply(false); 6451 self.reviewData.settings()[index].main_user_statistics(false); 6452 self.reviewData.settings()[index].user_statistics(false); 6453 break; 6454 // default: 6455 // self.reviewData.settings()[index].message(''); 6456 // self.reviewData.settings()[index].send_reply(false); 6457 // self.reviewData.settings()[index].main_user_statistics(false); 6458 // self.reviewData.settings()[index].user_statistics(false); 6459 // break; 6460 } 6461 }; 6462 6463 self.messageTypeChanged = () => { 6464 var i = 0; 6465 6466 self.setDefaultMessageType(); 6467
6468 self.reviewData.settings().forEach(function (setting) { 6469 self.changeMessageType(i); 6470 i++; 6471 }); 6472 }; 6473 6474 self.setMessageForStation = (index) => { 6475 self.changeMessageType(index); 6476 }; 6477 6478 self.setDefaultMessageType = () => { 6479 switch (self.reviewData.messageType()) { 6480 case 'nps': 6481 case 'nps+': 6482 case 'nps++': 6483 self.reviewData.message(self.reviewData.npsMessage() /* + '{nimimerkki}'*/); 6484 break; 6485 case 'own': 6486 case 'own+': 6487 self.reviewData.message(self.reviewData.ownMessage() /* + '{nimimerkki}'*/); 6488 break; 6489 default: 6490 if (self.reviewData.settings()[0]) { 6491 self.reviewData.message(self.reviewData.settings()[0].message()); 6492 } 6493 break; 6494 } 6495 }; 6496 6497 self.stationSettingChanged = function (obj, event) { 6498 if (event.originalEvent) { 6499 if (self.reviewData.stationSetting() === '0' || self.reviewData.stationSetting() === '') { 6500 self.getDefaultReviewSettings(); 6501 } else { 6502 self.getStationReviewSettings(); 6503 } 6504 } 6505 }; 6506 6507 self.userStatisticsChanged = () => { 6508 var i = 0; 6509
6510 self.reviewData.settings().forEach(function (setting) { 6511 self.changeUserStatisticSetting(i); 6512 i++; 6513 }); 6514 }; 6515 6516 self.changeUserStatisticSetting = (index) => { 6517 if (self.reviewData.userStatistics()) { 6518 self.reviewData.settings()[index].user_statistics(true); 6519 } else { 6520 self.reviewData.settings()[index].user_statistics(false); 6521 } 6522 }; 6523 6524 self.deleteStationSettings = (id) => { 6525 var data = { 6526 companyId: ko.toJS(self.account.company.id), 6527 stationId: id, 6528 }; 6529 6530 $.ajax({ 6531 type: 'POST', 6532 url: 'asiakkuudet/deleteStationSettings/', 6533 data: data, 6534 }) 6535 .done(function (response) { 6536 self.setReviewData(response.data, 1); 6537 }) 6538 .fail(function (response) { 6539 global.show_message(errorText); 6540 }); 6541 }; 6542 6543 self.setReviewMessage = () => { 6544 var i = 0; 6545 self.reviewData.settings().forEach((settings) => { 6546 self.changeMessageType(i); 6547 i++; 6548 }); 6549 }; 6550 6551 self.showReplyMessageInput = (reply = false) => { 6552 var messageType = self.reviewData.messageType(); 6553 var sendReply = ko.toJS(reply); 6554 6555 if (sendReply === true || messageType === 'msg') return true; 6556 6557 return false; 6558 }; 6559 6560 self.showAdditionalReviewFields = () => { 6561 var messageType = self.reviewData.messageType(); 6562 6563 if (messageType != 'msg' && messageType != '') return true; 6564 6565 return true; 6566 }; 6567 6568 self.reviewMessageType = () => { 6569 var messageType = self.reviewData.messageType(); 6570 6571 if (messageType === 'nps' || messageType === 'own') return 'stats'; 6572 6573 if (messageType === 'nps+' || messageType === 'own+' || messageType === 'nps++') return 'stats+'; 6574 6575 if (messageType === 'msg') return 'message'; 6576 6577 return ''; 6578 }; 6579 6580 self.followUpSettings = { 6581 id: ko.observable(null), 6582 callrobot: ko.observable(false), 6583 sms: ko.observable(true),//default true 6584 contact_person: ko.observable(true),//default true 6585 contact_person2: ko.observable(false), 6586 other_contact_persons: ko.observableArray([]), 6587 send_interval: ko.observable('3'),//default 3 6588 sms_template: ko.observable(''), 6589 enabled_at: ko.observable(null), 6590 }; 6591 6592 self.resetFollowUpSettings = function(){ 6593 self.followUpSettings.id(null); 6594 self.followUpSettings.callrobot(false); 6595 self.followUpSettings.sms(true); 6596 self.followUpSettings.contact_person(true); 6597 self.followUpSettings.contact_person2(false); 6598 self.followUpSettings.send_interval('3'); 6599 self.followUpSettings.sms_template(''); 6600 self.followUpSettings.enabled_at(null); 6601 self.followUpSettings.other_contact_persons([]); 6602 }; 6603 6604 self.populateFollowUpSettings = function(data){ 6605 self.resetFollowUpSettings(); 6606 var smsTemplate = data.sms_template != '' ? data.sms_template : self.defaultFollowUpSmsTemplate(); 6607 self.followUpSettings.id(data.id); 6608 self.followUpSettings.callrobot(data.callrobot); 6609 self.followUpSettings.sms(data.sms); 6610 self.followUpSettings.contact_person(data.contact_person); 6611 self.followUpSettings.contact_person2(data.contact_person2); 6612 self.followUpSettings.send_interval(data.send_interval); 6613 self.followUpSettings.sms_template(smsTemplate); 6614 self.followUpSettings.enabled_at(data.enabled_at); 6615 if(data.other_contact_persons && data.other_contact_persons.length > 0){ 6616 data.other_contact_persons.forEach(function(contactPerson){ 6617 self.followUpSettings.other_contact_persons.push({ 6618 id: ko.observable(contactPerson.id), 6619 msisdn: ko.observable(contactPerson.msisdn), 6620 sales_name: ko.observable(contactPerson.sales_name), 6621 }); 6622 }); 6623 } 6624 } 6625 self.defaultFollowUpSmsTemplate = ko.observable(); 6626 self.getFollowUpTemplateText = function(){ 6627 if(self.followUpSettings.sms_template() && self.followUpSettings.sms_template() != ''){ 6628 return self.followUpSettings.sms_template(); 6629 } 6630 return self.defaultFollowUpSmsTemplate(); 6631 }; 6632 self.editFollowUpSmsText = ko.observable(''); 6633 6634 self.editSmsFollowupTextDialog = function(){ 6635 self.editFollowUpSmsText(self.getFollowUpTemplateText()); 6636 $("#editSmsFollowupTextDialog").dialog({ 6637 resizable: true, 6638 height: 400, 6639 width: 400, 6640 title: 'Tekstiviesti follow-up pohja', 6641 modal: true, 6642 buttons: { 6643 Peruuta: function(){ 6644 $(this).dialog('close'); 6645 }, 6646 Tallenna: function(){ 6647 self.saveSmsFolloupText(); 6648 $(this).dialog('close'); 6649 } 6650 } 6651 }); 6652 }; 6653 6654 self.saveSmsFolloupText = function(){ 6655 var data = { 6656 companyId: ko.toJS(self.account.company.id), 6657 followUpText: ko.toJS(self.editFollowUpSmsText) 6658 }; 6659 6660 jQuery 6661 .ajax({ 6662 type: 'POST', 6663 dataType: 'json', 6664 url: '/asiakkuudet/saveSmsFolloupText', 6665 data: data, 6666 }) 6667 .then(function(data) { 6668 if(data && data.followUpSettings) 6669 self.populateFollowUpSettings(data.followUpSettings); 6670 }) 6671 .fail(function(error) { 6672 alert(error.responseJSON); 6673 }); 6674 }; 6675 6676 self.followUpContactPerson = function() { 6677 return { 6678 id: ko.observable(), 6679 msisdn: ko.observable(), 6680 sales_name: ko.observable(), 6681 }; 6682 }; 6683 6684 self.addFollowUpContactPerson = function() { 6685 var contactPerson = self.followUpContactPerson(); 6686 self.followUpSettings.other_contact_persons.push(contactPerson); 6687 }; 6688 6689 self.removeFollowUpContactPerson = function(contactPerson) { 6690 if (contactPerson.id()) { 6691 return self.confirmRemoveFollowUpContactPerson(contactPerson); 6692 } 6693 self.followUpSettings.other_contact_persons.remove(contactPerson); 6694 }; 6695 6696 self.confirmRemoveFollowUpContactPerson = function(contactPerson) { 6697 var $dialog = $('<div />') 6698 .html( 6699 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa vastaanottajan?</p>' 6700 ) 6701 .dialog({ 6702 resizable: false, 6703 height: 200, 6704 width: 400, 6705 title: 'Poista vastaanottaja', 6706 modal: true, 6707 buttons: { 6708 Ei: function() { 6709 $(this).dialog('close'); 6710 }, 6711 Kyllä: function() { 6712 jQuery 6713 .ajax({ 6714 url: '/asiakkuudet/delete_follow_up_contact_person/' + contactPerson.id(), 6715 type: 'post', 6716 dataType: 'json', 6717 }) 6718 .done(function(responseJSON) { 6719 self.followUpSettings.other_contact_persons.remove(contactPerson); 6720 $dialog.dialog('close'); 6721 global.show_message(responseJSON); 6722 }) 6723 .fail(function(response) { 6724 global.show_message(response.responseJSON); 6725 global.close_loading_dialog(); 6726 }); 6727 }, 6728 }, 6729 }); 6730 }; 6731 6732 self.paymentTerminalDevices = ko.observableArray([]); 6733 6734 self.newPaymentTerminalDevice = { 6735 terminalId: ko.observable(''), 6736 terminalName: ko.observable(''), 6737 isDefault: ko.observable(false), 6738 }; 6739 6740 self.resetNewPaymentTerminalDevice = function () { 6741 self.newPaymentTerminalDevice.terminalId(''); 6742 self.newPaymentTerminalDevice.terminalName(''); 6743 self.newPaymentTerminalDevice.isDefault(false); 6744 }; 6745 6746 self.editPaymentTerminalDevice = { 6747 id: ko.observable(''), 6748 terminalId: ko.observable(''), 6749 terminalName: ko.observable(''), 6750 isDefault: ko.observable(false), 6751 }; 6752 6753 self.resetEditPaymentTerminalDevice = function () { 6754 self.editPaymentTerminalDevice.id(''); 6755 self.editPaymentTerminalDevice.terminalId(''); 6756 self.editPaymentTerminalDevice.terminalName(''); 6757 self.editPaymentTerminalDevice.isDefault(false); 6758 }; 6759 6760 self.populateEditPaymentTerminalDevice = function (data) { 6761 self.editPaymentTerminalDevice.id(data.id);
6762 self.editPaymentTerminalDevice.terminalId(data.terminal_id); 6763 self.editPaymentTerminalDevice.terminalName(data.terminal_name); 6764 self.editPaymentTerminalDevice.isDefault(data.is_default); 6765 }; 6766 6767 self.getTerminalStatus = function (device) { 6768 var data = { 6769 user_name: device.user_name, 6770 password: device.password, 6771 url: device.url, 6772 terminal_id: device.terminal_id, 6773 }; 6774 window.PaymentTerminal.getTerminalStatus(data); 6775 }; 6776 6777 self.addPaymentDeviceDialog = function () { 6778 $('#addPaymentDeviceDialog').dialog({ 6779 resizable: false, 6780 height: 400, 6781 width: 400, 6782 title: 'Lisää uusi maksupääte', 6783 modal: true, 6784 buttons: { 6785 Peruuta: function () { 6786 $(this).dialog('close'); 6787 }, 6788 Tallenna: function () { 6789 self.addPaymentTerminalDevice(); 6790 $(this).dialog('close'); 6791 }, 6792 }, 6793 }); 6794 }; 6795 6796 self.addPaymentTerminalDevice = function () { 6797 var data = { 6798 companyId: ko.toJS(self.account.company.id), 6799 newPaymentTerminalDevice: ko.toJS(self.newPaymentTerminalDevice), 6800 }; 6801 6802 jQuery 6803 .ajax({ 6804 type: 'POST', 6805 dataType: 'json', 6806 url: '/asiakkuudet/addPaymentDevice', 6807 data: data, 6808 }) 6809 .then(function (data) { 6810 if (self.paymentTerminalDevices.length > 0) self.paymentTerminalDevices.removeAll(); 6811 6812 self.paymentTerminalDevices(data); 6813 self.resetNewPaymentTerminalDevice(); 6814 }) 6815 .fail(function (error) { 6816 alert(error.responseJSON); 6817 }); 6818 }; 6819 6820 self.togglePaymentDeviceStatus = function (action, data) { 6821 self.populateEditPaymentTerminalDevice(data); 6822 return modifyPaymentDeviceOnServer(action); 6823 }; 6824 6825 self.editPaymentDeviceDialog = function (action, data) { 6826 self.populateEditPaymentTerminalDevice(data); 6827 $('#editPaymentDeviceDialog').dialog({ 6828 resizable: false, 6829 height: 400, 6830 width: 400, 6831 title: 'Muokkaa maksupäätelaitteen tietoja', 6832 modal: true, 6833 buttons: { 6834 Peruuta: function () { 6835 $(this).dialog('close'); 6836 }, 6837 Tallenna: function () { 6838 modifyPaymentDeviceOnServer(action); 6839 $(this).dialog('close'); 6840 }, 6841 }, 6842 }); 6843 }; 6844 6845 var modifyPaymentDeviceOnServer = function (action) { 6846 var data = { 6847 action: action, 6848 companyId: ko.toJS(self.account.company.id), 6849 editPaymentTerminalDevice: ko.toJS(self.editPaymentTerminalDevice), 6850 }; 6851 jQuery 6852 .ajax({ 6853 type: 'POST', 6854 dataType: 'json', 6855 url: 'asiakkuudet/updatePaymentDevice', 6856 data: data, 6857 }) 6858 .then(function (data) { 6859 if (self.paymentTerminalDevices.length > 0) self.paymentTerminalDevices.removeAll(); 6860 6861 self.paymentTerminalDevices(data); 6862 self.resetEditPaymentTerminalDevice(); 6863 }) 6864 .fail(function (error) { 6865 alert(error.responseJSON); 6866 }); 6867 }; 6868 6869 self.createInnohinausApiKey = function() { 6870 var companyId = ko.toJS(self.account.company.id); 6871 6872 global.show_loading_dialog(); 6873 6874 jQuery 6875 .ajax({ 6876 type: 'POST', 6877 dataType: 'json', 6878 url: `asiakkuudet/create_api_key/innohinaus/${companyId}`, 6879 }) 6880 .then(function (response) { 6881 if (response.data && response.data.innohinaus) { 6882 self.apiKeys.push(response.data.innohinaus); 6883 } 6884 6885 if (response.data && response.data[`innohinaus-update`]) { 6886 self.apiKeys.push(response.data[`innohinaus-update`]); 6887 } 6888 6889 global.close_loading_dialog(); 6890 }) 6891 .fail(function (response) { 6892 global.show_message(response.responseJSON); 6893 global.close_loading_dialog(); 6894 }); 6895 }; 6896 6897 self.populateEinvoiceData = function(data, log){ 6898 self.account.company.invoice_company_name(data.company_name || ''); 6899 self.account.company.e_invoice_address(data.e_invoice_address || ''); 6900 self.account.company.e_invoice_operator(data.e_invoice_operator || ''); 6901 }; 6902 6903 self.populateCompanyData = function(data){ 6904 self.account.company.company_name(data.company_name || ''); 6905 self.account.company.address(data.address || '');
6906 self.account.company.zipcode(data.zipcode || ''); 6907 self.account.company.city(data.city || ''); 6908 6909 self.account.company.phone(data.phone || ''); 6910 self.account.company.email(data.email || ''); 6911 6912 self.account.company.business_id(data.business_id || ''); 6913 } 6914 6915 self.autoPopulating = ko.observable(false); 6916 self.autoPopulateAccount = function () { 6917 var businessId = self.account.company.business_id(); 6918 if (!businessId) { 6919 return self.errorDialog('Täytä ensin yrityksen y-tunnus'); 6920 } 6921 6922 if (businessId.length < 9) { 6923 return self.errorDialog('Tarkista y-tunnuksen pituus'); 6924 } 6925 6926 self.autoPopulating(true); 6927 var eInvoicePromise = jQuery 6928 .ajax({ 6929 method: 'get', 6930 url: '/rest/_search/e_invoice', 6931 dataType: 'json', 6932 data: { 6933 type: 'e_invoice', 6934 identifier: businessId, 6935 originatorApp: 'asiakkuudet', 6936 }, 6937 }) 6938 .then(function (response) { 6939 if (!response || !response.data) { 6940 self.errorDialog('Virhe verkkolaskutietojen hakemisessa'); 6941 return; 6942 } 6943 if (response.data && response.data.length > 1) { 6944 self.errorDialog('Y-tunnukselle useampi verkkolaskuosoite. Valitse oikea osoite manuaalisesti.'); 6945 return; 6946 } 6947 var data = response.data && response.data[0]; 6948 if (!data) { 6949 self.errorDialog('Y-tunnukselle ei löytynyt verkkolaskuosoitetta'); 6950 } else { 6951 self.populateEinvoiceData(data); 6952 } 6953 }) 6954 .fail(function (error) { 6955 var msg = JSON.parse(error.responseText) || 'Virhe haussa. Yritä myöhemmin uudelleen.'; 6956 self.errorDialog(msg); 6957 }); 6958 6959 var companyPromise = jQuery 6960 .ajax({ 6961 method: 'get', 6962 url: '/rest/_search/', 6963 dataType: 'json', 6964 data: { 6965 type: 'company', 6966 identifier: businessId, 6967 originatorApp: 'asiakkuudet', 6968 }, 6969 }) 6970 .then(function (response) { 6971 if (!response || !response.customer) { 6972 self.errorDialog('Virhe yritystietojen hakemisessa'); 6973 } 6974 var data = response.customer; 6975 if (!data) { 6976 self.errorDialog('Y-tunnukselle ei löytynyt verkkolaskuosoitetta'); 6977 } else { 6978 self.populateCompanyData(data); 6979 console.log({ 6980 text: 'Verkkolaskutiedot haettu onnistuneesti', 6981 addnCls: 'humane-jackedup-success', 6982 }); 6983 } 6984 }) 6985 .fail(function (error) { 6986 var msg = JSON.parse(error.responseText) || 'Virhe haussa. Yritä myöhemmin uudelleen.'; 6987 self.errorDialog(msg); 6988 }); 6989 6990 jQuery.when(eInvoicePromise, companyPromise).always(function () { 6991 self.autoPopulating(false); 6992 global.show_message({ 6993 title: 'Asiakuuden automaattinen täyttö', 6994 text: 'Verkkolasku ja yrityksen tiedot haettu onnistuneesti.', 6995 type: 'success', 6996 }); 6997 }); 6998 } 6999 7000 self.showCreateInnohinausApiKeysBtn = ko.pureComputed(function() { 7001 return ko.toJS(self.account.preferences.mod_innohinaus_api) && self.apiKeys && !ko.utils.arrayFirst(self.apiKeys(), function(element) { 7002 return element.api_name == 'innohinaus'; 7003 }); 7004 }); 7005 7006 self.kycBankOwnerTypes = ko.observableArray([ 7007 { 7008 name: 'Valitse', value: '' 7009 }, 7010 { 7011 name: 'Yritys tai yhteisö', value: 'company' 7012 }, 7013 { 7014 name: 'Yksityishenkilö', value: 'person' 7015 }, 7016 ]) 7017 7018 self.kycRegistrationOptions = ko.observableArray([ 7019 { value: '', name: 'Valitse' }, 7020 { value: 'yes', name: 'On rekisterissä' }, 7021 { value: 'no', name: 'Ei rekisterissä' } 7022 ]) 7023 7024 self.countries = ko.observableArray([ 7025 { 7026 name: 'Suomi', 7027 }, 7028 { 7029 name: 'Afganistan', 7030 }, 7031 { 7032 name: 'Alankomaat', 7033 }, 7034 { 7035 name: 'Alankomaiden Karibia', 7036 }, 7037 { 7038 name: 'Albania', 7039 }, 7040 { 7041 name: 'Algeria', 7042 }, 7043 { 7044 name: 'Amerikan Samoa', 7045 }, 7046 { 7047 name: 'Andorra', 7048 }, 7049 { 7050 name: 'Angola', 7051 }, 7052 { 7053 name: 'Anguilla', 7054 }, 7055 { 7056 name: 'Antarktis', 7057 }, 7058 { 7059 name: 'Antigua ja Barbuda', 7060 }, 7061 { 7062 name: 'Arabiemiirikunnat', 7063 }, 7064 { 7065 name: 'Argentiina', 7066 }, 7067 { 7068 name: 'Armenia', 7069 }, 7070 { 7071 name: 'Aruba', 7072 }, 7073 { 7074 name: 'Australia', 7075 }, 7076 { 7077 name: 'Azerbaidžan', 7078 }, 7079 { 7080 name: 'Bahama', 7081 }, 7082 { 7083 name: 'Bahrain', 7084 }, 7085 { 7086 name: 'Bangladesh', 7087 }, 7088 { 7089 name: 'Barbados', 7090 }, 7091 { 7092 name: 'Belgia', 7093 }, 7094 { 7095 name: 'Belize', 7096 }, 7097 { 7098 name: 'Benin', 7099 }, 7100 { 7101 name: 'Bermuda', 7102 }, 7103 { 7104 name: 'Bhutan', 7105 }, 7106 { 7107 name: 'Bolivia', 7108 }, 7109 { 7110 name: 'Bosnia ja Hertsegovina', 7111 }, 7112 { 7113 name: 'Botswana', 7114 }, 7115 { 7116 name: 'Bouvetânsaari', 7117 }, 7118 { 7119 name: 'Brasilia', 7120 }, 7121 { 7122 name: 'Brittiläinen Intian valtameren alue', 7123 }, 7124 { 7125 name: 'Brittiläiset Neitsytsaaret', 7126 }, 7127 { 7128 name: 'Brunei', 7129 }, 7130 { 7131 name: 'Bulgaria', 7132 }, 7133 { 7134 name: 'Burkina Faso', 7135 }, 7136 { 7137 name: 'Burundi', 7138 }, 7139 { 7140 name: 'Caymansaaret', 7141 }, 7142 { 7143 name: 'Chile', 7144 }, 7145 { 7146 name: 'Cookinsaaret', 7147 }, 7148 { 7149 name: 'Costa Rica', 7150 }, 7151 { 7152 name: 'Curaçao', 7153 }, 7154 { 7155 name: 'Djibouti', 7156 }, 7157 { 7158 name: 'Dominica', 7159 }, 7160 { 7161 name: 'Dominikaaninen tasavalta', 7162 }, 7163 { 7164 name: 'Ecuador', 7165 }, 7166 { 7167 name: 'Egypti', 7168 }, 7169 { 7170 name: 'El Salvador', 7171 }, 7172 { 7173 name: 'Eritrea', 7174 }, 7175 { 7176 name: 'Espanja', 7177 }, 7178 { 7179 name: 'Etiopia', 7180 }, 7181 { 7182 name: 'Etelä-Afrikka', 7183 }, 7184 { 7185 name: 'Etelä-Georgia ja Eteläiset Sandwichsaaret', 7186 }, 7187 { 7188 name: 'Etelä-Sudan', 7189 }, 7190 { 7191 name: 'Falklandinsaaret', 7192 }, 7193 { 7194 name: 'Färsaaret', 7195 }, 7196 { 7197 name: 'Fidži', 7198 }, 7199 { 7200 name: 'Filippiinit', 7201 }, 7202 { 7203 name: 'Gabon', 7204 }, 7205 { 7206 name: 'Gambia', 7207 }, 7208 { 7209 name: 'Georgia', 7210 }, 7211 { 7212 name: 'Ghana', 7213 }, 7214 { 7215 name: 'Gibraltar', 7216 }, 7217 { 7218 name: 'Grenada', 7219 }, 7220 { 7221 name: 'Grönlanti', 7222 }, 7223 { 7224 name: 'Guadeloupe', 7225 }, 7226 { 7227 name: 'Guam', 7228 }, 7229 { 7230 name: 'Guatemala', 7231 }, 7232 { 7233 name: 'Guernsey', 7234 }, 7235 { 7236 name: 'Guinea', 7237 }, 7238 { 7239 name: 'Guinea-Bissau', 7240 }, 7241 { 7242 name: 'Guyana', 7243 }, 7244 { 7245 name: 'Haiti', 7246 }, 7247 { 7248 name: 'Heard ja McDonaldinsaaret', 7249 }, 7250 { 7251 name: 'Honduras', 7252 }, 7253 { 7254 name: 'Hongkong', 7255 }, 7256 { 7257 name: 'Indonesia', 7258 }, 7259 { 7260 name: 'Intia', 7261 }, 7262 { 7263 name: 'Irak', 7264 }, 7265 { 7266 name: 'Iran', 7267 }, 7268 { 7269 name: 'Irlanti', 7270 }, 7271 { 7272 name: 'Islanti', 7273 }, 7274 { 7275 name: 'Israel', 7276 }, 7277 { 7278 name: 'Italia', 7279 }, 7280 { 7281 name: 'Itä-Timor', 7282 }, 7283 { 7284 name: 'Itävalta', 7285 }, 7286 { 7287 name: 'Jamaika', 7288 }, 7289 { 7290 name: 'Japani', 7291 }, 7292 { 7293 name: 'Jemen', 7294 }, 7295 { 7296 name: 'Jersey', 7297 }, 7298 { 7299 name: 'Jordania', 7300 }, 7301 { 7302 name: 'Joulusaari', 7303 }, 7304 { 7305 name: 'Kambodža', 7306 }, 7307 { 7308 name: 'Kamerun', 7309 }, 7310 { 7311 name: 'Kanada', 7312 }, 7313 { 7314 name: 'Kap Verde', 7315 }, 7316 { 7317 name: 'Kazakstan', 7318 }, 7319 { 7320 name: 'Kenia', 7321 }, 7322 { 7323 name: 'Keski-Afrikan tasavalta', 7324 }, 7325 { 7326 name: 'Kiina', 7327 }, 7328 { 7329 name: 'Kirgisia', 7330 }, 7331 { 7332 name: 'Kiribati', 7333 }, 7334 { 7335 name: 'Kolumbia', 7336 }, 7337 { 7338 name: 'Komorit', 7339 }, 7340 { 7341 name: 'Kongon demokraattinen tasavalta', 7342 }, 7343 { 7344 name: 'Kongon tasavalta', 7345 }, 7346 { 7347 name: 'Kookossaaret', 7348 }, 7349 { 7350 name: 'Korean demokraattinen kansantasavalta', 7351 }, 7352 { 7353 name: 'Korean tasavalta', 7354 }, 7355 { 7356 name: 'Kreikka', 7357 }, 7358 { 7359 name: 'Kroatia', 7360 }, 7361 { 7362 name: 'Kuuba', 7363 }, 7364 { 7365 name: 'Kuwait', 7366 }, 7367 { 7368 name: 'Kypros', 7369 }, 7370 { 7371 name: 'Laos', 7372 }, 7373 { 7374 name: 'Latvia', 7375 }, 7376 { 7377 name: 'Lesotho', 7378 }, 7379 { 7380 name: 'Libanon', 7381 }, 7382 { 7383 name: 'Liberia', 7384 }, 7385 { 7386 name: 'Libya', 7387 }, 7388 { 7389 name: 'Liechtenstein', 7390 }, 7391 { 7392 name: 'Liettua', 7393 }, 7394 { 7395 name: 'Luxemburg', 7396 }, 7397 { 7398 name: 'Länsi-Sahara', 7399 }, 7400 { 7401 name: 'Macao', 7402 }, 7403 { 7404 name: 'Madagaskar', 7405 }, 7406 { 7407 name: 'Malawi', 7408 }, 7409 { 7410 name: 'Malediivit', 7411 }, 7412 { 7413 name: 'Malesia', 7414 }, 7415 { 7416 name: 'Mali', 7417 }, 7418 { 7419 name: 'Malta', 7420 }, 7421 { 7422 name: 'Mansaari', 7423 }, 7424 { 7425 name: 'Marokko', 7426 }, 7427 { 7428 name: 'Marshallinsaaret', 7429 }, 7430 { 7431 name: 'Martinique', 7432 }, 7433 { 7434 name: 'Mauritania', 7435 }, 7436 { 7437 name: 'Mauritius', 7438 }, 7439 { 7440 name: 'Mayotte', 7441 }, 7442 { 7443 name: 'Meksiko', 7444 }, 7445 { 7446 name: 'Mikronesian liittovaltio', 7447 }, 7448 { 7449 name: 'Moldova', 7450 }, 7451 { 7452 name: 'Monaco', 7453 }, 7454 { 7455 name: 'Mongolia', 7456 }, 7457 { 7458 name: 'Montenegro', 7459 }, 7460 { 7461 name: 'Montserrat', 7462 }, 7463 { 7464 name: 'Mosambik', 7465 }, 7466 { 7467 name: 'Myanmar', 7468 }, 7469 { 7470 name: 'Namibia', 7471 }, 7472 { 7473 name: 'Nauru', 7474 }, 7475 { 7476 name: 'Nepal', 7477 }, 7478 { 7479 name: 'Nicaragua', 7480 }, 7481 { 7482 name: 'Niger', 7483 }, 7484 { 7485 name: 'Nigeria', 7486 }, 7487 { 7488 name: 'Niue', 7489 }, 7490 { 7491 name: 'Norfolkinsaari', 7492 }, 7493 { 7494 name: 'Norja', 7495 }, 7496 { 7497 name: 'Norsunluurannikko', 7498 }, 7499 { 7500 name: 'Oman', 7501 }, 7502 { 7503 name: 'Pakistan', 7504 }, 7505 { 7506 name: 'Palau', 7507 }, 7508 { 7509 name: 'Palestiina', 7510 }, 7511 { 7512 name: 'Panama', 7513 }, 7514 { 7515 name: 'Papua-Uusi-Guinea', 7516 }, 7517 { 7518 name: 'Paraguay', 7519 }, 7520 { 7521 name: 'Peru', 7522 }, 7523 { 7524 name: 'Pohjois-Mariaanit', 7525 }, 7526 { 7527 name: 'Pitcairn', 7528 }, 7529 { 7530 name: 'Pohjois-Makedonia', 7531 }, 7532 { 7533 name: 'Portugali', 7534 }, 7535 { 7536 name: 'Puerto Rico', 7537 }, 7538 { 7539 name: 'Puola', 7540 }, 7541 { 7542 name: 'Päiväntasaajan Guinea', 7543 }, 7544 { 7545 name: 'Qatar', 7546 }, 7547 { 7548 name: 'Ranska', 7549 }, 7550 { 7551 name: 'Ranskan eteläiset alueet', 7552 }, 7553 { 7554 name: 'Ranskan Guayana', 7555 }, 7556 { 7557 name: 'Ranskan Polynesia', 7558 }, 7559 { 7560 name: 'Réunion', 7561 }, 7562 { 7563 name: 'Romania', 7564 }, 7565 { 7566 name: 'Ruanda', 7567 }, 7568 { 7569 name: 'Ruotsi', 7570 }, 7571 { 7572 name: 'Saint Barthélemy', 7573 }, 7574 { 7575 name: 'Saint Helena, Ascension ja Tristan da Cunha', 7576 }, 7577 { 7578 name: 'Saint Kitts ja Nevis', 7579 }, 7580 { 7581 name: 'Saint Lucia', 7582 }, 7583 { 7584 name: 'Saint Martin (Ranska)', 7585 }, 7586 { 7587 name: 'Saint-Pierre ja Miquelon', 7588 }, 7589 { 7590 name: 'Saint Vincent ja Grenadiinit', 7591 }, 7592 { 7593 name: 'Saksa', 7594 }, 7595 { 7596 name: 'Salomonsaaret', 7597 }, 7598 { 7599 name: 'Sambia', 7600 }, 7601 { 7602 name: 'Samoa', 7603 }, 7604 { 7605 name: 'San Marino', 7606 }, 7607 { 7608 name: 'São Tomé ja PrÃncipe', 7609 }, 7610 { 7611 name: 'Saudi-Arabia', 7612 }, 7613 { 7614 name: 'Senegal', 7615 }, 7616 { 7617 name: 'Serbia', 7618 }, 7619 { 7620 name: 'Seychellit', 7621 }, 7622 { 7623 name: 'Sierra Leone', 7624 }, 7625 { 7626 name: 'Singapore', 7627 }, 7628 { 7629 name: 'Sint Maarten (Alankomaat)', 7630 }, 7631 { 7632 name: 'Slovakia', 7633 }, 7634 { 7635 name: 'Slovenia', 7636 }, 7637 { 7638 name: 'Somalia', 7639 }, 7640 { 7641 name: 'Sri Lanka', 7642 }, 7643 { 7644 name: 'Sudan', 7645 }, 7646 { 7647 name: 'Suriname', 7648 }, 7649 { 7650 name: 'Svalbard ja Jan Mayen', 7651 }, 7652 { 7653 name: 'Swazimaa', 7654 }, 7655 { 7656 name: 'Sveitsi', 7657 }, 7658 { 7659 name: 'Syyria', 7660 }, 7661 { 7662 name: 'Tadžikistan', 7663 }, 7664 { 7665 name: 'Taiwan', 7666 }, 7667 { 7668 name: 'Tansania', 7669 }, 7670 { 7671 name: 'Tanska', 7672 }, 7673 { 7674 name: 'Thaimaa', 7675 }, 7676 { 7677 name: 'Togo', 7678 }, 7679 { 7680 name: 'Tokelau', 7681 }, 7682 { 7683 name: 'Tonga', 7684 }, 7685 { 7686 name: 'Trinidad ja Tobago', 7687 }, 7688 { 7689 name: 'TÅ¡ad', 7690 }, 7691 { 7692 name: 'TÅ¡ekki', 7693 }, 7694 { 7695 name: 'Tunisia', 7696 }, 7697 { 7698 name: 'Turkki', 7699 }, 7700 { 7701 name: 'Turkmenistan', 7702 }, 7703 { 7704 name: 'Turks- ja Caicossaaret', 7705 }, 7706 { 7707 name: 'Tuvalu', 7708 }, 7709 { 7710 name: 'Uganda', 7711 }, 7712 { 7713 name: 'Ukraina', 7714 }, 7715 { 7716 name: 'Unkari', 7717 }, 7718 { 7719 name: 'Uruguay', 7720 }, 7721 { 7722 name: 'Uusi-Kaledonia', 7723 }, 7724 { 7725 name: 'Uusi-Seelanti', 7726 }, 7727 { 7728 name: 'Uzbekistan', 7729 }, 7730 { 7731 name: 'Valko-Venäjä', 7732 }, 7733 { 7734 name: 'Vanuatu', 7735 }, 7736 { 7737 name: 'Vatikaanivaltio (Pyhä istuin)', 7738 }, 7739 { 7740 name: 'Venezuela', 7741 }, 7742 { 7743 name: 'Venäjä', 7744 }, 7745 { 7746 name: 'Vietnam', 7747 }, 7748 { 7749 name: 'Viro', 7750 }, 7751 { 7752 name: 'Wallis ja Futunasaaret', 7753 }, 7754 { 7755 name: 'Yhdistynyt kuningaskunta', 7756 }, 7757 { 7758 name: 'Yhdysvallat', 7759 }, 7760 { 7761 name: 'Yhdysvaltain Neitsytsaaret', 7762 }, 7763 { 7764 name: 'Yhdysvaltain pienet erillissaaret', 7765 }, 7766 { 7767 name: 'Zimbabwe', 7768 }, 7769 ]); 7770}; 7771 7772;var getNegativeValue = function(val){ 7773 return parseFloat(String(ko.toJS(val)).replace(",", ".")) * -1; 7774}; 7775 7776// format sum in view.
7777var formatAmount = function(amount) { 7778 var formatted = (+ ('' + ko.toJS(amount)).replace(',','.')); 7779 return formatted.toFixed(2).replace('.',','); 7780}; 7781 7782var CreditInvoiceDialogVm = function(params) { 7783 7784 'use strict'; 7785 var self = this; 7786 7787 self.changed = ko.observable(false); // A pub-sub flag that parent subscribers can check for 7788 self.crediting = ko.observable(false); // Flag to check if we should show spinner when crediting 7789 self.credited = ko.observable(false); 7790 7791 self.dialog = null; // reference to jQuery ui dialog obj 7792 7793 self.infoModal = { 7794 7795 $elem: $('#infoModal'), 7796 title: ko.observable(''), 7797 text: ko.observable(''), 7798 7799 show: function(text, title){ 7800 7801 this.text(text); 7802 this.title(title); 7803 7804 this.$elem.dialog({ 7805 7806 width:400, 7807 //height:200, 7808 autoOpen: true, 7809 modal: true, 7810 resizable: false, 7811 draggable: false, 7812 beforeclose: function(event, ui) {event.stopPropagation();}, 7813 close: function(){ 7814 self.changed(true); //Set the changed param to true, so parent Dialog knows to refresh 7815 $(this).dialog('destroy'); 7816 return true; 7817 }, 7818 buttons: { 7819 'Ok': function() { 7820 $(this).dialog('close'); 7821 } 7822 } 7823 }); 7824 } 7825 }; 7826 7827 self.errorModal = { 7828 7829 $elem: $('#errorModal'), 7830 title: ko.observable(''), 7831 text: ko.observable(''), 7832 7833 show: function(text, title){ 7834 7835 this.text(text); 7836 this.title(title); 7837 7838 this.$elem.dialog({ 7839 7840 width:400, 7841 //height:200, 7842 autoOpen: true, 7843 modal: true, 7844 resizable: false, 7845 draggable: false, 7846 beforeclose: function(event, ui) {event.stopPropagation();}, 7847 close: function(){ 7848 $(this).dialog('destroy') 7849 }, 7850 buttons: { 7851 'Sulje': function() { 7852 $(this).dialog('close'); 7853 } 7854 } 7855 }); 7856 } 7857 }; 7858 7859 self.invoiceCreditAmount = ko.observable(false); 7860 7861 self.selectedCreditType = ko.observable(); 7862 7863 self.selectedCreditSubType = ko.observable(); 7864 7865 self.setSelectedCreditType = function(){ 7866 7867 if(self.invoice.type() === 'credit_note' || self.invoice.type() === 'paid_to_customer'){ 7868 return self.selectedCreditType('amountToPay'); 7869 } 7870 7871 if(self.openAmountCreditingIsAllowed()){ 7872 return self.selectedCreditType('openAmount'); 7873 } 7874 }; 7875 7876 self.setSelectedCreditSubType = function(){ 7877 7878 if(self.vatExcludedCreditingIsAllowed() && self.vatAmountCreditingIsAllowed()){ 7879 return self.selectedCreditSubType('vatIncluded'); 7880 } 7881 7882 if(self.vatExcludedCreditingIsAllowed()){ 7883 return self.selectedCreditSubType('vatExcluded'); 7884 } 7885 7886 if(self.vatAmountCreditingIsAllowed()){ 7887 return self.selectedCreditSubType('vatAmount'); 7888 } 7889 }; 7890 7891 self.vatOptions = ko.observableArray(['25.5', '24', '14', '10', '0']); 7892 7893 self.preferences = ko.mapping.fromJS(params.preferences); 7894 self.invoice = ko.mapping.fromJS(params.invoice); 7895 self.invoiceTotals = ko.mapping.fromJS(params.invoiceTotals); 7896 7897 var today = new Date(), 7898 dd = String(today.getDate()).padStart(2, '0'), 7899 mm = String(today.getMonth() + 1).padStart(2, '0'), 7900 yyyy = today.getFullYear(); 7901 7902 //Holds details about the creditInvoice thats going to be applied 7903 self.creditInvoice = { 7904 items: ko.observableArray([]), 7905 deliveryOptions: { 7906 deliveryMethod: ko.observable('no_delivery'), //How creditInvoice will be delivered, mail/email/no_delivery 7907 email: ko.observable('') 7908 }, 7909 partlyCreditAmount: ko.observable(), 7910 ownRiskAmount: ko.observable(), 7911 paidToCustomerAmount: ko.observable(self.invoiceTotals.amountToPay()),
7912 paidToCustomerDate: ko.observable(dd + '.' + mm + '.' + yyyy), 7913 vatDetails: ko.observableArray([]), 7914 creditType: ko.computed(function (){ 7915 return self.selectedCreditType(); 7916 }), 7917 creditSubType: ko.computed(function (){ 7918 return self.selectedCreditSubType(); 7919 }), 7920 }; 7921 7922 7923 self.creditInvoice.makeItems = function(){ 7924 7925 var amountToCreditLeft = self.creditInvoice.creditAmount(); 7926 7927 var items = [], makeItem = function(invoiceVatDetailRow){ 7928 7929 var creditType = self.selectedCreditType(), 7930 creditSubType = self.selectedCreditSubType(), 7931 type = 'credit', 7932 name = 'Hyvitys', 7933 unitprice = invoiceVatDetailRow.vatIncludedAmount > amountToCreditLeft ? amountToCreditLeft : invoiceVatDetailRow.vatIncludedAmount, 7934 unit = 'kpl', 7935 vat = invoiceVatDetailRow.vat, 7936 vat_included = 1; 7937 7938 if(creditSubType === 'vatIncluded'){ 7939 type = 0; 7940 } 7941 7942 if(creditSubType === 'vatExcluded'){ 7943 type = 20; 7944 name = 'Hyvitys, ALV-0%'; 7945 } 7946 7947 if(creditSubType === 'vatAmount'){ 7948 type = 21; 7949 name = 'Hyvitys, ALV'; 7950 } 7951 7952 if(creditType === 'ownRisk'){ 7953 name = 'Omavastuu'; 7954 type = 60; 7955 vat = 0; 7956 } 7957 7958 if(creditType === 'paidToCustomer'){ 7959 name = 'Maksettu suoraan myyjälle'; 7960 } 7961 7962 if(creditType === 'vatExcludedAmount'){ 7963 vat_included = 0; 7964 name = 'Vakuutusyhtiön osuus'; 7965 type = 43; 7966 } 7967 7968 if(creditType === 'vatAmount'){ 7969 vat_included = 0; 7970 name = 'ALV-vähennys'; 7971 type = 41; 7972 } 7973 7974 if(self.invoice.type() === 'credit_note'){ 7975 name = 'Hyvityslaskun mitätöinti (' + self.invoice.invoice_number() + ')'; 7976 unitprice = invoiceVatDetailRow.vatIncludedAmount * -1; 7977 } 7978 7979 amountToCreditLeft -= unitprice; 7980 7981 return { 7982 type: ko.observable(type), 7983 name: ko.observable(name), 7984 unitprice: ko.observable(unitprice), 7985 unit: ko.observable(unit), 7986 vatFreeAmount: ko.observable(),
7987 vatAmount: ko.observable(), 7988 vatIncludedAmount: ko.observable(), 7989 vat: ko.observable(vat), 7990 vat_included: ko.observable(vat_included) 7991 }; 7992 }; 7993 7994 _.each(ko.toJS(self.invoiceTotals.vatDetails), function(elem, index){ 7995 //console.log('_.each ...'); 7996 //console.log(elem, index); 7997 //console.log('amountToCreditLeft before:', amountToCreditLeft); 7998 7999 if(self.invoice.type() !== 'credit_note' && amountToCreditLeft < 0){ 8000 items.push(makeItem(elem)); 8001 } 8002 8003 if(self.invoice.type() === 'credit_note' && amountToCreditLeft > 0){ 8004 items.push(makeItem(elem)); 8005 } 8006 8007 if(self.invoice.type() === 'paid_to_customer'){ 8008 items.push(makeItem(elem)); 8009 } 8010 8011 //console.log('amountToCreditLeft after:', amountToCreditLeft); 8012 }); 8013 8014 self.creditInvoice.items(items); 8015 }; 8016 8017 self.creditInvoice.creditAmount = ko.computed(function(){ 8018 8019 var creditType = self.selectedCreditType(), 8020 creditAmount = self.invoiceTotals[creditType]; 8021 8022 //Override calculation of ownRisk creditAmount 8023 if(creditType === 'ownRisk'){ 8024 creditAmount = ko.toJS(self.creditInvoice.ownRiskAmount); 8025 } 8026 8027 //Override calculation of ownRisk creditAmount 8028 if(creditType === 'paidToCustomer'){ 8029 creditAmount = ko.toJS(self.creditInvoice.paidToCustomerAmount); 8030 } 8031 8032 //Override calculation of custom creditAmount 8033 if(creditType === 'partly'){ 8034 creditAmount = ko.toJS(self.creditInvoice.partlyCreditAmount); 8035 } 8036 8037 //Make creditAmount always negative 8038 creditAmount = getNegativeValue(creditAmount); 8039 8040 if(isNaN(creditAmount)){ 8041 return 0; 8042 } 8043 8044 return creditAmount; 8045 }); 8046 8047 //CreditAmount has changed, make new creditItems 8048 self.creditInvoice.creditAmount.subscribe(function(){ 8049 self.creditInvoice.makeItems(); 8050 }); 8051 8052 self.selectedCreditType.subscribe(function(){ 8053 self.setSelectedCreditSubType(); 8054 self.creditInvoice.makeItems(); 8055 }); 8056 8057 self.selectedCreditSubType.subscribe(function(){ 8058 self.creditInvoice.makeItems(); 8059 }); 8060 8061 self.creditInvoice.openAmountAfterCreditInvoice = ko.computed(function(){ 8062 8063 var openAmount = parseFloat(ko.toJS(self.invoiceTotals.openAmount)), 8064 creditAmount = self.creditInvoice.creditAmount(); 8065 8066 if(isNaN(openAmount) || isNaN(creditAmount)){ 8067 return 0; 8068 } 8069 8070 //creditAmount will always be negative 8071 openAmount = (openAmount + creditAmount); 8072 8073 //Return 0 if openAmount would be less than zero 8074 return openAmount < 0 ? 0 : openAmount; 8075 }); 8076 8077 self.creditInvoice.amountToPayAfterCreditInvoice = ko.computed(function(){ 8078 8079 var amountToPay = parseFloat(ko.toJS(self.invoiceTotals.amountToPay)), 8080 creditAmount = self.creditInvoice.creditAmount(); 8081 8082 if(isNaN(amountToPay) || isNaN(creditAmount)){ 8083 return 0; 8084 } 8085 8086 //creditAmount will always be negative 8087 amountToPay = (amountToPay + creditAmount); 8088 8089 if(self.invoice.type() === 'credit_note'){ 8090 return amountToPay; 8091 } 8092 8093 //Return 0 if openAmount would be less than zero 8094 return amountToPay < 0 ? 0 : amountToPay; 8095 }); 8096 8097 self.getCreditAmountFromVatDetails = function(){ 8098 8099 var creditAmount = 0, vatDetails = ko.toJS(self.creditInvoice.vatDetails); 8100 8101 _.each(vatDetails, function(elem, index){ 8102 8103 creditAmount += (+ ko.toJS(elem.vatFreeAmount).toString().replace(",", ".")); 8104 creditAmount += (+ ko.toJS(elem.vatAmount).toString().replace(",", ".")); 8105 }); 8106 8107 return creditAmount; 8108 }; 8109 8110 self.setData = function(){ 8111 8112 self.reset(); 8113 self.setSelectedCreditType(); 8114 self.presetDeliveryMethod(); 8115 }; 8116 8117 //Preset the delivery method to the same as on crossed invoice 8118 self.presetDeliveryMethod = function(){ 8119 8120 var crossedInvoiceDeliveryMethod = ko.toJS(self.invoice.delivery_by), 8121 deliverCreditNotesToCustomers = ko.toJS(self.preferences.credit_note_delivery); 8122 8123 if(deliverCreditNotesToCustomers) 8124 self.creditInvoice.deliveryOptions.deliveryMethod(crossedInvoiceDeliveryMethod); 8125 }; 8126 8127 self.reset = function(){ 8128 self.selectedCreditType(false); 8129 self.creditInvoice.vatDetails([]); 8130 self.creditInvoice.items([]); 8131 }; 8132 8133 self.show = function(isAdmin = false){ 8134 8135 //If jQuery UI dialog has not been inited yet 8136 if(self.dialog === null){ 8137 8138 self.dialog = $('#credit-invoice-dialog').dialog({ 8139 8140 width:800, 8141 height:600, 8142 autoOpen: false, 8143 modal: true, 8144 resizable: false, 8145 draggable: false, 8146 beforeclose: function(event) { 8147 $('link#extrabs').remove(); 8148 $('script#bsjs').remove(); 8149 event.stopPropagation();
8150 $('#errorModal') 8151 }, 8152 close: function(){ 8153 self.close(); 8154 }, 8155 title: 'Lisää hyvitys laskuun', 8156 buttons: { 8157 'Sulje': function() { 8158 self.dialog.dialog('close'); 8159 } 8160 } 8161 }); 8162 } 8163 8164 self.dialog.dialog('open'); 8165 8166 // Only append BS if it's not loaded already 8167 if (isAdmin === false) { 8168 self.dialog.append( 8169 $('<link />', { 8170 id: 'extrabs', 8171 rel: 'stylesheet', 8172 href:'//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'} 8173 ) 8174 ); 8175 } 8176 }; 8177 8178 self.close = function(){ 8179 8180 if(self.dialog){ 8181 self.dialog.dialog('destroy'); 8182 self.dialog = null; 8183 } 8184 }; 8185 8186 self.makeCreditInvoice = function(){ 8187 8188 try { 8189 self.validateCreditInvoice(); 8190 }catch(exception){ 8191 return self.errorModal.show(exception, 'Virhe luotaessa hyvitystä'); 8192 } 8193 8194 8195 var data = { 8196 invoiceId: ko.toJS(self.invoice.id), 8197 creditInvoice: ko.toJS(self.creditInvoice) 8198 }; 8199 8200 self.crediting(true); 8201 8202 //Show success / error message 8203 $.ajax({ 8204 type: 'post', 8205 url: '/iv_laskutus_ja_reskontra/creditInvoice', 8206 data: data 8207 }).fail(function(response) { 8208 self.crediting(false); 8209 8210 var parsed = $.parseJSON(response.responseText); 8211 //console.log(parsed); 8212 self.errorModal.show(parsed.text, 'Virhe luotaessa hyvitystä'); 8213 }).done(function(response) { 8214 //console.log(response); 8215 self.crediting(false); 8216 self.credited(true); 8217 self.infoModal.show(response.text, 'Hyvitys luotu onnistuneesti'); 8218 8219 //Refresh the datatables 8220 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null){ 8221 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 8222 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 8223 } 8224 8225 if(pages.iv_laskutus_ja_reskontra.$datatable != null){ 8226 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 8227 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 8228 } 8229 8230 if(pages.reskontra.$datatable != null){ 8231 pages.reskontra.$datatable.fnClearTable( 0 ); 8232 pages.reskontra.$datatable.fnDraw(); 8233 } 8234 }); 8235 8236 }; 8237 8238 self.validateCreditInvoice = function(){ 8239 8240 //Check that there is enough vatIncluded amount left on invoice to credit 8241 var creditAmount = self.creditInvoice.creditAmount(), 8242 invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8243 8244 if(self.invoice.type() !== 'credit_note' && self.invoice.type() !== 'paid_to_customer' && Math.abs(creditAmount) > invoiceTotals.amountToPay){ 8245 throw "Hyvitettävä summa ylittää laskun maksettavan summan. Tarkista hyvitys!"; 8246 } 8247 8248 if(self.selectedCreditType() === 'partly'){ 8249 8250 if(self.selectedCreditSubType() === 'vatExcluded' && (creditAmount > invoiceTotals.vatExcludedAmount)){ 8251 throw 'Hyvitettävä summa ylittää laskun ALV-0% osuuden. Tarkista hyvitys!'; 8252 } 8253 8254 if(self.selectedCreditSubType() === 'vatAmount' && (creditAmount > invoiceTotals.vatAmount)){ 8255 throw 'Hyvitettävä summa ylittää laskun ALV-osuuden. Tarkista hyvitys!'; 8256 } 8257 } 8258 }; 8259 8260 8261 self.openAmountCreditingIsAllowed = ko.computed(function(){ 8262 8263 var invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8264 8265 return (invoiceTotals.openAmount > 0 && (invoiceTotals.amountToPay != invoiceTotals.openAmount)); 8266 }); 8267 8268 self.amountToPayCreditingIsAllowed = ko.computed(function(){ 8269 8270 var invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8271 8272 return ((self.invoice.type() !== 'credit_note' && invoiceTotals.amountToPay > 0) 8273 || (self.invoice.type() === 'credit_note' && invoiceTotals.amountToPay < 0)); 8274 }); 8275 8276 self.vatExcludedCreditingIsAllowed = ko.computed(function(){ 8277 8278 var invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8279 8280 return (invoiceTotals.vatExcludedAmount > 0); 8281 }); 8282 8283 self.vatAmountCreditingIsAllowed = ko.computed(function(){ 8284 8285 var invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8286
8287 return (invoiceTotals.vatAmount > 0); 8288 }); 8289 8290 self.creditingIsAllowed = ko.computed(function(){ 8291 8292 if(self.invoice.type() === 'corporate_chain_invoice') 8293 return false; 8294 8295 if(self.invoice.type() === 'paid_to_customer') 8296 return true; 8297 8298 return (self.openAmountCreditingIsAllowed() || self.amountToPayCreditingIsAllowed()); 8299 }); 8300 8301 self.creditingNotAllowedText = ko.computed(function () { 8302 8303 var invoiceTotals = ko.mapping.toJS(params.invoiceTotals); 8304 8305 if(self.invoice.type() === 'corporate_chain_invoice') 8306 return 'Ketjulaskulle ei voida suoraan tehdä hyvitystä. Hyvitykset tulee tehdä alkuperäiselle laskulle.'; 8307 8308 if(invoiceTotals.openAmount === 0){ 8309 return 'Laskuun ei voida kohdistaa hyvityksiä. Laskulla ei maksettavaa osuutta.' 8310 } 8311 8312 return ''; 8313 }) 8314 8315}; 8316 8317; 8318var CustomerCreditInvoiceDialogVM = function () { 8319 8320 'use strict'; 8321 var self = this; 8322 8323 //constanst 8324 self.dialog = null; 8325 self.dialogElem = '#customer-credit-invoice-dialog'; 8326 self.invoiceVatAmount = 0; 8327 self.invoiceVatFreeAmount = 0; 8328 // observables 8329 self.data = { 8330 creditType: ko.observable(''), 8331 amount: ko.observable(0), 8332 vatBase: ko.observable(), 8333 vatDetails: null, 8334 itemsToCredit: ko.observableArray([]), 8335 }; 8336 self.invoiceId = ko.observable(0) 8337 self.amountToCredit = ko.observable(0) 8338 self.amountToCreditVat = ko.observable(0) 8339 self.amountToCreditVatFree = ko.observable(0) 8340 self.items = ko.observableArray([]); 8341 self.amountToPay = ko.observable(0); 8342 self.openAmount = ko.observable(0); 8343 self.openAmountAfterCredit = ko.observable(0); 8344 self.amountToPayAfterCredit = ko.observable(0); 8345 self.hasMultipleVatBases = ko.observable(false); 8346 self.isInsuranceInvoice = ko.observable(false); 8347 self.inputAmount = ko.observable(0); 8348 self.invoiceStatus = ko.observable(''); 8349 8350 self.toPrice = function (value) { 8351 var amount = value.toFixed(2) 8352 return amount.replace('.', ',') + ' â¬' 8353 } 8354 8355 self.shouldShowReminderFeesOption = ko.computed(function() { 8356 var status = self.invoiceStatus(); 8357 8358 return status === '11' || status === '13' 8359 }); 8360 8361 function getItemSum(items) { 8362 let sum = 0; 8363 let vatTotal = 0; 8364 items.forEach(function (item) { 8365 sum += parseFloat(item.itemTotal.replace(',', '.')); 8366 vatTotal += parseFloat(item.vatTotal.replace(',', '.')); 8367 }) 8368 return { sum, vatTotal } 8369 } 8370 8371 function setItemSum(items) { 8372 let { sum, vatTotal } = getItemSum(items) 8373 self.data.amount(sum); 8374 self.amountToCreditVat(self.toPrice(vatTotal)) 8375 self.amountToCreditVatFree(self.toPrice(sum - vatTotal)) 8376 } 8377 8378 function getVatForOpenAmount() { 8379 let { sum, vatTotal } = getItemSum(self.items()) 8380 let percentage = self.openAmount() / self.amountToPay() 8381 8382 self.amountToCreditVat(self.toPrice(vatTotal * percentage)) 8383 self.amountToCreditVatFree(self.toPrice((sum - vatTotal) * percentage)) 8384 } 8385 8386 self.data.itemsToCredit.subscribe(function (newItems) { 8387 setItemSum(newItems); 8388 }, 'change') 8389 8390 self.data.amount.subscribe(function (value) { 8391 self.amountToCredit(value); 8392 8393 switch (self.data.creditType()) { 8394 case 'items': 8395 case 'full': 8396 case 'openAmount': 8397 case 'removeFeesAndInterests': 8398 return; 8399 default: 8400 if (value === 0) { 8401 self.amountToCreditVat(self.toPrice(0)) 8402 self.amountToCreditVatFree(self.toPrice(0)) 8403 return; 8404 } 8405 if (!isNaN(parseInt(self.data.vatBase()))) { 8406 const vat = parseInt(self.data.vatBase()); 8407 const vatFree = value / (1 + (vat / 100)) 8408 const vatAmount = value - vatFree 8409 self.amountToCreditVat(self.toPrice(vatAmount)) 8410 self.amountToCreditVatFree(self.toPrice(vatFree)) 8411 return; 8412 } 8413 self.amountToCreditVat('-') 8414 self.amountToCreditVatFree('-') 8415 } 8416 }, 'change') 8417 8418 self.amountToCredit.subscribe(function (value) { 8419 self.openAmountAfterCredit(self.openAmount() - value); 8420 self.amountToPayAfterCredit(self.amountToPay() - value); 8421 }, 'change') 8422 8423 self.data.creditType.subscribe(function (type) { 8424 switch (type) { 8425 case 'full': 8426 self.data.amount(self.amountToPay()); 8427 self.amountToCreditVat(self.toPrice(self.invoiceVatAmount)) 8428 self.amountToCreditVatFree(self.toPrice(self.invoiceVatFreeAmount)) 8429 return; 8430 case 'openAmount': 8431 self.data.amount(self.openAmount()); 8432 getVatForOpenAmount(); 8433 return; 8434 case 'partial': 8435 if (self.inputAmount() != 0) { 8436 $('input#amount_to_credit_input').first().trigger('change') 8437 } 8438 return self.data.amount(self.data.amount()); 8439 case 'items': 8440 return setItemSum(self.data.itemsToCredit()); 8441 } 8442 }) 8443 // init the link to other popup 8444 $('p.header-remark a#create-request-for-crediting').first().on('click', function (event) { 8445 event.preventDefault(); 8446 if (window.LaskutusJaReskontra) { 8447 window.LaskutusJaReskontra.invoiceDialog.showRequestForCreditingDialog(); 8448 } 8449 }) 8450 8451 $('input#amount_to_credit_input').first().on('change', function (event) { 8452 var value = event.target.value; 8453 if (value.match(/^\d+([\.|\,]?\d{1,2})?$/)) { 8454 var amount = value.replace(',', '.') 8455 self.data.amount(parseFloat(amount)) 8456 $('#credit-amount-input-warning').first().remove() 8457 return; 8458 } 8459 $(this).after('<div id="credit-amount-input-warning" style="position: absolute; z-index: 10; border-radius: 3px; color: #ad3f1a;">Virheellinen numeromuoto</div>') 8460 }) 8461 8462 $('input#amount_to_credit_input').first().on('focus', function (event) { 8463 $(this).trigger('select') 8464 8465 }) 8466 8467 8468 self.validateAndSetData = function (data) { 8469 8470 if (data.invoice_items.length === 0) { 8471 throw Error('Virhe laskuriveissä. Hyvitystä ei voida luoda.') 8472 } 8473 if (Object.keys(data.vatDetails).length === 0) { 8474 throw Error('Virhe haettaessa laskun alv-kantaa. Hyvitystä ei voida luoda.') 8475 } 8476 if (typeof data.invoiceTotals.amountToPay === 'undefined' || typeof data.invoiceTotals.openAmount === 'undefined') { 8477 throw Error('Laskun tiedoissa havaitu virhe. Hyvitystä ei voida luoda.') 8478 } 8479 8480 var originatorApp = data.invoice.originator_app; 8481 8482 if ( 8483 (originatorApp === 'innokorjaamo') || 8484 (originatorApp === 'innorahti') || 8485 (originatorApp === 'innohinaus') || 8486 (originatorApp === 'innohinaus-app') || 8487 (originatorApp === 'tujaus') 8488 ) { 8489 return { creditingNotAllowed: true } 8490 } 8491 8492 self.isInsuranceInvoice(data.isInsuranceCompany); 8493 // If we have insurance related items set isInsuranceInvoice. If we have other non 0 type items, dont allow creditting 8494 var hasNonNormalItems = false
8495 data.invoice_items.forEach(item => { 8496 8497 let type = parseInt(item.type); 8498 8499 if(([41, 42, 43, 60].indexOf(type) !== -1)){ 8500 self.isInsuranceInvoice(true); 8501 } 8502 8503 if ([2, 3, 6, 20, 21, 40].indexOf(type) !== -1) { 8504 hasNonNormalItems = true; 8505 } 8506 }) 8507 if (hasNonNormalItems) { 8508 return { creditingNotAllowed: true } 8509 } 8510 8511 // set constants 8512 self.invoiceId(data.invoice.id); 8513 self.invoiceVatAmount = data.invoiceTotals.vatAmount; 8514 self.invoiceVatFreeAmount = data.invoiceTotals.vatExcludedAmount; 8515 self.invoiceStatus(data.invoice.status); 8516 8517 //set observables 8518 self.items(data.invoice_items) 8519 if (Object.keys(data.vatDetails).length > 1) { 8520 self.hasMultipleVatBases(true) 8521 } else { 8522 var vatDetails = Object.values(data.vatDetails)[0]; 8523 self.data.vatBase(vatDetails.vatRate); 8524 self.data.vatDetails = { 8525 vatName: vatDetails.vatName, 8526 vatType: vatDetails.vatType, 8527 vatUnit: vatDetails.vatUnit, 8528 vatCode: vatDetails.vatCode 8529 } 8530 } 8531 self.amountToPay(data.invoiceTotals.amountToPay); 8532 self.openAmount(data.invoiceTotals.openAmount); 8533 8534 return { creditingNotAllowed: false } 8535 } 8536 8537 self.confirmationModal = { 8538 $elem: $('#confirmationModal'), 8539 partialCreditText: ko.computed(function () { 8540 if (self.data.creditType() == 'full') { 8541 if(self.isInsuranceInvoice()){ 8542 return '<strong>HUOM!</strong><br><br>Olet hyvittämässä vakuutustapaukseen liittyvää laskua.' + 8543 '<br><br><strong>Huomioithan, että tapaukseen liittyy mahdollisesti useampi lasku (vakuutusyhtiön lasku, omavastuulasku, ALV-lasku) jotka tulee hyvittää erikseen.</strong>' + 8544 '<br><br>Haluatko varmasti hyvittää koko laskun?'; 8545 } 8546 return 'Haluatko varmasti hyvittää koko laskun?'; 8547 } else if (self.data.creditType() == 'removeFeesAndInterests') { 8548 return 'Haluatko varmasti hyvittää laskulle kertyneet muistutus- ja korkokulut?'; 8549 } 8550 else { 8551 return 'Haluatko varmasti hyvittää laskusta ' + self.toPrice(self.amountToCredit()) + '?'; 8552 } 8553 8554 8555 }), 8556 8557 show: function (callback) { 8558 var error = self.validateData() 8559 if (error) { 8560 return global.show_message({ type: 'error', text: error }) 8561 } 8562 8563 var modalTitle = self.data.creditType() === 'removeFeesAndInterests' 8564 ? 'Vahvista muistutus- ja korkokulujen hyvitys' 8565 : 'Varmista hyvitys'; 8566 8567 var action = self.data.creditType() === 'removeFeesAndInterests' ? 'Vahvista hyvitys' : 'Lisää hyvitys'; 8568 8569 this.$elem.dialog({ 8570 8571 width: 600, 8572 //height:200, 8573 autoOpen: true, 8574 modal: true, 8575 resizable: false, 8576 draggable: false, 8577 title: modalTitle, 8578 beforeclose: function (event, ui) { event.stopPropagation(); }, 8579 close: function () { 8580 $(this).dialog('destroy'); 8581 return true; 8582 }, 8583 buttons: { 8584 [action]: function () { 8585 self.createCreditNote(callback) 8586 $(this).dialog('close'); 8587 }, 8588 'Peruuta': function () { 8589 $(this).dialog('close'); 8590 } 8591 } 8592 }); 8593 } 8594 } 8595 8596 self.validateData = function () { 8597 if (self.data.amount() > self.amountToPay()) 8598 return 'Hyvityksen määrä ei voi olla suurempi kuin laskun summa!' 8599 8600 if (self.data.amount() <= 0) 8601 return 'Hyvityksen määrä täytyy olla suurempi kuin 0 euroa' 8602 8603 if (self.data.creditType() === 'items' && self.data.itemsToCredit().length < 1) 8604 return 'Et ole valinnut hyvitettäviä laskurivejä.' 8605 8606 if (self.data.creditType() === 'partial' && typeof self.data.vatBase() === 'undefined') 8607 return 'Tiedoista puuttuu alvikanta. Ota yhteyttä asiakaspalveluun. Voit tehdä hyvityspyynnön hyvitysikkunan linkin kautta.' 8608 8609 return false 8610 } 8611 8612 self.show = function ({ callback }) { 8613 self.data.creditType('full'); 8614 self.dialog = $(self.dialogElem).dialog({ 8615 width: 800, 8616 height: 600, 8617 autoOpen: true, 8618 modal: true, 8619 resizable: false, 8620 draggable: false, 8621 title: 'Laskun hyvitys', 8622 beforeclose: function (event, ui) { 8623 event.stopPropagation(); 8624 }, 8625 close: function () { 8626 self.dialog.dialog('destroy'); 8627 }, 8628 buttons: { 8629 'Peruuta': function () { 8630 $(this).dialog('close'); 8631 }, 8632 'Lisää hyvitys': function () { 8633 self.confirmationModal.show(callback); 8634 } 8635 } 8636 }); 8637 } 8638 8639 self.createCreditNote = function (callback) { 8640 let data = ko.toJS(self.data); 8641 data.isInsuranceInvoice = self.isInsuranceInvoice(); 8642 $.ajax({ 8643 dataType: 'json', 8644 type: 'POST', 8645 url: '/reskontra/addCreditNote/' + self.invoiceId(), 8646 data: data, 8647 beforeSend: function (request) { 8648 var loadingText = self.data.creditType() === 'removeFeesAndInterests' 8649 ? 'Hyvitetään laskun muistutus- ja korkokuluja' 8650 : 'Luodaan hyvitystä...'; 8651 global.showLoadingDialog(loadingText); 8652 } 8653 }).done(function (response) { 8654 var successText = self.data.creditType() === 'removeFeesAndInterests'
8655 ? 'Laskun muistutus- ja korkokulut hyvitetty onnistuneesti' 8656 : 'Hyvitys luotu!'; 8657 global.show_message({ type: 'success', text: successText }) 8658 8659 setTimeout(function () { 8660 self.dialog.dialog('close') 8661 if (typeof callback === 'function') { 8662 callback() 8663 } 8664 }, 1000) 8665 8666 }).error(function (response) { 8667 global.show_message(JSON.parse(response.responseText)); 8668 }).always(function () { 8669 global.close_loading_dialog(); 8670 }) 8671 } 8672}; 8673 8674;var InvoiceLedgerServiceActionsVM = function (params) { 8675 'use strict'; 8676 var self = this; 8677 console.log('InvoiceLedgerServiceActionsVM: ',params); 8678 8679 self.changed = ko.observable(false); //A pub-sub flag that parent subscribers can check for 8680 self.invoice = params.invoice; 8681 8682 self.changed = ko.observable(false); //A pub-sub flag that parent subscribers can check for 8683 8684 self.dialog = null; // reference to jQuery ui dialog obj 8685 8686 self.infoModal = { 8687 8688 $elem: $('#ledgerServiceActionsInfoModal'), 8689 title: ko.observable(''), 8690 text: ko.observable(''), 8691 8692 show: function(text, title){ 8693 8694 this.text(text); 8695 this.title(title); 8696 8697 this.$elem.dialog({ 8698 8699 width:400, 8700 //height:200, 8701 autoOpen: true, 8702 modal: true, 8703 resizable: false, 8704 draggable: false, 8705 beforeclose: function(event, ui) {event.stopPropagation();}, 8706 close: function(){ 8707 self.changed(true); //Set the changed param to true, so parent Dialog knows to refresh 8708 $(this).dialog('destroy'); 8709 return true; 8710 }, 8711 buttons: { 8712 'Ok': function() { 8713 $(this).dialog('close'); 8714 } 8715 } 8716 }); 8717 } 8718}; 8719 8720 self.showError = function(text, title){ 8721 return global.show_message({ 8722 type: 'error', 8723 title: title, 8724 text: text 8725 }); 8726 }; 8727 var originalDueDate = self.invoice ? new Date(self.invoice.due_date) : null; 8728 var today = new Date(), 8729 dd = String(today.getDate()).padStart(2, '0'), 8730 mm = String(today.getMonth() + 1).padStart(2, '0'), 8731 yyyy = today.getFullYear(); 8732 8733 //self.actionType = ko.observable('addNote'); 8734 //self.actionItemCode = ko.observable('Manual actions needed'); 8735 8736 self.ledgerAction = { 8737 actionType: ko.observable('addNote'), 8738 actionNoteType: ko.observable(null), 8739 sendToKredinor: ko.observable(true), 8740 showToCompany: ko.observable(true), 8741 newDueDate: ko.observable(originalDueDate), 8742 removeFeesType: ko.observable('removeFeesOnly'), 8743 message: ko.observable(''), 8744 interestFromDate: ko.observable(dd + '.' + mm + '.' + yyyy), 8745 stopUntilDate: ko.observable(dd + '.' + mm + '.' + yyyy), 8746 stopForNowOrUntilDate: ko.observable(null), 8747 }; 8748 8749 self.setData = function () { 8750 self.reset(); 8751 }; 8752 8753 self.reset = function () { 8754 self.ledgerAction.actionType('addNote'); 8755 self.ledgerAction.newDueDate(originalDueDate); 8756 self.ledgerAction.message(''); 8757 self.ledgerAction.interestFromDate(dd + '.' + mm + '.' + yyyy); 8758 self.ledgerAction.stopUntilDate(dd + '.' + mm + '.' + yyyy); 8759 }; 8760 8761 self.show = function () { 8762 //If jQuery UI dialog has not been inited yet 8763 if (self.dialog === null) { 8764 self.dialog = $('#ledger-service-actions-dialog').dialog({ 8765 width: 800, 8766 height: 660, 8767 autoOpen: false, 8768 modal: true, 8769 resizable: false, 8770 draggable: false, 8771 beforeclose: function (event) { 8772 $('link#extrabs').remove(); 8773 $('script#bsjs').remove(); 8774 event.stopPropagation(); 8775 }, 8776 close: function () { 8777 self.close(); 8778 }, 8779 title: 'Laskutuspalvelun toiminnot', 8780 buttons: { 8781 Tallenna: function () { 8782 self.takeAction(); 8783 }, 8784 Sulje: function () { 8785 self.dialog.dialog('close'); 8786 }, 8787 }, 8788 }); 8789 } 8790 8791 self.dialog.dialog('open'); 8792 }; 8793 8794 self.close = function () { 8795 if (self.dialog) { 8796 self.dialog.dialog('destroy'); 8797 self.dialog = null; 8798 } 8799 }; 8800 8801 self.getAccumulatedInterest = function(onSuccess, onError){ 8802 var dialog = $('<div />', {}).dialog({ 8803 autoOpen: true, 8804 modal: true, 8805 width: 500, 8806 position: { 8807 top: 50, 8808 }, 8809 hide: { 8810 effect: 'fade', 8811 speed: 3000, 8812 }, 8813 resizable: true, 8814 title: 'Laskun tiedot', 8815 draggable: true, 8816 buttons: { 8817 Sulje: function () { 8818 dialog.dialog('close'); 8819 }, 8820 }, 8821 }); 8822 dialog.html('Haetaan laskun korkotietoja...'); 8823 var data = { invoice_id: self.invoice.id }; 8824 $.ajax({ 8825 url: '/reskontra/fetchInvoiceInterestData', 8826 type: 'get', 8827 data: data, 8828 success: function(resp) { 8829 onSuccess(resp, dialog); 8830 }, 8831 error: function(response) { 8832 onError(response, dialog); 8833 } 8834 }); 8835 } 8836 8837 self.fetchInvoiceInterestData = function(){ 8838 function onSuccess(resp, target){ 8839 if(resp.data){ 8840 var dataString = JSON.stringify(resp.data, null, 4); 8841 dataString = dataString.replace(/[}{]/g, ''); 8842 dataString = dataString.trim() != '' ? dataString : 'Laskun tietoja ei löytynyt'; 8843 target.html('<pre>'+dataString+'</pre>'); 8844 }else{ 8845 target.html('Laskun tietoja ei löytynyt'); 8846 } 8847 } 8848 8849 function onError(response, target){ 8850 global.close_loading_dialog();
8851 try { 8852 target.html(JSON.parse(response.responseText)); 8853 }catch (exception){ 8854 target.html('Odottamaton virhe tapahtui palvelimella. Virhesanoma tallennettu palvelimen lokiin.'); 8855 } 8856 } 8857 8858 self.getAccumulatedInterest(onSuccess, onError); 8859 }; 8860 8861 self.takeAction = function(){ 8862 8863 console.log(ko.toJS(self.ledgerAction)); 8864 8865 var url, data; 8866 var actionType = self.ledgerAction.actionType(); 8867 var actionNoteType = self.ledgerAction.actionNoteType(); 8868 var message = self.ledgerAction.message(); 8869 var stopUntilDate = self.ledgerAction.stopForNowOrUntilDate() === "stopUntilDate" ? self.ledgerAction.stopUntilDate() : null; 8870 var hideLogItemFromSeller= + ( ! self.ledgerAction.showToCompany()); 8871 8872 switch(actionType){ 8873 case 'addNote': 8874 url = 'iv_laskutus_ja_reskontra/addNoteToLedgerService'; 8875 data = { invoice_id: self.invoice.id, message: message, hideLogItemFromSeller: hideLogItemFromSeller, sendToKredinor: self.ledgerAction.sendToKredinor()}; 8876 break; 8877 8878 case 'addActionNote': 8879 case 'removeFeesAction': 8880 url = 'iv_laskutus_ja_reskontra/addActionNoteToLedgerService'; 8881 data = { invoice_id: self.invoice.id, actionNoteType: actionNoteType, message: message, hideLogItemFromSeller: hideLogItemFromSeller}; 8882 break; 8883 8884 case 'postponeDueDate': 8885 url = "/iv_laskutus_ja_reskontra/update_due_date/".concat(self.invoice.id); 8886 data = { dueDate: self.ledgerAction.newDueDate(), message: message }; 8887 break; 8888 case 'blockInterestCalculation': 8889 url = '/iv_laskutus_ja_reskontra/blockInterestCalculation'; 8890 data = { invoice_id: self.invoice.id, message: message, interestFromDate: self.ledgerAction.interestFromDate()}; 8891 break; 8892 case 'stopCollectionAndReminder': 8893 url = '/iv_laskutus_ja_reskontra/stopDebtCollection'; 8894 data = { invoice_id: self.invoice.id, message: message, stopUntilDate: stopUntilDate }; 8895 break; 8896 case 'resumeCollectionAndReminder': 8897 url = '/iv_laskutus_ja_reskontra/resumeDebtCollection'; 8898 data = { invoice_id: self.invoice.id, message: message}; 8899 break; 8900 case 'stopInterestCalculation': 8901 8902 console.log('stopForNow:',self.ledgerAction.stopForNowOrUntilDate(), ' stopUntil:', stopUntilDate ); 8903 8904 url = '/iv_laskutus_ja_reskontra/stopInterestCalculation'; 8905 data = { invoice_id: self.invoice.id, message: message, stopUntilDate: stopUntilDate }; 8906 break; 8907 case 'resumeInterestCalculation': 8908 url = '/iv_laskutus_ja_reskontra/resumeInterestCalculation'; 8909 data = { invoice_id: self.invoice.id, message: message }; 8910 break; 8911 8912 default: 8913 return self.showError('Virheellinen toiminto', 'Virhe'); 8914 } 8915 8916 $.ajax({ 8917 url: url, 8918 type: 'post', 8919 data: data, 8920 beforeSend(jqXHR, settings) { 8921 global.showLoadingDialog('Suoritetaan toimintoa...'); 8922 }, 8923 success: function(resp) { 8924 global.close_loading_dialog(); 8925 //global.show_message(resp); 8926 self.infoModal.show(resp.text, 'Toiminto suoritettu onnistuneesti'); 8927 //Refresh the datatables 8928 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null){ 8929 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 8930 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 8931 } 8932 8933 if(pages.iv_laskutus_ja_reskontra.$datatable != null){ 8934 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 8935 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 8936 } 8937 8938 if(pages.reskontra.$datatable != null){ 8939 pages.reskontra.$datatable.fnClearTable( 0 ); 8940 pages.reskontra.$datatable.fnDraw(); 8941 } 8942 }, 8943 error: function(response) { 8944 global.close_loading_dialog(); 8945 try { 8946 global.show_message(JSON.parse(response.responseText)); 8947 }catch (exception){ 8948 global.show_message({'type': 'error', 'text': 'Odottamaton virhe tapahtui palvelimella. Virhesanoma tallennettu palvelimen lokiin.' }); 8949 } 8950 } 8951 }); 8952 }; 8953 8954 ko.bindingHandlers.ledgerActionsDatepicker = { 8955 init: function(element, valueAccessor, allBindings){ 8956 8957 var unWrappedValue = ko.unwrap(valueAccessor()); 8958 8959 $(element).datepicker({ 8960 format: 'dd.mm.yyyy', 8961 language: 'fi-FI', 8962 weekStart: 1, 8963 todayHighlight: true, 8964 startDate: '-24m' 8965 }); 8966 8967 $(element) 8968 .datepicker() 8969 .on('change', function (event) { 8970 var value = valueAccessor(); 8971 8972 if (ko.isObservable(value)) { 8973 value(event.target.value); 8974 } 8975 }); 8976 8977 $(element).datepicker('setDate', unWrappedValue); 8978 }, 8979 update: function (element, valueAccessor, allBindingsAccessor) { 8980 var unWrappedValue = ko.unwrap(valueAccessor()); 8981 8982 $(element).datepicker('setDate', unWrappedValue); 8983 ko.utils.triggerEvent(element, 'blur'); 8984 } 8985 }; 8986}; 8987 8988; 8989var InvoiceDialogVm = function() { 8990 8991 'use strict'; 8992 var self = this; 8993 8994 self.inited = ko.observable(false); 8995 8996 //self.dialog = $('<div />', {}); 8997 self.dialog = global.getGlobalDialogAndEmptyIfHasContent(); 8998 8999 self.changeAccountingPeriodDialog = { 9000 jqDialog: null, 9001 dialogElem: '#change-accounting-period-dialog', 9002 accountingDate: ko.observable() 9003 }; 9004 9005 self.addInvoiceNoteDialog = { 9006 jqDialog: null, 9007 dialogElem: '#add-invoice-note-dialog', 9008 ledgerService: ko.observable(''), 9009 noteOptions: ko.observableArray([ 9010 { value: 0, label: 'Oma muistiinpano' }, 9011 { value: 1, label: 'Viesti Innovoicen asiakaspalveluun' } 9012 ]), 9013 type: ko.observable(0), 9014 message: ko.observable(''), 9015 showToCompany: ko.observable(true), 9016 actionItemCode: ko.observable('Manual actions needed') 9017 }; 9018 9019 self.addInvoiceNoteDialog.reset = function(){ 9020 self.addInvoiceNoteDialog.ledgerService(''); 9021 self.addInvoiceNoteDialog.noteOptions([ 9022 { value: 0, label: 'Oma muistiinpano' }, 9023 { value: 1, label: 'Viesti Innovoicen asiakaspalveluun' } 9024 ]); 9025 self.addInvoiceNoteDialog.type(0); 9026 self.addInvoiceNoteDialog.message(''); 9027 self.addInvoiceNoteDialog.showToCompany(false); 9028 self.addInvoiceNoteDialog.actionItemCode(''); 9029 }; 9030 9031 self.postponeDueDateDialog = { 9032 jqDialog: null, 9033 dialogElem: '#postpone-due-date-dialog', 9034 dueDate: ko.observable(), 9035 message: ko.observable('') 9036 }; 9037 9038 self.editReminderStopDialog = { 9039 jqDialog: null, 9040 dialogElem: '#edit-reminder-stop-dialog', 9041 reminderStop: ko.observable(), 9042 reminderStopEnd: ko.observable(), 9043 reminderStopEndDate: ko.observable() 9044 }; 9045 9046 self.requestForCreditingDialog = { 9047 jqDialog: null, 9048 dialogElem: '#request-for-crediting-dialog', 9049 template: ko.observable('default'), 9050 creditType: ko.observable(), 9051 creditAmount: ko.observable(), 9052 additionalInfo: ko.observable(), 9053 }; 9054 9055 self.requestForCreditingDialog.evaluateDialogTemplateForInvoice = function (invoice) { 9056 9057 if( ! self.inited()) 9058 return 'default'; 9059 9060 var originatorApp = ko.toJS(invoice.originator_app); 9061 9062 if(window.App.company.field_of_work === 'car_service' && window.App.company.mod_innokorjaamo && originatorApp === 'innokorjaamo') 9063 return 'car_service'; 9064 9065 if(window.App.company.field_of_work === 'freight' && originatorApp === 'innorahti') 9066 return 'freight'; 9067 9068 if(window.App.company.field_of_work === 'car_tow' && (originatorApp === 'innohinaus' || originatorApp === 'innohinaus-app')) 9069 return 'car_tow'; 9070 9071 return 'default' 9072 } 9073 9074 self.requestForCreditingDialog.reset = function(){ 9075 9076 self.requestForCreditingDialog.creditType(null); 9077 self.requestForCreditingDialog.creditAmount(null); 9078 self.requestForCreditingDialog.additionalInfo(null); 9079 }; 9080 9081 self.requestForCreditingDialog.buttons = ko.computed(function(){ 9082 9083 console.log('self.requestForCreditingDialog.buttons called, template: ', self.requestForCreditingDialog.template(), ' creditType:', self.requestForCreditingDialog.creditType()); 9084 9085 9086 if(self.requestForCreditingDialog.template() === 'car_tow'){ 9087 9088 return { 9089 'Sulje': function () { 9090 $(this).dialog('close'); 9091 }, 9092 'Siirry kuormakirjaan': function (){ 9093 self.requestForCreditingDialog.navigateToTowingRecord(); 9094 } 9095 }; 9096 } 9097 9098 if(self.requestForCreditingDialog.template() === 'car_service'){ 9099 9100 return { 9101 'Sulje': function () { 9102 $(this).dialog('close'); 9103 }, 9104 'Lähetä hyvityspyyntö': function (){ 9105 self.requestForCreditingDialog.sendRequest(); 9106 }, 9107 'Siirry työmääräykseen': function (){ 9108 self.requestForCreditingDialog.navigateToJobOrder(); 9109 } 9110 }; 9111 } 9112 9113 if(self.requestForCreditingDialog.template() === 'freight'){ 9114 9115 return { 9116 'Sulje': function () { 9117 $(this).dialog('close'); 9118 }, 9119 'Lähetä hyvityspyyntö': function (){ 9120 self.requestForCreditingDialog.sendRequest(); 9121 }, 9122 'Siirry rahtikirjaan': function (){ 9123 self.requestForCreditingDialog.navigateToFreight(); 9124 }, 9125 }; 9126 } 9127 9128 return { 9129 'Peruuta': function () { 9130 $(this).dialog('close'); 9131 }, 9132 'Lähetä': function () { 9133 self.requestForCreditingDialog.sendRequest(); 9134 } 9135 }; 9136 }); 9137 9138 self.creditInvoiceDialog = null; 9139 self.customerCreditInvoiceVM = null; 9140 9141 self.ledgerServiceActionsDialog = null; 9142 9143 self.data = null; 9144 9145 self.invoiceId = ko.observable(); 9146 9147 self.setData = function(data){ 9148 9149 //console.log('InvoiceDialogVm::setData: ', data); 9150 9151 //Load the new data into ViewModel 9152 ko.mapping.fromJS(data, {}, self.data); 9153 9154 self.creditInvoiceDialog.setData(ko.mapping.toJS(self.data)); 9155 self.ledgerServiceActionsDialog.setData(ko.mapping.toJS(self.data)); 9156 }; 9157 9158 self.init = function(params){ 9159 if(typeof params.id !== "undefined") { 9160 self.invoiceId(params.id) 9161 } 9162 //console.log('InvoiceDialogVm::init'); 9163 self.customerCreditInvoiceVM = new CustomerCreditInvoiceDialogVM(params); 9164 9165 self.data = ko.mapping.fromJS(params); 9166 9167 self.creditInvoiceDialog = new CreditInvoiceDialogVm(params); 9168 self.ledgerServiceActionsDialog = new InvoiceLedgerServiceActionsVM(params); 9169 9170 self.creditInvoiceDialog.changed.subscribe(function(){ 9171 // console.log('InvoiceDialogVm creditInvoiceDialog.changed'); 9172 self.refresh(); 9173 }); 9174 9175 self.ledgerServiceActionsDialog.changed.subscribe(function(){ 9176 self.refresh(); 9177 }); 9178 9179 // Apply to vm to popup 9180 ko.applyBindings(self.customerCreditInvoiceVM, $('#customer-credit-invoice-dialog')[0]);
9181 ko.applyBindings(self.creditInvoiceDialog, $('#credit-invoice-dialog')[0]); 9182 ko.applyBindings(self.ledgerServiceActionsDialog, $('#ledger-service-actions-dialog')[0]); 9183 ko.applyBindings(self.postponeDueDateDialog, $('#postpone-due-date-dialog')[0]); 9184 ko.applyBindings(self.changeAccountingPeriodDialog, $('#change-accounting-period-dialog')[0]); 9185 ko.applyBindings(self.addInvoiceNoteDialog, $('#add-invoice-note-dialog')[0]); 9186 ko.applyBindings(self.editReminderStopDialog, $('#edit-reminder-stop-dialog')[0]); 9187 ko.applyBindings(self.requestForCreditingDialog, $('#request-for-crediting-dialog')[0]); 9188 9189 self.initJqueryElements(); 9190 9191 self.inited(true); 9192 }; 9193 9194 self.initJqueryElements = function () { 9195 9196 $('.edit_reminder_stop').dblclick(function (e) { 9197 self.editReminderStopDialog.show($(e.target).text()); 9198 }); 9199 9200 $('a.edit_due_date').on('click',function (e) { 9201 e.preventDefault(); 9202 self.postponeDueDateDialog.show($(e.target).text()); 9203 }); 9204 9205 $('a.edit_accounting_period').on('click',function (e) { 9206 e.preventDefault(); 9207 var accountingDate = $(e.target).data('accounting-date'); 9208 self.changeAccountingPeriodDialog.show(accountingDate); 9209 }); 9210 9211 $('input#accounting_date') 9212 .datepicker({minViewMode: "months", orientation: "bottom left"}); 9213 9214 var last_reminder_select_value = $('#reminder_and_debt_collection_stop').val(); 9215 $('#reminder_and_debt_collection_stop').on('focus', function () { 9216 last_reminder_select_value = $(this).val(); 9217 }); 9218 9219 $('select#reminder_and_debt_collection_stop').on('change', function(e){ 9220 last_reminder_select_value = $(this).val(); 9221 self.setReminderAndDebtCollectionStop(); 9222 }); 9223 }; 9224 9225 self.setReminderAndDebtCollectionStop = function(){ 9226 9227 var reminder_and_debt_collection_stop = document.querySelector('#reminder_and_debt_collection_stop').value; 9228 9229 $.ajax({ 9230 url: '/reskontra/reminder_and_debt_collection_stop', 9231 data: { 9232 invoiceId: self.invoiceId(), 9233 reminder_and_debt_collection_stop: reminder_and_debt_collection_stop 9234 }, 9235 type: 'POST', 9236 dataType: 'json', 9237 beforeSend: function(request){ 9238 global.showLoadingDialog('Asetetaan muistutus- ja perintäestoa'); 9239 }, 9240 success: function(responseJSON){ 9241 global.show_message(responseJSON); 9242 global.close_loading_dialog(); 9243 }, 9244 error: function(data){ 9245 var errorJSON = data.responseJSON; 9246 if(errorJSON){ 9247 global.show_message(errorJSON); 9248 } else { 9249 global.show_message({ 9250 type: 'error', 9251 text: 'Virhe asetettaessa muistutus- ja perintäestoa' 9252 }); 9253 } 9254 global.close_loading_dialog(); 9255 } 9256 }); 9257 } 9258 9259 self.requestForCreditingDialog.sendRequest = function(){ 9260 9261 9262 9263 if(! self.requestForCreditingDialog.creditAmount()){ 9264 9265 return global.show_message({ 9266 type: 'error', 9267 title: 'Virhe!', 9268 text: 'Ole hyvä ja syötä hyvitettävä summa (sis. alv)' 9269 }); 9270 9271 } 9272 9273 9274 9275 if( ! self.requestForCreditingDialog.additionalInfo()){ 9276 9277 return global.show_message({ 9278 type: 'error', 9279 title: 'Virhe!', 9280 text: 'Ole hyvä ja täytä hyvityksen syy' 9281 }); 9282 } 9283 9284 global.showLoadingDialog("Lähetetään hyvityspyyntöä..."); 9285 9286 $.ajax({ 9287 9288 url: 'logger/addRequestForCrediting/', 9289 type: 'post', 9290 data: { 9291 id: self.invoiceId(), 9292 message: self.requestForCreditingDialog.additionalInfo(), 9293 creditType: 'other_amount', 9294 otherAmount: self.requestForCreditingDialog.creditAmount() 9295 } 9296 }).done(function (responseJSON) { 9297 9298 global.close_loading_dialog(); 9299 global.show_message({ 9300 type: 'success', 9301 title: 'Hyvityspyyntö lähetetty', 9302 text: 'Hyvityspyyntö lähetetty onnistuneesti!' 9303 }); 9304 9305 self.requestForCreditingDialog.reset(); 9306 self.requestForCreditingDialog.jqDialog.dialog('destroy'); 9307 9308 }).fail(function (response) { 9309 9310 var responseJSON = $.parseJSON(response.responseText); 9311 9312 global.close_loading_dialog(); 9313 global.show_message(responseJSON); 9314 }); 9315 }; 9316 9317 self.requestForCreditingDialog.navigateToTowingRecord = function (){ 9318 window.location = '/kuormakirja/navigate_by_invoice/'.concat(self.invoiceId()); 9319 }; 9320 9321 self.requestForCreditingDialog.navigateToJobOrder = function (){ 9322 window.location = '/innokorjaamo/navigate_by_invoice/'.concat(self.invoiceId()); 9323 }; 9324 9325 self.requestForCreditingDialog.navigateToFreight = function (){ 9326 window.location = '/innorahti/navigate_by_invoice/'.concat(self.invoiceId()); 9327 }; 9328 9329 self.requestForCreditingDialog.show = function(){ 9330 9331 var dialogTemplate = self.requestForCreditingDialog.evaluateDialogTemplateForInvoice(ko.toJS(self.data.invoice)); 9332 self.requestForCreditingDialog.template(dialogTemplate); 9333 9334 self.requestForCreditingDialog.jqDialog = $(self.requestForCreditingDialog.dialogElem).dialog({ 9335 width: 400, 9336 autoOpen: true, 9337 modal: true, 9338 resizable: false, 9339 draggable: false, 9340 title: 'Lähetä hyvityspyyntö', 9341 beforeclose: function (event, ui) { 9342 event.stopPropagation(); 9343 }, 9344 close: function(){ 9345 self.requestForCreditingDialog.jqDialog.dialog('destroy'); 9346 }, 9347 buttons: self.requestForCreditingDialog.buttons() 9348 }); 9349 9350 }; 9351 9352 self.editReminderStopDialog.show = function(reminderStop){ 9353 9354 var d = new Date(); 9355 9356 if(reminderStop === 'Päällä'){ 9357 self.editReminderStopDialog.reminderStop('1'); 9358 }else { 9359 self.editReminderStopDialog.reminderStop('0'); 9360 } 9361 9362 self.editReminderStopDialog.reminderStopEnd(false); 9363 self.editReminderStopDialog.reminderStopEndDate(d.toLocaleDateString("fi-FI")); 9364 9365 self.editReminderStopDialog.jqDialog = $(self.editReminderStopDialog.dialogElem).dialog({ 9366 9367 width: 340, 9368 height: 260, 9369 autoOpen: true, 9370 modal: false, 9371 resizable: false, 9372 draggable: true, 9373 beforeclose: function(event, ui) { 9374 event.stopPropagation(); 9375 }, 9376 buttons: { 9377 'Peruuta': function() { 9378 self.editReminderStopDialog.jqDialog.dialog('destroy'); 9379 }, 9380 'Hyväksy': function() { 9381 self.editReminderStopDialog.updateReminderStop(); 9382 } 9383 } 9384 }); 9385 }; 9386 9387 self.editReminderStopDialog.updateReminderStop = function(){ 9388 9389 var reminderStop = self.editReminderStopDialog.reminderStop(), 9390 reminderStopEnd = self.editReminderStopDialog.reminderStopEnd(), 9391 reminderStopEndDate = reminderStopEnd ? self.editReminderStopDialog.reminderStopEndDate() : null; 9392 9393 9394 console.log('updateReminderStop:', reminderStop, reminderStopEnd, reminderStopEndDate); 9395 9396 var data = ko.toJSON({ 9397 'reminderStop': reminderStop, 9398 'reminderStopEnd': reminderStopEnd, 9399 'reminderStopEndDate': reminderStopEndDate 9400 }); 9401 9402 $.ajax({ 9403 "dataType": 'json', 9404 "type": "POST", 9405 data: { 9406 'data': data 9407 }, 9408 "url" : "/iv_laskutus_ja_reskontra/update_huomautus_esto/" .concat(self.invoiceId()), 9409 "beforeSend":function(request){ 9410 global.showLoadingDialog('Päivitetään huomautus- ja korkoestoa Rivertylle...'); 9411 } 9412 }).done(function(responseJSON){ 9413 console.log('responseJSON!:', responseJSON); 9414 self.editReminderStopDialog.jqDialog.dialog('close'); 9415 global.show_message(responseJSON, self.refresh()); 9416 // self.refresh(); 9417 }).always(function(){ 9418 global.close_loading_dialog(); 9419 }).error(function(response){ 9420 console.log('updateReminderStop error:', response); 9421 global.show_message($.parseJSON(response.responseText)); 9422 }); 9423 }; 9424 9425 9426 self.changeAccountingPeriodDialog.show = function(currentAccountingPeriod){ 9427 9428 var vm = self.changeAccountingPeriodDialog; 9429 9430 vm.accountingDate(currentAccountingPeriod); 9431 9432 vm.jqDialog = $(vm.dialogElem).dialog({ 9433 width: 260, 9434 height: 200, 9435 autoOpen: true, 9436 modal: false, 9437 resizable: false, 9438 draggable: true, 9439 beforeclose: function(event, ui) { 9440 event.stopPropagation(); 9441 }, 9442 buttons: { 9443 'Peruuta': function() { 9444 vm.jqDialog.dialog('destroy'); 9445 }, 9446 'Hyväksy': function() { 9447 vm.updateAccountingDate(); 9448 } 9449 } 9450 }); 9451 }; 9452 9453 self.changeAccountingPeriodDialog.updateAccountingDate = function(){ 9454 9455 var vm = self.changeAccountingPeriodDialog, data = { 9456 'accountingDate': vm.accountingDate() 9457 }; 9458 9459 var url; 9460 9461 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null && pages.reskontra.$datatable === null){ 9462 url = "/iv_laskutus_ja_reskontra/update_accounting_date/" .concat(self.invoiceId()); 9463 }else{ 9464 url = "/reskontra/update_accounting_date/" .concat(self.invoiceId()); 9465 } 9466 9467 $.ajax({ 9468 "dataType": 'json', 9469 "type": "POST", 9470 data: data, 9471 "url" : url, 9472 "beforeSend":function(request){ 9473 global.showLoadingDialog('Päivitetään kirjanpitokautta...'); 9474 } 9475 }).done(function(responseJSON){ 9476 console.log('responseJSON!:', responseJSON); 9477 vm.jqDialog.dialog('close'); 9478 global.show_message(responseJSON, self.refresh()); 9479 //self.refresh(); 9480 }).always(function(){ 9481 global.close_loading_dialog(); 9482 }).error(function(response){ 9483 console.log('UpdateDueDate error:', response); 9484 global.show_message($.parseJSON(response.responseText)); 9485 }); 9486 }; 9487 9488 self.addInvoiceNoteDialog.show = function(){ 9489 self.addInvoiceNoteDialog.reset(); 9490 var ledgerService = self.data.invoice.ledger_service(); 9491 self.addInvoiceNoteDialog.ledgerService(ledgerService); 9492 9493 /* 9494 if(ledgerService === 'kredinor'){ 9495 var kredinorNote = { value: 2, label: 'Viesti Kredinorille' }; 9496 var kredinorAction = { value: 3, label: 'Tehtävä Kredinorille' }; 9497 self.addInvoiceNoteDialog.noteOptions.push(kredinorNote); 9498 self.addInvoiceNoteDialog.noteOptions.push(kredinorAction); 9499 } 9500 */ 9501 9502 self.addInvoiceNoteDialog.jqDialog = $(self.addInvoiceNoteDialog.dialogElem).dialog({ 9503 width: 400, 9504 autoOpen: true, 9505 modal: false, 9506 resizable: false, 9507 draggable: true, 9508 title: 'Lisää muistiinpano', 9509 beforeclose: function(event, ui) { 9510 event.stopPropagation(); 9511 }, 9512 buttons: { 9513 'Peruuta': function() { 9514 self.addInvoiceNoteDialog.jqDialog.dialog('destroy'); 9515 }, 9516 'Lähetä': function() { 9517 self.addInvoiceNoteDialog.addNote(); 9518 } 9519 }, 9520 }); 9521 } 9522 9523 self.addInvoiceNoteDialog.addNote = function(){ 9524 var invoice = self.data.invoice; 9525 var url, data; 9526 var type = self.addInvoiceNoteDialog.type(); 9527 global.showLoadingDialog('Lisätään viestiä'); 9528 switch(type){ 9529 case 0: // log message 9530 url = 'logger/makeLogEntry/'; 9531 data = { id: invoice.id(), message: self.addInvoiceNoteDialog.message(), notify: '0' }; 9532 break; 9533 case 1: // log and ticket 9534 url = 'logger/makeLogEntry/'; 9535 data = { id: invoice.id(), message: self.addInvoiceNoteDialog.message(), notify: '1' }; 9536 break; 9537 case 2: // message to kredinor and log 9538 url = 'iv_laskutus_ja_reskontra/addNoteToLedgerService'; 9539 data = { invoice_id: invoice.id(), message: self.addInvoiceNoteDialog.message(), addFollowUp: false, showToCompany: self.addInvoiceNoteDialog.showToCompany() }; 9540 break; 9541 case 3: // action to kredinor and log 9542 url = 'iv_laskutus_ja_reskontra/addNoteToLedgerService'; 9543 data = { invoice_id: invoice.id(), message: self.addInvoiceNoteDialog.message(), addFollowUp: true, showToCompany: self.addInvoiceNoteDialog.showToCompany(), actionItemCode: self.addInvoiceNoteDialog.actionItemCode() }; 9544 break; 9545 default: 9546 global.show_message({ 9547 type: 'error', 9548 title: 'Virhe! Muistiinpanoa ei voi lähettää', 9549 text: 'Virheellinen muistiinpanon tyyppi.' 9550 }); 9551 break; 9552 } 9553 $.ajax({ 9554 url: url, 9555 type: 'post', 9556 data: data, 9557 success: function(resp) { 9558 self.addInvoiceNoteDialog.jqDialog.dialog('destroy'); 9559 global.close_loading_dialog(); 9560 global.show_message({ 9561 type: 'success', 9562 title: 'Valmis', 9563 text: 'Viesti lisätty onnistuneesti.', 9564 }); 9565 }, 9566 error: function(response) { 9567 global.close_loading_dialog(); 9568 try { 9569 global.show_message(JSON.parse(response.responseText)); 9570 }catch (exception){ 9571 global.show_message({'type': 'error', 'text': 'Odottamaton virhe tapahtui palvelimella. Virhesanoma tallennettu palvelimen lokiin.' }); 9572 } 9573 } 9574 }); 9575 }; 9576 9577 self.postponeDueDateDialog.show = function(currentDueDate){ 9578 9579 var statusCheckResult = pages.reskontra.checkInvoiceStatusBeforeChangeDueDate(ko.toJS(self.data)); 9580 9581 if (statusCheckResult) { 9582 return global.show_message({ 9583 type: 'error', 9584 title: 'Virhe!', 9585 text: statusCheckResult 9586 }); 9587 } 9588 9589 self.postponeDueDateDialog.dueDate(currentDueDate); 9590 self.postponeDueDateDialog.message(''); 9591 9592 self.postponeDueDateDialog.jqDialog = $(self.postponeDueDateDialog.dialogElem).dialog({ 9593 width: 260, 9594 height: 300, 9595 autoOpen: true, 9596 modal: false, 9597 resizable: false, 9598 draggable: true, 9599 beforeclose: function(event, ui) { 9600 event.stopPropagation(); 9601 }, 9602 buttons: { 9603 'Peruuta': function() { 9604 self.postponeDueDateDialog.jqDialog.dialog('destroy'); 9605 }, 9606 'Hyväksy': function() { 9607 self.postponeDueDateDialog.updateDueDate(); 9608 } 9609 } 9610 }); 9611 } 9612 9613 self.postponeDueDateDialog.updateDueDate = function(){ 9614 9615 var data = { 9616 'dueDate': self.postponeDueDateDialog.dueDate(), 9617 'message': self.postponeDueDateDialog.message() 9618 }; 9619 var url; 9620 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null && pages.reskontra.$datatable === null){ 9621 url = "/iv_laskutus_ja_reskontra/update_due_date/" .concat(self.invoiceId()); 9622 }else{ 9623 url = "/reskontra/update_due_date/" .concat(self.invoiceId()); 9624 } 9625 $.ajax({ 9626 "dataType": 'json', 9627 "type": "POST", 9628 data: data, 9629 "url" : url, 9630 "beforeSend":function(request){ 9631 global.showLoadingDialog('Siirretään eräpäivää...'); 9632 } 9633 }).done(function(responseJSON){ 9634 console.log('responseJSON!:', responseJSON); 9635 self.postponeDueDateDialog.jqDialog.dialog('close'); 9636 global.show_message(responseJSON, self.refresh()); 9637 //self.refresh(); 9638 }).always(function(){ 9639 global.close_loading_dialog(); 9640 }).error(function(response){ 9641 console.log('UpdateDueDate error:',
9641 response); 9642 global.show_message($.parseJSON(response.responseText)); 9643 }); 9644 }; 9645 9646 self.show = function(){ 9647 9648 $.ajax({ 9649 9650 processData:false, 9651 dataType: 'html', 9652 type: "GET", 9653 url: "/ajax/get_invoice_html/".concat(self.invoiceId()), 9654 9655 "beforeSend":function(request){ 9656 9657 self.dialog.dialog({ 9658 width:800, 9659 height:600, 9660 modal:true, 9661 resizable:false, 9662 title:'Laskun tiedot', 9663 close: function(){ 9664 // cleanup the dialogs for this invoice 9665 if(self.changeAccountingPeriodDialog.jqDialog){ 9666 self.changeAccountingPeriodDialog.jqDialog.remove(); 9667 } 9668 if(self.addInvoiceNoteDialog.jqDialog){ 9669 self.addInvoiceNoteDialog.jqDialog.remove(); 9670 } 9671 if(self.postponeDueDateDialog.jqDialog){ 9672 self.postponeDueDateDialog.jqDialog.remove(); 9673 } 9674 if(self.editReminderStopDialog.jqDialog){ 9675 self.editReminderStopDialog.jqDialog.remove(); 9676 } 9677 if(self.requestForCreditingDialog.jqDialog){ 9678 self.requestForCreditingDialog.jqDialog.remove(); 9679 } 9680 self.dialog.dialog('close'); 9681 } 9682 }); 9683 9684 global.show_ajax_loader(self.dialog); 9685 }, 9686 "success": function(response){ 9687 9688 self.dialog.html(response); 9689 9690 $(this).delegate(':button','click',function(){ 9691 $(this).data({'invoice_id': invoice_id, 'open_sum':open_sum}); 9692 }); 9693 } 9694 }); 9695 }; 9696 9697 self.refresh = function(){ 9698 self.creditInvoiceDialog.close(); 9699 self.ledgerServiceActionsDialog.close(); 9700 self.show(); 9701 }; 9702 9703 self.showCreditInvoiceDialog = function(){ 9704 self.creditInvoiceDialog.show(true); 9705 }; 9706 9707 self.showLedgerServiceActionsDialog = function(){ 9708 self.ledgerServiceActionsDialog.show(true); 9709 }; 9710 9711 self.showAccumulatedInterest = function(onSuccess, onError){ 9712 self.ledgerServiceActionsDialog.getAccumulatedInterest(onSuccess, onError); 9713 } 9714 9715 self.showSuggestCreditLossDialog = function(){ 9716 9717 var $dialog = $('<div />', {"id": "suggest-credit-loss-dialog", "style":"text-align:left;"}).html('Haluatko varmasti lähettää laskusta luotttappiosuosituksen?'); 9718 9719 $dialog.dialog({ 9720 autoOpen: true, 9721 modal: true, 9722 resizable: false, 9723 draggable: false, 9724 title: 'Luottotappiosuositus', 9725 beforeclose: function(event, ui) { 9726 event.stopPropagation() 9727 }, 9728 buttons: { 9729 'Peruuta': function() { 9730 $dialog.dialog('close'); 9731 }, 9732 'Lähetä luottotappiosuositus': function() { 9733 self.suggestCreditLoss($dialog); 9734 } 9735 } 9736 }); 9737 }; 9738 9739 self.showAddCreditLossDialog = function(){ 9740 9741 var creditLossStop = self.data.invoice.credit_loss_stop(); 9742 9743 var dialog = $('<div></div>') 9744 .append( 9745 $('<label />', {'style': 'width:auto;'}).html('Automaattisen luottotappiomerkinnän esto'), 9746 $('<br />', {'style': 'clear:both'}), 9747 $('<label />', {'style': 'width:auto;'}).html('Päällä').append( 9748 $('<input />', {style: 'float:left', type: 'radio', name:'credit_loss_stop', value: 1, checked: creditLossStop}) 9749 ), 9750 $('<br />', {'style': 'clear:both'}), 9751 $('<label />', {'style': 'width:auto;'}).html('Pois päältä').append( 9752 $('<input />', {style: 'float:left', type: 'radio', name:'credit_loss_stop', value: 0, checked: (! creditLossStop)}), 9753 ), 9754 $('<br />', {'style': 'clear:both'}) 9755 ); 9756 9757 dialog.dialog({ 9758 width: 400, 9759 autoOpen: true, 9760 modal: true, 9761 resizable: false, 9762 draggable: false, 9763 title: 'Luottotappioasetukset', 9764 beforeclose: function(event, ui) { 9765 event.stopPropagation() 9766 }, 9767 close: function(){ 9768 dialog.dialog('destroy'); 9769 dialog.remove(); 9770 }, 9771 buttons: { 9772 'Peruuta': function() { 9773 dialog.dialog('close'); 9774 }, 9775 'Tallenna muutokset': function() { 9776 self.updateCreditLossStopSetting(dialog); 9777 }, 9778 'Merkitse luottotappioksi': function() { 9779 9780 if(confirm("Haluatko varmasti merkitä laskun avoimen osuuden luottotappioksi?")){ 9781 self.addCreditLoss(dialog); 9782 } 9783 } 9784 } 9785 }); 9786 }; 9787 9788 self.showNullifyCreditLossDialog = function(){ 9789 9790 var dialog = $('<div></div>') 9791 .append( 9792 $('<br />', {'style': 'clear:both'}), 9793 $('<label />', {'style': 'width:auto;'}).html('Poista koko luottotappio').append( 9794 $('<input />', {style: 'float:left', type: 'checkbox', class:'nullify_open_credit_loss_amount', value: 1, checked: fal
9794se}) 9795 .on('change', function(){ 9796 if($(this).is(':checked')){ 9797 $('input.nullify_amount').prop('disabled', true) 9798 } else { 9799 $('input.nullify_amount').prop('disabled', false) 9800 } 9801 }) 9802 ), 9803 $('<br />', {'style': 'clear:both'}), 9804 $('<br />', {'style': 'clear:both'}), 9805 $('<label />', {'style': 'width:auto; float:left;'}).html('Anna poistettava summa'), 9806 $('<br />', {'style': 'clear:both'}), 9807 $('<input />', {style: 'float:left', type: 'text', class:'nullify_amount', value: ''}), 9808 $('<br />', {'style': 'clear:both'}) 9809 ); 9810 9811 dialog.dialog({ 9812 width: 400, 9813 autoOpen: true, 9814 modal: true, 9815 resizable: false, 9816 draggable: false, 9817 title: 'Poista luottotappio', 9818 beforeclose: function(event, ui) { 9819 event.stopPropagation() 9820 }, 9821 close: function(){ 9822 dialog.dialog('destroy'); 9823 dialog.remove(); 9824 }, 9825 buttons: { 9826 'Peruuta': function() { 9827 dialog.dialog('close'); 9828 }, 9829 'Poista luottotappio': function() { 9830 //console.log($('input.nullify_open_credit_loss_amount').is( ":checked" ), $('input.nullify_amount').val()); 9831 let nullifyFully = $('input.nullify_open_credit_loss_amount').is( ":checked" ); 9832 let amount = $('input.nullify_amount').val(); 9833 if(confirm("Haluatko varmasti poistaa luottotappion?")){ 9834 self.nullifyCreditLoss(dialog, nullifyFully, amount); 9835 } 9836 } 9837 } 9838 }); 9839 }; 9840 9841 self.confirmAddCreditLoss = function(){ 9842 var dialog = $('<div />', {"id": "confirm-add-credit-loss-dialog", "style":"text-align:left;"}).html('Haluatko varmasti merkitä laskun avoimen osuuden luottotappioksi?'); 9843 9844 dialog.dialog({ 9845 width: 400, 9846 autoOpen: true, 9847 modal: true, 9848 resizable: false, 9849 draggable: false, 9850 title: 'Merkitse luottotappioksi', 9851 beforeclose: function(event, ui) { 9852 event.stopPropagation() 9853 }, 9854 buttons: { 9855 'Peruuta': function() { 9856 dialog.dialog('close'); 9857 }, 9858 'Merkitse luottotappioksi': function() { 9859 self.addCreditLoss(dialog); 9860 } 9861 } 9862 }); 9863 }; 9864 9865 self.suggestCreditLoss = function($dialog){ 9866 9867 $.ajax({ 9868 "dataType": 'json', 9869 "type": "POST", 9870 "url" : "/iv_laskutus_ja_reskontra/suggestCreditLoss/" .concat(self.invoiceId()), 9871 "beforeSend":function(request){ 9872 global.showLoadingDialog('Lähetetään luottotappiosuositusta...'); 9873 } 9874 }).done(function(responseJSON){ 9875 9876 console.log('responseJSON!:', responseJSON); 9877 $dialog.dialog("close"); 9878 global.show_message(responseJSON); 9879 }).always(function(){ 9880 global.close_loading_dialog(); 9881 }).error(function(response){ 9882 console.log('addCreditLoss error:', response); 9883 global.show_message($.parseJSON(response.responseText)); 9884 }); 9885 }; 9886 9887 self.updateCreditLossStopSetting = function($dialog){ 9888 9889 var creditLossStop = $dialog.find('input:radio[name=credit_loss_stop]:checked').val(); 9890 9891 $.ajax({ 9892 "dataType": 'json', 9893 "type": "POST", 9894 "data": { 9895 credit_loss_stop: creditLossStop 9896 }, 9897 "url" : "/iv_laskutus_ja_reskontra/update_credit_loss_stop_setting/" .concat(self.invoiceId()), 9898 "beforeSend":function(request){ 9899 global.showLoadingDialog('Tallenetaan luottotappioeston asetus..'); 9900 } 9901 }).done(function(responseJSON){ 9902 9903 console.log('responseJSON!:', responseJSON); 9904 9905 //Refresh the datatables 9906 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null){ 9907 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 9908 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 9909 } 9910 9911 if(pages.iv_laskutus_ja_reskontra.$datatable != null){ 9912 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 9913 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 9914 } 9915 9916 $dialog.dialog("close"); 9917 global.show_message(responseJSON, function(){self.refresh();}); 9918 // self.refresh(); 9919 }).always(function(){ 9920 global.close_loading_dialog(); 9921 }).error(function(response){ 9922 console.log('addCreditLoss error:', response); 9923 global.show_message($.parseJSON(response.responseText)); 9924 }); 9925 }; 9926 9927 self.addCreditLoss = function($dialog){ 9928 var url; 9929 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null && pages.reskontra.$datatable === null){ 9930 url = "/iv_laskutus_ja_reskontra/addCreditLoss/" .concat(self.invoiceId()); 9931 }else{ 9932 url = "/reskontra/addCreditLoss/" .concat(self.invoiceId()); 9933 } 9934 $.ajax({ 9935 "dataType": 'json', 9936 "type": "POST", 9937 "url" : url, 9938 "beforeSend":function(request){ 9939 global.showLoadingDialog('Merkitään luottotappiota...'); 9940 } 9941 }).done(function(responseJSON){ 9942 9943 console.log('responseJSON!:', responseJSON); 9944 9945 //Refresh the datatables 9946 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null){ 9947 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 9948 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 9949 } 9950 9951 if(pages.iv_laskutus_ja_reskontra.$datatable != null){ 9952 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 9953 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 9954 } 9955 9956 if( pages.reskontra.$datatable !== null ){ 9957 pages.reskontra.$datatable.fnClearTable( 0 ); 9958 pages.reskontra.$datatable.fnDraw(); 9959 } 9960 9961 $dialog.dialog("close"); 9962 global.show_message(responseJSON, function(){self.refresh();}); 9963 // self.refresh(); 9964 }).always(function(){ 9965 global.close_loading_dialog(); 9966 }).error(function(response){ 9967 console.log('addCreditLoss error:', response); 9968 global.show_message($.parseJSON(response.responseText)); 9969 }); 9970 }; 9971 9972 9973 self.nullifyCreditLoss = function($dialog, nullifyFully, amount){ 9974 let url = ''; 9975 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null && pages.reskontra.$datatable === null){ 9976 url = "/iv_laskutus_ja_reskontra/nullifyCreditLoss/" .concat(self.invoiceId()); 9977 } 9978 $.ajax({ 9979 "dataType": 'json', 9980 "type": "POST", 9981 "url" : url, 9982 "data": { 9983 nullifyFully, 9984 amount 9985 }, 9986 "beforeSend":function(request){ 9987 global.showLoadingDialog('Poistetaan luottotappiota...'); 9988 } 9989 }).done(function(responseJSON){ 9990 9991 //Refresh the datatables 9992 if(pages.iv_laskutus_ja_reskontra.$datatable_iv != null){ 9993 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 9994 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 9995 } 9996 9997 if(pages.iv_laskutus_ja_reskontra.$datatable != null){ 9998 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 9999 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 10000 } 10001 10002 if( pages.reskontra.$datatable !== null ){ 10003 pages.reskontra.$datatable.fnClearTable( 0 ); 10004 pages.reskontra.$datatable.fnDraw(); 10005 } 10006 10007 $dialog.dialog("close"); 10008 global.show_message(responseJSON, function(){self.refresh();}); 10009 // self.refresh(); 10010 }).always(function(){ 10011 global.close_loading_dialog(); 10012 }).error(function(response){ 10013 global.show_message(JSON.parse(response.responseText)); 10014 }); 10015 }; 10016
10017 self.insertInvoiceToArvatoIfRequiredAndPrintPdf = function(){ 10018 10019 10020 if(self.data.invoice.status() == 0){ 10021 self.insertInvoiceToArvatoAndPrintPdf(); 10022 }else { 10023 self.printInvoicePdf(); 10024 } 10025 }; 10026 10027 self.printInvoicePdf = function(){ 10028 10029 window.open('/lasku/pdf/'.concat(self.invoiceId())); 10030 return false; 10031 }; 10032 10033 self.insertInvoiceToArvatoAndPrintPdf = function(w){ 10034 10035 var dialog = $('<div />', {"style":"text-align:left;"}).html('HUOM! Lasku muuttuu luonnoksesta avoimeksi tulostuksen yhteydessä. <br/><br/><strong>Itse tulostettuja laskuja ei toimiteta asiakkaalle Innovoicen toimesta.</strong>') 10036 .dialog({ 10037 autoOpen: true, 10038 modal: true, 10039 resizable: false, 10040 draggable: false, 10041 title: 'Laskun tulostus', 10042 beforeclose: function(event, ui) {event.stopPropagation()}, 10043 close: function(){ 10044 dialog.dialog('destroy'); 10045 dialog.remove(); 10046 }, 10047 buttons: { 10048 'Peruuta': function() { 10049 dialog.dialog('close'); 10050 }, 10051 'Tulosta lasku': function() { 10052 10053 $.ajax({ 10054 "dataType": 'json', 10055 "type": "POST", 10056 "url" : "/reskontra/insertInvoiceToLedgerForPrinting/".concat(self.invoiceId()), 10057 "beforeSend":function(request){ 10058 global.showLoadingDialog('Muodostetaan tulostettavaa laskua...'); 10059 }, 10060 "success": function(responseJSON){ 10061 10062 if(responseJSON.type == 'success'){ 10063 self.printInvoicePdf(); 10064 10065 if( pages.reskontra.$datatable !== null ){ 10066 pages.reskontra.$datatable.fnClearTable( 0 ); 10067 pages.reskontra.$datatable.fnDraw(); 10068 } 10069 10070 self.refresh(); 10071 } 10072 10073 global.close_loading_dialog(); 10074 dialog.dialog('close'); 10075 }, 10076 error: function(response){ 10077 global.close_loading_dialog(); 10078 global.show_message({ 10079 type: 'error', 10080 title: 'Virhe! Laskua ei voitu tulostaa', 10081 text: 'Laskua ei voitu muuttaa luonnoksesta avoimeksi, yritä myöhemmin uudelleen. Mikäli virhe jatkuu, ota yhteyttä Innovoicen asiakaspalveluun.' 10082 }); 10083 } 10084 }); 10085 } 10086 } 10087 }); 10088 }; 10089 10090 self.showRequestForCreditingDialog = function() { 10091 10092 return self.requestForCreditingDialog.show(); 10093 } 10094 10095 self.showCustomerCreditInvoiceDialog = function() { 10096 10097 try{ 10098 var result = self.customerCreditInvoiceVM.validateAndSetData(ko.toJS(self.data)) 10099 } catch (error){ 10100 return global.show_message({type: 'error', text: error.message}) 10101 } 10102 10103 if(result.creditingNotAllowed){ 10104 return self.showRequestForCreditingDialog() 10105 } 10106 10107 function updateTablesAndInvoiceDialog(){ 10108 self.show() 10109 10110 if( pages.reskontra.$datatable !== null ){ 10111 pages.reskontra.$datatable.fnClearTable( 0 ); 10112 pages.reskontra.$datatable.fnDraw(); 10113 } 10114 10115 } 10116 return self.customerCreditInvoiceVM.show({callback: updateTablesAndInvoiceDialog}); 10117 } 10118}; 10119 10120;var LedgerPaymentsDialogVm = function() { 10121 'use strict'; 10122 var self = this; 10123 self.paymentDialog = null; 10124 //self.inited = ko.observable(false); 10125 10126 self.show_ledger_payment_report = function(reportDate, isHandled) { 10127 var $dialog = $('<div />') 10128 10129 if ($dialog.hasClass('ui-dialog-content')) { 10130 $dialog.dialog('destroy'); 10131 } 10132 10133 $.ajax({ 10134 processData: false, 10135 dataType: 'json', 10136 type: 'GET', 10137 url: 'innovoice_ledger_payments/daily_report?date=' + reportDate, 10138 beforeSend: function(request) { 10139 $dialog.dialog({ 10140 width: 1200, 10141 height: 600, 10142 modal: true, 10143 resizable: true, 10144 title: 'Suoritukset ' + reportDate, 10145 close: function() { 10146 $dialog.dialog('destroy'); 10147 } 10148 }); 10149 global.show_ajax_loader($dialog); 10150 }, 10151 success: function(response) { 10152 $dialog.html(response.viewFile); 10153 10154 }, 10155 error: function(response) { 10156 $dialog.dialog('close'); 10157 var responseJSON = JSON.parse(response.responseText); 10158 10159 global.close_loading_dialog(); 10160 global.show_message(responseJSON); 10161 } 10162 }); 10163 10164 var buttons = {
10165 'Päivitä tiedot': function(){ 10166 $dialog.dialog('close'); 10167 self.show_ledger_payment_report(reportDate); 10168 }, 10169 'Lataa suoritukset': function(){ 10170 self.downloadPayments(reportDate); 10171 } 10172 } 10173 10174 if(parseInt(isHandled) === 0){ 10175 buttons["Merkitse käsitellyksi"] = function(){ 10176 self.showConfirmDialog('<span>Merkitse päivä käsitellyks?</span>', self.markDateHandled, {entryDate: reportDate}) 10177 } 10178 } 10179 $dialog.dialog('option', 'buttons', buttons) 10180 10181 } //show_ledger_payment_report 10182 10183 self.downloadPayments = function(reportDate){ 10184 url = 'innovoice_ledger_payments/exportPaymentData/?date=' + reportDate; 10185 window.location.href=url; 10186 } 10187 10188 self.refreshDatatables = function(){ 10189 if( pages.reskontra.$datatable !== null ){ 10190 pages.reskontra.$datatable.fnClearTable( 0 ); 10191 pages.reskontra.$datatable.fnDraw(); 10192 } 10193 if( pages.innovoice_ledger.$ledger_payments_dt !== null ){ 10194 pages.innovoice_ledger.$ledger_payments_dt.fnClearTable(0); 10195 pages.innovoice_ledger.$ledger_payments_dt.fnDraw(); 10196 } 10197 if( pages.innovoice_ledger.$ledger_payment_totals_dt !== null ){ 10198 pages.innovoice_ledger.$ledger_payment_totals_dt.fnClearTable(0); 10199 pages.innovoice_ledger.$ledger_payment_totals_dt.fnDraw(); 10200 } 10201 } 10202 10203 self.refreshTotalsDatatable = function(){ 10204 if( pages.innovoice_ledger.$ledger_payment_totals_dt !== null ){ 10205 pages.innovoice_ledger.$ledger_payment_totals_dt.fnClearTable(0); 10206 pages.innovoice_ledger.$ledger_payment_totals_dt.fnDraw(); 10207 } 10208 } 10209 10210 self.show_ledger_payment = function(paymentId) { 10211 self.paymentDialog = $('#show-ledger-payment-dialog'); 10212 10213 if(self.paymentDialog.length === 0){ 10214 self.paymentDialog = $('<div id="show-ledger-payment-dialog"/>') 10215 } 10216 10217 if (self.paymentDialog.hasClass('ui-dialog-content')) { 10218 self.paymentDialog.dialog('destroy'); 10219 } 10220 10221 $.ajax({ 10222 processData: false, 10223 dataType: 'json', 10224 type: 'GET', 10225 url: 'innovoice_ledger_payments/get_payment?id=' + paymentId, 10226 beforeSend: function(request) { 10227 self.paymentDialog.dialog({ 10228 width: 900, 10229 height: 600, 10230 modal: true, 10231 resizable: false, 10232 title: 'Suorituksen tiedot', 10233 // close: function() { 10234 // $dialog.dialog('close'); 10235 // }, 10236 }); 10237 global.show_ajax_loader(self.paymentDialog); 10238 }, 10239 success: function(response) { 10240 10241 var payment = response.payment; 10242 10243 self.paymentDialog.html(response.viewFile); 10244 10245 }, 10246 10247 }); 10248 10249 } //show_ledger_payment 10250 10251 self.reallocatePayment = function(paymentId, creditDate) { 10252 10253 var $form = $('<form />').append( 10254 $('<p />').html('Anna Laskun numero'), 10255 $('<input />', { type: 'text', name: 'invoiceNo', id: 'invoiceId', class: 'form-control' }).val(''), 10256 $('<br><br>'), 10257 $('<p />').html('Kirjauspäivä'), 10258 $('<input />', { type: 'text', name: 'allocationDate', id: 'allocationDate', class: 'form-control' }).datepicker( 10259 { 10260 format: 'dd.mm.yyyy', 10261 calendarWeeks: true, 10262 language: 'fi', 10263 weekStart: 1, 10264 clearBtn: true, 10265 todayHighlight: true, 10266 defaultViewDate: 'today', 10267 autoclose: true 10268 } 10269 ).datepicker('setDate', new Date()) 10270 ); 10271 10272 // TODO JONNE: tänne pitäisi saada suorituksen(jonka id on paymentId) unallocated_reporting_add_date (päivämäärä jolloin se on hyvitetty) 10273 // jotta sitä voi tarvittaessa muuttaa. Esim heidi voi asettaa hyvitksen ja uuden kohdistuksen samalle päivälle kuin milloin suoritus tullut sisään. 10274 10275 if(creditDate){ 10276 $form.append( 10277 $('<br><br>'), 10278 $('<p />').html('Kirjauspäivä'), 10279 $('<input />', { type: 'text', name: 'creditDate', id: 'creditDate', class: 'form-control' }).datepicker( 10280 { 10281 format: 'dd.mm.yyyy', 10282 calendarWeeks: true, 10283 language: 'fi', 10284 weekStart: 1, 10285 clearBtn: true, 10286 todayHighlight: true, 10287 defaultViewDate: 'today', 10288 autoclose: true 10289 } 10290 ).datepicker('setDate', new Date(creditDate)) 10291 ); 10292 } 10293 10294 var $dialog = $('<div />', { style: 'text-align:left;' }) 10295 .append($form) 10296 .dialog({ 10297 width: 320, 10298 autoOpen: true, 10299 modal: true, 10300 resizable: false, 10301 draggable: false, 10302 beforeClose: function(event, ui) { 10303 event.stopPropagation(); 10304 }, 10305 close: function() { 10306 $dialog.dialog('destroy'); 10307 }, 10308 title: 'Kohdista maksu laskulle', 10309 buttons: { 10310 'Kohdista Maksu': function() { 10311 $form.trigger('submit'); 10312 }, 10313 Peruuta: function() { 10314 $(this).dialog('close'); 10315 }, 10316 }, 10317 }); 10318 10319 $form.on('submit', function(e) { 10320 //Get the data from the form element 10321 e.stopPropagation() 10322 var data = _.object( 10323 $form.serializeArray().map(function(v) {
10324 return [v.name, v.value]; 10325 }) 10326 ); 10327 10328 if(!data.invoiceNo){ 10329 window.alert('Laskun numero on pakollinen') 10330 return false; 10331 } 10332 //Add some extra data 10333 _.extend(data, { paymentId: paymentId }); 10334 10335 e.preventDefault(); 10336 10337 global.show_loading_dialog('Kohdistetaan laskulle...'); 10338 10339 $.ajax({ 10340 url: '/innovoice_ledger_payments/reallocatePayment', 10341 dataType: 'json', 10342 type: 'POST', 10343 data: data, 10344 }) 10345 .done(function(responseJSON) { 10346 $dialog.dialog('close'); 10347 global.close_loading_dialog(); 10348 self.paymentDialog.dialog('close'); 10349 self.show_ledger_payment(paymentId); 10350 self.refreshDatatables() 10351 global.show_message(responseJSON); 10352 }) 10353 .fail(function(response) { 10354 var responseJSON = JSON.parse(response.responseText); 10355 10356 global.close_loading_dialog(); 10357 global.show_message(responseJSON); 10358 }); 10359 }); 10360 } 10361 10362 self.refundPayment = function(paymentId) { 10363 10364 var $form = $('<form />').append( 10365 $('<p />').html('Kommentti (valinnainen)'), 10366 $('<input />', { type: 'text', name: 'comment', id: 'comment', class: 'text medium' }).val('') 10367 ); 10368 10369 var $dialog = $('<div />', { style: 'text-align:left;' }) 10370 .append($form) 10371 .dialog({ 10372 width: 320, 10373 autoOpen: true, 10374 modal: true, 10375 resizable: false, 10376 draggable: false, 10377 beforeClose: function(event, ui) { 10378 event.stopPropagation(); 10379 }, 10380 close: function() { 10381 $dialog.dialog('destroy'); 10382 }, 10383 title: 'Merkitse maksu palautetuksi', 10384 buttons: { 10385 'Palauta Maksu': function() { 10386 $form.trigger('submit'); 10387 }, 10388 Peruuta: function() { 10389 $(this).dialog('close'); 10390 }, 10391 }, 10392 }); 10393 10394 $form.on('submit', function(e) { 10395 //Get the data from the form element 10396 var data = _.object( 10397 $form.serializeArray().map(function(v) { 10398 return [v.name, v.value]; 10399 }) 10400 ); 10401 10402 //Add some extra data 10403 _.extend(data, { paymentId: paymentId }); 10404 10405 e.preventDefault(); 10406 10407 global.show_loading_dialog('Merkitään palautetuksi...'); 10408 10409 $.ajax({ 10410 url: '/innovoice_ledger_payments/refundPayment', 10411 dataType: 'json', 10412 type: 'POST', 10413 data: data, 10414 }) 10415 .done(function(responseJSON) { 10416 $dialog.dialog('close'); 10417 global.close_loading_dialog(); 10418 self.paymentDialog.dialog('close'); 10419 self.show_ledger_payment(paymentId); 10420 self.refreshTotalsDatatable() 10421 global.show_message(responseJSON); 10422 }) 10423 .fail(function(response) { 10424 var responseJSON = JSON.parse(response.responseText); 10425 10426 global.close_loading_dialog(); 10427 global.show_message(responseJSON); 10428 }); 10429 }); 10430 10431 } 10432 10433 self.confirmDeletePayment = function(paymentId) { 10434 10435 var data = { paymentId: paymentId }; 10436 var html = '<strong>Huom! Poista ainoastaan suoritukset jotka eivät kuulu Innovoicen järjestelmään!</strong></br></br><span>Haluatko varmasti poistaa suorituksen?</span>'; 10437 10438 self.showConfirmDialog(html, self.deletePayment, data); 10439 10440 } 10441 10442 10443 self.markAsInterest = function(paymentId) { 10444 10445 var $form = $('<form />').append( 10446 $('<p />').html('Anna Laskun numero'), 10447 $('<input />', { type: 'text', name: 'invoiceNo', id: 'invoiceId', class: 'text medium' }).val(''), 10448 $('<br><br>'), 10449 $('<input />', { type: 'text', name: 'allocationDate', id: 'allocationDate', class: 'form-control' }).datepicker( 10450 { 10451 format: 'dd.mm.yyyy', 10452 calendarWeeks: true, 10453 language: 'fi', 10454 weekStart: 1, 10455 clearBtn: true, 10456 todayHighlight: true, 10457 defaultViewDate: 'today', 10458 autoclose: true 10459 } 10460 ).datepicker('setDate', new Date()), 10461 $('<br><br>'), 10462 $('<p />').html('Kommentti (valinnainen)'), 10463 $('<input />', { type: 'text', name: 'comment', id: 'comment', class: 'text medium' }).val('') 10464 ); 10465 10466 var $dialog = $('<div />', { style: 'text-align:left;' }) 10467 .append($form) 10468 .dialog({ 10469 width: 320, 10470 autoOpen: true, 10471 modal: true, 10472 resizable: false, 10473 draggable: false, 10474 beforeClose: function(event, ui) { 10475 event.stopPropagation(); 10476 }, 10477 close: function() { 10478 $dialog.dialog('destroy'); 10479 }, 10480 title: 'Kirjaa maksu korkotuotoksi', 10481 buttons: { 10482 'Tee Kirjaus': function() { 10483 $form.trigger('submit'); 10484 }, 10485 Peruuta: function() { 10486 $(this).dialog('close'); 10487 }, 10488 }, 10489 }); 10490 10491 $form.on('submit', function(e) { 10492 //Get the data from the form element 10493 var data = _.object( 10494 $form.serializeArray().map(function(v) {
10495 return [v.name, v.value]; 10496 }) 10497 ); 10498 10499 //Add some extra data 10500 _.extend(data, { paymentId: paymentId }); 10501 10502 e.preventDefault(); 10503 10504 global.show_loading_dialog('Merkitään korkotuotoksi...'); 10505 10506 $.ajax({ 10507 url: '/innovoice_ledger_payments/markAsInterest', 10508 dataType: 'json', 10509 type: 'POST', 10510 data: data, 10511 }) 10512 .done(function(responseJSON) { 10513 $dialog.dialog('close'); 10514 global.close_loading_dialog(); 10515 self.paymentDialog.dialog('close'); 10516 self.show_ledger_payment(paymentId); 10517 self.refreshTotalsDatatable() 10518 global.show_message(responseJSON); 10519 }) 10520 .fail(function(response) { 10521 var responseJSON = JSON.parse(response.responseText); 10522 10523 global.close_loading_dialog(); 10524 global.show_message(responseJSON); 10525 }); 10526 }); 10527 10528 } 10529 10530 self.deletePayment = function(data){ 10531 global.show_loading_dialog('Poistetaan suoritusta...'); 10532 10533 $.ajax({ 10534 url: '/innovoice_ledger_payments/deletePayment', 10535 dataType: 'json', 10536 type: 'POST', 10537 data: data, 10538 }) 10539 .done(function(responseJSON) { 10540 // $dialog.dialog('close'); 10541 global.close_loading_dialog(); 10542 self.paymentDialog.dialog('close'); 10543 self.refreshDatatables(); 10544 global.show_message(responseJSON); 10545 }) 10546 .fail(function(response) { 10547 var responseJSON = JSON.parse(response.responseText); 10548 10549 global.close_loading_dialog(); 10550 global.show_message(responseJSON); 10551 }); 10552 } 10553 10554 self.showConfirmDialog = function(html, callback, data){ 10555 var $dialog = $('<div />', { style: 'text-align:left;' }) 10556 .dialog({ 10557 width: 320, 10558 autoOpen: true, 10559 modal: true, 10560 resizable: false, 10561 draggable: false, 10562 close: function() { 10563 $dialog.dialog('destroy'); 10564 }, 10565 buttons: { 10566 'Kyllä': function() { 10567 if(typeof callback === 'function'){ 10568 callback(data); 10569 $(this).dialog('close'); 10570 } 10571 }, 10572 Peruuta: function() { 10573 $(this).dialog('close'); 10574 }, 10575 }, 10576 }).html(html); 10577 } 10578 10579 self.markDateHandled = function(data){ 10580 global.show_loading_dialog('Käsitellään pyyntöä...'); 10581 $.ajax({ 10582 url: '/innovoice_ledger_payments/markDateAsHandled', 10583 dataType: 'json', 10584 type: 'POST', 10585 data: data, 10586 }) 10587 .done(function(responseJSON) { 10588 10589 global.close_loading_dialog(); 10590 self.refreshTotalsDatatable() 10591 global.show_message(responseJSON); 10592 }) 10593 .fail(function(response) { 10594 var responseJSON = JSON.parse(response.responseText); 10595 10596 global.close_loading_dialog(); 10597 global.show_message(responseJSON); 10598 }); 10599 } 10600 10601 self.getPaymentLog = function(paymentId, element){ 10602 $.ajax({ 10603 url: '/innovoice_ledger_payments/getPaymentLog', 10604 dataType: 'json', 10605 type: 'POST', 10606 data: {paymentId: paymentId}, 10607 beforeSend: function(){ 10608 } 10609 }) 10610 .done(function(response) { 10611 element.html(response.data.view); 10612 }) 10613 .fail(function(response) { 10614 var responseJSON = JSON.parse(response.responseText); 10615 global.show_message(responseJSON); 10616 }); 10617 10618 } 10619 10620 self.addLogEntry = function(paymentId, message, element, input){ 10621 10622 $.ajax({ 10623 url: '/innovoice_ledger_payments/addPaymentLogItem', 10624 dataType: 'json', 10625 type: 'POST', 10626 data: {paymentId: paymentId, message: message}, 10627 beforeSend: function(){ 10628 } 10629 }) 10630 .done(function(response) { 10631 element.html(response.data.view); 10632 input.val(''); 10633 }) 10634 .fail(function(response) { 10635 var responseJSON = JSON.parse(response.responseText); 10636 global.show_message(responseJSON); 10637 }); 10638 } 10639 10640} 10641 10642;var PaymentTerminalVm = function (data) { 10643 'use strict'; 10644 var self = this; 10645 self.receiptId = null; 10646 self.currentPayment = ko.observableArray([]); 10647 self.selectedPaymentTerminal = ko.observable(''); 10648 self.paymentTerminalError = ko.observable(''); 10649 self.paymentTerminalResponse = ko.observable(''); 10650 self.wsConnection = new WSConnection(); 10651 self.originatorApp = null; 10652 self.tempTransaction = null; 10653 self.refundTransaction = ko.observableArray([]); 10654 self.checkTransaction = ko.observableArray([]); 10655 self.previousTransactionId = null; 10656 self.showErrorMessage = function(message) { 10657 humane.log(message, { 10658 addnCls: 'humane-jackedup-error', 10659 timeout: 8000, 10660 }); 10661 }; 10662 10663 self.showAbort = ko.observable(false); 10664 10665 // asiakkuudet page status and terminalinfo response will be set here 10666 self.wsConnection.connection.response.subscribe(function(response){ 10667 if(response.result && response.result.response_to && (response.result.response_to == 'Status' || response.result.response_to == 'TerminalInfo')){ 10668 self.paymentTerminalResponse(JSON.stringify(response.result, undefined, 2)); 10669 } 10670 }); 10671 10672 self.wsConnection.connection.status.subscribe(function(status){ 10673 if(status == 'error'){ 10674 self.paymentTerminalError(''); 10675 self.paymentTerminalError(self.wsConnection.connection.msg); 10676 } 10677 }); 10678 10679 // if paymentTerminal is connected and connection reason matches case defined below do something 10680 self.wsConnection.connection.connected.subscribe(function(connected){ 10681 if (connected && self.wsConnection.connection.connectionReason() === 'check') { 10682 self.wsSendCheck(); 10683 } 10684 if (connected && self.wsConnection.connection.connectionReason() === 'purchase') { 10685 self.wsSendPurchase(); 10686 } 10687 if (connected && self.wsConnection.connection.connectionReason() === 'refund') { 10688 self.wsSendRefund(); 10689 } 10690 }); 10691 10692 self.getTerminalStatus = function (terminalData) { 10693 self.paymentTerminalError(''); 10694 self.paymentTerminalResponse(''); 10695 if ( 10696 !terminalData || 10697 !terminalData.user_name || 10698 !terminalData.password || 10699 !terminalData.terminal_id || 10700 !terminalData.url 10701 ) { 10702 var msg = 'Yhteyden luomiseen tarvittavat tiedot puutteelliset'; 10703 self.paymentTerminalError(msg); 10704 } else { 10705 self.wsConnection.setWsConnectionData({ 10706 selectedTerminal: terminalData, 10707 connectionReason: 'TerminalInfo', 10708 }); 10709 self.wsConnection.wsConnect(); 10710 $('#wsDialog').dialog({ 10711 width: 400, 10712 modal: true, 10713 resizable: false, 10714 title: 'Maksupäätelaitteen tila', 10715 close: function () { 10716 if (self.wsConnection.ws) self.wsConnection.ws.close(); 10717 }, 10718 buttons: { 10719 'Hae tila': function(){ 10720 self.wsConnection.setWsConnectionData({ 10721 selectedTerminal: terminalData, 10722 connectionReason: 'Status', 10723 }); 10724 self.wsConnection.wsConnect(); 10725 }, 10726 'Hae tiedot': function(){ 10727 self.wsConnection.setWsConnectionData({ 10728 selectedTerminal: terminalData, 10729 connectionReason: 'TerminalInfo', 10730 }); 10731 self.wsConnection.wsConnect(); 10732 } 10733 } 10734 }); 10735 } 10736 }; 10737 10738 self.connectPaymentTerminalPurchase = function(paymentTerminals, paymentSum, receiptId, payment, origin){ 10739 var ladda = Ladda.create(document.querySelector('#connectToTerminalButton')); 10740 ladda.start(); 10741 self.paymentTerminalError(''); 10742 self.wsConnection.resetWsConnectionData(); 10743 if (!self.selectedPaymentTerminal()) { 10744 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Valitse ensin maksupäätelaite!' }); 10745 ladda.remove(); 10746 return; 10747 } 10748 10749 var terminalData = paymentTerminals.find(function(terminal){ 10750 return terminal.terminal_id == self.selectedPaymentTerminal(); 10751 }); 10752 if ( 10753 !terminalData || 10754 !terminalData.user_name || 10755 !terminalData.password || 10756 !terminalData.terminal_id 10757 ) { 10758 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Maksupäätelaitteen tiedot puutteelliset!' }); 10759 ladda.remove(); 10760 return; 10761 } 10762 if ( 10763 !paymentSum || paymentSum == 0 10764 ) { 10765 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Maksurivien summa virheellinen!' }); 10766 ladda.remove(); 10767 return; 10768 } 10769 10770 if(!payment){ 10771 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Kuormakirjalle ei löydy maksutapahtumaa!' }); 10772 ladda.remove(); 10773 return; 10774 } 10775 10776 self.receiptId = receiptId; 10777 self.originatorApp = origin; 10778 self.currentPayment(payment); 10779 self.wsConnection.setWsConnectionData({ 10780 selectedTerminal: terminalData, 10781 amountToPay: paymentSum, 10782 connectionReason: 'purchase', 10783 }); 10784 self.wsConnection.wsConnect(); 10785 }; 10786 10787 self.connectPaymentTerminalRefund = function(paymentTerminals, receiptId, payment, origin){ 10788 self.paymentTerminalError(''); 10789 self.wsConnection.resetWsConnectionData(); 10790 self.previousTransactionId = payment.payment_terminal_transaction_id; 10791 try{ 10792 var fetchTransaction = self.getPaymentTerminalTransaction({ transactionId: self.previousTransactionId }); 10793 fetchTransaction.then(function(data){ 10794 self.refundTransaction(data); 10795 self.currentPayment(payment); 10796 self.receiptId = receiptId; 10797 self.originatorApp = origin; 10798 var terminalData = paymentTerminals.find(function(terminal){ 10799 return terminal.terminal_id == data.terminal_id; 10800 }); 10801 if(!terminalData){ 10802 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Maksupäätetapahtumaan liitetttyä maksupäätettä ei löytynyt!' }); 10803 ladda.remove(); 10804 return; 10805 } 10806 self.wsConnection.setWsConnectionData({ 10807 selectedTerminal: terminalData, 10808 connectionReason: 'refund', 10809 }); 10810 self.wsConnection.wsConnect(); 10811 }); 10812 fetchTransaction.fail(function(response){ 10813 var responseJson = JSON.parse(response.responseText), 10814 error; 10815 error = responseJson.error || responseJson || 'Maksupäätetapahtuman haku epäonnistui'; 10816 self.showErrorMessage(error); 10817 self.wsConnection.wsDisconnect(); 10818 }); 10819 }catch(err){ 10820 self.paymentTerminalError('Maksupäätetapahtuman haku epäonnistui'); 10821 } 10822 }; 10823 10824 self.connectPaymentTerminalCheck = function(paymentTerminals, receiptId, payment, pendingPaymentTerminalTransaction, origin){ 10825 self.paymentTerminalError(''); 10826 self.wsConnection.resetWsConnectionData(); 10827 var transactionId = pendingPaymentTerminalTransaction.id; 10828 try{ 10829 var fetchTransaction = self.getPaymentTerminalTransaction({ transactionId: transactionId }); 10830 fetchTransaction.then(function(data){ 10831 self.checkTransaction(data); 10832 self.currentPayment(payment); 10833 self.receiptId = receiptId; 10834 self.originatorApp = origin; 10835 var terminalData = paymentTerminals.find(function(terminal){ 10836 return terminal.terminal_id == data.terminal_id; 10837 }); 10838 if(!terminalData){ 10839 self.wsConnection.setWsConnectionData({ status: 'error', msg: 'Maksupäätetapahtumaan liitetttyä maksupäätettä ei löytynyt!' }); 10840 ladda.remove(); 10841 return; 10842 } 10843 self.wsConnection.setWsConnectionData({ 10844 selectedTerminal: terminalData, 10845 connectionReason: 'check', 10846 }); 10847 self.wsConnection.wsConnect(); 10848 }); 10849 fetchTransaction.fail(function(response){ 10850 var responseJson = JSON.parse(response.responseText), 10851 error; 10852 error = responseJson.error || responseJson || 'Maksupäätetapahtuman haku epäonnistui'; 10853 self.showErrorMessage(error); 10854 self.wsConnection.wsDisconnect(); 10855 }); 10856 }catch(err){ 10857 self.paymentTerminalError('Maksupäätetapahtuman haku epäonnistui'); 10858 } 10859 }; 10860 10861 self.reconnect = function(){ 10862 self.wsConnection.wsConnect(); 10863 }; 10864 10865 self.completePaymentTerminalPayment = function(companyData, transactionData){ 10866 self.wsSendPrint(companyData, transactionData); 10867 self.wsClose(); 10868 } 10869 10870 self.completePaymentTerminalRefund = function(companyData, transactionData){ 10871 self.wsSendPrint(companyData, transactionData); 10872 self.wsClose(); 10873 } 10874 10875 self.wsSendPurchase = function(){ 10876 try { 10877 var amount = self.wsConnection.connection.amountToPay(); 10878 amount = Math.round(100 * amount); 10879 10880 var setTransaction = self.setTransactionToPayment({ 10881 paymentId: self.currentPayment().id, 10882 transactionType: 'Purchase', 10883 receiptId: self.receiptId, 10884 origin: self.originatorApp, 10885 terminalId: self.wsConnection.connection.selectedTerminal()['terminal_id'], 10886 amount: amount, 10887 }); 10888 10889 setTransaction.then(function(response){ 10890 self.tempTransaction = response.transaction; 10891 var sendParams = { 10892 cashier_language: 'fi', 10893 receipt_id: self.receiptId, 10894 amount: amount, 10895 currency: 'EUR', 10896 no_timeout: false, 10897 }; 10898 self.wsConnection.wsSend('Purchase', sendParams); 10899 }); 10900 setTransaction.fail(function(response){ 10901 var responseJson = JSON.parse(response.responseText), 10902 error; 10903 error = responseJson.error || responseJson || 'Maksun lähetys epäonnistui'; 10904 self.showErrorMessage(error); 10905 self.wsConnection.wsDisconnect(); 10906 }); 10907 } catch (error) { 10908 self.paymentTerminalError('Maksun lähetys epäonnistui'); 10909 console.log(error); 10910 } 10911 }; 10912 10913 self.wsSendCheck = function(){ 10914 var data = ko.toJS(self.checkTransaction); 10915 var sendParams = { 10916 receipt_id: parseInt(data['receipt_id']), 10917 amount: parseInt(data['amount']), 10918 currency: 'EUR', 10919 }; 10920 self.wsConnection.wsSend('Check', sendParams); 10921 }; 10922 10923 self.wsSendRefund = function(){ 10924 try { 10925 var data = ko.toJS(self.refundTransaction); 10926 var setTransaction = self.setTransactionToPayment({ 10927 paymentId: self.currentPayment().id, 10928 transactionType: 'Refund', 10929 previousTransactionId: self.previousTransactionId, 10930 receiptId: self.receiptId, 10931 origin: self.originatorApp, 10932 terminalId: self.wsConnection.connection.selectedTerminal()['terminal_id'], 10933 amount: parseInt(data['amount']), 10934 }); 10935 10936 setTransaction.then(function(response){ 10937 self.tempTransaction = response.transaction; 10938 var sendParams = { 10939 cashier_language: 'fi', 10940 receipt_id: self.receiptId, 10941 amount: parseInt(data['amount']), 10942 currency: 'EUR', 10943 }; 10944 self.showAbort(true); 10945 self.wsConnection.wsSend('Refund', sendParams); 10946 }); 10947 setTransaction.fail(function(response){ 10948 var responseJson = JSON.parse(response.responseText), 10949 error; 10950 error = responseJson.error || responseJson || 'Hyvityksen lähetys epäonnistui'; 10951 self.showErrorMessage(error); 10952 self.wsConnection.wsDisconnect(); 10953 }); 10954 } catch (error) { 10955 self.paymentTerminalError('Hyvityksen lähetys epäonnistui'); 10956 console.log(error); 10957 } 10958 }; 10959 10960 self.wsClose = function(){ 10961 self.paymentTerminalError(''); 10962 self.selectedPaymentTerminal(''); 10963 self.wsConnection.wsDisconnect(); 10964 }; 10965 10966 self.wsSendAbort = function(){ 10967 var sendParams = {}; 10968 self.wsConnection.wsSend('Abort', sendParams); 10969 self.revertOrRemoveTransactionOnPayment({ 10970 transactionId: self.tempTransaction.id, 10971 paymentId: self.currentPayment().id, 10972 origin: self.originatorApp, 10973 }); 10974 }; 10975 10976 self.setTransactionToPayment = function(data){ 10977 return jQuery 10978 .ajax({ 10979 url: '/payment_devices/setTransactionToPayment', 10980 method: 'post', 10981 data: data, 10982 }); 10983 }; 10984 10985 self.updateTransactionData = function(data){ 10986 return jQuery 10987 .ajax({ 10988 url: '/payment_devices/updateTransactionData', 10989 method: 'post', 10990 data: data, 10991 }); 10992 }; 10993 10994 self.revertOrRemoveTransactionOnPayment = function(data){ 10995 return jQuery 10996 .ajax({ 10997 url: '/payment_devices/revertTransactionOnPayment', 10998 method: 'post', 10999 data: data, 11000 }); 11001 }; 11002 11003 self.deleteTransactionFromPayment = function(data){ 11004 return jQuery 11005 .ajax({ 11006 url: '/payment_devices/deleteTransactionFromPayment', 11007 method: 'post', 11008 data: data, 11009 }); 11010 }; 11011 11012 self.getPaymentTerminalTransaction = function(data){ 11013 return jQuery 11014 .ajax({ 11015 url:
11015 '/payment_devices/getPTTransaction', 11016 method: 'post', 11017 data: data, 11018 }); 11019 }; 11020 11021 self.wsSendPrint = function(companyData, transactionData){ 11022 var receiptImages = generateReceiptImg(transactionData, companyData); 11023 receiptImages.forEach(function(receiptImg){ 11024 var sendParams = { 11025 eject: receiptImages.length == 1, 11026 image: { 11027 format: 'png', 11028 data: receiptImg, 11029 }, 11030 }; 11031 console.log('sendParams',sendParams); 11032 self.wsConnection.wsSend('Print', sendParams); 11033 }); 11034 }; 11035 11036function generateReceiptImg(transactionData, companyData) { 11037 var receiptData = transactionData.customer_receipt; 11038 var images = []; 11039 // set default height and width, will be changed if got terminal specific values 11040 var maxWidth = 365; 11041 var maxHeight = 1000; 11042 var lineheight = 25; 11043 var font = 'bold 25px Courier New'; 11044 var lines = receiptData.split(/\r?\n|\\n/); 11045 lines = mergeWithCompanyData(lines, companyData); 11046 11047 var splitLines = []; 11048 var i; 11049 for (i = 0; i < lines.length; i++) { 11050 var splitLine = fragmentText(lines[i], maxWidth, font); 11051 splitLines.push.apply(splitLines, splitLine); 11052 } 11053 11054 lines = splitLines; 11055 11056 // if refund add empty line and signature line 11057 if (transactionData.transaction_type === 'Refund') { 11058 var signatureLine = getSignatureLine(maxWidth, font); 11059 lines.push(''); 11060 lines.push(signatureLine); 11061 } 11062 11063 if (self.wsConnection.connection.terminalInfo().printer) { 11064 var printerInfo = self.wsConnection.connection.terminalInfo().printer; 11065 if (printerInf.max_height) maxHeight = printerInfo.max_height; 11066 if (printerInfo.max_width) maxWidth = printerInfo.max_width; 11067 } 11068 11069 // set canvas height by lines length + some extra for padding 11070 var heightByLines = lineheight * (lines.length + 3); 11071 if (heightByLines < maxHeight) { 11072 var img = generateReceiptBase64(lines, heightByLines, maxWidth, lineheight, font); 11073 images.push(img); 11074 } else { 11075 var chunkSize = Math.round(maxHeight / lineheight); 11076 var i; 11077 for (i = 0; i < lines.length; i += chunkSize) { 11078 var linesChunk = lines.slice(i, i + chunkSize); 11079 var img = generateReceiptBase64(linesChunk, heightByLines, maxWidth, lineheight, font); 11080 images.push(img); 11081 } 11082 } 11083 return images; 11084} 11085 11086function mergeWithCompanyData(lines, companyData) { 11087 var mergeLines = []; 11088 //company name and newline 11089 if('invoice_company_name' in companyData && companyData['invoice_company_name'] != ''){ 11090 mergeLines.push(companyData['invoice_company_name']); 11091 mergeLines.push(''); 11092 } 11093 //company address 11094 if('invoice_address' in companyData && companyData['invoice_address'] != ''){ 11095 mergeLines.push(companyData['invoice_address']); 11096 } 11097 //company zipcode and city if both exist and newline 11098 if('invoice_zipcode' in companyData && companyData['invoice_zipcode'] != '' 11099 && 11100 'invoice_city' in companyData && companyData['invoice_city'] != ''){ 11101 mergeLines.push(companyData['invoice_zipcode']+' '+companyData['invoice_city']); 11102 mergeLines.push(''); 11103 } 11104 //company email 11105 if('invoice_email' in companyData && companyData['invoice_email'] != ''){ 11106 mergeLines.push(companyData['invoice_email']); 11107 } 11108 //company phone 11109 if('invoice_phone' in companyData && companyData['invoice_phone'] != ''){ 11110 mergeLines.push(companyData['invoice_phone']); 11111 mergeLines.push(''); 11112 } 11113 11114 mergeLines.push.apply(mergeLines, lines); 11115 return mergeLines; 11116} 11117 11118function fragmentText(text, maxWidth, font) { 11119 var lineCheckCanvas = document.createElement('canvas'); 11120 var context = lineCheckCanvas.getContext('2d'); 11121 context.font = font; 11122 11123 var words = text.split(' '), 11124 lines = [], 11125 line = ''; 11126 if (context.measureText(text).width < maxWidth) { 11127 return [text]; 11128 } 11129 while (words.length > 0) { 11130 var split = false; 11131 while (context.measureText(words[0]).width >= maxWidth) { 11132 var tmp = words[0]; 11133 words[0] = tmp.slice(0, -1); 11134 if (!split) { 11135 split = true; 11136 words.splice(1, 0, tmp.slice(-1)); 11137 } else { 11138 words[1] = tmp.slice(-1) + words[1]; 11139 } 11140 } 11141 if (context.measureText(line + words[0]).width < maxWidth) { 11142 line += words.shift() + ' '; 11143 } else { 11144 lines.push(line); 11145 line = ''; 11146 } 11147 if (words.length === 0) { 11148 lines.push(line); 11149 } 11150 } 11151 11152 return lines; 11153} 11154 11155function getSignatureLine(maxWidth, font) { 11156 var lineCheckCanvas = document.createElement('canvas'); 11157 var context = lineCheckCanvas.getContext('2d'); 11158 context.font = font; 11159 var line = '_'; 11160 while (context.measureText(line).width <= maxWidth) { 11161 line = line + line; 11162 } 11163 return line; 11164} 11165 11166function generateReceiptBase64(data, height, width, lineheight, font) { 11167 var canvas = document.createElement('canvas'); 11168 canvas.height = height; 11169 canvas.width = width; 11170 var ctx = canvas.getContext('2d'); 11171 // set canvas background as white 11172 ctx.fillStyle = '#ffffff'; 11173 ctx.fillRect(0, 0, canvas.width, canvas.height); 11174 11175 ctx.font = font; 11176 var x = 10; 11177 var y = 50; 11178 // set font color to black 11179 ctx.fillStyle = 'black'; 11180 // loop throught receipt lines and them to canvas 11181 var i; 11182 for (i = 0; i < data.length; i++) ctx.fillText(data[i], x, y + i * lineheight); 11183 11184 // set canvas base64 blob as image to return 11185 return canvas.toDataURL('image/png').split(';base64,')[1]; 11186} 11187 11188}; 11189;var ServiceSubscriptionVM = function() { 11190 var self = this; 11191 self.defaults = ko.observableArray([]); 11192 self.chosenService = ko.observable(); 11193 self.activeSubscription = null; 11194 self.allowEdit = ko.observable(false); 11195 self.data = { 11196 id: ko.observable(null), 11197 service_name: ko.observable(), 11198 service_description: ko.observable(), 11199 type: ko.observable(), 11200 company_id: ko.observable(), 11201 quantity: ko.observable(), 11202 amount: ko.observable('0.00'), 11203 vat: ko.observable(24), 11204 created: ko.observable() 11205 }; 11206 11207 self.clearDataExcludingId = function(){ 11208 11209 self.data.service_name(undefined); 11210 self.data.service_description(undefined); 11211 self.data.type(undefined); 11212 self.data.quantity(1); 11213 self.data.amount('0.00'); 11214 self.data.vat(24); 11215 } 11216 11217 self.emptyData = function(options){ 11218 11219 if(options.clearCompanyId){ 11220 self.data.company_id(undefined); 11221 } 11222 self.clearDataExcludingId(); 11223 self.data.id(null); 11224 self.data.created(undefined); 11225 11226 self.chosenService(undefined); 11227 self.activeSubscription = null; 11228 self.setAllowEditFalse(); 11229 } 11230 11231 self.setAllowEditTrue = function(){ 11232 self.allowEdit(true); 11233 } 11234 self.setAllowEditFalse = function(){ 11235 self.allowEdit(false); 11236 } 11237 11238 self.setDefaults = function(defaults){ 11239 self.defaults(defaults); 11240 } 11241 11242 self.revertChanges = function(){ 11243 self.setAllowEditFalse(); 11244 self.resetActiveSubscription(); 11245 } 11246 11247 self.setActiveSubscription = function(subscription){ 11248 self.activeSubscription = subscription; 11249 11250 var defaultValues = self.getDefaultsByDescription(subscription.service_description); 11251 if(defaultValues){ 11252 self.chosenService(defaultValues); 11253 } 11254 11255 self.setData(subscription); 11256 } 11257 11258 self.resetActiveSubscription = function(){ 11259 self.setData(self.activeSubscription); 11260 } 11261 11262 self.getDefaultsByDescription = function(desc){ 11263 11264 return self.defaults().find(defaults => 11265 defaults.description === desc); 11266 11267 } 11268 11269 self.isActive = ko.pureComputed(function(){ 11270 return self.data.created() && self.data.id(); 11271 }) 11272 11273 self.status = ko.pureComputed(function(){ 11274 return self.data.created() && self.data.id() ? 'Veloitus Aktiivinen' : 'Ei Aktiivinen'; 11275 }) 11276 11277 self.setCompanyId = function(companyId){ 11278 self.data.company_id(companyId) 11279 } 11280 11281 self.setDefaultsValues = function(){ 11282 11283 if(!self.chosenService()){ 11284 self.clearDataExcludingId(); 11285 return; 11286 } 11287 if(self.chosenService().description === self.data.service_description()){ 11288 return; 11289 } 11290 11291 var qty = self.chosenService().quantity ? self.chosenService().quantity : 1; 11292 11293 self.data.type(self.chosenService().type); 11294 self.data.service_description(self.chosenService().description) 11295 self.data.quantity(qty); 11296 self.setAmount(self.chosenService().monthly_fee); 11297 self.data.vat(self.chosenService().vat) 11298 self.data.service_name(self.chosenService().name) 11299 return; 11300 } 11301 11302 self.setData = function(subscription){ 11303 if(!subscription || typeof subscription == 'undefined'){ 11304 window.alert('kuukausiveloituksen tiedot puutteelliset. Ota yhteyttä dev-tiimiin.') 11305 return; 11306 } 11307 self.data.id(subscription.id);
11308 self.data.service_name(subscription.service_name ? subscription.service_name : ''); 11309 self.data.service_description(subscription.service_description ? subscription.service_description: '') 11310 self.data.type(subscription.type ? subscription.type : ''); 11311 self.data.quantity(subscription.quantity ? subscription.quantity : 1); 11312 self.setAmount(subscription.amount); 11313 self.data.vat(subscription.vat) 11314 self.data.created(subscription.created); 11315 } 11316 11317 self.setAmount = function(value){ 11318 if(!value || typeof value == 'undefined'){ 11319 self.data.amount('0,00'); 11320 } 11321 self.data.amount(value.toFixed(2).replace('.', ',')); 11322 } 11323 11324 self.createServiceSubscription = function(){ 11325 11326 if(!self.validateSaveOrUpdate()){ 11327 return; 11328 } 11329 11330 global.showLoadingDialog('Ladataan...'); 11331 11332 jQuery 11333 .ajax({ 11334 url: 'asiakkuudet/createServiceSubscription', 11335 method: 'post', 11336 data: {data: ko.toJS(self.data)} 11337 }) 11338 .then(function(success) { 11339 global.show_message(success); 11340 self.setActiveSubscription(success.data); 11341 self.setAllowEditFalse(); 11342 }) 11343 .fail(function(error) { 11344 global.show_message(error.responseJSON); 11345 }) 11346 .always(function(){ 11347 global.close_loading_dialog(); 11348 }) 11349 } 11350 11351 self.deleteServiceSubscription = function(){ 11352 if(!window.confirm('Haluatko varmasti poistaa kuukausiveloituksen? \n\nHUOM. Kuukausiveloituksen poisto EI poista palvelua käytöstä!')){ 11353 return; 11354 } 11355 11356 global.showLoadingDialog('Ladataan...'); 11357 11358 jQuery 11359 .ajax({ 11360 url: 'asiakkuudet/deleteServiceSubscription', 11361 method: 'post', 11362 data: { 11363 id: self.data.id(), 11364 company_id: self.data.company_id() 11365 } 11366 }) 11367 .then(function(success) { 11368 global.show_message(success); 11369 self.emptyData({clearCompanyId: false}); 11370 }) 11371 .fail(function(error) { 11372 global.show_message(error.responseJSON); 11373 }) 11374 .always(function(){ 11375 global.close_loading_dialog(); 11376 }) 11377 } 11378 11379 self.editServiceSubscription = function(){ 11380 11381 if(!self.validateSaveOrUpdate()){ 11382 return; 11383 } 11384 11385 global.showLoadingDialog('Ladataan...'); 11386 11387 jQuery 11388 .ajax({ 11389 url: 'asiakkuudet/editServiceSubscription', 11390 method: 'post', 11391 data: {data: ko.toJS(self.data)} 11392 }) 11393 .then(function(success) { 11394 global.show_message(success); 11395 self.setActiveSubscription(success.data); 11396 self.setAllowEditFalse(); 11397 }) 11398 .fail(function(error) { 11399 global.show_message(error.responseJSON); 11400 }) 11401 .always(function(){ 11402 global.close_loading_dialog(); 11403 }) 11404 } 11405 11406 self.validateSaveOrUpdate = function(){ 11407 if(!self.data.type()){ 11408 window.alert('valitse veloituksen tyyppi') 11409 return false; 11410 } 11411 if(!self.data.amount()){ 11412 window.alert('anna veloituksen hinta') 11413 return false; 11414 } 11415 11416 if(!/^\d+$|^\d+\,?\d+$/.test(self.data.amount())){ 11417 window.alert('anna veloituksen hinta muodossa 12,00') 11418 return false; 11419 } 11420 11421 if(!self.data.quantity()){ 11422 window.alert('anna veloituksen kappalemäärä'); 11423 return false; 11424 } 11425 if(!self.data.company_id()){ 11426 window.alert('yrityksen id puuttuu, veloitusta ei voida päivittää. Ota yhteyttä kehitystiimiin.'); 11427 return false; 11428 } 11429 11430 return true; 11431 } 11432 11433} 11434 11435;var CompanyDocumentsVM = function() { 11436 var self = this; 11437 11438 self.types = [ 11439 {type: 'iv_payment_terminal_contract', name: 'IV maksupäätesopimus (allekirjoitettu versio)'}, 11440 {type: 'iv_service_contract', name: 'IV palvelusopimus (Allekirjoitettu versio)'}, 11441 {type: 'kredinor_invoicing_contract', name: 'Kredinor laskupalvelusopimus'}, 11442 {type: 'kredinor_power_of_attorney', name: 'Kredinor valtakirja'}, 11443 {type: 'contact_person_payment_failure', name: 'Maksuhäiriöt, vastuuhenkilöt (IV haku)'}, 11444 {type: 'company_payment_failure', name: 'Maksuhäiriöt, yritys (IV haku)'}, 11445 {type: 'other_document', name: 'Muu dokumentti'}, 11446 {type: 'traficom_contract', name: 'Ajoneuvotietohaku-palvelukuvaus'}, 11447 {type: 'traficom_permit', name: 'Traficom lupa'}, 11448 {type: 'forclosure_payment_denial', name: 'Ulosoton maksukielto'}, 11449 {type: 'forclosure_payment_denial_cancelation', name: 'Ulosoton maksukiellon peruutus'}, 11450 {type: 'forclosure_investigation_request', name: 'Ulosoton selvityspyyntö'}, 11451 {type: 'company_information_report', name: 'Yritystietoraportti (laaja)'}, 11452 {type: 'company_information_report_alfa', name: 'Yritystietoraportti (Rating Alfa)'}, 11453 {type: 'company_information_report_short', name: 'Yritystietoraportti (suppea)'}, 11454 {type: 'follow_link_service_contract', name: 'Lisäpalvelun käyttöönottosopimus: Seurantalinkki'}, 11455 {type: 'post_marketing_service_contract', name: 'Lisäpalvelun käyttöönottosopimus: Jälkimarkkinointi'}, 11456 {type: 'accounting_service_contract', name: 'Lisäpalvelun käyttöönottosopimus: Kirjanpitointegraatio'}, 11457 {type: 'shifts_service_contract', name: 'Lisäpalvelun käyttöönottosopimus: Työajanseruanta'}, 11458 {type: 'payment_link_service_contract', name: 'Lisäpalvelun käyttöönottosopimus: Maksulinkki'}, 11459 {type: 'payment_link_kyc_accept', name: 'Maksulinkki kyc hyväksyntä'}, 11460 {type: 'company_pep_document', name: 'Yrityksen pep ja pakotteet'}, 11461 {type: 'company_trade_reg_extract', name: 'Yrityksen kaupparekisteriote'}, 11462 ]; 11463 11464 self.typeOptions = ko.observableArray(self.types.sort(function(a, b){return a.name > b.name ? 1 : -1})); 11465 // add categories here if needed (also add in backend) 11466 11467 self.signDocTypes = [ 11468 {type: 'trafi', name: 'Ajoneuvotietohaku-palvelukuvaus'}, 11469 {type: 'kredinor', name: 'Kredinor laskupalvelusopimus'}, 11470 {type: 'debt_collection_power_of_attorney', name: 'Kredinor valtakirja'}, 11471 {type: 'follow_link', name: 'Lisäpalvelun käyttöönottosopimus: Seurantalinkki'}, 11472 {type: 'post_marketing', name: 'Lisäpalvelun käyttöönottosopimus: Jälkimarkkinointi'}, 11473 {type: 'accounting', name: 'Lisäpalvelun käyttöönottosopimus: Kirjanpitointegraatio'}, 11474 {type: 'shifts', name: 'Lisäpalvelun käyttöönottosopimus: Työajanseruanta'}, 11475 {type: 'payment_link', name: 'Lisäpalvelun käyttöönottosopimus: Maksulinkki'}, 11476 ]; 11477 11478 self.signableDocuments = ko.observableArray(self.signDocTypes.sort(function(a, b){return a.name > b.name ? 1 : -1})); 11479 11480 // Create the observale arrays 11481 self.documents = ko.observableArray([]); 11482 self.typeFilter = ko.observable(''); 11483 self.formVisible = ko.observable(false); 11484 11485 self.newDocDate = ko.observable(''); 11486 self.newDocFileName = ko.observable(''); 11487 self.newDocFile = ko.observable(null); 11488 self.newDocType = ko.observable(''); 11489 self.newDocTempName = ko.observable(''); 11490 11491 self.companyId = ko.observable(null); 11492 11493 self.unsignedDocuments = ko.observableArray([]); 11494 self.contactPersonEmail = ko.observable(''); 11495 self.selectedSignableDocument = ko.observable(''); 11496 11497 self.setUnsignedDocumentsData = function(data, email){ 11498 self.unsignedDocuments([]); 11499 self.unsignedDocuments(data); 11500 if(email){ 11501 self.contactPersonEmail(email); 11502 } 11503 } 11504 11505 self.setData = function(documents, companyId){ 11506 // empty the observable arrays 11507 self.documents([]); 11508 self.typeFilter(''); 11509 self.formVisible(false); 11510 11511 self.newDocDate(''); 11512 self.newDocFileName(''); 11513 self.newDocFile(null); 11514 self.newDocType(''); 11515 self.newDocTempName(''); 11516 11517 self.companyId(companyId) 11518 11519 if(!documents && !(documents instanceof Array)){ 11520 return; 11521 }
11522 documents.forEach(document => { 11523 11524 self.addOne(document) 11525 }); 11526 11527 self.sort(); 11528 } 11529 11530 self.sort = function(){ 11531 self.documents.sort((a, b)=>{ 11532 let aParts = a.doc_date.split('.'); 11533 let bParts = b.doc_date.split('.'); 11534 11535 if(aParts[2] !== bParts[2]){ 11536 return bParts[2] - aParts[2]; 11537 } 11538 if(aParts[1] !== bParts[1]){ 11539 return bParts[1] - aParts[1]; 11540 } 11541 if(aParts[0] !== bParts[0]){ 11542 return bParts[0] - aParts[0]; 11543 } 11544 11545 }) 11546 } 11547 11548 self.typeFilter.subscribe((value) => { 11549 self.documents().forEach((document)=>{ 11550 if(!value){ 11551 document.visible(true); 11552 return; 11553 } 11554 if(value === document.type){ 11555 document.visible(true); 11556 return; 11557 } 11558 document.visible(false); 11559 }) 11560 }); 11561 11562 self.addOne = function(document){ 11563 11564 let data = { 11565 id: document.id ? document.id : null, 11566 company_id: document.company_id ? document.company_id : null, 11567 doc_name: document.doc_name ? document.doc_name : null, 11568 type: document.type ? document.type : null, 11569 typeTranslation: document.type_translation ? document.type_translation : '', 11570 doc_date: document.doc_date ? document.doc_date : null, 11571 doc_type: document.doc_type ? document.doc_type : null, 11572 added_by: document.added_by ? document.added_by : '', 11573 created: document.created ? document.created : null, 11574 visible: ko.observable(true) 11575 } 11576 if(!self.validate(data)){ 11577 return; 11578 } 11579 11580 self.documents.push(data); 11581 } 11582 11583 self.removeOne = function(item){ 11584 self.documents.remove(item); 11585 } 11586 11587 self.validate = function(data){ 11588 11589 return !!data.id && !!data.type && !!data.doc_name && !!data.doc_date && !!data.id && data.company_id == self.companyId(); 11590 } 11591 11592 11593 self.addDocument = function(){ 11594 11595 global.showLoadingDialog('Ladataan...'); 11596 11597 let data = new FormData() 11598 data.append('file', self.newDocFile()); 11599 data.append('docDate', self.newDocDate()) 11600 data.append('docType', self.newDocType()) 11601 data.append('client_company_id', self.companyId()) 11602 data.append('tempName', self.newDocTempName()) 11603 11604 jQuery 11605 .ajax({ 11606 url: 'asiakkuudet/addDocument', 11607 method: 'post', 11608 data: data, 11609 contentType: false, 11610 processData: false, 11611 }) 11612 .then(function(success) { 11613 global.show_message(success); 11614 self.hideForm() 11615 self.addOne(success.data); 11616 self.sort(); 11617 }) 11618 .fail(function(error) { 11619 global.show_message(error.responseJSON); 11620 }) 11621 .always(function(){ 11622 global.close_loading_dialog(); 11623 }) 11624 11625 } 11626 11627 self.addSignableDocument = function(){ 11628 11629 global.showLoadingDialog('Ladataan...'); 11630 11631 let data = { 11632 type: self.selectedSignableDocument(), 11633 client_company_id: self.companyId(), 11634 } 11635 11636 jQuery 11637 .ajax({ 11638 url: 'asiakkuudet/addUnsignedDocument', 11639 method: 'post', 11640 data: data, 11641 }) 11642 .then(function(success) { 11643 global.show_message(success); 11644 self.setUnsignedDocumentsData(success.data, false); 11645 }) 11646 .fail(function(error) { 11647 global.show_message(error.responseJSON); 11648 }) 11649 .always(function(){ 11650 global.close_loading_dialog(); 11651 self.selectedSignableDocument(''); 11652 }) 11653 11654 } 11655 11656 self.removeSignableDocument = function(id){ 11657 11658 global.showLoadingDialog('Ladataan...'); 11659 11660 let data = { 11661 id: id, 11662 client_company_id: self.companyId(), 11663 } 11664 11665 jQuery 11666 .ajax({ 11667 url: 'asiakkuudet/deleteUnsignedDocument', 11668 method: 'post', 11669 data: data, 11670 }) 11671 .then(function(success) { 11672 global.show_message(success); 11673 var data = success.data ? success.data : []; 11674 self.setUnsignedDocumentsData(data, false); 11675 }) 11676 .fail(function(error) { 11677 global.show_message(error.responseJSON); 11678 }) 11679 .always(function(){ 11680 global.close_loading_dialog(); 11681 }) 11682 11683 } 11684 11685 self.getDocument = function(item) { 11686 let url = '/asiakkuudet/getDocument/' + item.id; 11687 window.open(url, '_blank'); 11688 }; 11689 11690 self.deleteDocument = function(item){ 11691 11692 if(!window.confirm('Haluatko varmasti poistaa dokumentin ' + item.doc_name + ' (' + item.typeTranslation + ') ?')){ 11693 return; 11694 } 11695 11696 global.showLoadingDialog('Poistetaan...'); 11697 jQuery 11698 .ajax({ 11699 url: '/asiakkuudet/deleteDocument/' + item.id, 11700 method: 'post', 11701 contentType: false, 11702 processData: false, 11703 }) 11704 .then(function(success) { 11705 global.show_message(success); 11706 self.removeOne(item); 11707 }) 11708 .fail(function(error) { 11709 global.show_message(error.responseJSON); 11710 }) 11711 .always(function(){ 11712 global.close_loading_dialog(); 11713 }) 11714 } 11715 11716 11717 self.sendSigningRequest = function(){ 11718 11719 if(!window.confirm('Varmista, että asiakkaan tiedot on syötetty oikein asiakaskortille ja tiedot näkyvät sopimuksella avaamalla ja tarkastamalla sopimus')){ 11720 return; 11721 } 11722 11723 global.showLoadingDialog('Ladataan...'); 11724 11725 let data = new FormData() 11726 data.append('email', self.contactPersonEmail()); 11727 11728 11729 jQuery 11730 .ajax({ 11731 url: 'asiakkuudet/sendSigningRequest/' + self.companyId(), 11732 method: 'post', 11733 data: data, 11734 contentType: false, 11735 processData: false, 11736 }) 11737 .then(function(success) { 11738 global.show_message(success); 11739 }) 11740 .fail(function(error) { 11741 global.show_message(error.responseJSON); 11742 }) 11743 .always(function(){ 11744 global.close_loading_dialog(); 11745 }) 11746 } 11747 11748 self.showForm = function(){ 11749 self.formVisible(true); 11750 } 11751 11752 self.hideForm = function(){ 11753 self.newDocDate(''); 11754 self.newDocType(''); 11755 self.newDocFile(null); 11756 self.newDocFileName(''); 11757 self.newDocTempName(''); 11758 self.formVisible(false); 11759 } 11760 11761 11762 self.dragDropHandler = function(item, ev) { 11763 11764 let dropArea = $('#drop_zone'); 11765 dropArea.removeClass('highlight'); 11766 ev.preventDefault(); 11767 11768 if (ev.originalEvent.dataTransfer.items) { 11769 // Use DataTransferItemList interface to access the file(s) 11770 if(ev.originalEvent.dataTransfer.items.length !== 1){ 11771 window.alert('Voit ladata ainoastaan yhden tiedoston kerrallaan.'); 11772 return; 11773 } 11774
11775 [...ev.originalEvent.dataTransfer.items].forEach((item, i) => { 11776 11777 if (item.kind === "file") { 11778 const file = item.getAsFile(); 11779 self.newDocFile(file) 11780 self.newDocFileName(file.name) 11781 } 11782 }); 11783 } else { 11784 11785 window.alert('Jokin meni vikaan. Yritä lisätä tiedosto painikkeen kautta.') 11786 } 11787 } 11788 11789 self.processDocument = function(_, evt){ 11790 let file = evt.target.files[0]; 11791 if(file && file.name){ 11792 self.newDocFile(file) 11793 self.newDocFileName(file.name) 11794 } 11795 } 11796 11797 11798 self.addElementBinding = function(){ 11799 11800 let dropArea = $('#drop_zone'); 11801 11802 function preventDefaults (e) { 11803 e.preventDefault() 11804 e.stopPropagation() 11805 }; 11806 11807 dropArea.on('dragenter dragover', function(e){ 11808 preventDefaults(e) 11809 dropArea.addClass('highlight') 11810 }) 11811 11812 dropArea.on('dragleave', function(e){ 11813 preventDefaults(e) 11814 dropArea.removeClass('highlight') 11815 }) 11816 11817 } 11818} 11819 11820ko.bindingHandlers.company_doc_datepicker = { 11821 init: function(element, valueAccessor, allBindings){ 11822 11823 var options = valueAccessor(), 11824 value = ko.unwrap(options); 11825 11826 $(element).datepicker({ 11827 format: 'dd.mm.yyyy', 11828 language: 'fi-FI', 11829 weekStart: 1, 11830 todayHighlight: true, 11831 startDate: '-180m', 11832 todayBtn: 'linked', 11833 forceParse: false 11834 }); 11835 11836 $(element).on('changeDate', function(){ 11837 $(element).datepicker('hide'); 11838 }) 11839 } 11840}; 11841 11842;var CompanyRestrictionsVM = function() { 11843var self = this; 11844 11845 self.companyId = ko.observable(null); 11846 self.restrictions = ko.observableArray([]); 11847 11848 self.showHeader = ko.observable(false); 11849 self.showRestrictions = ko.observable(false); 11850 self.deleteButtons = ko.observableArray([]); 11851 11852 11853 self.toggleRestrictions = function(){ 11854 self.showRestrictions(!self.showRestrictions()); 11855 } 11856 11857 self.setData = function(companyId, restrictions){ 11858 11859 self.restrictions([]); 11860 self.companyId(companyId); 11861 self.deleteButtons([]); 11862 self.showHeader(false); 11863 11864 if(!restrictions && !(restrictions instanceof Array)){ 11865 return; 11866 } 11867 11868 restrictions.forEach(function(item){ 11869 if(self.validate(item)){ 11870 if(!self.deleteButtons().find(function(i){return i.type === item.type})){ 11871 self.deleteButtons.push({reason: item.reason, type: item.type}); 11872 } 11873 11874 self.restrictions.push(item); 11875 } 11876 }); 11877 11878 if(self.restrictions().length > 0){ 11879 self.showHeader(true); 11880 } else { 11881 self.showHeader(false); 11882 } 11883 11884 } 11885 11886 self.validate = function(data){ 11887 return !!data.id && !!data.service && !!data.reason && !!data.date && !!data.origValue && data.company_id == self.companyId(); 11888 } 11889 11890 self.restrictionExists = function(field){ 11891 let filtered = self.restrictions().filter(function(item){ 11892 return item.field_name == field; 11893 }) 11894 11895 if(filtered.length > 0){ 11896 return true; 11897 } 11898 return false; 11899 } 11900 11901 self.deleteRestrictions = function(type, successCallback){ 11902 if(!window.confirm('Haluatko varmasti palveluestot?')){ 11903 return; 11904 } 11905 11906 let client_company_id = self.companyId(); 11907 11908 if(!client_company_id){ 11909 window.alert('Virheellinen yritys id!'); 11910 return; 11911 } 11912 11913 global.showLoadingDialog('Ladataan...'); 11914 11915 jQuery 11916 .ajax({ 11917 url: 'asiakkuudet/deleteCompanyRestrictions/'+client_company_id, 11918 method: 'post', 11919 data: {type: type}, 11920 dataType: 'json', 11921 }) 11922 .done(function(responseJSON) { 11923 global.show_message({type: 'success', title: 'Valmis', text: 'Esto poistettu, päivitetään asiakkuuskortti'}); 11924 console.log(responseJSON); 11925 successCallback(responseJSON); 11926 }) 11927 .fail(function(error) { 11928 global.show_message(error.responseJSON); 11929 }) 11930 .always(function(){ 11931 global.close_loading_dialog(); 11932 }) 11933 11934 } 11935 11936 self.getRestrictions = function(companyId) 11937 { 11938 11939 // reset some data 11940 self.restrictions([]); 11941 self.showHeader(false); 11942 self.showRestrictions(false); 11943 if(!companyId){ 11944 return; 11945 } 11946 11947 jQuery 11948 .ajax({ 11949 url: 'asiakkuudet/getCompanyRestrictions/'+companyId, 11950 method: 'get', 11951 }) 11952 .then(function(success) { 11953 self.setData(companyId, success.data); 11954 }) 11955 .fail(function(error) { 11956 console.log('Could not get company restrictions') 11957 }); 11958 11959 } 11960 11961 self.removeRow = function(item){ 11962 11963 self.restrictions.remove(item); 11964 } 11965 11966} 11967 11968;var CompanyMessagingDetailsVM = function() { 11969 var self = this; 11970 11971 // add categories here if needed (also add in backend)
11972 self.categories = ['sms', 'email', 'warning']; 11973 11974 // Create the observale arrays 11975 self.categories.forEach((cat)=>{ 11976 self[cat] = ko.observableArray([]); 11977 }) 11978 11979 self.companyId = ko.observable(null); 11980 11981 self.setData = function(companyId, details){ 11982 // empty the observable arrays 11983 self.categories.forEach((cat)=>{ 11984 self[cat]([]); 11985 }) 11986 11987 self.companyId(companyId) 11988 11989 if(!details && !(details instanceof Array)){ 11990 return; 11991 } 11992 details.forEach(detail => { 11993 11994 self.addOne(detail) 11995 }); 11996 11997 self.categories.forEach((cat)=>{ 11998 self.sort(cat); 11999 }) 12000 12001 } 12002 12003 self.sort = function(category){ 12004 self[category].sort((a, b)=>{ 12005 return a.order - b.order; 12006 }) 12007 } 12008 12009 self.addOne = function(details){ 12010 // this is for if someone sets the order to 0 in the backend it would not show in client 12011 if(details.order === 0){ 12012 details.order = 10000; 12013 } 12014 let data = { 12015 id: details.id ? ko.observable(details.id) : null, 12016 company_id: details.company_id ? details.company_id : null, 12017 category: details.category ? details.category : null, 12018 type: details.type ? ko.observable(details.type) : null, 12019 value: details.value ? ko.observable(details.value) : null, 12020 order: (details.order || details.order === 0) ? details.order : null, 12021 name: details.name ? ko.observable(details.name) : null, 12022 description: details.description ? ko.observable(details.description) : null, 12023 edit: ko.observable(false) 12024 } 12025 if(!self.validate(data)){ 12026 return; 12027 } 12028 12029 self[data.category].push(data); 12030 } 12031 12032 self.updateOne = function(details){ 12033 // this is for if someone sets the order to 0 in the backend it would not show in client 12034 if(details.order === 0){ 12035 details.order = 10000; 12036 } 12037 let data = { 12038 id: details.id ? ko.observable(details.id) : null, 12039 company_id: details.company_id ? details.company_id : null, 12040 category: details.category ? details.category : null, 12041 type: details.type ? ko.observable(details.type) : null, 12042 value: details.value ? ko.observable(details.value) : null, 12043 order: details.order ? details.order : null, 12044 name: details.name ? ko.observable(details.name) : null, 12045 description: details.description ? ko.observable(details.description) : null, 12046 edit: ko.observable(false) 12047 } 12048 if(!self.validate(data)){ 12049 // console.log(data) 12050 return; 12051 } 12052 12053 let oldItems = self[data.category](); 12054 let oldItem = oldItems.find((item)=>{ 12055 return item.id === data.id; 12056 }) 12057 self[data.category].replace(oldItem, data); 12058 12059 } 12060 12061 self.validate = function(data){ 12062 12063 const isValidCategory = data.category && (self.categories.indexOf(data.category) !== -1); 12064 // const value = isValidCategory && !!data.id && !!data.type && !!data.value && !!data.order && !!data.name && data.company_id == self.companyId(); 12065 // console.log('validate', value, data) 12066 return isValidCategory && !!data.id && !!data.type && !!data.value && !!data.order && !!data.name && !!data.description && data.company_id == self.companyId(); 12067 } 12068 12069 self.allowEdit = function(detail, value){ 12070 //console.log(detail); 12071 if(value){ 12072 detail.oldValue = detail.value(); 12073 } else { 12074 detail.value(detail.oldValue) 12075 } 12076 detail.edit(value); 12077 } 12078 12079 self.updateValue = function(item, context, action){ 12080 // console.log(item, context, action); 12081 if(action === 'delete' && !window.confirm('Haluatko varmasti poistaa rivin?')){ 12082 return; 12083 } 12084 global.showLoadingDialog('Ladataan...'); 12085 12086 let data = ko.toJS(item); 12087 data.action = action; 12088 data.client_company_id = self.companyId(); 12089 12090 jQuery 12091 .ajax({ 12092 url: 'asiakkuudet/modifyCompanyMessagingDetail', 12093 method: 'post', 12094 data: data 12095 }) 12096 .then(function(success) { 12097 global.show_message(success); 12098 switch(action){ 12099 case 'edit': 12100 self.updateOne(success.data); 12101 case 'create': 12102 self[context].remove(item); 12103 self.addOne(success.data); 12104 self.sort(context); 12105 case 'delete': 12106 self.removeRow(item, context) 12107 } 12108 12109 }) 12110 .fail(function(error) { 12111 global.show_message(error.responseJSON); 12112 }) 12113 .always(function(){ 12114 global.close_loading_dialog(); 12115 }) 12116 12117 } 12118 12119 self.addEmpty = function(category){ 12120 let data = { 12121 id: ko.observable(null), 12122 company_id: self.companyId(), 12123 type: ko.observable(''), 12124 value: ko.observable(''), 12125 name: ko.observable(''), 12126 description: ko.observable(''), 12127 edit: ko.observable(true) 12128 } 12129 self[category].push(data); 12130 } 12131 12132 self.removeRow = function(item, context){ 12133 12134 self[context].remove(item); 12135 } 12136 12137 self.setDropDownOption = function(detail, options){ 12138 //console.log(detail, options); 12139 12140 var option = options instanceof Array ? options.filter((item)=>{ 12141 return item.type === detail.type() 12142 }) : false;
12143 12144 if(!option || option.length !== 1){ 12145 return; 12146 } 12147 12148 ko.isObservable(detail.name) && detail.name(option[0].name) 12149 ko.isObservable(detail.description) && detail.description(option[0].description) 12150 12151 } 12152 12153} 12154;// Underscore.js 1.5.1 12155// http://underscorejs.org 12156// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 12157// Underscore may be freely distributed under the MIT license. 12158!function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,v=e.reduce,h=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,w=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.1";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(j.has(n,a)&&t.call(e,n[a],a,n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a<e.computed&&(e={value:n,computed:a})}),e.value},j.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=j.random(r++),e[r-1]=e[t],e[t]=n}),e};var F=function(n){return j.isFunction(n)?n:function(t){return t[n]}};j.sortBy=function(n,t,r){var e=F(t);return j.pluck(j.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index<t.index?-1:1}),"value")};var k=function(n,t,r,e){var u={},i=F(null==t?j.identity:t);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};j.groupBy=function(n,t,r){return k(n,t,r,function(n,t,r){(j.has(n,t)?n[t]:n[t]=[]).push(r)})},j.countBy=function(n,t,r){return k(n,t,r,function(n,t){j.has(n,t)||(n[t]=0),n[t]++})},j.sortedIndex=function(n,t,r,e){r=null==r?j.identity:F(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])<u?i=o+1:a=o}return i},j.toArray=function(n){return n?j.isArray(n)?o.call(n):n.length===+n.length?j.map(n,j.identity):j.values(n):[]},j.size=function(n){return null==n?0:n.length===+n.length?n.length:j.keys(n).length},j.first=j.head=j.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},j.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},j.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},j.rest=j.tail=j.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},j.compact=function(n){return j.filter(n,j.identity)};var R=function(n,t,r){return t&&j.every(n,j.isArray)?c.apply(r,n):(A(n,function(n){j.isArray(n)||j.isArguments(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r)};j.flatten=function(n,t){return R(n,t,[])}
12158,j.without=function(n){return j.difference(n,o.call(arguments,1))},j.uniq=j.unique=function(n,t,r,e){j.isFunction(t)&&(e=r,r=t,t=!1);var u=r?j.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:j.contains(a,r))||(a.push(r),i.push(n[e]))}),i},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=function(n){var t=o.call(arguments,1);return j.filter(j.uniq(n),function(n){return j.every(t,function(t){return j.indexOf(t,n)>=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var M=function(){};j.bind=function(n,t){var r,e;if(w&&n.bind===w)return w.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));M.prototype=n.prototype;var u=new M;M.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u=null;return function(){var i=this,a=arguments,o=function(){u=null,r||(e=n.apply(i,a))},c=r&&!u;return clearTimeout(u),u=setTimeout(o,t),c&&(e=n.apply(i,a)),e}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push(n[r]);return t},j.pairs=function(n){var t=[];for(var r in n)j.has(n,r)&&t.push([r,n[r]]);return t},j.invert=function(n){var t={};for(var r in n)j.has(n,r)&&(t[n[r]]=r);return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={}
12158,r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};
12158return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}.call(this); 12159//# sourceMappingURL=underscore-min.map 12160;$.ajaxSetup({ 12161 // Disable caching of AJAX responses 12162 cache: false, 12163}); 12164 12165var urlParams = new URLSearchParams(window.location.search); 12166console.log(window.location.pathname, urlParams.toString()); 12167var intialSearch = ''; 12168if (urlParams.has('lasku') && (window.location.pathname === '/iv_laskutus_ja_reskontra' || window.location.pathname === '/reskontra')) { 12169 intialSearch = urlParams.get('lasku'); 12170 window.history.replaceState({}, '', window.location.pathname); 12171} 12172 12173var callbacks = {}; 12174 12175callbacks.success_add_refund_payment = function () { 12176 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnClearTable(0); 12177 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnDraw(); 12178}; 12179 12180function setClipboardText(text, successMessage) { 12181 if (!navigator.clipboard || typeof navigator.clipboard.writeText !== 'function') { 12182 if(window.toastr) { 12183 window.toastr.error('Selain ei tue kopiointia leikepöydälle'); 12184 } 12185 return; 12186 } 12187 if(!text){ 12188 if(window.toastr) { 12189 window.toastr.error('Kopioitava teksti on tyhjä'); 12190 } 12191 return; 12192 } 12193 navigator.clipboard.writeText(text).then(function() { 12194 if(window.toastr && successMessage) { 12195 window.toastr.success(successMessage, '', {timeOut: 2000}); 12196 } 12197 } 12198 ).catch(function() { 12199 if(window.toastr) { 12200 window.toastr.error('Tekstin kopiointi leikepöydälle epäonnistui'); 12201 } 12202 }); 12203} 12204 12205 12206var global = {}; 12207 12208global.dataTablesLanguage = { 12209 sProcessing: 'Ladataan...', 12210 sLengthMenu: 'Näytä _MENU_ riviä', 12211 sZeroRecords: 'Ei yhtään riviä', 12212 sInfo: 'Näytetään rivit _START_ - _END_, yhteensä _TOTAL_ rivistä', 12213 sInfoEmpty: 'Näytetään rivit 0 - 0, yhteensä 0 rivistä', 12214 sInfoFiltered: '(suodatettu _MAX_ rivistä)', 12215 sInfoPostFix: '', 12216 sSearch: 'Etsi:', 12217 sUrl: '', 12218 oPaginate: { 12219 sFirst: 'Ensimmäinen', 12220 sPrevious: 'Edellinen', 12221 sNext: 'Seuraava', 12222 sLast: 'Viimeinen', 12223 }, 12224}; 12225 12226//Global properties 12227global.$dialog = ''; 12228global.$loading_dialog = $( 12229 '<div><p style="margin: 0 auto; width: 66px; padding-top:38px;"><img src="/assets/images/ajax_loading.gif" width="66" height="66" /></p></div>' 12230); 12231global.$ajax_loader = $( 12232 '<p style="text-align:center;"><img src="/assets/images/ajax_loading.gif" width="66" height="66" /></p>' 12233); 12234global.$mini_loader = $( 12235 '<p style="text-align:center;"><img src="/assets/images/ajax_loading.gif" width="14" height="14" /></p>' 12236); 12237global.viewModels = {}; 12238 12239//Global Methods 12240global.init = function () { 12241 global.$dialog = $('#dialog'); 12242 12243 $(document.body).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { 12244 var JSON; 12245 global.close_loading_dialog(); 12246 12247 if (thrownError === 'Unauthorized') { 12248 JSON = $.parseJSON(jqXHR.responseText); 12249 global.show_message(JSON, function () { 12250 window.location = 'auth/login/'; 12251 }); 12252 } 12253 12254 if (thrownError === 'Forbidden') { 12255 JSON = { 12256 type: 'error', 12257 title: 'Ei käyttöoikeuksia', 12258 text: 'Sinulla ei ole riittäviä käyttöoikeuksia toimintoon', 12259 }; 12260 global.show_message(JSON); 12261 } 12262 12263 if (thrownError === 'Internal Server Error') { 12264 JSON = { 12265 type: 'error', 12266 text: 'Sivustolla ilmeni virhe yrittäessään suorittaa haluttua toimintoa, ole hyvä ja yritä uudelleen', 12267 }; 12268 global.show_message(JSON); 12269 } 12270 }); 12271 12272 global.$loading_dialog.dialog({ 12273 modal: true, 12274 resizable: false, 12275 draggable: false, 12276 width: 320, 12277 height: 240, 12278 closeOnEscape: false, 12279 autoOpen: false, 12280 open: function () { 12281 $(this).parents('.ui-dialog:first').find('.ui-dialog-titlebar-close').remove(); 12282 }, 12283 }); 12284 12285 // $('.tip_small').tooltip({ 12286 // tipClass: 'tooltip_small', 12287 // effect: 'fade', 12288 // fadeOutSpeed: 100, 12289 // predelay: 400, 12290 // }); 12291 // 12292 // $('.tip_big').tooltip({ 12293 // tipClass: 'tooltip_big', 12294 // effect: 'fade', 12295 // fadeOutSpeed: 100, 12296 // predelay: 400, 12297 // }); 12298 // 12299 // $('.tip').tooltip({ 12300 // effect: 'fade', 12301 // fadeOutSpeed: 100, 12302 // predelay: 400, 12303 // position: 'top right', 12304 // offset: [0, 0], 12305 // }); 12306 12307 $('#omat_tiedot') 12308 .button({}) 12309 .on('click', function () { 12310 window.location = '/omat_tiedot/'; 12311 }); 12312 12313 //Make all links inside datatables to call the functions in href attribute to be called via ajax 12314 $('body').on('click', 'a.ajax', function (e) { 12315 e.preventDefault(); 12316 12317 var namespace = $(e.target).attr('name'); 12318 var method = $(e.target).attr('target'); 12319 var ajax_url = $(e.target).attr('href'); 12320 var additional_params = $(e.target).parent('td').data(); 12321 12322 //console.log(namespace, method, ajax_url, additional_params); 12323 //console.log('isFunction()', $.isFunction(window[namespace][method])); 12324 //console.log(typeof(window[namespace]), namespace, method, namespace[method]); 12325 12326 //If namespace and method are defined call the corresponding method 12327 if (typeof method != 'undefined' && typeof namespace != 'undefined') { 12328 if (typeof pages[namespace] != 'undefined') { 12329 if ($.isFunction(pages[namespace][method])) { 12330 pages[namespace][method](ajax_url, additional_params); 12331 } 12332 } 12333 12334 if (typeof window[namespace] != 'undefined') { 12335 if ($.isFunction(window[namespace][method])) { 12336 window[namespace][method](ajax_url, additional_params); 12337 } 12338 } 12339 } 12340 }); 12341 12342 //Make all links inside datatables to call the functions in href attribute to be called via ajax 12343 $('.dataTable').on('click', 'a', function (e) { 12344 e.preventDefault(); 12345 var namespace = $(e.target).attr('name'); 12346 var method = $(e.target).attr('class'); 12347 var ajax_url = $(e.target).attr('href'); 12348 var additional_params = $(e.target).parent('td').data(); 12349 12350 //console.log(namespace, method, ajax_url, additional_params); 12351 //console.log('isFunction()', $.isFunction(window[namespace][method])); 12352 // console.log(typeof(window[namespace]), namespace, method, namespace[method]); 12353 // console.log(window[namespace][method]()); 12354 12355 //If namespace and method are defined call the corresponding method 12356 if (typeof method != 'undefined' && typeof namespace != 'undefined') { 12357 if (typeof pages[namespace] != 'undefined') { 12358 if ($.isFunction(pages[namespace][method])) { 12359 pages[namespace][method](ajax_url, additional_params); 12360 } 12361 } 12362 12363 if (typeof window[namespace] != 'undefined') { 12364 if ($.isFunction(window[namespace][method])) { 12365 window[namespace][method](ajax_url, additional_params); 12366 } 12367 } 12368 } 12369 }); 12370}; 12371 12372global.getGlobalDialogAndEmptyIfHasContent = function () { 12373 // if element does not exist, create it 12374 if (!$('#dialog').length) { 12375 $('<div id="dialog"></div>').appendTo('body'); 12376 } 12377 // set global property to #dialog, may have been reset to something else 12378 global.$dialog = $('#dialog'); 12379 12380 // check if it has content and close it (will remove any inner dialogs from InvoiceDialog) 12381 if (global.$dialog.hasClass('ui-dialog-content')) { 12382 console.log('closing global dialog!'); 12383 global.$dialog.dialog('close'); 12384 } 12385 // check if it still has content and destroy it 12386 if (global.$dialog.hasClass('ui-dialog-content')) { 12387 console.log('destroying global dialog!'); 12388 global.$dialog.dialog('destroy'); 12389 } 12390 return global.$dialog; 12391}; 12392 12393global.show_ajax_loader = function ($dialog, $separateLoaderDiv) { 12394 if ($separateLoaderDiv) { 12395 $separateLoaderDiv.html(global.$ajax_loader); 12396 } else { 12397 var dialog_height = $dialog.dialog('option', 'height') / 2 - 106; 12398 global.$ajax_loader.css('padding-top', dialog_height); 12399 12400 $dialog.html(global.$ajax_loader); 12401 } 12402}; 12403 12404//Show a dialog with a loading bar 12405global.show_loading_dialog = function (dialog_title) { 12406 global.$loading_dialog.dialog('option', 'title', dialog_title); 12407 global.$loading_dialog.dialog('open') 12408}; 12409 12410global.close_loading_dialog = function () { 12411 global.$loading_dialog.dialog('close'); 12412}; 12413 12414global.showLoadingDialog = function (title) { 12415 global.$loading_dialog.dialog({ 12416 modal: true, 12417 resizable: false, 12418 draggable: false, 12419 width: 320, 12420 height: 240, 12421 title: title, 12422 closeOnEscape: false, 12423 autoOpen: true, 12424 open: function () { 12425 $(this).parents('.ui-dialog:first').find('.ui-dialog-titlebar-close').remove(); 12426 }, 12427 }).parents('.ui-dialog').css('z-index', 9998); 12428}; 12429 12430global.show_message = function (msgJSON, callback) { 12431 var icon = ''; 12432 var $message_dialog = ''; 12433 var timer; 12434 12435 switch (msgJSON.type) { 12436 case 'success': 12437 icon = 'ui-icon-circle-check'; 12438 break; 12439 case 'error': 12440 icon = 'ui-icon-circle-close'; 12441 break; 12442 case 'alert': 12443 icon = 'ui-icon-alert'; 12444 break; 12445 } 12446 12447 if ((msgJSON.title === '' || typeof msgJSON.title === 'undefined') && msgJSON.type === 'error') { 12448 msgJSON.title = 'Virhe!'; 12449 } 12450 12451 $message_dialog = $('<div />', {}); 12452 $message_dialog.append($('<p />', {})).html(msgJSON.text); 12453
12454 if (msgJSON.type !== 'info') { 12455 $message_dialog.prepend( 12456 $('<span />', { class: 'ui-icon ' + icon, style: 'float:left; margin:0 7px 50px 0;' }) 12457 ); 12458 } 12459 12460 $message_dialog.dialog({ 12461 title: msgJSON.title, 12462 modal: true, 12463 buttons: { 12464 Ok: function () { 12465 $(this).dialog('close'); 12466 }, 12467 }, 12468 open: function () { 12469 if (msgJSON.type === 'success') { 12470 timer = setTimeout(function () { 12471 $message_dialog.dialog('widget').hide('highlight', {}, 1500, function () { 12472 $message_dialog.dialog('close'); 12473 }); 12474 }, 2000); 12475 } 12476 if (msgJSON.type === 'info') { 12477 } 12478 }, 12479 beforeClose: function () { 12480 clearTimeout(timer); 12481 }, 12482 close: function () { 12483 if (typeof callback !== 'undefined') { 12484 callback(); 12485 } 12486 $(this).dialog('destroy'); 12487 $(this).remove(); 12488 }, 12489 }).parents('.ui-dialog').css('z-index', 9999); 12490}; 12491 12492global.show_log = function (url) { 12493 global.$dialog = $('<div />'); 12494 var $dialog = global.$dialog; // 12495 12496 if (typeof url != 'undefined') { 12497 $.ajax({ 12498 processData: false, 12499 dataType: 'html', 12500 type: 'GET', 12501 url: url, 12502 beforeSend: function (request) { 12503 $dialog.dialog({ 12504 width: 650, 12505 height: 450, 12506 title: 'Tapahtumaloki', 12507 close: function (e) { 12508 e.stopPropagation(); 12509 }, 12510 }); 12511 global.show_ajax_loader($dialog); 12512 }, 12513 success: function (response) { 12514 $dialog.html(response); 12515 }, 12516 }); 12517 } 12518}; //show_log 12519 12520global.showJob = function (url) { 12521 var dialog = $('<div />'); 12522 12523 if (dialog.hasClass('ui-dialog-content')) dialog.dialog('destroy'); 12524 12525 if (typeof url != 'undeifned') { 12526 $.ajax({ 12527 processData: false, 12528 dataType: 'html', 12529 type: 'GET', 12530 url: url, 12531 beforeSend: function (request) { 12532 dialog.dialog({ 12533 width: 800, 12534 height: 600, 12535 title: 'Kuormakirja', 12536 close: function (e) { 12537 e.stopPropagation(); 12538 dialog.dialog('destroy'); 12539 }, 12540 }); 12541 global.show_ajax_loader(dialog); 12542 }, 12543 success: function (response) { 12544 dialog.html(response); 12545 }, 12546 }); 12547 } 12548}; 12549 12550global.add_payment = function (url, params) { 12551 var d = new Date(); 12552 12553 //Define the URL and success function for the invoice payment case 12554 /* 12555 if(target_type == 'invoice'){ 12556 var url = '/ajax/add_payment/' + id; 12557 var success_callback = function(responseJSON, statusText, xhr, $form) { 12558 global.close_loading_dialog(); 12559 global.show_message(responseJSON); 12560 $add_payment_dialog.dialog("destroy"); 12561 12562 //Refresh the datatables 12563 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable( 0 ); 12564 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 12565 12566 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable( 0 ); 12567 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 12568 } 12569 } 12570 12571 //Define the URL and success function for the refund payment case 12572 if(target_type == 'refund'){ 12573 var url = '/ajax/add_refund_payment/' + id; 12574 var success_callback = function(responseJSON, statusText, xhr, $form) { 12575 global.close_loading_dialog(); 12576 global.show_message(responseJSON); 12577 $add_payment_dialog.dialog("destroy"); 12578 12579 //Refresh the datatable 12580 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnReloadAjax(); 12581 } 12582 } 12583 */ 12584 12585 $add_payment_dialog = $('<div></div>') 12586 .append( 12587 $('<form />', { id: 'add_payment_form', method: 'post', action: url }) 12588 .append( 12589 $('<fieldset />', { class: 'fs-invisible', style: '' }) 12590 .append('<p>Syötä maksusuorituksen summa euroissa ja lisää suorituksen päivämäärä</p>') 12591 .append( 12592 $('<ol />') 12593 .append( 12594 $('<li />') 12595 .append($('<label for="amount">Summa:</label>')) 12596 .append( 12597 $( 12598 '<input type="text" name="amount" id="amount" value="' + 12599 params.open_sum + 12600 '" class="text small" />' 12601 ) 12602 ) 12603 .append(' €') 12604 ) 12605 .append( 12606 $('<li />') 12607 .append($('<label id="created_label" for="created">Päivämäärä:</label>')) 12608 .append( 12609 $( 12610 '<input type="text" class="text small" id="created" name="created" value="' + 12611 d.getDate() + 12612 '.' + 12613 (d.getMonth() + 1) + 12614 '.' + 12615 d.getFullYear() + 12616 '" />' 12617 ).datepicker($.datepicker.regional.fi) 12618 ) 12619 ) 12620 .append( 12621 $('<li />').append( 12622 $('<button type="submit">Tallenna maksusuoritus</button>').button() 12623 ) 12624 ) 12625 ) 12626 ) 12627 .submit(function () { 12628 $(this).ajaxSubmit({ 12629 dataType: 'json', 12630 beforeSubmit: function () { 12631 global.show_loading_dialog('Tallennetaan maksusuoritusta...'); 12632 }, 12633 success: function (responseJSON, statusText, xhr, $form) { 12634 global.close_loading_dialog(); 12635 global.show_message(responseJSON); 12636 $add_payment_dialog.dialog('close'); 12637 12638 var fn = window.callbacks[responseJSON.data.callback]; 12639 12640 if ($.isFunction(fn)) { 12641 fn(); 12642 } 12643 }, 12644 }); 12645 return false;
12646 }) 12647 ) 12648 .dialog({ 12649 width: 400, 12650 //height:200, 12651 autoOpen: true, 12652 modal: true, 12653 resizable: false, 12654 draggable: false, 12655 beforeClose: function (event, ui) { 12656 event.stopPropagation(); 12657 }, 12658 close: function () { 12659 $(this).dialog('destroy'); 12660 $(this).remove(); 12661 }, 12662 title: 'Lisää maksusuoritus', 12663 buttons: { 12664 Peruuta: function () { 12665 $(this).dialog('close'); 12666 }, 12667 }, 12668 }); 12669}; //add_payment 12670 12671global.setCompaniesOptions = function () { 12672 if ( 12673 !localStorage.getItem('companiesOptions') && 12674 window.App && 12675 window.App.user.access_level >= 100 12676 ) { 12677 $.ajax({ 12678 processData: false, 12679 dataType: 'json', 12680 type: 'GET', 12681 url: '/ajax/getCompaniesOptions/', 12682 success: function (companiesJSON) { 12683 localStorage.setItem('companiesOptions', JSON.stringify(companiesJSON)); 12684 }, 12685 }); 12686 } 12687}; 12688 12689global.clearCompaniesOptions = function () { 12690 localStorage.removeItem('companiesOptions'); 12691}; 12692 12693global.renderCompaniesFilterOptions = function (selectEl) { 12694 if (localStorage.getItem('companiesOptions') === null) { 12695 return; 12696 } 12697 var companiesJSON = JSON.parse(localStorage.getItem('companiesOptions')); 12698 $.each(companiesJSON, function (key, value) { 12699 $(selectEl).append('<option value=' + key + '>' + value + '</option>'); 12700 }); 12701 $(selectEl).selectpicker('refresh'); 12702}; 12703 12704var pages = { 12705 auth: { 12706 init: function () { 12707 // clear companies options from localstorage on login page 12708 global.clearCompaniesOptions(); 12709 12710 $('#username').focus(); 12711 12712 $('#login_btn').button({ icons: { primary: 'ui-icon-locked' }, text: true }); 12713 12714 $('#login_tabs').tabs(); 12715 }, 12716 12717 init_activate: function () { 12718 $('#activate_btn') 12719 .button({ icons: { primary: 'ui-icon-locked' }, text: true }) 12720 .hover( 12721 function () { 12722 $(this).button('option', 'icons', { primary: 'ui-icon-unlocked' }); 12723 }, 12724 function () { 12725 $(this).button('option', 'icons', { primary: 'ui-icon-locked' }); 12726 } 12727 ); 12728 12729 $('#add_car') 12730 .button({ icons: { primary: 'ui-icon-plusthick' }, text: true }) 12731 .on('click', function () { 12732 pages.auth.add_car(); 12733 }) 12734 .trigger('click'); 12735 }, 12736 12737 forgot_password_dialog: function () { 12738 $('<div />', { style: 'text-align:left;' }) 12739 .append( 12740 $('<p />').html('Anna sähköpostiosoitteesi lähetetään'), 12741 $('<form>', { method: 'post', action: '/ajax/forgot_password/' }).append( 12742 $('<input />', { type: 'text', name: 'email', id: 'email', class: 'text medium' }) 12743 ) 12744 ) 12745 .submit(function () { 12746 $(this).ajaxSubmit({ 12747 processData: true, 12748 data: post_data, 12749 dataType: 'json', 12750 //show the loading message 12751 beforeSubmit: function () { 12752 global.show_loading_dialog('Lähetetään sähköpostia...'); 12753 }, 12754 12755 // success identifies the function to invoke when the server response 12756 // has been received; here we apply a fade-in effect to the new content 12757 success: function (responseJSON, statusText, xhr, $form) { 12758 global.close_loading_dialog(); 12759 var $message_dialog = $('<div />') 12760 .append( 12761 '<p><span class="ui-icon-check" style="float:left; margin:0 7px 50px 0;"></span>Sähköpostiisi on lähetetty ohjeet kuinka saat uuden salasanasi käyttöön</p>' 12762 ) 12763 .dialog({ 12764 title: 'Salasana vaihdettu!', 12765 modal: true, 12766 close: function () {}, 12767 buttons: { 12768 Jatka: function () { 12769 $(this).dialog('close'); 12770 }, 12771 }, 12772 }); 12773 }, 12774 }); 12775 return false; 12776 }) 12777 .dialog({ 12778 width: 320, 12779 autoOpen: true, 12780 modal: true, 12781 resizable: false, 12782 draggable: false, 12783 beforeClose: function (event, ui) { 12784 event.stopPropagation(); 12785 }, 12786 title: 'Olen unohtanut salasanani', 12787 buttons: { 12788 Peruuta: function () { 12789 $(this).dialog('close'); 12790 }, 12791 'Lähetä lasku': function () { 12792 $(this).dialog('close'); 12793 }, 12794 }, 12795 }); 12796 }, 12797 12798 add_car: function () { 12799 $num = $('#cars tbody tr').size();
12800 $remove_btn = $('<button type="button" style="float:right; padding:0px 5px;">Poista</button>') 12801 .button({ icons: { primary: 'ui-icon-trash' }, text: true }) 12802 .on('click', function (e) { 12803 e.stopPropagation(); 12804 $wrapper = $(this).parent().parent(); 12805 $('<div />') 12806 .html( 12807 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen auton?</p>' 12808 ) 12809 .dialog({ 12810 resizable: false, 12811 height: 180, 12812 width: 340, 12813 title: 'Poista auto', 12814 modal: true, 12815 buttons: { 12816 Ei: function () { 12817 $(this).dialog('close'); 12818 }, 12819 Kyllä: function () { 12820 $(this).dialog('close'); 12821 12822 $wrapper.hide('highlight', function () { 12823 $(this).remove(); 12824 }); 12825 }, 12826 }, 12827 }); 12828 }); 12829 12830 $car_data = $('<tr />', { class: 'car', style: 'width:900px;' }).append( 12831 $('<td />').append( 12832 '<input type="text" name="cars[' + 12833 $num + 12834 '][phone]" id="cars[' + 12835 $num + 12836 '][phone]" class="text medium-small required" />' 12837 ), 12838 $('<td />').append( 12839 '<input type="text" name="cars[' + 12840 $num + 12841 '][registry_nr]" id="cars[' + 12842 $num + 12843 '][registry_nr]" class="text small" />' 12844 ), 12845 $('<td />').append( 12846 '<input type="text" name="cars[' + 12847 $num + 12848 '][car_nr]" id="cars[' + 12849 $num + 12850 '][car_nr]" class="text small required" />' 12851 ), 12852 $('<td />').append( 12853 '<input type="text" name="cars[' + 12854 $num + 12855 '][stationary_position]" id="cars[' + 12856 $num + 12857 '][stationary_position]" class="text small required" />' 12858 ) 12859 ); 12860 12861 if ($num > 0) { 12862 $car_data.append($('<td />').append($remove_btn)); 12863 } 12864 12865 /* 12866 $('<div />', {"style":"float:left;"}) 12867 .append( 12868 $('<ol />', {"style":"float:left; width:100%;"}) 12869 .append( 12870 $('<li />',{"style":"float:left; clear:none; display:inline; width:auto; padding-right:20px;"}) 12871 .append('<label for="phone">Puhelinnumero:</label>') 12872 .append('<input type="text" name="cars['+$num+'][phone]" id="cars['+$num+'][phone]" class="text small required" />'), 12873 $('<li />',{"style":"float:left; clear:none; display:inline; width:auto; padding-right:20px;"}) 12874 .append('<label for="registry_nr">Rek. Numero:</label>') 12875 .append('<input type="text" name="cars['+$num+'][registry_nr]" id="cars['+$num+'][registry_nr]" class="text vsmall" />'), 12876 $('<li />',{"style":"float:left; clear:none; display:inline; width:auto; padding-right:20px;"}) 12877 .append('<label for="car_nr">Järjestysnumero:</label>') 12878 .append('<input type="text" name="cars['+$num+'][car_nr]" id="cars['+$num+'][car_nr]" class="text xsmall required" />'), 12879 $('<li />',{"style":"float:left; clear:none; display:inline; width:auto;"}) 12880 .append('<label for="stationary_position">Asemapaikka:</li>') 12881 .append('<input type="text" name="cars['+$num+'][stationary_position]" id="cars['+$num+'][stationary_position]" class="text medium-small required" />'), 12882 $('<li />',{"style":"float:left; clear:none; display:inline; width:auto;"}) 12883 .append($('<div />', {"class": "buttons"})) 12884 ) 12885 12886 ) 12887 ); 12888 12889 $remove_btn.prependTo($car_data.find('div.buttons')); 12890 */ 12891 12892 $('#cars').prepend($car_data); 12893 }, //add_car 12894 }, 12895 12896 iv_asiakkuudet: { 12897 //IV_Asiakkuudet properties 12898 car_types_JSON: {}, 12899 car_brands_JSON: {}, 12900 contract_types_JSON: {}, 12901 $innotaxi_datatable: '', 12902 $accounts_datatable: '', 12903 $accounts_datatable_disabled: '', 12904 $accounts_datatable_deleted: '', 12905 12906 //IV_Asiakkuudet Methods 12907 init: function () { 12908 $('#accounts_tabs').tabs(); 12909 12910 $('#actions #new_account:button') 12911 .button({ icons: { primary: 'ui-icon-plusthick' } }) 12912 .on('click', function () { 12913 window.AccountCard.show(); 12914 }); 12915 12916 $('#accounts_dt').delegate('#accounts_dt a.show_account_card', 'click', function (e) { 12917 e.preventDefault(); 12918 var company_id = $(e.target).attr('href'); 12919 var action = $(e.target).attr('class'); 12920 12921 switch (action) { 12922 case 'show_account_card': 12923 window.AccountCard.show(company_id); 12924 break; 12925 } 12926 }); 12927 12928 //Init the asiakkuudet datatable 12929 pages.iv_asiakkuudet.$accounts_datatable = $('#accounts_dt').dataTable({ 12930 oLanguage: global.dataTablesLanguage, 12931 sPaginationType: 'full_numbers', 12932 bPaginate: true, 12933 iDisplayLength: 10, 12934 bAutoWidth: false, 12935 bJQueryUI: true, 12936 bProcessing: true,
12937 bServerSide: false, 12938 sAjaxSource: 'ajax/get_accounts_json/', 12939 aoColumns: [ 12940 /** company_id **/ null, 12941 /** Yritys **/ null, 12942 /** Y-tunnus **/ { bVisible: false, bSearchable: false }, 12943 /** Kaupunki **/ null, 12944 /** Yhteyshenkilö **/ null, 12945 /** Puhelinnumero **/ null, 12946 /** Sähköposti **/ null, 12947 /** Asiakkuus luotu **/ { sType: 'date-eu' }, 12948 /** User type **/ { bVisible: true, bSearchable: false }, 12949 ], 12950 aaSorting: [[7, 'desc']], 12951 fnServerData: function (sSource, aoData, fnCallback) { 12952 $.getJSON(sSource, null, function (json) { 12953 /* Do whatever additional processing you want on the callback, then tell DataTables */ 12954 fnCallback(json); 12955 }); 12956 }, 12957 //Called before each row is shown 12958 fnRowCallback: function (nRow, aData, iDisplayIndex) { 12959 var company_id = aData[0]; 12960 var company_name = aData[1]; 12961 var user_type = aData[8]; 12962 12963 //Add the transaction id to every rows data object 12964 $('td:eq(1)', nRow).html( 12965 '<a href="' + company_id + '" class="show_account_card" >' + company_name + '</a>' 12966 ); 12967 return nRow; 12968 }, 12969 }); 12970 12971 pages.iv_asiakkuudet.$accounts_datatable_disabled = $('#accounts_dt_disabled').dataTable({ 12972 oLanguage: global.dataTablesLanguage, 12973 sPaginationType: 'full_numbers', 12974 bPaginate: true, 12975 iDisplayLength: 10, 12976 bAutoWidth: false, 12977 bJQueryUI: true, 12978 bProcessing: true, 12979 bServerSide: false, 12980 sAjaxSource: 'ajax/get_accounts_json/', 12981 aoColumns: [ 12982 /** company_id **/ null, 12983 /** Yritys **/ null, 12984 /** Y-tunnus **/ { bVisible: false, bSearchable: false }, 12985 /** Kaupunki **/ null, 12986 /** Yhteyshenkilö **/ null, 12987 /** Puhelinnumero **/ null, 12988 /** Sähköposti **/ null, 12989 /** Asiakkuus luotu **/ { sType: 'date-eu' }, 12990 /** User type **/ { bVisible: true, bSearchable: false }, 12991 ], 12992 aaSorting: [[7, 'desc']], 12993 fnServerData: function (sSource, aoData, fnCallback) { 12994 $.getJSON(sSource, null, function (json) { 12995 /* Do whatever additional processing you want on the callback, then tell DataTables */ 12996 fnCallback(json); 12997 }); 12998 }, 12999 //Called before each row is shown 13000 fnRowCallback: function (nRow, aData, iDisplayIndex) { 13001 var company_id = aData[0]; 13002 var company_name = aData[1]; 13003 var user_type = aData[8]; 13004 13005 //Add the transaction id to every rows data object 13006 $('td:eq(1)', nRow).html( 13007 '<a href="' + company_id + '" class="show_account_card" >' + company_name + '</a>' 13008 ); 13009 return nRow; 13010 }, 13011 }); 13012 13013 pages.iv_asiakkuudet.$accounts_datatable_deleted = $('#accounts_dt_deleted').dataTable({ 13014 oLanguage: global.dataTablesLanguage, 13015 sPaginationType: 'full_numbers', 13016 bPaginate: true, 13017 iDisplayLength: 10, 13018 bAutoWidth: false, 13019 bJQueryUI: true, 13020 bProcessing: true, 13021 bServerSide: false, 13022 sAjaxSource: 'ajax/get_accounts_json/', 13023 aoColumns: [ 13024 /** company_id **/ null, 13025 /** Yritys **/ null, 13026 /** Y-tunnus **/ { bVisible: false, bSearchable: false }, 13027 /** Kaupunki **/ null, 13028 /** Yhteyshenkilö **/ null, 13029 /** Puhelinnumero **/ null, 13030 /** Sähköposti **/ null, 13031 /** Asiakkuus luotu **/ { sType: 'date-eu' }, 13032 /** User type **/ { bVisible: true, bSearchable: false }, 13033 ], 13034 aaSorting: [[7, 'desc']], 13035 fnServerData: function (sSource, aoData, fnCallback) { 13036 $.getJSON(sSource, null, function (json) { 13037 /* Do whatever additional processing you want on the callback, then tell DataTables */ 13038 fnCallback(json); 13039 }); 13040 }, 13041 //Called before each row is shown 13042 fnRowCallback: function (nRow, aData, iDisplayIndex) { 13043 var company_id = aData[0]; 13044 var company_name = aData[1];
13045 var user_type = aData[8]; 13046 13047 //Add the transaction id to every rows data object 13048 $('td:eq(1)', nRow).html( 13049 '<a href="' + company_id + '" class="show_account_card" >' + company_name + '</a>' 13050 ); 13051 return nRow; 13052 }, 13053 }); 13054 }, 13055 }, //IV_Asiakkuudet 13056 13057 iv_laskutus_ja_reskontra: { 13058 $datatable: null, 13059 $datatable_iv: null, 13060 recurring_invoicing: null, 13061 $part_payments_datatable: null, 13062 $datatable_money_transfers: null, 13063 $datatable_refunds: null, 13064 $datatable_direct_payments: null, 13065 $datatable_deductions: null, 13066 $datatable_remittances: null, 13067 13068 init: function () { 13069 // iv_laskut specific jQuery functions. 13070 $('#invoices_tabs').tabs(); 13071 13072 $('#new_invoice_person') 13073 .button({ icons: { primary: 'ui-icon-plusthick' } }) 13074 .on('click', function () { 13075 //pages.reskontra.show_invoice_dialog('person'); 13076 window.location = '/lasku/kuluttajalasku/'; 13077 }); 13078 13079 $('#new_invoice_company') 13080 .button({ icons: { primary: 'ui-icon-plusthick' } }) 13081 .on('click', function () { 13082 //pages.reskontra.show_invoice_dialog('company'); 13083 window.location = '/lasku/yrityslasku/'; 13084 }); 13085 13086 $('#new_part_payment') 13087 .button({ icons: { primary: 'ui-icon-plusthick' } }) 13088 .wrap($('<div />', { style: 'float:left;margin-right:7px;' })) 13089 .on('click', function () { 13090 window.location = '/osamaksu/'; 13091 }); 13092 13093 $('#new_deduction') 13094 .button({ icons: { primary: 'ui-icon-plusthick' } }) 13095 .wrap($('<div />', { style: 'float:left;margin-right:7px;' })) 13096 .on('click', function () { 13097 window.location = '/veloitukset/'; 13098 }); 13099 13100 $('#new_invoice') 13101 .button({ icons: { primary: null, secondary: 'ui-icon-triangle-1-s' } }) 13102 .wrap($('<div />', { style: 'float:left;' })) 13103 .wrap($('<div />', {})) 13104 .parent() 13105 .parent() 13106 .append( 13107 $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }).append( 13108 $('<li />', {}).append( 13109 $('<a />', { href: '/lasku/kuluttajalasku/' }) 13110 .on('click', function () { 13111 window.location = '/lasku/kuluttajalasku/'; 13112 }) 13113 .text('Kuluttajalle') 13114 ), 13115 $('<li />', {}).append( 13116 $('<a />', { href: '/lasku/yrityslasku/' }) 13117 .on('click', function () { 13118 window.location = '/lasku/yrityslasku/'; 13119 }) 13120 .text('Yritykselle') 13121 ), 13122 $('<li />', {}).append( 13123 $('<a />', { href: '/lasku/vakuutusyhtio/' }) 13124 .on('click', function () { 13125 window.location = '/lasku/vakuutusyhtio/'; 13126 }) 13127 .text('Vakuutusyhtiölle') 13128 ) 13129 ) 13130 ) 13131 .parent() 13132 .parent() 13133 .find('#new_invoice') 13134 .on('click', function () { 13135 console.log('#new_invoice'); 13136 13137 //pages.reskontra.show_invoice_dialog('company'); 13138 //window.location = '/lasku/yrityslasku/'; 13139 var $menu = $(this).parent().next(); 13140 13141 if ($menu.is(':visible')) { 13142 $menu.hide(); 13143 } else { 13144 $menu.show().position({ 13145 my: 'left top', 13146 at: 'left bottom', 13147 of: this, 13148 }); 13149 } 13150 13151 var menu = $(this).parent().next(); 13152 $(document).one('click', function () { 13153 menu.hide(); 13154 }); 13155 return false; 13156 }) 13157 .parent() 13158 .buttonset() 13159 .next() 13160 .hide() 13161 .menu(); 13162 13163 13164 $('#new_report') 13165 .button({ icons: { primary: null, secondary: 'ui-icon-triangle-1-s' } }) 13166 .wrap($('<div />', { style: 'float:left;' })) 13167 .wrap($('<div />', {})) 13168 .parent() 13169 .parent() 13170 .append( 13171 $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }).append( 13172 /* 13173 $('<li />', {}).append( 13174 $('<a />', { href: '/' }) 13175 .on('click', function (e) { 13176 e.preventDefault(); 13177 window.InvoiceReport.reportModal.openDialog(); 13178 }) 13179 .text('Myynnit') 13180 ), 13181 */ 13182 $('<li />', {}).append( 13183 $('<a />', { href: '/' }) 13184 .on('click', function (e) { 13185 e.preventDefault(); 13186 pages.iv_laskutus_ja_reskontra.showCreateOpenInvoicesReportDialog(); 13187 }) 13188 .text('Avoimet laskut') 13189 ) 13190 /* 13191 $('<li />', {}).append( 13192 $('<a />', { href: '/' }) 13193 .on('click', function (e) { 13194 e.preventDefault(); 13195 window.CreditLossReport.reportModal.openDialog(); 13196 }) 13197 .text('Luottotappiot') 13198 ) 13199 */ 13200 ) 13201 ) 13202 .parent() 13203 .parent()
13204 .find('#new_report') 13205 .on('click', function () { 13206 console.log('#new_report'); 13207 13208 //pages.reskontra.show_invoice_dialog('company'); 13209 //window.location = '/lasku/yrityslasku/'; 13210 var $menu = $(this).parent().next(); 13211 13212 if ($menu.is(':visible')) { 13213 $menu.hide(); 13214 } else { 13215 $menu.show().position({ 13216 my: 'left top', 13217 at: 'left bottom', 13218 of: this, 13219 }); 13220 } 13221 13222 var menu = $(this).parent().next(); 13223 $(document).one('click', function () { 13224 menu.hide(); 13225 }); 13226 return false; 13227 }) 13228 .parent() 13229 .buttonset() 13230 .next() 13231 .hide() 13232 .menu(); 13233 13234 /* 13235 .parent() 13236 .buttonset() 13237 .next() 13238 .hide() 13239 .menu() 13240 */ 13241 13242 $('#get_iv_invoices') 13243 .button({ icons: { primary: 'ui-icon-search' } }) 13244 .on('click', function () { 13245 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 13246 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 13247 }); 13248 13249 $('#iv_invoices_dt').on('click', 'a.show_invoice, a.show_invoice_log', function (e) { 13250 e.preventDefault(); 13251 13252 var invoice_id = $(e.target).attr('href'); 13253 var action = $(e.target).attr('class'); 13254 switch (action) { 13255 case 'show_invoice': 13256 pages.iv_laskutus_ja_reskontra.show_invoice(invoice_id); 13257 break; 13258 case 'show_invoice_log': 13259 pages.iv_laskutus_ja_reskontra.show_invoice_log(invoice_id); 13260 break; 13261 } 13262 }); 13263 13264 $('#invoices_filter_form').on('change', 'input:checkbox', function () { 13265 var filter = $(this).attr('name'), 13266 is_checked = $(this).is(':checked'); 13267 13268 if (filter != 'all' && is_checked) { 13269 $('#invoices_filter_form').find('input[name=all]').prop('checked', false); 13270 } 13271 13272 if (filter == 'all' && is_checked) { 13273 $('#invoices_filter_form') 13274 .find('input:checkbox:checked') 13275 .each(function (index, elem) { 13276 if ($(elem).attr('name') != 'all') { 13277 $(elem).prop('checked', false); 13278 } 13279 }); 13280 } 13281 }); 13282 13283 $('#iv_invoices_filter_form').on('change', 'input:checkbox', function () { 13284 var filter = $(this).attr('name'), 13285 is_checked = $(this).is(':checked'); 13286 13287 if (filter != 'all' && is_checked) { 13288 $('#iv_invoices_filter_form').find('input[name=all]').prop('checked', false); 13289 } 13290 13291 if (filter == 'all' && is_checked) { 13292 $('#iv_invoices_filter_form') 13293 .find('input:checkbox:checked') 13294 .each(function (index, elem) { 13295 if ($(elem).attr('name') != 'all') { 13296 $(elem).prop('checked', false); 13297 } 13298 }); 13299 } 13300 }); 13301 13302 $('#invoices_dt').on( 13303 'click', 13304 'a.show_invoice, a.show_account_card, a.show_invoice_log', 13305 function (e) { 13306 e.preventDefault(); 13307 13308 var invoice_id = $(e.target).attr('href'); 13309 var action = $(e.target).attr('class'); 13310 var companyId = $(e.target).attr('data-companyId'); 13311 13312 switch (action) { 13313 case 'show_invoice': 13314 pages.iv_laskutus_ja_reskontra.show_invoice(invoice_id); 13315 break; 13316 case 'show_account_card': 13317 window.AccountCard.show(companyId); 13318 break; 13319 case 'show_invoice_log': 13320 pages.iv_laskutus_ja_reskontra.show_invoice_log(invoice_id); 13321 break; 13322 } 13323 } 13324 ); 13325 13326 $('#invoices_dt').on( 13327 'contextmenu', 13328 'a.show_account_card', 13329 function (e) { 13330 e.preventDefault(); 13331 13332 // var invoice_id = $(e.target).attr('href'); 13333 var action = $(e.target).attr('class'); 13334 var companyId = $(e.target).attr('data-companyId'); 13335 13336 switch (action) { 13337 case 'show_account_card': 13338 setClipboardText(companyId, 'Asiakkaan id kopioitu leikepöydälle'); 13339 break; 13340 } 13341 } 13342 ); 13343 13344 $('#direct_payments_dt').on( 13345 'click', 13346 'a.show_add_payment_dialog, a.show_account_card, a.show_invoice_log,' + 13347 ' a.show_towing_record, a.show_direct_payment_log, a.show_job_order, a.show_direct_payment', 13348 function (e) { 13349 e.preventDefault(); 13350 var id = $(e.target).attr('href'); 13351 var action = $(e.target).attr('class'); 13352 var companyId = $(e.target).attr('data-companyId'); 13353 var openAmount = $(e.target).attr('data-openAmount'); 13354 13355 switch (action) { 13356 case 'show_add_payment_dialog': 13357 pages.iv_laskutus_ja_reskontra.showAddDirectPaymentDialog(id, openAmount); 13358 break; 13359 case 'show_account_card': 13360 window.AccountCard.show(companyId); 13361 break; 13362 case 'show_towing_record': 13363 global.showJob(id); 13364 break; 13365 case 'show_direct_payment_log': 13366 global.show_log(id); 13367 break; 13368 case 'show_job_order': 13369 window.openDialog(id); 13370 case 'show_direct_payment': 13371 pages.iv_laskutus_ja_reskontra.show_direct_payment(id); 13372 break; 13373 } 13374 } 13375 ); 13376 13377 $('#part_payments_filter_form').on('change', 'input:checkbox', function () { 13378 var filter = $(this).attr('name'), 13379 is_checked = $(this).is(':checked'); 13380 13381 if (filter != 'all' && is_checked) { 13382 $('#part_payments_filter_form').find('input[name=all]').prop('checked', false); 13383 } 13384 13385 if (filter == 'all' && is_checked) { 13386 $('#part_payments_filter_form')
13387 .find('input:checkbox:checked') 13388 .each(function (index, elem) { 13389 if ($(elem).attr('name') != 'all') { 13390 $(elem).prop('checked', false); 13391 } 13392 }); 13393 } 13394 }); 13395 13396 $('#part_payments_dt').on('click', 'a', function (e) { 13397 e.preventDefault(); 13398 13399 var id = $(e.target).attr('href'); 13400 var action = $(e.target).attr('class'); 13401 13402 switch (action) { 13403 case 'show_part_payment_log': 13404 global.show_log(id); 13405 break; 13406 case 'show_part_payment': 13407 pages.iv_laskutus_ja_reskontra.show_part_payment(id); 13408 break; 13409 case 'show_invoice': 13410 pages.iv_laskutus_ja_reskontra.show_invoice(id); 13411 break; 13412 case 'show_invoice_log': 13413 pages.iv_laskutus_ja_reskontra.show_invoice_log(id); 13414 break; 13415 } 13416 }); 13417 13418 $('#money_transfers_dt').on('click', 'a', function (e) { 13419 e.preventDefault(); 13420 13421 var id = $(e.target).attr('href'); 13422 var action = $(e.target).attr('class'); 13423 var moneyTransferDate = $(e.target).attr('data-date'); 13424 13425 switch (action) { 13426 case 'show_money_transfer_open': 13427 pages.iv_laskutus_ja_reskontra.show_money_transfer(id, moneyTransferDate, 'open'); 13428 break; 13429 case 'show_money_transfer_transferred': 13430 pages.iv_laskutus_ja_reskontra.show_money_transfer(id, moneyTransferDate, 'transferred'); 13431 break; 13432 case 'show_money_transfer_deleted': 13433 pages.iv_laskutus_ja_reskontra.show_money_transfer(id, moneyTransferDate, 'deleted'); 13434 break; 13435 case 'download_report': 13436 window.open(id); 13437 break; 13438 } 13439 }); 13440 13441 $('#refunds_dt').on('click', 'a', function (e) { 13442 e.preventDefault(); 13443 13444 var id = $(e.target).attr('href'); 13445 var action = $(e.target).attr('class'); 13446 var open_sum = $(e.target).parent('td').data('open_sum'); 13447 13448 switch (action) { 13449 case 'show_account_card': 13450 window.AccountCard.show(id); 13451 break; 13452 case 'show_invoice': 13453 pages.iv_laskutus_ja_reskontra.show_invoice(id); 13454 break; 13455 case 'show_log': 13456 global.show_log(id); 13457 break; 13458 } 13459 }); 13460 13461 $('#iv_deductions_dt').on('click', 'a', function (e) { 13462 e.preventDefault(); 13463 13464 var id = $(e.target).attr('href'), 13465 action = $(e.target).attr('class'); 13466 13467 switch (action) { 13468 case 'show_account_card': 13469 window.AccountCard.show(id); 13470 break; 13471 case 'show_deduction_card': 13472 pages.iv_laskutus_ja_reskontra.showDeductionCard(id); 13473 break; 13474 case 'show_invoice': 13475 pages.iv_laskutus_ja_reskontra.show_invoice(id); 13476 break; 13477 } 13478 }); 13479 13480 $('#iv_remittances_dt').on('click', 'a', function (e) { 13481 e.preventDefault(); 13482 13483 var data = $(e.target).attr('href'), 13484 action = $(e.target).attr('class'); 13485 13486 switch (action) { 13487 case 'try-reject-remittance': 13488 pages.iv_laskutus_ja_reskontra.confirm_action( 13489 'Varmista toiminta', 13490 'Haluatko varmasti hylätä kohdistuksen?', 13491 function () { 13492 pages.iv_laskutus_ja_reskontra.tryActionRemittance(data); 13493 } 13494 ); 13495 break; 13496 case 'try-allocate-remittance': 13497 pages.iv_laskutus_ja_reskontra.confirm_action( 13498 'Varmista toiminta', 13499 'Haluatko varmasti kohdistaa laskukohdistuksen?', 13500 function () { 13501 pages.iv_laskutus_ja_reskontra.tryActionRemittance(data); 13502 } 13503 ); 13504 break; 13505 } 13506 }); 13507 13508 $('#iv_deductions_filter_form').on('change', 'input:checkbox', function () { 13509 var filter = $(this).attr('name'), 13510 is_checked = $(this).is(':checked'); 13511 13512 if (filter != 'all' && is_checked) { 13513 $('#iv_deductions_filter_form').find('input[name=all]').prop('checked', false); 13514 } 13515 13516 if (filter == 'all' && is_checked) { 13517 $('#iv_deductions_filter_form')
13518 .find('input:checkbox:checked') 13519 .each(function (index, elem) { 13520 if ($(elem).attr('name') != 'all') { 13521 $(elem).prop('checked', false); 13522 } 13523 }); 13524 } 13525 13526 if (filter === 'open' && is_checked) { 13527 $('#iv_deductions_filter_form') 13528 .find('input:checkbox:checked') 13529 .each(function (index, elem) { 13530 if ($(elem).attr('name') != 'open') { 13531 $(elem).prop('checked', false); 13532 } 13533 }); 13534 } 13535 13536 if (filter === 'debited' && is_checked) { 13537 $('#iv_deductions_filter_form') 13538 .find('input:checkbox:checked') 13539 .each(function (index, elem) { 13540 if ($(elem).attr('name') != 'debited') { 13541 $(elem).prop('checked', false); 13542 } 13543 }); 13544 } 13545 13546 if (filter === 'credited' && is_checked) { 13547 $('#iv_deductions_filter_form') 13548 .find('input:checkbox:checked') 13549 .each(function (index, elem) { 13550 if ($(elem).attr('name') != 'credited') { 13551 $(elem).prop('checked', false); 13552 } 13553 }); 13554 } 13555 }); 13556 13557 // $('#invoices_filter_form #month, #invoices_filter_form #year, #iv_invoices_filter_form select, #corporate-chain-invoices_filter_form select, #part_payments_filter_form #month, #part_payments_filter_form #year, #iv_deductions_filter_form #year, #iv_deductions_filter_form #month').selectmenu({ 13558 // style: 'popup', 13559 // width: 200, 13560 // menuWidth: 200, 13561 // }); 13562 13563 // $('#invoices_filter_form .company-select').searchable({ 13564 // warnNoMatch: 'Ei tuloksia', 13565 // wildcards: true 13566 // }); 13567 // 13568 // $('#part_payments_filter_form .company-part-payment').searchable({ 13569 // warnNoMatch: 'Ei tuloksia', 13570 // wildcards: true 13571 // }); 13572 // 13573 // $('#iv_deductions_filter_form .company-select').searchable({ 13574 // warnNoMatch: 'Ei tuloksia', 13575 // wildcards: true 13576 // }); 13577 13578 $('#invoices_filter_form, #part_payments_filter_form, #iv_deductions_filter_form').keypress( 13579 function (e) { 13580 if (e.keyCode == 13) e.preventDefault(); 13581 } 13582 ); 13583 13584 pages.iv_laskutus_ja_reskontra.gaiSelected = []; 13585 13586 //$('#invoice_card_tabs').tabs(); 13587 13588 $('#get_yearly_payment_invoices') 13589 .button({ icons: { primary: 'ui-icon-search' } }) 13590 .on('click', function () { 13591 pages.iv_laskutus_ja_reskontra.$datatable_yearly_payments.fnClearTable(0); 13592 pages.iv_laskutus_ja_reskontra.$datatable_yearly_payments.fnDraw(); 13593 }); 13594 13595 $('#yearly_payment_invoices_filter_form select').selectmenu({ 13596 style: 'popup', 13597 width: 200, 13598 menuWidth: 200, 13599 }); 13600 13601 $('#upload_gothia_payment_file') 13602 .button({ text: true, icons: { primary: 'ui-icon-arrowthickstop-1-s' } }) 13603 .on('click', function () { 13604 pages.iv_laskutus_ja_reskontra.show_upload_gothia_payment_file_dialog(); 13605 }); 13606 13607 $('#mark_payments_paid') 13608 .button({ text: true, icons: { primary: 'ui-icon-arrowthickstop-1-s' } }) 13609 .on('click', function () { 13610 pages.iv_laskutus_ja_reskontra.confirm_mark_payments( 13611 pages.iv_laskutus_ja_reskontra.gaiSelected 13612 ); 13613 }); 13614 13615 pages.iv_laskutus_ja_reskontra.showDeductionCard = function (id) { 13616 global.$dialog = $('<div />', {}); 13617 var $dialog = global.$dialog; 13618 13619 if ($dialog.hasClass('ui-dialog-content')) { 13620 $dialog.dialog('destroy'); 13621 } 13622 13623 $dialog.on('click', 'a', function (e) { 13624 e.preventDefault(); 13625 13626 var id = $(e.target).attr('href'), 13627 action = $(e.target).attr('class'); 13628 13629 switch (action) { 13630 case 'show_invoice': 13631 pages.iv_laskutus_ja_reskontra.show_invoice(id); 13632 break; 13633 } 13634 }); 13635 13636 $.ajax({ 13637 processData: false, 13638 dataType: 'html', 13639 method: 'GET', 13640 url: 'veloitukset/getDeductionCardHtml/' + id + '/', 13641 beforeSend: function (request) { 13642 $dialog.dialog({ 13643 width: 800, 13644 height: 600, 13645 modal: true, 13646 resizable: false, 13647 title: 'Veloituksen tiedot', 13648 close: function () { 13649 $dialog.dialog('destroy'); 13650 }, 13651 }); 13652 13653 global.show_ajax_loader($dialog); 13654 }, 13655 success: function (response) { 13656 $dialog.html(response); 13657 }, 13658 }); 13659 }; 13660 13661 pages.iv_laskutus_ja_reskontra.recurring_invoicing = new recurringInvoicing({ 13662 showStation: false, 13663 isAdmin: true, 13664 controller: '/iv_laskutus_ja_reskontra', 13665 invoiceEndpoint: '/iv_laskutus_ja_reskontra/customerInvoicesDataTable/' 13666 }); 13667
13668 pages.iv_laskutus_ja_reskontra.recurring_invoicing.init(); 13669 13670 pages.iv_laskutus_ja_reskontra.$datatable = $('#invoices_dt').dataTable({ 13671 oSearch: {"sSearch": intialSearch}, 13672 oLanguage: global.dataTablesLanguage, 13673 sPaginationType: 'full_numbers', 13674 iDisplayLength: 10, 13675 bPaginate: true, 13676 bAutoWidth: false, 13677 bJQueryUI: true, 13678 bFilter: true, 13679 bInfo: true, 13680 bProcessing: true, 13681 bServerSide: true, 13682 sAjaxSource: '/iv_laskutus_ja_reskontra/customerInvoicesDataTable/', 13683 aoColumns: [ 13684 /** invoice_id **/ null, 13685 /** gothia_invoice_nr **/ { bVisible: false, bSearchable: true, bSortable: false }, 13686 /** ref_nr **/ { bVisible: false, bSearchable: true, bSortable: false }, 13687 /** Lähettäjä **/ null, 13688 /** Velallinen **/ null, 13689 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 13690 /** Päiväys **/ null, 13691 /** Eräpäivä **/ null, 13692 /** Summa **/ { bSearchable: false, bSortable: false }, 13693 /** Avoinna **/ { bSearchable: false, bSortable: false }, 13694 /** Rahoitettu **/ null, 13695 /** Viitteemme **/ null, 13696 /** Laskun **/ { bSearchable: false, bSortable: 'status' }, 13697 /** status **/ { bVisible: false, bSearchable: false, bSortable: false }, 13698 /** company_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 13699 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 13700 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 13701 /** ledger_service **/ { bVisible: false, bSearchable: false, bSortable: false }, 13702 ], 13703 aaSorting: [[0, 'desc']], 13704 13705 fnServerParams: function (aoData) { 13706 var company = $('#ac-tab-sent') 13707 .find('select[name=company] option:selected') 13708 .attr('value'); 13709 var month = $('#ac-tab-sent').find('select[name=month] option:selected').attr('value'); 13710 var year = $('#ac-tab-sent').find('select[name=year] option:selected').attr('value'); 13711 13712 var filters = []; 13713 filters.push('client_invoices'); 13714 13715 $('#invoices_filter_form input:checkbox:checked').each(function () { 13716 console.log($(this).attr('name')); 13717 filters.push($(this).attr('name')); 13718 }); 13719 13720 aoData.push({ name: 'month', value: month }); 13721 aoData.push({ name: 'year', value: year }); 13722 aoData.push({ name: 'company', value: company }); 13723 aoData.push({ name: 'filters', value: filters }); 13724 }, 13725 13726 fnDrawCallback: function () { 13727 var company = $('#ac-tab-sent').find('select[name=company] option:selected').html(); 13728 var month = $('#ac-tab-sent').find('select[name=month] option:selected').html(); 13729 var year = $('#ac-tab-sent').find('select[name=year] option:selected').html(); 13730 $('span#month_year').html(month + ', ' + year); 13731 }, 13732 13733 /* 13734 "fnServerData": function ( sSource, aoData, fnCallback ) { 13735 13736 var company = $('#company option:selected').attr("value"); 13737 var month = $('#month option:selected').attr("value"); 13738 var year = $('#year option:selected').attr("value"); 13739 13740 sSource += year + "/" + month + "/" + company + '/'; 13741 13742 var data = {'filters':[]}; 13743 data.filters.push('client_invoices'); 13744 13745 $('#invoices_filter_form input:checkbox:checked').each(function(){ 13746 data.filters.push($(this).attr('name')); 13747 }); 13748 13749 $.post( sSource, data, function (json){ 13750 $('span#month_year').html(json.month + ", " + json.year); 13751 fnCallback(json); 13752 }, "json" ); 13753 13754 $.getJSON(sSource, data, function (json){ 13755 $('span#month_year').html(json.month + ", " + json.year); 13756 fnCallback(json); 13757 }); 13758 }, 13759 */ 13760 //Called before each row is shown 13761 fnRowCallback: function (nRow, aData, iDisplayIndex) { 13762 var invoice_id = aData[0]; 13763 var receiver = aData[4]; 13764 var open_sum = aData[9]; 13765 var row_class = aData[13]; 13766 var status = aData[12]; 13767 var company_id = aData[14]; 13768 var customer_id = aData[15]; 13769 var customer_type = aData[16]; 13770 var ledger_service = aData[17]; 13771 var company_name = aData[3]; 13772 13773 // Add the transaction id to every rows data object 13774 $(nRow).addClass(row_class); 13775 $('td:eq(0)', nRow).html( 13776 '<a href="' + invoice_id + '" class="show_invoice" >' + invoice_id + '</a>' 13777 ); 13778 $('td:eq(1)', nRow).html( 13779 '<a href="' + 13780 company_id + 13781 '" class="show_account_card" data-companyId="' + 13782 company_id + 13783 '">' + 13784 company_name + 13785 '</a>' 13786 ); 13787 $('td:eq(2)', nRow).html( 13788 '<a href="' + 13789 customer_id + 13790 '" class="show_customer_card" data-cType="' + 13791 customer_type + 13792 '" data-cId="' + 13793 customer_id + 13794 '">' + 13795 receiver + 13796 '</a>' 13797 ); 13798 $('td:eq(7)', nRow) 13799 .html(ledger_service); 13800 13801 $('td:eq(9)', nRow) 13802 .addClass('status') 13803 .html('<a href="' + invoice_id + '" class="show_invoice_log" >' + status + '</a>'); 13804 13805 return nRow; 13806 }, 13807 }); 13808 13809 // We haveto fallback to delegate, because we got an ancient jQuery. :( 13810 $('#invoices_dt').on('click', 'a.show_customer_card', function (e) { 13811 e.preventDefault(); 13812 var custId = $(this).data('cid'); 13813 window.CustomerCard.show(custId); 13814 }); 13815 13816 pages.iv_laskutus_ja_reskontra.$part_payments_datatable = $('#part_payments_dt').dataTable({ 13817 oLanguage: global.dataTablesLanguage, 13818 sPaginationType: 'full_numbers', 13819 bPaginate: true, 13820 bAutoWidth: false, 13821 bJQueryUI: true, 13822 bFilter: true, 13823 bInfo: true, 13824 bProcessing: true,
13825 bServerSide: true, 13826 sAjaxSource: 'osamaksu/get_part_payments/', 13827 aoColumns: [ 13828 /** SopimusNr **/ { bVisible: true, bSearchable: true }, 13829 /** Yritys **/ { bVisible: true, bSearchable: true }, 13830 /** Toimipiste **/ { bVisible: false, bSearchable: false }, 13831 /** Luotonhakija **/ { bVisible: true, bSearchable: false }, 13832 /** Summa **/ { bVisible: true, bSearchable: false }, 13833 /** Sopimuksen pvm **/ { sType: 'date-eu', bVisible: true, bSearchable: false }, 13834 /** Käsirahan eräpäivä **/ { sType: 'date-eu', bVisible: false, bSearchable: false }, 13835 /** Toimitus pvm **/ { sType: 'date-eu', bSearchable: false }, 13836 /** Rahoitus pvm **/ { bVisible: false, bSearchable: false }, 13837 /** Sopimuksen tila **/ { sType: 'date-eu', bSearchable: false }, 13838 /** Käsirahan tila **/ { bSearchable: false }, 13839 /** Käsirahalasku ID **/ { bVisible: false, bSearchable: true }, 13840 /** Tililasku ID **/ { bVisible: false, bSearchable: true }, 13841 /** Käsirahalasku **/ null, 13842 /** Tililasku **/ null, 13843 /** Company id **/ { bVisible: false, bSearchable: true }, 13844 ], 13845 aaSorting: [[0, 'desc']], 13846 13847 fnServerParams: function (aoData) { 13848 var company = $('#osamaksusopimukset') 13849 .find('select[name=company] option:selected') 13850 .attr('value'); 13851 var month = $('#osamaksusopimukset') 13852 .find('select[name=month] option:selected') 13853 .attr('value'); 13854 var year = $('#osamaksusopimukset') 13855 .find('select[name=year] option:selected') 13856 .attr('value'); 13857 13858 var filters = []; 13859 13860 $('#part_payments_filter_form input:checkbox:checked').each(function () { 13861 filters.push($(this).attr('name')); 13862 }); 13863 13864 // filters.push('part_payments'); 13865 13866 aoData.push({ name: 'month', value: month }); 13867 aoData.push({ name: 'year', value: year }); 13868 aoData.push({ name: 'company', value: company }); 13869 aoData.push({ name: 'filters', value: filters }); 13870 }, 13871 13872 fnDrawCallback: function () { 13873 var company = $('#osamaksusopimukset') 13874 .find('select[name=company] option:selected') 13875 .html(); 13876 var month = $('#osamaksusopimukset').find('select[name=month] option:selected').html(); 13877 var year = $('#osamaksusopimukset').find('select[name=year] option:selected').html(); 13878 //$('span#month_year').html(month + ', ' + year); 13879 $('span#pp_month_year').html(month + ', ' + year); 13880 }, 13881 13882 //Called before each row is shown 13883 fnRowCallback: function (nRow, aData, iDisplayIndex) { 13884 var part_payment_id = aData[0]; 13885 var company_name = aData[1]; 13886 var part_payment_status = aData[9]; 13887 var down_payment_status = aData[10]; 13888 13889 var down_payment_invoice_id = aData[11]; 13890 var part_payment_invoice_id = aData[12]; 13891 13892 var down_payment_invoice_no = aData[13]; 13893 var part_payment_invoice_no = aData[14]; 13894 var company_id = aData[15]; 13895 var signature_type = aData[16]; 13896 //var open_sum = aData[8]; 13897 //var row_class = aData[12]; 13898 //var status = aData[11]; 13899 13900 if (signature_type === 'self_signed') { 13901 part_payment_status = part_payment_status + ' [online]'; 13902 } 13903 13904 //Add the transaction id to every rows data object 13905 //$(nRow).addClass(row_class); 13906 $('td:eq(0)', nRow).html( 13907 '<a href="' + 13908 part_payment_id + 13909 '" class="show_part_payment" >' + 13910 part_payment_id + 13911 '</a>' 13912 ); 13913 $('td:eq(1)', nRow).html( 13914 '<a href="' + 13915 company_id + 13916 '" class="show_account_card" data-companyId="' + 13917 company_id + 13918 '">' + 13919 company_name + 13920 '</a>' 13921 ); 13922 $('td:eq(6)', nRow).html(
13923 '<a href="/logs/getLogHtml/part_payment/' + 13924 part_payment_id + 13925 '" name="global" class="show_part_payment_log" >' + 13926 part_payment_status + 13927 '</a>' 13928 ); 13929 13930 if (part_payment_invoice_id == null) { 13931 $('td:eq(9)', nRow).html(''); 13932 } else { 13933 $('td:eq(9)', nRow).html( 13934 '<a href="' + 13935 part_payment_invoice_id + 13936 '" class="show_invoice" >' + 13937 part_payment_invoice_no + 13938 '</a>' 13939 ); 13940 } 13941 13942 if (down_payment_invoice_id == null) { 13943 $('td:eq(7)', nRow).html(''); 13944 $('td:eq(8)', nRow).html(''); 13945 } else { 13946 $('td:eq(7)', nRow).html( 13947 '<a href="' + 13948 down_payment_invoice_id + 13949 '" class="show_invoice_log" >' + 13950 down_payment_status + 13951 '</a>' 13952 ); 13953 $('td:eq(8)', nRow) 13954 .addClass('status') 13955 .html( 13956 '<a href="' + 13957 down_payment_invoice_id + 13958 '" class="show_invoice" >' + 13959 down_payment_invoice_no + 13960 '</a>' 13961 ); 13962 } 13963 13964 return nRow; 13965 }, 13966 }); 13967 13968 // We haveto fallback to delegate, because we got an ancient jQuery. :( 13969 $('#part_payments_dt').on('click', 'a.show_account_card', function (e) { 13970 e.preventDefault(); 13971 var cId = $(this).data('companyid'); 13972 window.AccountCard.show(cId); 13973 }); 13974 13975 $('#part_payments_filter_form input:checkbox, #part_payments_filter_form select').change( 13976 function (e) { 13977 pages.iv_laskutus_ja_reskontra.$part_payments_datatable.fnClearTable(0); 13978 pages.iv_laskutus_ja_reskontra.$part_payments_datatable.fnDraw(); 13979 } 13980 ); 13981 13982 $('#invoices_filter_form input:checkbox, #invoices_filter_form select').change(function (e) { 13983 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 13984 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 13985 setTimeout(function () { 13986 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 13987 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 13988 }, 1); 13989 }); 13990 13991 $('#iv_invoices_filter_form input:checkbox, #iv_invoices_filter_form select').change(function (e) { 13992 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 13993 // If fnDraw() is called when switching checkboxes, previous filter will override all filter 13994 setTimeout(function () { 13995 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 13996 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 13997 }, 1); 13998 }); 13999 14000 pages.iv_laskutus_ja_reskontra.$datatable_iv = $('#iv_invoices_dt').dataTable({ 14001 oLanguage: global.dataTablesLanguage, 14002 sPaginationType: 'full_numbers', 14003 iDisplayLength: 10, 14004 bPaginate: true, 14005 bAutoWidth: false, 14006 bJQueryUI: true, 14007 bFilter: true, 14008 bInfo: true, 14009 bProcessing: true, 14010 bServerSide: true, 14011 sAjaxSource: 'ajax/get_invoices_json/', 14012 aoColumns: [ 14013 /** invoice_id **/ null, 14014 /** gothia_invoice_number **/ { bVisible: false, bSearchable: false }, 14015 /** ref_nr **/ { bVisible: false, bSearchable: false, bSortable: false }, 14016 /** Lähettäjä **/ { bVisible: false, bSearchable: false, bSortable: false }, 14017 /** Velallinen **/ null, 14018 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 14019 /** Päiväys **/ { sType: 'date-eu' }, 14020 /** Eräpäivä **/ { sType: 'date-eu' }, 14021 /** Summa **/ { sType: 'currency', bSearchable: false, bSortable: false }, 14022 /** Avoinna **/ { sType: 'currency', bSearchable: false, bSortable: false }, 14023 /** Rahoitettu **/ { bVisible: false, bSearchable: false }, 14024 /** Viitteemme **/ null, 14025 /** Laskun **/ null, 14026 /** status **/ { bVisible: false }, 14027 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 14028 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 14029 ], 14030 aaSorting: [[0, 'desc']], 14031 14032 fnServerParams: function (aoData) {
14033 var month = $('#ac-tab-iv_invoices') 14034 .find('select[name=month] option:selected') 14035 .attr('value'); 14036 var year = $('#ac-tab-iv_invoices') 14037 .find('select[name=year] option:selected') 14038 .attr('value'); 14039 14040 var filters = []; 14041 $('#iv_invoices_filter_form input:checkbox:checked').each(function(){ 14042 console.log($(this).attr('name')); 14043 filters.push($(this).attr('name')); 14044 }); 14045 14046 aoData.push({ name: 'month', value: month }); 14047 aoData.push({ name: 'year', value: year }); 14048 aoData.push({ name: 'company', value: 30 }); 14049 aoData.push({ name: 'filters', value: filters }); 14050 }, 14051 14052 fnDrawCallback: function () { 14053 var month = $('#ac-tab-iv_invoices') 14054 .find('select[name=month] option:selected') 14055 .attr('value'); 14056 var year = $('#ac-tab-iv_invoices') 14057 .find('select[name=year] option:selected') 14058 .attr('value'); 14059 14060 $('span#month_year').html(month + ', ' + year); 14061 }, 14062 14063 //Called before each row is shown 14064 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14065 var invoice_id = aData[0]; 14066 var open_sum = aData[9]; 14067 var row_class = aData[13]; 14068 var status = aData[12]; 14069 14070 //Add the transaction id to every rows data object 14071 $(nRow).addClass(row_class); 14072 $('td:eq(0)', nRow).html( 14073 '<a href="' + invoice_id + '" class="show_invoice" >' + invoice_id + '</a>' 14074 ); 14075 $('td:eq(7)', nRow) 14076 .addClass('status') 14077 .html('<a href="' + invoice_id + '" class="show_invoice_log" >' + status + '</a>'); 14078 14079 return nRow; 14080 }, 14081 }); 14082 14083 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers = $( 14084 'table#money_transfers_dt' 14085 ).dataTable({ 14086 oLanguage: global.dataTablesLanguage, 14087 sPaginationType: 'full_numbers', 14088 bAutoWidth: false, 14089 bJQueryUI: true, 14090 bFilter: true, 14091 bInfo: true, 14092 bPaginate: true, 14093 bProcessing: true, 14094 bServerSide: true, 14095 sAjaxSource: 'iv_laskutus_ja_reskontra/moneyTransfersDataTable/', 14096 aoColumns: [ 14097 /** id **/ { bVisible: false }, 14098 /** Money_transfer date **/ { sType: 'date-eu' }, 14099 /** Sales **/ { bSortable: false, bSearchable: false }, 14100 /** Deductions **/ { bSortable: false, bSearchable: false }, 14101 /** To be paid **/ { bSortable: false, bSearchable: false }, 14102 /** report **/ { bSortable: false, bSearchable: false }, 14103 ], 14104 aaSorting: [[1, 'desc']], 14105 14106 fnServerParams: function (aoData) { 14107 var filters = []; 14108 14109 $('#money_transfers_filter_form input[name=filters]:checked').each(function () { 14110 filters.push($(this).val()); 14111 14112 //console.log(filters); 14113 }); 14114 14115 aoData.push({ name: 'filters', value: filters }); 14116 }, 14117 14118 //Called before each row is shown 14119 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14120 var id = aData[0]; 14121 var money_transfer_date = aData[1]; 14122 var count_open = aData[2]; 14123 var count_transferred = aData[3]; 14124 var count_deleted = aData[4]; 14125 var report_url = aData[5]; 14126 14127 //Add the transaction id to every rows data object 14128 //$(nRow).data({"id":id}); 14129 $('td:eq(0)', nRow).html( 14130 money_transfer_date 14131 ); 14132 $('td:eq(1)', nRow).html( 14133 '<a href="' + id + '" data-date="' + money_transfer_date + '" class="show_money_transfer_open" >' + 'Avoimet (' + count_open + ')' + '</a>' 14134 ); 14135 $('td:eq(2)', nRow).html( 14136 '<a href="' + id + '" data-date="' + money_transfer_date + '" class="show_money_transfer_transferred" >' + 'Tilitetyt (' + count_transferred + ')' + '</a>' 14137 ); 14138 $('td:eq(3)', nRow).html( 14139 '<a href="' + id + '" data-date="' + money_transfer_date + '" class="show_money_transfer_deleted" >' + 'Poistetut (' + count_deleted + ')' + '</a>' 14140 ); 14141 $('td:eq(4)', nRow).html( 14142 '<a href="' + 14143 report_url + 14144 '" class="download_report" >Kaikki</a> <a style="padding-left:10px;" href="' + 14145 report_url + 14146 '/0/1" class="download_report" >Vain rahoitukset</a>' 14147 ); 14148 return nRow; 14149 }, 14150 }); 14151 14152 $('#money_transfers_filter_form input[name=filters]').change(function (e) { 14153 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnClearTable(0); 14154 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnDraw(); 14155 }); 14156 14157 pages.iv_laskutus_ja_reskontra.$datatable_refunds = $('#refunds_dt').dataTable({ 14158 oLanguage: global.dataTablesLanguage, 14159 sPaginationType: 'full_numbers', 14160 bAutoWidth: false, 14161 bJQueryUI: true, 14162 bFilter: true, 14163 bInfo: true, 14164 bPaginate: true, 14165 bProcessing: true,
14166 bServerSide: true, 14167 sAjaxSource: 'iv_laskutus_ja_reskontra/get_refunds_json/', 14168 aoColumns: [ 14169 /** id **/ null, 14170 /** Yritys ID **/ { bVisible: false }, 14171 /** Yritys **/ null, 14172 /** Yritys ID **/ { bVisible: false }, 14173 /** Laskunr **/ null, 14174 /** Hyvityslaskunr ID **/ { bVisible: false }, 14175 /** Hyvityslaskunr **/ { bVisible: false }, 14176 /** PalautusLaskunr ID **/ { bVisible: false }, 14177 /** PalautusLaskunr **/ null, 14178 /** Hyvityspvm **/ { sType: 'date-eu' }, 14179 /** Viite **/ { bVisible: false }, 14180 /** Palautettava **/ { bSearchable: false }, 14181 /** Palautettu **/ { bSearchable: false }, 14182 /** Jäännös **/ { bVisible: false, bSearchable: false }, 14183 /** Palautuspvm **/ { sType: 'date-eu', bSearchable: false }, 14184 /** Tila **/ null, 14185 ], 14186 aaSorting: [[0, 'desc']], 14187 14188 fnServerParams: function (aoData) { 14189 /* 14190 var open_refunds = $('#refunds_filter_form input[name=open_refunds]').is(':checked'), 14191 paid_refunds = $('#refunds_filter_form input[name=paid_refunds]').is(':checked'); //.attr("value"); 14192 aoData.push({"name": "open_refunds", 'value': open_refunds}); 14193 aoData.push({"name": "paid_refunds", 'value': paid_refunds}); 14194 */ 14195 var filters = []; 14196 14197 $('#refunds_filter_form input:checkbox:checked').each(function () { 14198 filters.push($(this).attr('name')); 14199 }); 14200 14201 aoData.push({ name: 'filters', value: filters }); 14202 }, 14203 14204 //Called before each row is shown 14205 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14206 var id = aData[0]; 14207 var company_id = aData[1]; 14208 var company_name = aData[2]; 14209 var invoice_id = aData[3]; 14210 var invoice_no = aData[4]; 14211 var refund_invoice_id = aData[7]; 14212 var refund_invoice_no = aData[8]; 14213 var credit_invoice_id = aData[5]; 14214 var credit__invoice_no = aData[6]; 14215 var status = aData[15]; 14216 //var refund_sum = ( + aData[5].replace(",",".")); 14217 //var paid_sum = ( + aData[6].replace(",",".")); 14218 var open_sum = +aData[13]; 14219 //Add the transaction id to every rows data object 14220 $('td:eq(2)', nRow).html( 14221 '<a href="' + invoice_id + '" class="show_invoice" >' + invoice_no + '</a>' 14222 ); 14223 $('td:eq(3)', nRow).html( 14224 '<a href="' + 14225 refund_invoice_id + 14226 '" class="show_invoice" >' + 14227 refund_invoice_no + 14228 '</a>' 14229 ); 14230 $('td:eq(1)', nRow).html( 14231 '<a href="' + 14232 company_id + 14233 '" class="show_account_card" data-companyId="' + 14234 company_id + 14235 '">' + 14236 company_name + 14237 '</a>' 14238 ); 14239 $('td:eq(8)', nRow).html( 14240 '<a href="/logs/getLogHtml/refund/' + 14241 id + 14242 '" class="show_log" name="global" >' + 14243 status + 14244 '</a>' 14245 ); 14246 return nRow; 14247 }, 14248 }); 14249 14250 $('#refunds_filter_form').on('change', 'input', function (e) { 14251 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnClearTable(0); 14252 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnDraw(); 14253 }); 14254 14255 pages.iv_laskutus_ja_reskontra.$datatable_direct_payments = $( 14256 '#direct_payments_dt' 14257 ).dataTable({ 14258 oLanguage: global.dataTablesLanguage, 14259 sPaginationType: 'full_numbers', 14260 bAutoWidth: false, 14261 bJQueryUI: true, 14262 bFilter: true, 14263 bInfo: true, 14264 bPaginate: true, 14265 bProcessing: true, 14266 bServerSide: true, 14267 sAjaxSource: 'iv_laskutus_ja_reskontra/directPaymentsDataTable/', 14268 aoColumns: [ 14269 /** ID **/ null, 14270 /** Yritys ID **/ { bVisible: false }, 14271 /** Yritys **/ null, 14272 /** Maksunumero **/ { bVisible: false }, 14273 /** TyömääräysId **/ { bVisible: false }, 14274 /** Työmääräysnumero **/ { bVisible: false }, 14275 /** KuormakirjaId **/ { bVisible: false }, 14276 /** Kuormakirjanumero **/ { bVisible: false }, 14277 /** Työn nro **/ { bSortable: false }, 14278 /** Toimipiste **/ { bVisible: false }, 14279 /** Pvm **/ null, 14280 /** Tyyppi **/ null, 14281 /** Maksaja **/ { bVisible: false }, 14282 /** Työn suorittaja **/ null, 14283 /** Summa **/ { bSortable: false }, 14284 /** Tilitetty **/ { bVisible: true, bSortable: false }, 14285 /** Avoinna **/ { bVisible: true, bSortable: false }, 14286 /** Tilakoodi **/ { bVisible: false }, 14287 /** Tila **/ { bSortable: 'status' }, 14288 /** Row class **/ { bVisible: false, bSearchable: false }, 14289 ], 14290 aaSorting: [[0, 'desc']], 14291 14292 fnServerParams: function (aoData) { 14293 var filters = [], 14294 payment_type; 14295
14296 var month = 14297 $('#direct_payments_filter_form select.month option:selected').attr('value') || 'all'; 14298 var year = 14299 $('#direct_payments_filter_form select.year option:selected').attr('value') || 'all'; 14300 var company = $( 14301 '#direct_payments_filter_form select[name="company"] option:selected' 14302 ).attr('value'); 14303 $('#direct_payments_filter_form input:checkbox:checked').each(function () { 14304 filters.push($(this).attr('name')); 14305 }); 14306 14307 payment_type = $('#direct_payments_filter_form') 14308 .find('select[name=payment_type] option:selected') 14309 .attr('value'); 14310 14311 filters.push(payment_type); 14312 14313 aoData.push({ name: 'filters', value: filters }); 14314 aoData.push({ name: 'company', value: company }); 14315 aoData.push({ name: 'month', value: month }); 14316 aoData.push({ name: 'year', value: year }); 14317 }, 14318 14319 //Called before each row is shown 14320 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14321 var id = aData[0], 14322 companyId = aData[1], 14323 companyName = aData[2], 14324 ourReference = aData[3], 14325 jobOrderId = aData[4], 14326 towingRecordId = aData[6], 14327 towingRecordNo = aData[7], 14328 paymentType = aData[11], 14329 amountToPay = aData[14], 14330 moneyTrasferred = aData[15], 14331 openAmount = aData[16], 14332 status = aData[18], 14333 jobOrderNumber = aData[20], 14334 jobType = aData[21]; 14335 14336 if (towingRecordId) { 14337 if (jobType === 'towing_record') { 14338 $('td:eq(2)', nRow).html( 14339 '<a href="kuormakirjat/get_towing_record_html/' + 14340 towingRecordId + 14341 '" name="kuormakirjat" class="show_towing_record" >' + 14342 towingRecordNo + 14343 '</a>' 14344 ); 14345 } 14346 } 14347 if (!towingRecordId) { 14348 if (jobType === 'job_order') { 14349 var jobOrderReference = ourReference.split('/'); 14350 jobOrderType = jobOrderReference[1]; 14351 if (jobOrderType !== ' RAH') { 14352 $('td:eq(2)', nRow).html( 14353 '<a href="' + 14354 jobOrderId.toString() + 14355 '" name="global" class="show_job_order" >' + 14356 jobOrderNumber.toString() + 14357 '</a>' 14358 ); 14359 } else { 14360 $('td:eq(2)', nRow).html(jobOrderNumber.toString()); 14361 } 14362 } 14363 } 14364 if (paymentType === 'Korttimaksu') { 14365 $('td:eq(4)', nRow).html( 14366 '<a href="' + id + '" class="show_direct_payment" >' + paymentType + '</a>' 14367 ); 14368 } 14369 $('td:eq(7)', nRow).html( 14370 '<a href="' + 14371 id + 14372 '" class="show_add_payment_dialog" data-moneyTransferred="' + 14373 moneyTrasferred + 14374 '" >' + 14375 moneyTrasferred + 14376 '</a>' 14377 ); 14378 14379 $('td:eq(8)', nRow).html(openAmount); 14380 $('td:eq(1)', nRow).html( 14381 '<a href="' + 14382 companyId + 14383 '" class="show_account_card" data-companyId="' + 14384 companyId + 14385 '">' + 14386 companyName + 14387 '</a>' 14388 ); 14389 $('td:eq(9)', nRow).html( 14390 '<a href="/logs/getLogHtml/direct_payment/' + 14391 id + 14392 '" class="show_direct_payment_log" name="global" >' + 14393 status + 14394 '</a>' 14395 ); 14396 14397 return nRow; 14398 }, 14399 }); 14400 14401 $('#iv_deductions_filter_form input:checkbox, #iv_deductions_filter_form select').change( 14402 function (e) { 14403 // setTimeout used to prevent refreshing dataTable before new filters are applied 14404 setTimeout(function () { 14405 pages.iv_laskutus_ja_reskontra.$datatable_deductions.fnClearTable(0); 14406 pages.iv_laskutus_ja_reskontra.$datatable_deductions.fnDraw(); 14407 }, 1); 14408 } 14409 ); 14410 14411 pages.iv_laskutus_ja_reskontra.$datatable_deductions = $('#iv_deductions_dt').dataTable({ 14412 oLanguage: global.dataTablesLanguage, 14413 sPaginationType: 'full_numbers', 14414 bAutoWidth: false, 14415 bJQueryUI: true, 14416 bFilter: true, 14417 bInfo: true, 14418 bPaginate: true, 14419 bProcessing: true,
14420 bServerSide: true, 14421 sAjaxSource: 'veloitukset/getDeductionsDataTable/', 14422 aoColumns: [ 14423 /** id **/ null, 14424 /** company_name **/ null, 14425 /** type_description **/ null, 14426 /** created **/ null, 14427 /** amount **/ null, 14428 /** invoice_id **/ null, 14429 /** status **/ null, 14430 ], 14431 aaSorting: [[0, 'desc']], 14432 14433 fnServerParams: function (aoData) { 14434 var filters = []; 14435 var company = $('#iv_deductions_filter_form') 14436 .find('select[name=company] option:selected') 14437 .attr('value'); 14438 var month = $('#iv_deductions_filter_form') 14439 .find('select[name=month] option:selected') 14440 .attr('value'); 14441 var year = $('#iv_deductions_filter_form') 14442 .find('select[name=year] option:selected') 14443 .attr('value'); 14444 14445 $('#iv_deductions_filter_form input:checkbox:checked').each(function () { 14446 filters.push($(this).attr('name')); 14447 }); 14448 14449 aoData.push({ name: 'filters', value: filters }); 14450 aoData.push({ name: 'company', value: company }); 14451 aoData.push({ name: 'year', value: year }); 14452 aoData.push({ name: 'month', value: month }); 14453 }, 14454 14455 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14456 var id = aData[0], 14457 companyId = aData[1], 14458 companyName = aData[2], 14459 created = aData[3], 14460 amount = aData[4], 14461 invoiceId = aData[5], 14462 status = aData[6]; 14463 typeDescription = aData[7]; 14464 14465 $('td:eq(0)', nRow).html( 14466 '<a href="' + 14467 id + 14468 '" class="show_deduction_card" data-deductionId="' + 14469 id + 14470 '">' + 14471 id + 14472 '</a>' 14473 ); 14474 14475 $('td:eq(1)', nRow).html( 14476 '<a href="' + 14477 companyId + 14478 '" class="show_account_card" data-companyId="' + 14479 companyId + 14480 '">' + 14481 companyName + 14482 '</a>' 14483 ); 14484 14485 $('td:eq(2)', nRow).html(typeDescription); 14486 14487 if (invoiceId === null) invoiceId = ''; 14488 14489 $('td:eq(5)', nRow).html( 14490 '<a href="' + invoiceId + '" class="show_invoice" >' + invoiceId + '</a>' 14491 ); 14492 14493 return nRow; 14494 }, 14495 }); 14496 14497 $('#remittance-filter-form input:checkbox, #remittance-filter-form select').change(function ( 14498 e 14499 ) { 14500 // setTimeout used to prevent refreshing dataTable before new filters are applied 14501 setTimeout(function () { 14502 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnClearTable(0); 14503 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnDraw(); 14504 }, 1); 14505 }); 14506 14507 pages.iv_laskutus_ja_reskontra.$datatable_remittances = $('#iv_remittances_dt').DataTable({ 14508 oLanguage: global.dataTablesLanguage, 14509 sPaginationType: 'full_numbers', 14510 bAutoWidth: false, 14511 bJQueryUI: true, 14512 bFilter: true, 14513 bInfo: true, 14514 bPaginate: true, 14515 bProcessing: true, 14516 bServerSide: true, 14517 sAjaxSource: 'remittances/getRemittancesDataTable/', 14518 aoColumns: [ 14519 /** id **/ null, 14520 /** status **/ { bSearchable: false }, 14521 /** account */ null, 14522 /** type */ { bVisible: true, bSearchable: false }, 14523 /** amount (remittance) **/ { bSearchable: false }, 14524 /** invoice_no **/ null, 14525 /** invoice_total **/ { bSearchable: false }, 14526 /** entry_date */ { bSearchable: false }, 14527 /** updated */ { bSearchable: false }, 14528 /** source --> actions */ { bSearchable: false }, 14529 ], 14530 aaSorting: [[0, 'desc']], 14531 14532 fnServerParams: function (aoData) { 14533 var filters = []; 14534 14535 $('#remittance-filter-form input:checkbox:checked').each(function () { 14536 filters.push($(this).attr('name')); 14537 }); 14538 if (filters === undefined || filters.length == 0) { 14539 filters.push('unallocated', 'allocated', 'rejected'); 14540 } 14541 aoData.push({ name: 'filters', value: filters }); 14542 }, 14543 14544 fnRowCallback: function (nRow, aData, iDisplayIndex) { 14545 var id = aData[0], 14546 status = aData[1], 14547 account = aData[2], 14548 type = aData[3], 14549 amount = aData[4], 14550 invoice_no = aData[5], 14551 invoice_total = aData[6], 14552 entry_date = aData[7], 14553 updated = aData[8], 14554 source = aData[9]; 14555 14556 var statusDescription = ''; 14557 switch (status) { 14558 case '0': 14559 statusDescription = 'Kohdistamaton'; 14560 break; 14561 case '1': 14562 statusDescription = 'Kohdistettu'; 14563 break; 14564 case '2': 14565 statusDescription = 'Hylätty'; 14566 break; 14567 } 14568 14569 $('td:eq(1)', nRow).html(statusDescription); 14570 if (status === '0') { 14571 var data = { remittance_id: id, updated: updated }; 14572 $('td:eq(9)', nRow).html( 14573 "<a href='" + 14574 JSON.stringify({ 14575 remittance_id: id, 14576 updated: updated, 14577 url: '/remittances/tryToRejectRemittance', 14578 }) + 14579 "' class='try-reject-remittance'>Hylkää</a>" + 14580 ' ' + 14581 "<a href='" + 14582 JSON.stringify({ 14583 remittance_id: id, 14584 updated: updated, 14585 url: '/remittances/tryToAllocateRemittance', 14586 }) + 14587 "' class='try-allocate-remittance'>Kohdista</a>" 14588 ); 14589 } else { 14590 $('td:eq(9)', nRow).html("<a href=''></a>"); 14591 } 14592 }, 14593 }); 14594 $('#direct_payments_filter_form').on('change', 'input, select', function (e) { 14595 pages.iv_laskutus_ja_reskontra.$datatable_direct_payments.fnClearTable(0); 14596 pages.iv_laskutus_ja_reskontra.$datatable_direct_payments.fnDraw(); 14597 }); 14598 14599 $('select[name=company]').each(function () { 14600 global.renderCompaniesFilterOptions(this); 14601 }); 14602 }, // init Laskutus ja reskontra end 14603 14604 init_show_invoice: function (invoice) { 14605 invoice_id = invoice.id; 14606 open_sum = invoice.open_sum; 14607 invoice_items = invoice.items; 14608 14609 $('.edit_invoice_data').editable('/ajax/update_invoice_data', { 14610 submitdata: { invoice_id: invoice_id }, 14611 indicator: 'Tallennetaan...', 14612 tooltip: 'Muokkaa', 14613 placeholder: '', 14614 id: 'field', 14615 event: 'dblclick', 14616 }); 14617 14618 $('.edit_area_invoice_data').editable('/ajax/update_invoice_data', { 14619 submitdata: { invoice_id: invoice_id }, 14620 indicator: 'Tallennetaan...', 14621 tooltip: 'Muokkaa', 14622 placeholder: '', 14623 id: 'field', 14624 type: 'textarea', 14625 event: 'dblclick', 14626 submit: 'Tallenna', 14627 data: function (value, settings) { 14628 /* Convert <br> to newline. */ 14629 var retval = value.replace(/<br[\s\/]?>/gi, '\n'); 14630 return retval.trim(); 14631 }, 14632 }); 14633 14634 $('.edit_invoice_data_details').editable('/ajax/update_invoice_data_details', { 14635 submitdata: { invoice_id: invoice_id }, 14636 indicator: 'Tallennetaan...', 14637 tooltip: 'Muokkaa', 14638 placeholder: '', 14639 id: 'field', 14640 event: 'dblclick', 14641 data: function (value, settings) { 14642 /* Convert <br> to newline. */ 14643 var retval = value.replace(/<br[\s\/]?>/gi, '\n'); 14644 return retval.trim(); 14645 }, 14646 }); 14647 14648 $('.edit_invoice_item_data').editable('/ajax/update_invoice_item_data', { 14649 indicator: 'Tallennetaan...', 14650 tooltip: 'Muokkaa', 14651 placeholder: '', 14652 id: 'field', 14653 event: 'dblclick', 14654 data: function (val) { 14655 return val.trim(); 14656 }, 14657 }); 14658 14659 $('.edit_is_financed').editable('/ajax/update_invoice_data', { 14660 data: " {0:'Ei', 1:'Kyllä'}", 14661 submitdata: { invoice_id: invoice_id }, 14662 type: 'select', 14663 indicator: 'Tallennetaan...', 14664 tooltip: 'Muokkaa', 14665 placeholder: '', 14666 id: 'field', 14667 submit: 'Tallenna', 14668 event: 'dblclick', 14669 }); 14670 14671 $('.edit_next_notification').editable('/ajax/update_invoice_data', { 14672 data: " {0:'Ei määritelty', sp:'Selvityspyyntö (Asiakas)', kp:'Korjauspyyntö (Myyjä)'}", 14673 submitdata: { invoice_id: invoice_id }, 14674 type: 'select', 14675 indicator: 'Tallennetaan...', 14676 tooltip: 'Muokkaa', 14677 placeholder: '', 14678 id: 'field', 14679 submit: 'Tallenna', 14680 event: 'dblclick', 14681 }); 14682 14683 $('.edit_seller_notification').editable('/ajax/update_invoice_data', { 14684 data: " {0:'Ei määritelty', kp:'Korjauspyyntö (Myyjä)'}", 14685 submitdata: { invoice_id: invoice_id }, 14686 type: 'select', 14687 indicator: 'Tallennetaan...', 14688 tooltip: 'Muokkaa', 14689 placeholder: '', 14690 id: 'field', 14691 submit: 'Tallenna', 14692 event: 'dblclick', 14693 }); 14694 14695 $('#show_invoice_pdf') 14696 .button({ icons: { primary: 'ui-icon-document' } }) 14697 .on('click', function () { 14698 //window.location = 'iv_laskutus_ja_reskontra/get_pdf_invoice/' + invoice_id + '/download'; 14699 14700 //show_invoice_pdf 14701 pages.iv_laskutus_ja_reskontra.show_invoice_pdf(invoice_id); 14702 }); 14703 14704 var invoiceDeliveryMethods = function () { 14705 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 14706 $list.append( 14707 $('<li />', {}).append( 14708 $('<a />', { href: '' }) 14709 .on('click', function (e) { 14710 e.preventDefault(); 14711 pages.iv_laskutus_ja_reskontra.send_invoice_by_mail(invoice.id); 14712 }) 14713 .text('Postitse') 14714 ), 14715 $('<li />', {}).append( 14716 $('<a />', { href: '' }) 14717 .on('click', function (e) { 14718 e.preventDefault(); 14719 pages.iv_laskutus_ja_reskontra.send_invoice_by_email(invoice.id, invoice.email); 14720 }) 14721 .text('Sähköpostitse') 14722 ) 14723 ); 14724 if (invoice.invoice.customer_type !== 'person') { 14725 $list.append( 14726 $('<li />', {}).append( 14727 $('<a />', { href: '' }) 14728 .on('click', function (e) { 14729 e.preventDefault(); 14730 pages.iv_laskutus_ja_reskontra.send_invoice_by_e_invoice(invoice.id); 14731 }) 14732 .text('Verkkolaskuna') 14733 ) 14734 ); 14735 } 14736 14737 $list.append( 14738 $('<li />', {}).append( 14739 $('<a />', { href: '' }) 14740 .on('click', function (e) { 14741 e.preventDefault(); 14742 pages.iv_laskutus_ja_reskontra.insert_invoice_to_ledger(invoice.id); 14743 }) 14744 .text('Lähetä reskontraan (ei toimitusta)') 14745 ) 14746 ); 14747 return $list; 14748 }; 14749 14750 $('#send_invoice') 14751 .button({ icons: { primary: 'ui-icon-mail-closed', secondary: 'ui-icon-triangle-1-s' } }) 14752 .wrap($('<div />', { style: 'float:left;' })) 14753 .wrap($('<div />', {})) 14754 .parent() 14755 .parent() 14756 .append(invoiceDeliveryMethods()) 14757 .parent() 14758 .parent() 14759 .find('#send_invoice') 14760 .on('click', function () { 14761 var $menu = $(this).parent().next(); 14762 14763 if ($menu.is(':visible')) { 14764 $menu.hide(); 14765 } else { 14766 $menu.show().position({ 14767 my: 'left top', 14768 at: 'left bottom', 14769 of: this, 14770 }); 14771 } 14772 14773 var menu = $(this).parent().next(); 14774 $(document).one('click', function () { 14775 menu.hide(); 14776 }); 14777 return false;
14778 }) 14779 .parent() 14780 .buttonset() 14781 .next() 14782 .hide() 14783 .menu(); 14784 14785 $('#copy_invoice') 14786 .button({ icons: { primary: 'ui-icon-copy' } }) 14787 .on('click', function () { 14788 pages.iv_laskutus_ja_reskontra.copy_invoice(invoice_id); 14789 }); 14790 14791 $('#delete_draft') 14792 .button({ icons: { primary: 'ui-icon-trash' } }) 14793 .on('click', function () { 14794 pages.iv_laskutus_ja_reskontra.confirm_delete_draft(invoice_id); 14795 }); 14796 14797 $('#add_payment') 14798 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14799 .on('click', function () { 14800 pages.iv_laskutus_ja_reskontra.show_add_payment_dialog(invoice_id, open_sum, 'invoice'); 14801 }); 14802 14803 $('#add_credit_line') 14804 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14805 .on('click', function () { 14806 pages.iv_laskutus_ja_reskontra.show_add_credit_line_dialog(invoice_id, invoice_items); 14807 }); 14808 14809 $('#show-credit-invoice-dialog') 14810 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14811 .on('click', function () { 14812 LaskutusJaReskontra.invoiceDialog.showCreditInvoiceDialog(); 14813 }); 14814 14815 $('#show-invoice-ledger-service-actions-dialog') 14816 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14817 .on('click',function() { 14818 LaskutusJaReskontra.invoiceDialog.showLedgerServiceActionsDialog(); 14819 }); 14820 14821 $('#modify').button({ icons: { primary: 'ui-icon-pencil' } }); 14822 14823 $('#add_log_item') 14824 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14825 .on('click',function() { 14826 window.LaskutusJaReskontra.invoiceDialog.addInvoiceNoteDialog.show(); 14827 }); 14828 14829 $('#print_invoice') 14830 .button({ icons: { primary: 'ui-icon-print' } }) 14831 .on('click', function () { 14832 w = window.open(); 14833 w.location = 'iv_laskutus_ja_reskontra/get_pdf_invoice/' + invoice_id; 14834 w.print(); 14835 w.close(); 14836 }); 14837 14838 $('#print_receipt') 14839 .button({ icons: { primary: 'ui-icon-print' } }) 14840 .on('click', function () { 14841 var receiptUrl = '/lasku/kuitti/' + invoice_id, 14842 w = window.open(); 14843 14844 w.location = receiptUrl; 14845 }); 14846 14847 $('#show_invoice .show_invoice_log').on('click', function (e) { 14848 e.preventDefault(); 14849 var invoice_id = $(this).attr('href'); 14850 pages.iv_laskutus_ja_reskontra.show_invoice_log(invoice_id); 14851 }); 14852 14853 $('#show_invoice a.show_invoice').on('click', function (e) { 14854 e.preventDefault(); 14855 var invoice_id = $(this).attr('href'); 14856 pages.iv_laskutus_ja_reskontra.show_invoice(invoice_id); 14857 }); 14858 14859 $('#send_by_mail') 14860 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 14861 .on('click', function (e) { 14862 pages.iv_laskutus_ja_reskontra.send_invoice_by_mail(invoice.id); 14863 }); 14864 14865 $('#send_by_email') 14866 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 14867 .on('click', function () { 14868 pages.iv_laskutus_ja_reskontra.send_invoice_by_email(invoice.id, invoice.email); 14869 }); 14870 14871 $('#send_invoice_copy_by_email') 14872 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 14873 .on('click', function () { 14874 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_email(invoice.id, invoice.email); 14875 }); 14876 14877 $('#send_credit_note_copy_by_email') 14878 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 14879 .on('click', function () { 14880 pages.iv_laskutus_ja_reskontra.send_credit_note_copy_by_email(invoice.id, invoice.email); 14881 }); 14882 14883 $('#add-credit-loss') 14884 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14885 .on('click', function () { 14886 LaskutusJaReskontra.invoiceDialog.showAddCreditLossDialog(); 14887 }); 14888 14889 $('#suggest-credit-loss') 14890 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14891 .on('click', function () { 14892 LaskutusJaReskontra.invoiceDialog.showSuggestCreditLossDialog(); 14893 }); 14894 14895 $('#nullify-credit-loss') 14896 .button({ icons: { primary: 'ui-icon-minusthick' } }) 14897 .on('click', function () { 14898 window.LaskutusJaReskontra.invoiceDialog.showNullifyCreditLossDialog(); 14899 }); 14900 14901 var creditLossMethods = function () { 14902 return $('<li />', {}).append( 14903 $('<a />', { href: '' }) 14904 .on('click', function (e) { 14905 e.preventDefault(); 14906 LaskutusJaReskontra.invoiceDialog.showSuggestCreditLossDialog(); 14907 }) 14908 .text('Luottotappiosuositus'), 14909 $('<li />', {}).append( 14910 $('<a />', { href: '' }) 14911 .on('click', function (e) { 14912 e.preventDefault(); 14913 LaskutusJaReskontra.invoiceDialog.showAddCreditLossDialog(); 14914 }) 14915 .text('Merkitse luottotappioksi') 14916 ) 14917 ); 14918 }; 14919 14920 $('#credit-loss') 14921 .button({ icons: { primary: 'ui-icon-plusthick' } }) 14922 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 14923 14924 .wrap($('<div />', { style: 'float:right;' })) 14925 .wrap($('<div />', {})) 14926 .parent() 14927 .parent() 14928 .append( 14929 $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }).append( 14930 creditLossMethods() 14931 ) 14932 ) 14933 .parent() 14934 .parent() 14935 .find('#credit-loss') 14936 .on('click', function () { 14937 var $menu = $(this).parent().next(); 14938 14939 if ($menu.is(':visible')) { 14940 $menu.hide(); 14941 } else { 14942 $menu.show().position({ 14943 my: 'left top', 14944 at: 'left bottom', 14945 of: this, 14946 }); 14947 } 14948 14949 var menu = $(this).parent().next(); 14950 $(document).one('click', function () { 14951 menu.hide(); 14952 }); 14953 return false;
14954 }) 14955 .parent() 14956 .buttonset() 14957 .next() 14958 .hide() 14959 .menu(); 14960 14961 var invoiceCopyDeliveryMethods = function () { 14962 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 14963 14964 $list.append( 14965 $('<li />', {}).append( 14966 $('<a />', { href: '' }) 14967 .on('click', function (e) { 14968 e.preventDefault(); 14969 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_mail(invoice.id); 14970 }) 14971 .text('Postitse') 14972 ), 14973 $('<li />', {}).append( 14974 $('<a />', { href: '' }) 14975 .on('click', function (e) { 14976 e.preventDefault(); 14977 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_email( 14978 invoice.id, 14979 invoice.email 14980 ); 14981 }) 14982 .text('Sähköpostitse') 14983 ) 14984 ); 14985 if (invoice.invoice.type != 'credit_note') { 14986 $list.append( 14987 $('<li />', {}).append( 14988 $('<a />', { href: '' }) 14989 .on('click', function (e) { 14990 e.preventDefault(); 14991 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_sms( 14992 invoice.id, 14993 invoice.phone 14994 ); 14995 }) 14996 .text('Tekstiviestillä') 14997 ) 14998 ); 14999 } 15000 if (invoice.invoice.customer_type !== 'person') { 15001 var disableEditing = 15002 invoice.isAutoliitto || invoice.isSos || invoice.isInsuranceCompany ? true : false; 15003 $list.append( 15004 $('<li />', {}).append( 15005 $('<a />', { href: '' }) 15006 .on('click', function (e) { 15007 e.preventDefault(); 15008 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_e_invoice( 15009 invoice.id, 15010 disableEditing, 15011 invoice.eInvoiceAddress, 15012 invoice.eInvoiceOperator, 15013 invoice.eInvoiceOperators 15014 ); 15015 }) 15016 .text('Verkkolaskuna') 15017 ) 15018 ); 15019 } 15020 15021 return $list; 15022 }; 15023 15024 $('#send_invoice_copy') 15025 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 15026 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 15027 15028 .wrap($('<div />', { style: 'float:left;' })) 15029 .wrap($('<div />', {})) 15030 .parent() 15031 .parent() 15032 .append(invoiceCopyDeliveryMethods()) 15033 .parent() 15034 .parent() 15035 .find('#send_invoice_copy') 15036 .on('click', function () { 15037 var $menu = $(this).parent().next(); 15038 15039 if ($menu.is(':visible')) { 15040 $menu.hide(); 15041 } else { 15042 $menu.show().position({ 15043 my: 'left top', 15044 at: 'left bottom', 15045 of: this, 15046 }); 15047 } 15048 15049 var menu = $(this).parent().next(); 15050 $(document).one('click', function () { 15051 menu.hide(); 15052 }); 15053 return false; 15054 }) 15055 .parent() 15056 .buttonset() 15057 .next() 15058 .hide() 15059 .menu(); 15060 15061 /* 15062 $('#send_invoice_copy').button({icons:{primary:'ui-icon-mail-closed'}}).on('click',function(){ 15063 pages.iv_laskutus_ja_reskontra.send_invoice_copy(invoice.id, invoice.email); 15064 }); 15065 */ 15066 15067 $('#show_invoice .edit_invoice_status').on('click', function (e) { 15068 e.preventDefault(); 15069 var invoice_id = $(this).attr('href'); 15070 pages.iv_laskutus_ja_reskontra.show_edit_invoice_status_dialog(invoice_id); 15071 }); 15072 15073 $('#delivery_stop') 15074 .find('input:radio[name=delivery_stop]') 15075 .change(function (e) { 15076 var delivery_stop = $(e.target).val(); 15077 15078 $.ajax({ 15079 url: '/ajax/set_invoice_delivery_stop/', 15080 data: { invoice_id: invoice_id, delivery_stop: delivery_stop }, 15081 type: 'POST', 15082 dataType: 'json', 15083 beforeSend: function (request) { 15084 global.showLoadingDialog('Muutetaan lähetyksen estoa...'); 15085 }, 15086 success: function (responseJSON) { 15087 global.show_message(responseJSON); 15088 global.close_loading_dialog(); 15089 }, 15090 error: function (data) { 15091 global.close_loading_dialog(); 15092 }, 15093 }); 15094 }); 15095 }, //init_show_invoice 15096 15097 showCreateOpenInvoicesReportDialog: function () { 15098 var dateTo = new Date(); 15099 dateTo.setDate(1); 15100 15101 var $createReportDialog = $('<div />') 15102 .append( 15103 $('<form method="post" action="/raportit/createOpenInvoicesReport/csv"/>').append( 15104 $('<label />', { id: 'date_to_label', style: 'width:auto; float:none;' }).html( 15105 'Hae avoimet laskut päivämäärällä' 15106 ), 15107 $( 15108 '<input type="text" class="text small" id="date_to" name="open_until_date" value="' + 15109 dateTo.getDate() + 15110 '.' + 15111 (dateTo.getMonth() + 1) + 15112 '.' + 15113 dateTo.getFullYear() + 15114 '" />' 15115 ).datepicker() 15116 ) 15117 ) 15118 .dialog({ 15119 width: 400, 15120 autoOpen: true, 15121 modal: true, 15122 resizable: false, 15123 draggable: false, 15124 beforeClose: function (event, ui) { 15125 event.stopPropagation(); 15126 }, 15127 title: 'Luo raportti avoimista laskuista', 15128 buttons: { 15129 Peruuta: function () { 15130 $(this).dialog('close'); 15131 }, 15132 'Luo raportti': function () { 15133 console.log($createReportDialog.find('form')); 15134 $createReportDialog.find('form').submit(); 15135 }, 15136 }, 15137 }); 15138 }, 15139 15140 show_invoice_pdf: function (invoice_id) { 15141 $('<div></div>') 15142 .append( 15143 $('<p />', {}).append( 15144 $('<strong />', {}).html('Laskun tila:'), 15145 $('<br />'), 15146 $('<input />', { 15147 name: 'invoice_status', 15148 id: 'invoice_status_current', 15149 type: 'radio', 15150 value: 'current', 15151 checked: 'checked', 15152 }), 15153 $('<label />', { 15154 for: 'invoice_status_current', 15155 style: 'display:inline; float:none;', 15156 }).html('Nykyinen'), 15157 $('<br />'), 15158 $('<input />', { 15159 name: 'invoice_status', 15160 id: 'invoice_status_original', 15161 type: 'radio', 15162 value: 'original', 15163 }), 15164 $('<label />', { 15165 for: 'invoice_status_original', 15166 style: 'display:inline; float:none;', 15167 }).html('Alkuperäinen') 15168 ), 15169 15170 $('<p />', {}).append( 15171 $('<strong />', {}).html('Kirjekuoren ikkuna:'), 15172 $('<br />'), 15173 $('<input />', { 15174 name: 'envelope_window_size', 15175 id: 'envelope_window_size_large', 15176 type: 'radio', 15177 value: 'large', 15178 checked: 'checked', 15179 }), 15180 $('<label />', { 15181 for: 'envelope_window_size_large', 15182 style: 'display:inline; float:none;', 15183 }).html('Suuri'), 15184 $('<br />'), 15185 $('<input />', { 15186 name: 'envelope_window_size', 15187 id: 'envelope_window_size_small', 15188 type: 'radio', 15189 value: 'small', 15190 }), 15191 $('<label />', { 15192 for: 'envelope_window_size_small', 15193 style: 'display:inline; float:none;', 15194 }).html('Pieni') 15195 ) 15196 ) 15197 .dialog({ 15198 autoOpen: true, 15199 modal: true, 15200 resizable: false, 15201 draggable: false, 15202 title: 'Valitse PDF-laskun asetukset', 15203 beforeClose: function (event, ui) { 15204 event.stopPropagation(); 15205 }, 15206 buttons: { 15207 Sulje: function () { 15208 $(this).dialog('close'); 15209 }, 15210 'Lataa PDF-tiedosto': function () {
15211 var invoice_status = $(this).find('input:radio[name=invoice_status]:checked').val(); 15212 var envelope_window_size = $(this) 15213 .find('input:radio[name=envelope_window_size]:checked') 15214 .val(); 15215 window.location = 15216 'iv_laskutus_ja_reskontra/get_pdf_invoice/' + 15217 invoice_id + 15218 '/' + 15219 invoice_status + 15220 '/' + 15221 envelope_window_size + 15222 '/download'; 15223 }, 15224 }, 15225 }); 15226 }, 15227 15228 send_invoice_by_mail: function (invoice_id) { 15229 $dialog = $('<div />', { style: 'text-align:left;' }) 15230 .html('Haluatko varmasti lähettää laskun?') 15231 .dialog({ 15232 autoOpen: true, 15233 modal: true, 15234 resizable: false, 15235 draggable: false, 15236 title: 'Lähetä lasku postitse', 15237 beforeClose: function (event, ui) { 15238 event.stopPropagation(); 15239 }, 15240 buttons: { 15241 Peruuta: function () { 15242 $dialog.dialog('close'); 15243 }, 15244 'Lähetä lasku': function () { 15245 $.ajax({ 15246 dataType: 'json', 15247 type: 'POST', 15248 url: '/ajax/send_invoice_by_mail/' + invoice_id, 15249 beforeSend: function (request) { 15250 global.showLoadingDialog('Lähetetään laskua...'); 15251 }, 15252 success: function (responseJSON) { 15253 if (responseJSON.type == 'success') { 15254 //Refresh the datatables 15255 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15256 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15257 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15258 } 15259 15260 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15261 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15262 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15263 } 15264 15265 if (pages.reskontra.$datatable != null) { 15266 pages.reskontra.$datatable.fnClearTable(0); 15267 pages.reskontra.$datatable.fnDraw(); 15268 } 15269 15270 LaskutusJaReskontra.showInvoiceDialog({ 15271 invoiceId: invoice_id, 15272 }); 15273 } 15274 15275 global.show_message(responseJSON); 15276 global.close_loading_dialog(); 15277 15278 $dialog.dialog('close'); 15279 }, 15280 error: function (response) { 15281 global.close_loading_dialog(); 15282 global.show_message($.parseJSON(response.responseText)); 15283 }, 15284 }); 15285 }, 15286 }, 15287 }); 15288 }, //send_invoice_by_mail 15289 15290 send_invoice_copy_by_mail: function (invoice_id) { 15291 $dialog = $('<div />', { style: 'text-align:left;' }) 15292 .html('Haluatko varmasti lähettää laskukopion postitse?') 15293 .dialog({ 15294 autoOpen: true, 15295 modal: true, 15296 resizable: false, 15297 draggable: false, 15298 title: 'Lähetä laskukopio postitse', 15299 beforeClose: function (event, ui) { 15300 event.stopPropagation(); 15301 }, 15302 buttons: { 15303 Peruuta: function () { 15304 $dialog.dialog('close'); 15305 }, 15306 'Lähetä laskukopio': function () { 15307 $.ajax({ 15308 dataType: 'json', 15309 type: 'POST', 15310 url: '/ajax/send_invoice_copy_by_mail/', 15311 data: { invoiceId: invoice_id }, 15312 beforeSend: function (request) { 15313 global.showLoadingDialog('Lähetetään laskukopiota...'); 15314 }, 15315 success: function (responseJSON) { 15316 if (responseJSON.type == 'success') { 15317 //Refresh the datatables 15318 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15319 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15320 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15321 } 15322 15323 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15324 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15325 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15326 } 15327 15328 LaskutusJaReskontra.showInvoiceDialog({ 15329 invoiceId: invoice_id, 15330 }); 15331 } 15332 15333 global.show_message(responseJSON); 15334 global.close_loading_dialog(); 15335 15336 $dialog.dialog('close'); 15337 }, 15338 error: function (response) { 15339 global.close_loading_dialog(); 15340 global.show_message($.parseJSON(response.responseText)); 15341 }, 15342 }); 15343 }, 15344 }, 15345 }); 15346 }, //send_invoice_by_mail 15347 15348 send_invoice_by_e_invoice: function (invoice_id) { 15349 $dialog = $('<div />', { style: 'text-align:left;' }) 15350 .html('Haluatko varmasti lähettää laskun verkkolaskuna?') 15351 .dialog({ 15352 autoOpen: true, 15353 modal: true, 15354 resizable: false, 15355 draggable: false, 15356 title: 'Lähetä lasku verkkolaskuna', 15357 beforeClose: function (event, ui) { 15358 event.stopPropagation(); 15359 }, 15360 buttons: { 15361 Peruuta: function () { 15362 $dialog.dialog('close'); 15363 }, 15364 'Lähetä lasku': function () { 15365 $.ajax({ 15366 dataType: 'json', 15367 type: 'POST', 15368 url: '/ajax/send_invoice_by_e_invoice/' + invoice_id, 15369 beforeSend: function (request) { 15370 global.showLoadingDialog('Lähetetään laskua...'); 15371 }, 15372 success: function (responseJSON) { 15373 if (responseJSON.type == 'success') { 15374 //Refresh the datatables 15375 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15376 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15377 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15378 } 15379 15380 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15381 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15382 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15383 } 15384 15385 if (pages.reskontra.$datatable != null) { 15386 pages.reskontra.$datatable.fnClearTable(0); 15387 pages.reskontra.$datatable.fnDraw(); 15388 } 15389 15390 LaskutusJaReskontra.showInvoiceDialog({ 15391 invoiceId: invoice_id, 15392 }); 15393 } 15394 15395 global.show_message(responseJSON); 15396 global.close_loading_dialog(); 15397 15398 $dialog.dialog('close'); 15399 }, 15400 error: function (response) { 15401 global.close_loading_dialog(); 15402 global.show_message($.parseJSON(response.responseText)); 15403 }, 15404 }); 15405 }, 15406 }, 15407 }); 15408 }, //send_invoice_by_mail 15409 15410 send_invoice_copy_by_e_invoice: function ( 15411 invoice_id, 15412 disableEditing, 15413 eInvoiceAddress, 15414 eInvoiceOperator, 15415 eInvoiceOperators 15416 ) { 15417 var selectEl = $('<select />', { 15418 type: 'text', 15419 name: 'eInvoiceOperator', 15420 id: 'eInvoiceOperator', 15421 class: 'form-control input-sm', 15422 }); 15423 $.each(eInvoiceOperators, function (i, obj) { 15424 $(selectEl).append('<option value=' + obj.code + '>' + obj.name + '</option>'); 15425 }); 15426 selectEl.val(eInvoiceOperator); 15427 selectEl.prop('disabled', disableEditing); 15428 15429 var eInvoiceInputField = $('<input />', { 15430 type: 'text', 15431 name: 'eInvoiceAddress', 15432 id: 'eInvoiceAddress', 15433 class: 'text medium', 15434 }).val(eInvoiceAddress); 15435 eInvoiceInputField.prop('disabled', disableEditing); 15436 15437 var $form = $('<form />').append( 15438 $('<label />').html('Verkkolaskuosoite'), 15439 eInvoiceInputField, 15440 $('<label />').html('Operaattori'), 15441 selectEl 15442 ); 15443 if (disableEditing) { 15444 $form.append( 15445 $('<input />', { type: 'hidden', name: 'eInvoiceAddress', id: 'eInvoiceAddress' }).val( 15446 eInvoiceAddress 15447 ), 15448 $('<input />', { type: 'hidden', name: 'eInvoiceOperator', id: 'eInvoiceOperator' }).val( 15449 eInvoiceOperator 15450 ) 15451 ); 15452 } 15453 15454 $form.submit(function (e) { 15455 //Get the data from the form element 15456 var data = _.object( 15457 $form.serializeArray().map(function (v) {
15458 return [v.name, v.value]; 15459 }) 15460 ); 15461 15462 //Add some extra data 15463 _.extend(data, { invoiceId: invoice_id }); 15464 15465 e.preventDefault(); 15466 15467 $.ajax({ 15468 dataType: 'json', 15469 type: 'POST', 15470 url: '/ajax/send_invoice_copy_by_e_invoice/', 15471 data: data, 15472 beforeSend: function (request) { 15473 global.showLoadingDialog('Lähetetään laskukopiota...'); 15474 }, 15475 success: function (responseJSON) { 15476 if (responseJSON.type == 'success') { 15477 //Refresh the datatables 15478 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15479 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15480 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15481 } 15482 15483 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15484 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15485 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15486 } 15487 15488 LaskutusJaReskontra.showInvoiceDialog({ 15489 invoiceId: invoice_id, 15490 }); 15491 } 15492 15493 global.show_message(responseJSON); 15494 global.close_loading_dialog(); 15495 15496 $dialog.dialog('close'); 15497 }, 15498 error: function (response) { 15499 global.close_loading_dialog(); 15500 global.show_message($.parseJSON(response.responseText)); 15501 }, 15502 }); 15503 }); 15504 15505 $dialog = $('<div />', { style: 'text-align:left;' }) 15506 .append($form) 15507 .dialog({ 15508 autoOpen: true, 15509 modal: true, 15510 resizable: false, 15511 draggable: false, 15512 title: 'Lähetä laskukopio verkkolaskuna', 15513 beforeClose: function (event, ui) { 15514 event.stopPropagation(); 15515 }, 15516 buttons: { 15517 Peruuta: function () { 15518 $dialog.dialog('close'); 15519 }, 15520 'Lähetä laskukopio': function () { 15521 $form.submit(); 15522 }, 15523 }, 15524 }); 15525 }, //send_invoice_copy_by_e_invoice 15526 15527 insert_invoice_to_ledger: function(invoice_id) { 15528 $dialog = $('<div />', { style: 'text-align:left;' }) 15529 .html( 15530 'Haluatko varmasti lähettää laskun reskontrattavaksi? HUOM! Asiakkaalle ei toimiteta laskua' 15531 ) 15532 .dialog({ 15533 autoOpen: true, 15534 modal: true, 15535 resizable: false, 15536 draggable: false, 15537 title: 'Lähetä lasku reskontraan', 15538 beforeClose: function (event, ui) { 15539 event.stopPropagation(); 15540 }, 15541 buttons: { 15542 Peruuta: function () { 15543 $dialog.dialog('close'); 15544 }, 15545 'Lähetä lasku': function () { 15546 $.ajax({ 15547 dataType: 'json', 15548 type: 'POST', 15549 url: '/iv_laskutus_ja_reskontra/insert_invoice_to_ledger/' + invoice_id, 15550 beforeSend: function(request) { 15551 global.showLoadingDialog('Lähetetään laskua...'); 15552 }, 15553 success: function (responseJSON) { 15554 if (responseJSON.type == 'success') { 15555 //Refresh the datatables 15556 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15557 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15558 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15559 } 15560 15561 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15562 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15563 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15564 } 15565 15566 if (pages.reskontra.$datatable != null) { 15567 pages.reskontra.$datatable.fnClearTable(0); 15568 pages.reskontra.$datatable.fnDraw(); 15569 } 15570 15571 LaskutusJaReskontra.showInvoiceDialog({ 15572 invoiceId: invoice_id, 15573 }); 15574 } 15575 15576 global.show_message(responseJSON); 15577 global.close_loading_dialog(); 15578 15579 $dialog.dialog('close'); 15580 }, 15581 error: function (response) { 15582 global.close_loading_dialog(); 15583 global.show_message($.parseJSON(response.responseText)); 15584 }, 15585 }); 15586 }, 15587 }, 15588 }); 15589 }, //send_invoice_by_mail 15590 15591 send_invoice_by_sms: function (invoiceId, phone) { 15592 var $form = $('<form />').append( 15593 $('<p />').html('Anna puhelinnumero'), 15594 $('<input />', { type: 'text', name: 'toSms', id: 'toSms', class: 'text medium' }).val( 15595 phone 15596 ) 15597 ); 15598 15599 $form.submit(function (e) { 15600 e.preventDefault(); 15601 var phone = document.getElementById('toSms').value; 15602 var data = { 15603 phone: phone, 15604 invoiceId: invoiceId, 15605 }; 15606 15607 global.showLoadingDialog('Lähetetään lasku...'); 15608 15609 $.ajax({ 15610 url: '/ajax/send_invoice_by_sms/', 15611 dataType: 'json', 15612 type: 'POST', 15613 data: data, 15614 }) 15615 .done(function (responseJSON) { 15616 $dialog.dialog('close'); 15617 global.show_message(responseJSON); 15618 global.close_loading_dialog(); 15619 }) 15620 .fail(function (response) { 15621 var responseJSON = $.parseJSON(response.responseText); 15622 global.close_loading_dialog(); 15623 global.show_message(responseJSON); 15624 }); 15625 }); 15626 15627 var $dialog = $('<div />', { style: 'text-align:left;' }) 15628 .append($form) 15629 .dialog({ 15630 width: 320, 15631 autoOpen: true, 15632 modal: true, 15633 resizable: false, 15634 draggable: false, 15635 beforeClose: function (event, ui) { 15636 event.stopPropagation(); 15637 }, 15638 close: function () { 15639 $(this).dialog('destroy'); 15640 $(this).remove(); 15641 }, 15642 title: 'Lähetä lasku sms viestinä', 15643 buttons: { 15644 Peruuta: function () { 15645 $(this).dialog('close'); 15646 }, 15647 'Lähetä lasku': function () { 15648 $form.submit(); 15649 }, 15650 }, 15651 }); 15652 }, 15653 send_invoice_by_email: function (invoice_id, email) { 15654 //console.log('send_invoice_by_email', 3406); 15655 15656 var $form = $('<form />', { 15657 method: 'POST', 15658 action: '/ajax/send_invoice_by_email/' + invoice_id, 15659 }).append( 15660 $('<p />').html('Anna sähköpostiosoite minne lasku lähetetään'), 15661 $('<input />', { 15662 type: 'text', 15663 name: 'send_to_email', 15664 id: 'send_to_email', 15665 class: 'text medium', 15666 }).val(email) 15667 ); 15668 15669 $form.submit(function (e) { 15670 e.preventDefault(); 15671 15672 $form.ajaxSubmit({ 15673 dataType: 'json', 15674 type: 'POST', 15675 15676 beforeSend: function (request) { 15677 global.showLoadingDialog('Lähetetään laskua...'); 15678 }, 15679 success: function (responseJSON) { 15680 if (responseJSON.type == 'success') { 15681 $dialog.dialog('close'); 15682 15683 //Refresh the datatables 15684 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 15685 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 15686 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 15687 } 15688 15689 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 15690 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 15691 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 15692 } 15693 15694 if (pages.reskontra.$datatable != null) { 15695 pages.reskontra.$datatable.fnClearTable(0); 15696 pages.reskontra.$datatable.fnDraw(); 15697 } 15698 15699 LaskutusJaReskontra.showInvoiceDialog({ 15700 invoiceId: invoice_id, 15701 }); 15702 } 15703 15704 global.show_message(responseJSON); 15705 global.close_loading_dialog(); 15706 }, 15707 error: function (response) { 15708 global.close_loading_dialog(); 15709 global.show_message($.parseJSON(response.responseText)); 15710 }, 15711 }); 15712 }); 15713 15714 var $dialog = $('<div />', { style: 'text-align:left;' }) 15715 .append($form) 15716 .dialog({ 15717 width: 320, 15718 autoOpen: true, 15719 modal: true, 15720 resizable: false, 15721 draggable: false, 15722 beforeClose: function (event, ui) { 15723 event.stopPropagation(); 15724 }, 15725 title: 'Lähetä lasku sähköpostitse', 15726 buttons: { 15727 Peruuta: function () { 15728 $(this).dialog('close'); 15729 }, 15730 'Lähetä lasku': function () { 15731 $form.submit(); 15732 }, 15733 }, 15734 }); 15735 }, //send_invoice_by_email 15736 15737 send_invoice_copy_by_sms: function (invoiceId, phone) { 15738 var $form = $('<form />').append( 15739 $('<p />').html('Anna puhelinnumero'), 15740 $('<input />', { type: 'text', name: 'toSms', id: 'toSms', class: 'text medium' }).val( 15741 phone 15742 ) 15743 ); 15744 15745 $form.submit(function (e) { 15746 e.preventDefault(); 15747 var phone = document.getElementById('toSms').value; 15748 var data = { 15749 phone: phone, 15750 invoiceId: invoiceId, 15751 }; 15752 15753 global.showLoadingDialog('Lähetetään laskukopiota...'); 15754 15755 $.ajax({ 15756 url: '/ajax/send_invoice_copy_by_sms/', 15757 dataType: 'json', 15758 type: 'POST', 15759 data: data, 15760 }) 15761 .done(function (responseJSON) { 15762 $dialog.dialog('close'); 15763 global.show_message(responseJSON); 15764 global.close_loading_dialog(); 15765 }) 15766 .fail(function (response) { 15767 var responseJSON = $.parseJSON(response.responseText); 15768 global.close_loading_dialog(); 15769 global.show_message(responseJSON); 15770 }); 15771 }); 15772 15773 var $dialog = $('<div />', { style: 'text-align:left;' }) 15774 .append($form) 15775 .dialog({ 15776 width: 320, 15777 autoOpen: true, 15778 modal: true, 15779 resizable: false, 15780 draggable: false, 15781 beforeClose: function (event, ui) { 15782 event.stopPropagation(); 15783 }, 15784 close: function () { 15785 $(this).dialog('destroy'); 15786 $(this).remove(); 15787 }, 15788 title: 'Lähetä laskukopio sms viestinä', 15789 buttons: { 15790 Peruuta: function () { 15791 $(this).dialog('close'); 15792 }, 15793 'Lähetä lasku': function () { 15794 $form.submit(); 15795 }, 15796 }, 15797 }); 15798 }, 15799 send_invoice_copy_by_email: function (invoice_id, email) { 15800 var $form = $('<form />').append( 15801 $('<p />').html('Anna sähköpostiosoite'), 15802 $('<input />', { type: 'text', name: 'toEmail', id: 'toEmail', class: 'text medium' }).val( 15803 email 15804 ) 15805 ); 15806 15807 $form.submit(function (e) { 15808 //Get the data from the form element 15809 var data = _.object( 15810 $form.serializeArray().map(function (v) {
15811 return [v.name, v.value]; 15812 }) 15813 ); 15814 15815 //Add some extra data 15816 _.extend(data, { invoiceId: invoice_id }); 15817 15818 e.preventDefault(); 15819 15820 global.showLoadingDialog('Lähetetään laskukopiota...'); 15821 15822 $.ajax({ 15823 url: '/ajax/send_invoice_copy_by_email/', 15824 dataType: 'json', 15825 type: 'POST', 15826 data: data, 15827 }) 15828 .done(function (responseJSON) { 15829 $dialog.dialog('close'); 15830 global.show_message(responseJSON); 15831 global.close_loading_dialog(); 15832 }) 15833 .fail(function (response) { 15834 var responseJSON = $.parseJSON(response.responseText); 15835 15836 // console.log('fail:', response); 15837 // console.log($.parseJSON(response.responseText)); 15838 global.close_loading_dialog(); 15839 global.show_message(responseJSON); 15840 }); 15841 }); 15842 15843 var $dialog = $('<div />', { style: 'text-align:left;' }) 15844 .append($form) 15845 .dialog({ 15846 width: 320, 15847 autoOpen: true, 15848 modal: true, 15849 resizable: false, 15850 draggable: false, 15851 beforeClose: function (event, ui) { 15852 event.stopPropagation(); 15853 }, 15854 title: 'Lähetä laskukopio sähköpostitse', 15855 buttons: { 15856 Peruuta: function () { 15857 $(this).dialog('close'); 15858 }, 15859 'Lähetä lasku': function () { 15860 $form.submit(); 15861 }, 15862 }, 15863 }); 15864 }, //send_invoice_copy_by_email 15865 15866 send_credit_note_copy_by_email: function (invoice_id, email) { 15867 var $form = $('<form />').append( 15868 $('<p />').html('Anna sähköpostiosoite'), 15869 $('<input />', { type: 'text', name: 'toEmail', id: 'toEmail', class: 'text medium' }).val( 15870 email 15871 ) 15872 ); 15873 15874 $form.submit(function (e) { 15875 //Get the data from the form element 15876 var data = _.object( 15877 $form.serializeArray().map(function (v) { 15878 return [v.name, v.value]; 15879 }) 15880 ); 15881 15882 //Add some extra data 15883 _.extend(data, { invoiceId: invoice_id }); 15884 15885 e.preventDefault(); 15886 15887 global.showLoadingDialog('Lähetetään hyvityslaskua...'); 15888 15889 $.ajax({ 15890 url: '/ajax/send_invoice_copy_by_email/', 15891 dataType: 'json', 15892 type: 'POST', 15893 data: data, 15894 }) 15895 .done(function (responseJSON) { 15896 $dialog.dialog('close'); 15897 global.show_message(responseJSON); 15898 global.close_loading_dialog(); 15899 }) 15900 .fail(function (response) { 15901 var responseJSON = $.parseJSON(response.responseText); 15902 15903 // console.log('fail:', response); 15904 // console.log($.parseJSON(response.responseText)); 15905 global.close_loading_dialog(); 15906 global.show_message(responseJSON); 15907 }); 15908 }); 15909 15910 var $dialog = $('<div />', { style: 'text-align:left;' }) 15911 .append($form) 15912 .dialog({ 15913 width: 320, 15914 autoOpen: true, 15915 modal: true, 15916 resizable: false, 15917 draggable: false, 15918 beforeClose: function (event, ui) { 15919 event.stopPropagation(); 15920 }, 15921 title: 'Lähetä laskukopio sähköpostitse', 15922 buttons: { 15923 Peruuta: function () { 15924 $(this).dialog('close'); 15925 }, 15926 'Lähetä lasku': function () { 15927 $form.submit(); 15928 }, 15929 }, 15930 }); 15931 }, //send_invoice_copy_by_email 15932 15933 send_invoice_copy: function (invoice_id, email) { 15934 $('<div></div>') 15935 .append( 15936 $('<p />', {}).append( 15937 $('<strong />', {}).html('Laskun tila:'), 15938 $('<br />'), 15939 $('<input />', { 15940 name: 'invoice_status', 15941 id: 'invoice_status_current', 15942 type: 'radio', 15943 value: 'current', 15944 checked: 'checked', 15945 }), 15946 $('<label />', { 15947 for: 'invoice_status_current', 15948 style: 'display:inline; float:none;', 15949 }).html('Nykyinen'), 15950 $('<br />'), 15951 $('<input />', { 15952 name: 'invoice_status', 15953 id: 'invoice_status_original', 15954 type: 'radio', 15955 value: 'original', 15956 }), 15957 $('<label />', { 15958 for: 'invoice_status_original', 15959 style: 'display:inline; float:none;', 15960 }).html('Alkuperäinen') 15961 ), 15962 $('<p />', {}).append( 15963 $('<strong />', {}).html('Laskun toimitus:'), 15964 $('<br />'), 15965 $('<input />', { 15966 name: 'invoice_status', 15967 id: 'invoice_status_current', 15968 type: 'radio', 15969 value: 'current', 15970 checked: 'checked', 15971 }), 15972 $('<label />', { 15973 for: 'invoice_status_current', 15974 style: 'display:inline; float:none;', 15975 }).html('Nykyinen'), 15976 $('<br />'), 15977 $('<input />', { 15978 name: 'invoice_status', 15979 id: 'invoice_status_original', 15980 type: 'radio', 15981 value: 'original', 15982 }), 15983 $('<label />', { 15984 for: 'invoice_status_original', 15985 style: 'display:inline; float:none;', 15986 }).html('Alkuperäinen') 15987 ) 15988 ) 15989 .dialog({ 15990 autoOpen: true, 15991 modal: true, 15992 resizable: false, 15993 draggable: false, 15994 title: 'Valitse PDF-laskun asetukset', 15995 beforeClose: function (event, ui) { 15996 event.stopPropagation(); 15997 }, 15998 buttons: { 15999 Sulje: function () { 16000 $(this).dialog('close'); 16001 }, 16002 'Lataa PDF-tiedosto': function () {
16003 var invoice_status = $(this).find('input:radio[name=invoice_status]:checked').val(); 16004 var envelope_window_size = $(this) 16005 .find('input:radio[name=envelope_window_size]:checked') 16006 .val(); 16007 window.location = 16008 'iv_laskutus_ja_reskontra/get_pdf_invoice/' + 16009 invoice_id + 16010 '/' + 16011 invoice_status + 16012 '/' + 16013 envelope_window_size + 16014 '/download'; 16015 }, 16016 }, 16017 }); 16018 16019 var $form = $('<form />').append( 16020 $('<p />').html('Anna sähköpostiosoite'), 16021 $('<input />', { type: 'text', name: 'toEmail', id: 'toEmail', class: 'text medium' }).val( 16022 email 16023 ) 16024 ); 16025 16026 $form.submit(function (e) { 16027 //Get the data from the form element 16028 var data = _.object( 16029 $form.serializeArray().map(function (v) { 16030 return [v.name, v.value]; 16031 }) 16032 ); 16033 16034 //Add some extra data 16035 _.extend(data, { invoiceId: invoice_id }); 16036 16037 e.preventDefault(); 16038 16039 global.showLoadingDialog('Lähetetään laskukopiota...'); 16040 16041 $.ajax({ 16042 url: '/ajax/send_invoice_copy_by_email/', 16043 dataType: 'json', 16044 type: 'POST', 16045 data: data, 16046 }) 16047 .done(function (responseJSON) { 16048 $dialog.dialog('close'); 16049 global.show_message(responseJSON); 16050 global.close_loading_dialog(); 16051 }) 16052 .fail(function (response) { 16053 var responseJSON = $.parseJSON(response.responseText); 16054 16055 // console.log('fail:', response); 16056 // console.log($.parseJSON(response.responseText)); 16057 global.close_loading_dialog(); 16058 global.show_message(responseJSON); 16059 }); 16060 }); 16061 16062 var $dialog = $('<div />', { style: 'text-align:left;' }) 16063 .append($form) 16064 .dialog({ 16065 width: 320, 16066 autoOpen: true, 16067 modal: true, 16068 resizable: false, 16069 draggable: false, 16070 beforeClose: function (event, ui) { 16071 event.stopPropagation(); 16072 }, 16073 title: 'Lähetä laskukopio sähköpostitse', 16074 buttons: { 16075 Peruuta: function () { 16076 $(this).dialog('close'); 16077 }, 16078 'Lähetä lasku': function () { 16079 $form.submit(); 16080 }, 16081 }, 16082 }); 16083 }, //send_invoice_copy 16084 16085 show_edit_invoice_status_dialog: function (invoice_id) { 16086 var d = new Date(); 16087 16088 var $edit_invoice_status_dialog = $('<div></div>'); 16089 16090 $edit_invoice_status_dialog 16091 .append( 16092 $('<label />', {}) 16093 .html('Uusi tila:') 16094 .append( 16095 $('<select />', { name: 'invoice_status', id: 'invoice_status' }).append( 16096 $('<option />', { value: 'sent' }).html('Avoin'), 16097 $('<option />', { value: 'credited' }).html('Hyvitetty'), 16098 $('<option />', { value: 'money_transferred' }).html('Tilitetty') 16099 ) 16100 ) 16101 ) 16102 .dialog({ 16103 width: 400, 16104 height: 350, 16105 autoOpen: true, 16106 modal: true, 16107 resizable: false, 16108 draggable: false, 16109 open: function () { 16110 $(this).find('#invoice_status').selectpicker(); 16111 }, 16112 title: 'Muuta laskun tila', 16113 beforeClose: function (event, ui) { 16114 event.stopPropagation(); 16115 }, 16116 buttons: { 16117 Peruuta: function () { 16118 $(this).dialog('close'); 16119 }, 16120 Tallenna: function () { 16121 var new_status = $(this).find('#invoice_status').val(); 16122 16123 if (new_status === 'paid_to_customer') { 16124 var $paid_to_customer_date_dialog = $('<div></div>'); 16125 var $paid_to_customer_datepicker = $( 16126 '<input type="text" class="text small" id="paid_to_customer_date" name="paid_to_customer_date" value="' + 16127 d.getDate() + 16128 '.' + 16129 (d.getMonth() + 1) + 16130 '.' + 16131 d.getFullYear() + 16132 '" />' 16133 ); 16134 16135 $paid_to_customer_date_dialog 16136 .append( 16137 $( 16138 '<label style="width:280px;" id="paid_to_customer_date_label" for="paid_to_customer_date">Päiväämärä jolloin lasku on suoritettu asiakkaalle</label>' 16139 ), 16140 $paid_to_customer_datepicker.datepicker($.datepicker.regional.fi) 16141 ) 16142 .dialog({ 16143 width: 320, 16144 height: 240, 16145 autoOpen: true, 16146 modal: true, 16147 resizable: false, 16148 draggable: false, 16149 title: 'Anna ohisuorituksen päivämäärä', 16150 beforeClose: function (event, ui) { 16151 event.stopPropagation(); 16152 }, 16153 buttons: { 16154 Peruuta: function () { 16155 $paid_to_customer_date_dialog.dialog('destroy'); 16156 }, 16157 Hyväksy: function () { 16158 var send_credit_invoice_to_customer = +$paid_to_customer_date_dialog 16159 .find('#send_credit_invoice_to_customer') 16160 .is(':checked'); 16161 var selectedDate = new Date( 16162 $paid_to_customer_datepicker.datepicker('getDate').getTime() 16163 ); 16164 var datestr = 16165 selectedDate.getFullYear() +
16166 '-' + 16167 (selectedDate.getMonth() + 1) + 16168 '-' + 16169 selectedDate.getDate(); 16170 pages.iv_laskutus_ja_reskontra.update_invoice_status( 16171 invoice_id, 16172 new_status, 16173 datestr, 16174 send_credit_invoice_to_customer 16175 ); 16176 $paid_to_customer_date_dialog.dialog('destroy'); 16177 $edit_invoice_status_dialog.dialog('close'); 16178 }, 16179 }, 16180 }); 16181 } else { 16182 pages.iv_laskutus_ja_reskontra.update_invoice_status(invoice_id, new_status); 16183 $(this).dialog('close'); 16184 } 16185 }, 16186 }, 16187 }); 16188 }, 16189 16190 update_invoice_status: function ( 16191 invoice_id, 16192 new_status, 16193 date, 16194 send_credit_invoice_to_customer 16195 ) { 16196 $.ajax({ 16197 dataType: 'json', 16198 type: 'POST', 16199 url: 'iv_laskutus_ja_reskontra/update_invoice_status/', 16200 data: { 16201 invoice_id: invoice_id, 16202 new_status: new_status, 16203 date: date, 16204 send_credit_invoice_to_customer: send_credit_invoice_to_customer, 16205 }, 16206 16207 beforeSend: function (request) { 16208 global.showLoadingDialog('Vaihdetaan laskun tilaa'); 16209 }, 16210 success: function (responseJSON) { 16211 global.close_loading_dialog(); 16212 16213 //Refresh the datatables 16214 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 16215 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 16216 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 16217 } 16218 16219 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 16220 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 16221 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 16222 } 16223 16224 //Refresh the invoice dialog 16225 global.show_message(responseJSON); 16226 16227 LaskutusJaReskontra.showInvoiceDialog({ 16228 invoiceId: invoice_id, 16229 }); 16230 }, 16231 error: function (data) { 16232 global.show_message($.parseJSON(data.responseText)); 16233 global.close_loading_dialog(); 16234 }, 16235 }); 16236 }, 16237 16238 init_show_money_transfer: function (money_transfer_id) { 16239 $('#money-transfer-items-tabs').tabs(); 16240 16241 $('#money_transfers_form').submit(function () { 16242 $(this).ajaxSubmit({ 16243 type: 'post', 16244 dataType: 'json', 16245 //show the loading message 16246 beforeSubmit: function () { 16247 global.showLoadingDialog('Merkitään tilityksiä...'); 16248 }, 16249 16250 success: function (responseJSON, statusText, xhr, $form) { 16251 if (responseJSON.type === 'success') { 16252 //Refresh the datatable and the dialog close the dialog 16253 dialogs.refresh(); 16254 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnClearTable(0); 16255 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnDraw(); 16256 } 16257 16258 global.show_message(responseJSON); 16259 global.close_loading_dialog(); 16260 }, 16261 error: function (data) { 16262 global.close_loading_dialog(); 16263 }, 16264 }); 16265 16266 return false; 16267 }); 16268 16269 $('#mark_money_transfers') 16270 .button({ icons: { primary: 'ui-icon-check' } }) 16271 .on('click', function () { 16272 $('#money_transfers_form').attr('action', 'tilitykset/mark_items_accepted_for_transfer'); 16273 $('#money_transfers_form').submit(); 16274 }); 16275 16276 $('#process_money_transfers') 16277 .button({ icons: { primary: 'ui-icon-check' } }) 16278 .on('click', function () { 16279 $('#money_transfers_form').attr('action', 'tilitykset/mark_items_transferred'); 16280 $('#money_transfers_form').submit(); 16281 }); 16282 16283 $('#execute_accepted_transfers') 16284 .button({ icons: { primary: 'ui-icon-check' } }) 16285 .on('click', function () { 16286 pages.iv_laskutus_ja_reskontra.execute_accepted_money_transfers(money_transfer_id); 16287 }); 16288 16289 $('#add_invoice_to_money_transfer') 16290 .button({ icons: { primary: 'ui-icon-refresh' } }) 16291 .on('click', function () { 16292 $('<div></div>') 16293 .html('Syötä laskun ID jonka haluat lisättävän t
16293ilitettäväksi') 16294 .dialog({ 16295 autoOpen: true, 16296 modal: true, 16297 resizable: false, 16298 draggable: false, 16299 title: 'Lisää yksittäinen lasku tilitykseen', 16300 beforeClose: function (event, ui) { 16301 event.stopPropagation(); 16302 }, 16303 buttons: { 16304 Peruuta: function () { 16305 $(this).dialog('close'); 16306 }, 16307 Lisää: function () { 16308 $(this).dialog('close'); 16309 pages.iv_laskutus_ja_reskontra.add_invoice_to_money_transfer( 16310 money_transfer_id, 16311 invoice_id 16312 ); 16313 }, 16314 }, 16315 }); 16316 }); 16317 16318 $('#refresh_money_transfer') 16319 .button({ icons: { primary: 'ui-icon-refresh' } }) 16320 .on('click', function () { 16321 $('<div></div>') 16322 .html( 16323 'Haluatko varmasti päivittää tilitysten tiedot? <br/><br/>Vähennykset sekä IBAN tieto haetaan uudestaan' 16324 ) 16325 .dialog({ 16326 autoOpen: true, 16327 modal: true, 16328 resizable: false, 16329 draggable: false, 16330 title: 'Päivitä tilitysten tiedot', 16331 beforeClose: function (event, ui) { 16332 event.stopPropagation(); 16333 }, 16334 buttons: { 16335 Peruuta: function () { 16336 $(this).dialog('close'); 16337 }, 16338 Päivitä: function () { 16339 $(this).dialog('close'); 16340 pages.iv_laskutus_ja_reskontra.refresh_money_transfer(money_transfer_id); 16341 }, 16342 }, 16343 }); 16344 }); 16345 16346 $('#money_transfer_items .copy_to_clipboard').on('click', function (e) { 16347 e.preventDefault(); 16348 var bank_barcode = $(this).attr('href'); 16349 window.prompt('Kopioi pankkiviivakoodi ja paina ok', bank_barcode); 16350 }); 16351 16352 $('#money_transfer_items .toggle_invoices').on('click', function (e) { 16353 e.preventDefault(); 16354 $(this).parents('tr').next().toggle(); 16355 }); 16356 16357 $('#money_transfer_items .toggle_service_charges').on('click', function (e) { 16358 e.preventDefault(); 16359 $(this).parents('tr').next().next().toggle(); 16360 }); 16361 16362 $('#money_transfer_items .toggle').on('click', function (e) { 16363 e.preventDefault(); 16364 $link = $(this); 16365 16366 checked = $link.hasClass('checked'); 16367 16368 if (!checked) { 16369 checked = true; 16370 $link.addClass('checked'); 16371 } else { 16372 checked = false; 16373 $link.removeClass('checked'); 16374 } 16375 16376 var col_index = $link.parents('th').index(); 16377 16378 $link 16379 .parents('table') 16380 .find('tbody tr') 16381 .each(function (i, e) { 16382 $(e) 16383 .find('td:eq(' + col_index + ') input') 16384 .prop('checked', checked); 16385 }); 16386 }); 16387 16388 $('#money_transfer_items .check_all').on('click', function (e) { 16389 e.preventDefault(); 16390 $link = $(this); 16391 16392 var col_index = $link.parents('th').index(); 16393 16394 $link 16395 .parents('table') 16396 .find('tbody tr') 16397 .each(function (i, e) { 16398 $(e) 16399 .find('td:eq(' + col_index + ') input') 16400 .prop('checked', true); 16401 }); 16402 16403 $link.removeClass('check_all').addClass('uncheck_all'); 16404 }); 16405 }, //init_show_invoice 16406 16407 refresh_money_transfer: function (money_transfer_id) { 16408 $.ajax({ 16409 processData: false, 16410 dataType: 'json', 16411 type: 'GET', 16412 url: 'ajax/refresh_money_transfer/' + money_transfer_id + '/', 16413 beforeSend: function (request) { 16414 global.showLoadingDialog('Päivitetään tilityksiä...'); 16415 }, 16416 success: function (responseJSON) { 16417 global.close_loading_dialog(); 16418 global.show_message(responseJSON); 16419 dialogs.refresh(); 16420 }, 16421 }); 16422 }, 16423 16424 create_money_transfer_from_invoices: function (invoices) { 16425 $.ajax({ 16426 processData: false, 16427 dataType: 'json', 16428 type: 'POST', 16429 url: 16430 'ajax/create_money_transfer_from_invoices/' + money_transfer_id + '/' + invoice_id + '/', 16431 beforeSend: function (request) { 16432 global.showLoadingDialog('Lisätään laskua tilitykseen...'); 16433 }, 16434 success: function (responseJSON) { 16435 global.close_loading_dialog(); 16436 global.show_message(responseJSON); 16437 dialogs.refresh(); 16438 }, 16439 }); 16440 }, 16441 16442 show_invoice_log: function (invoice_id) { 16443 var $dialog = $('<div />'); 16444 16445 if (invoice_id.length > 0) { 16446 $.ajax({ 16447 processData: false, 16448 dataType: 'html', 16449 type: 'GET', 16450 url: 'reskontra/get_invoice_log_html/' + invoice_id + '/', 16451 beforeSend: function (request) { 16452 $dialog.dialog({ 16453 width: 650, 16454 height: 450, 16455 title: 'Laskun tapahtumaloki', 16456 buttons: { 16457 'Lisää muistiinpano': function() { 16458 pages.iv_laskutus_ja_reskontra.add_log_item(invoice_id); 16459 }, 16460 }, 16461 close: function (e) { 16462 e.stopPropagation(); 16463 $('div#logs').remove(); 16464 $('div#convo').remove(); 16465 $dialog.dialog('destroy'); 16466 $dialog.remove(); 16467 }, 16468 }); 16469 global.show_ajax_loader($dialog); 16470 }, 16471 success: function (response) { 16472 $dialog.html(response); 16473 // Tabs for tought. 16474 $('.invoiceLogTabs').tabs(); 16475 $('div#convo article').each(function (index, article) { 16476 $('button.showTicket:first').addClass('active'); 16477 if (index > 0) { 16478 $(article).addClass('ticket-hidden'); 16479 } 16480 }); 16481 16482 $( 16483 "span:contains('This e-mail and any attachment may contain confidential and/or proprietary information')" 16484 ).addClass('trash'); 16485 $( 16486 "span:contains('immediately and destroy this e-mail and all of the contained information.')" 16487 ).addClass('trash'); 16488 $( 16489 "span:contains('arvato Financial Solutions is a global financial service provider')" 16490 ).addClass('trash'); 16491 $("span:contains('22 countries, including a strong presence in Europe')").addClass( 16492 'trash' 16493 ); 16494 $("span:contains('cash flow in all phases of the customer lifecycle')").addClass( 16495 'trash' 16496 ); 16497 $( 16498 "span:contains('customers making us Europeâs third largest integrated financial service provider')" 16499 ).addClass('trash'); 16500 $("span:contains('---------------------------------')").addClass('trash'); 16501 $( 16502 "span:contains('Gothia Financial Group is a part of the German company arvato
16502infoscore')" 16503 ).addClass('trash'); 16504 $("span:contains('Follow us on â¢')").parent().addClass('trash'); 16505 //$('span:blank').remove(); 16506 //$('div:blank').remove(); 16507 16508 //Add special click handler to show towing record popup instead of redirecting user to towing record page 16509 $dialog.on('click', 'a.show_towing_record', function (e) { 16510 e.preventDefault(); 16511 $dialog.dialog('close'); 16512 var url = $(this).data('url'); 16513 console.log('show_towing_record', url); 16514 kuormakirjat.show_towing_record(url); 16515 }); 16516 }, 16517 }); 16518 } 16519 }, //show_invoice_log 16520 16521 show_part_payment: function (part_payment_id) { 16522 // global.$dialog = $('<div />', {}); 16523 // var $dialog = global.$dialog; 16524 16525 // if ($dialog.hasClass('ui-dialog-content')) { 16526 // $dialog.dialog('destroy'); 16527 // } 16528 var $dialog = global.getGlobalDialogAndEmptyIfHasContent(); 16529 16530 $.ajax({ 16531 processData: false, 16532 dataType: 'html', 16533 type: 'GET', 16534 url: 'osamaksu/get_part_payment_dialog/' + part_payment_id + '/', 16535 beforeSend: function (request) { 16536 $dialog.dialog({ 16537 width: 800, 16538 height: 600, 16539 modal: true, 16540 resizable: false, 16541 title: 'Osamaksusopimuksen tiedot', 16542 close: function () { 16543 $dialog.dialog('close'); 16544 }, 16545 }); 16546 global.show_ajax_loader($dialog); 16547 }, 16548 success: function (response) { 16549 $dialog.html(response); 16550 /* 16551 $(this).delegate(':button','click',function(){ 16552 $(this).data({'invoice_id': invoice_id, 'open_sum':open_sum}); 16553 }); 16554 */ 16555 }, 16556 }); 16557 }, //show_part_payment 16558 16559 init_part_payment_dialog: function (part_payment_id) { 16560 $('#accept_for_money_transfer') 16561 .button({ icons: { primary: 'ui-icon-check' } }) 16562 .on('click', function () { 16563 $('<div></div>') 16564 .html( 16565 '<p>Haluatko varmasti hyväksyä osamaksusopimuksen tilitettäväksi?</p><p>Osamaksusopimus siirtyy tilityksiin heti kun kyseisen sopimuksen rahoituksen ehdot ovat täyttyneet ja suoritteet saapuneet Gothialta.</p>' 16566 ) 16567 .dialog({ 16568 width: 400, 16569 autoOpen: true, 16570 modal: true, 16571 resizable: false, 16572 draggable: false, 16573 title: 'Hyväksy osamaksusopimus tilitettäväksi', 16574 beforeClose: function (event, ui) { 16575 event.stopPropagation(); 16576 }, 16577 buttons: { 16578 Peruuta: function () { 16579 $(this).dialog('close'); 16580 }, 16581 Hyväksy: function () { 16582 $(this).dialog('close'); 16583 pages.iv_laskutus_ja_reskontra.accept_for_money_transfer(part_payment_id); 16584 }, 16585 }, 16586 }); 16587 }); 16588 16589 $('#create_part_payment_invoice') 16590 .button({ icons: { primary: 'ui-icon-plusthick' } }) 16591 .on('click', function () { 16592 $('<div></div>') 16593 .html('Haluatko varmasti luoda tililaskun?') 16594 .dialog({ 16595 autoOpen: true, 16596 modal: true, 16597 resizable: false, 16598 draggable: false, 16599 title: 'Luo tililasku', 16600 beforeClose: function (event, ui) { 16601 event.stopPropagation(); 16602 }, 16603 close: function () { 16604 $(this).dialog('destroy'); 16605 $(this).remove(); 16606 }, 16607 buttons: { 16608 Peruuta: function () { 16609 $(this).dialog('close'); 16610 }, 16611 'Luo tililasku': function () { 16612 $(this).dialog('close'); 16613 pages.iv_laskutus_ja_reskontra.create_part_payment_invoice(part_payment_id); 16614 }, 16615 }, 16616 }); 16617 }); 16618 16619 $('#create_down_payment_invoice') 16620 .button({ icons: { primary: 'ui-icon-plusthick' } }) 16621 .on('click', function () { 16622 $('<div></div>') 16623 .html('Haluatko varmasti luoda käsirahalaskun') 16624 .dialog({ 16625 autoOpen: true, 16626 modal: true, 16627 resizable: false, 16628 draggable: false, 16629 title: 'Luo käsirahalasku', 16630 beforeClose: function (event, ui) { 16631 event.stopPropagation(); 16632 }, 16633 close: function () { 16634 $(this).dialog('destroy'); 16635 $(this).remove(); 16636 }, 16637 buttons: { 16638 Peruuta: function () { 16639 $(this).dialog('close'); 16640 }, 16641 'Luo käsirahalasku': function () { 16642 $(this).dialog('close'); 16643 pages.iv_laskutus_ja_reskontra.create_down_payment_invoice(part_payment_id); 16644 }, 16645 }, 16646 }); 16647 }); 16648 16649 $('#approve_application') 16650 .button({ icons: { primary: 'ui-icon-check' } }) 16651 .on('click', function () { 16652 $('<div></div>') 16653 .html('Haluatko varmasti hyväksyä osamaksusopimuksen') 16654 .dialog({ 16655 autoOpen: true, 16656 modal: true, 16657 resizable: false, 16658 draggable: false, 16659 title: 'Hyväksy osamaksusopimus', 16660 beforeClose: function (event, ui) { 16661 event.stopPropagation(); 16662 }, 16663 close: function () { 16664 $(this).dialog('destroy'); 16665 $(this).remove(); 16666 }, 16667 buttons: { 16668 Peruuta: function () { 16669 $(this).dialog('close'); 16670 }, 16671 'Hyväksy osamaksusopimus': function () { 16672 $(this).dialog('close'); 16673 pages.iv_laskutus_ja_reskontra.approve_part_payment_application(part_payment_id); 16674 }, 16675 }, 16676 }); 16677 }); 16678 16679 $('#decline_application') 16680 .button({ icons: { primary: 'ui-icon-close' } }) 16681 .on('click', function () { 16682 $('<div></div>') 16683 .append( 16684 $('<label />', { style: 'width:auto;' }) 16685 .html('Syy hylkäämiselle') 16686 .append( 16687 $('<textarea />', { style: 'width:240px; height:36px;', name: 'decline_reason' }) 16688 ) 16689 ) 16690 .dialog({ 16691 autoOpen: true, 16692 modal: true, 16693 resizable: false, 16694 draggable: false, 16695 title: 'Hylkää osamaksusopimus', 16696 beforeClose: function (event, ui) { 16697 event.stopPropagation(); 16698 }, 16699 close: function () { 16700 $(this).dialog('destroy'); 16701 $(this).remove(); 16702 }, 16703 buttons: { 16704 Peruuta: function () { 16705 $(this).dialog('close'); 16706 }, 16707 'Hylkää sopimus': function () { 16708 $(this).dialog('close'); 16709 var decline_reason = $(this).find('textarea[name=decline_reason]').val(); 16710 pages.iv_laskutus_ja_reskontra.decline_part_payment_contract( 16711 part_payment_id, 16712 decline_reason 16713 ); 16714 }, 16715 }, 16716 }); 16717 }); 16718 16719 $('#cancel_contract') 16720 .button({ icons: { primary: 'ui-icon-close' } }) 16721 .on('click', function () { 16722 $('<div></div>') 16723 .append( 16724 $('<label />', { style: 'width:auto;' }) 16725 .html('Syy peruuttamiselle') 16726 .append( 16727 $('<textarea />', { style: 'width:240px; height:36px;', name: 'cancel_reason' }) 16728 ) 16729 ) 16730 .dialog({ 16731 autoOpen: true, 16732 modal: true, 16733 resizable: false, 16734 draggable: false, 16735 title: 'Peruuta osamaksusopimus', 16736 beforeClose: function (event, ui) { 16737 event.stopPropagation(); 16738 }, 16739 close: function () { 16740 $(this).dialog('destroy'); 16741 $(this).remove(); 16742 }, 16743 buttons: { 16744 Poistu: function () { 16745 $(this).dialog('close'); 16746 }, 16747 'Peruuta sopimus': function () { 16748 $(this).dialog('close'); 16749 var cancel_reason = $(this).find('textarea[name=cancel_reason]').val(); 16750 pages.iv_laskutus_ja_reskontra.cancel_part_payment_contract( 16751 part_payment_id, 16752 cancel_reason 16753 ); 16754 }, 16755 }, 16756 }); 16757 }); 16758 16759 $('#delete_contract') 16760 .button({ icons: { primary: 'ui-icon-trash' } }) 16761 .on('click', function () { 16762 $('<div></div>') 16763 .html('Haluatko varmasti poistaa osamaksusopimuksen?') 16764 .dialog({ 16765 autoOpen: true, 16766 modal: true, 16767 resizable: false, 16768 draggable: false, 16769 title: 'Poista osamaksusopimus', 16770 beforeClose: function (event, ui) { 16771 event.stopPropagation(); 16772 }, 16773 close: function () { 16774 $(this).dialog('destroy'); 16775 $(this).remove(); 16776 }, 16777 buttons: { 16778 Peruuta: function () { 16779 $(this).dialog('close'); 16780 }, 16781 'Poista sopimus': function () { 16782 pages.iv_laskutus_ja_reskontra.delete_part_payment_contract(part_payment_id); 16783 $(this).dialog('close'); 16784 }, 16785 }, 16786 }); 16787 }); 16788 16789 $('#convert_to_invoice') 16790 .button({ icons: { primary: 'ui-icon-transferthick-e-w' } }) 16791 .on('click', function () { 16792 $('<div></div>') 16793 .html('Haluatko varmasti muuntaa osamaksusopimuksen laskuksi?') 16794 .append( 16795 '<br/><br/><input id="addCancellationFee" type="checkbox" name="addCancellationFee" value="1" disabled="disabled"><span>Lisää peruutuskulu laskulle</span>' 16796 ) 16797 .dialog({ 16798 autoOpen: true, 16799 modal: true, 16800 resizable: false, 16801 draggable: false, 16802 title: 'Muunna osamaksusopimus laskuksi', 16803 beforeClose: function (event, ui) { 16804 event.stopPropagation(); 16805 }, 16806 close: function () { 16807 $(this).dialog('destroy'); 16808 $(this).remove(); 16809 }, 16810 buttons: { 16811 Peruuta: function () { 16812 $(this).dialog('close'); 16813 }, 16814 'Muunna sopimus': function () { 16815 var addCancellationFee = +$(this).find('#addCancellationFee').is(':checked'); 16816 16817 $(this).dialog('close'); 16818 pages.iv_laskutus_ja_reskontra.convert_part_payment_contract_to_invoice( 16819 part_payment_id, 16820 addCancellationFee 16821 ); 16822 }, 16823 }, 16824 }); 16825 }); 16826 16827 $('#accept_customer_account_terms') 16828 .button({ icons: { primary: 'ui-icon-check' } }) 16829 .on('click', function () { 16830 $('<div></div>') 16831 .html('Haluatko varmasti merkitä asiakkaan Rivertyn tiliehdot hyväksytyksi?') 16832 .append( 16833 $('<label />', { style: 'width:auto;' }) 16834 .html('Selite hyväksynnälle') 16835 .append( 16836 $('<textarea />', { 16837 style: 'width:320px; height:60px;', 16838 name: 'acceptance_description', 16839 }) 16840 ) 16841 ) 16842 .dialog({ 16843 width: 360, 16844 autoOpen: true, 16845 modal: true, 16846 resizable: false, 16847 draggable: false, 16848 title: 'Merkitse Rivertyn tiliehdot hyväksytyksi', 16849 beforeClose: function (event, ui) { 16850 event.stopPropagation(); 16851 }, 16852 close: function () { 16853 $(this).dialog('destroy'); 16854 $(this).remove(); 16855 }, 16856 buttons: { 16857 Peruuta: function () { 16858 $(this).dialog('close'); 16859 }, 16860 'Merkitse hyväksytyksi': function () { 16861 var acceptanceDescription = $(this) 16862 .find('textarea[name=acceptance_description]') 16863 .val(); 16864 16865 $(this).dialog('close'); 16866 global.showLoadingDialog('Merkitään tiliehtoja hyväksytyksi...'); 16867 16868 var data = { 16869 part_payment_id: part_payment_id, 16870 acceptance_description: acceptanceDescription, 16871 }; 16872 $.ajax({ 16873 url: 'osamaksu/accept_customer_account_Terms/', 16874 type: 'post', 16875 data: data, 16876 success: function (resp) { 16877 global.close_loading_dialog(); 16878 global.show_message(resp); 16879 }, 16880 }); 16881 }, 16882 }, 16883 }); 16884 }); 16885 16886 $('#add_log_item') 16887 .button({ icons: { primary: 'ui-icon-plusthick' } }) 16888 .on('click', function () { 16889 $('<div></div>') 16890 .append( 16891 $('<label />', { style: 'width:auto;' }) 16892 .html('Lokitapahtuma') 16893 .append( 16894 $('<textarea />', { style: 'width:320px; height:60px;', name: 'log_event' }) 16895 ) 16896 ) 16897 .dialog({ 16898 width: 360, 16899 autoOpen: true, 16900 modal: true, 16901 resizable: false, 16902 draggable: false, 16903 title: 'Lisää muistiinpano', 16904 beforeClose: function (event, ui) { 16905 event.stopPropagation(); 16906 }, 16907 close: function () { 16908 $(this).dialog('destroy'); 16909 $(this).remove(); 16910 }, 16911 buttons: { 16912 Peruuta: function () { 16913 $(this).dialog('close'); 16914 }, 16915 'Luo lokimerkintä': function () { 16916 $(this).dialog('close'); 16917 global.showLoadingDialog('Luodaan lokimerkintää...'); 16918 16919 var logEvent = $(this).find('textarea[name=log_event]').val(); 16920 16921 var data = { part_payment_id: part_payment_id, log_event: logEvent }; 16922 $.ajax({ 16923 url: 'osamaksu/add_log_item/', 16924 type: 'post', 16925 data: data, 16926 success: function (resp) { 16927 global.close_loading_dialog(); 16928 global.show_message(resp); 16929 }, 16930 }); 16931 }, 16932 }, 16933 }); 16934 $('button').addClass('btn btn-default'); 16935 }); 16936 16937 $('#approve_and_send_signature_invitation') 16938 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 16939 .on('click', function () { 16940 //console.log('enter_email_dialog', 5976); 16941 var customer_email = $('#customer_email').html(); 16942 var $email_input = $('<input />', { 16943 type: 'text', 16944 name: 'email', 16945 id: 'email', 16946 class: 'text medium', 16947 }).val(customer_email); 16948 $('<div />', { style: 'text-align:left;' }) 16949 .append( 16950 $('<p />').html('Syötä sähköpostiosoite minne allekirjoituskutsu lähetetään'), 16951 $email_input 16952 ) 16953 .dialog({ 16954 width: 320, 16955 autoOpen: true, 16956 modal: true, 16957 resizable: false, 16958 draggable: false, 16959 beforeClose: function (event, ui) { 16960 event.stopPropagation(); 16961 }, 16962 title: 'Hyväksy sopimus ja lähetä allekirjoituskutsu sähköpostiin', 16963 buttons: { 16964 Lähetä: function () { 16965
16965 $(this).dialog('close'); 16966 email = $email_input.val(); 16967 pages.iv_laskutus_ja_reskontra.approve_and_send_signature_invitation( 16968 part_payment_id, 16969 email 16970 ); 16971 }, 16972 Peruuta: function () { 16973 $(this).dialog('close'); 16974 }, 16975 }, 16976 }); 16977 }); 16978 16979 $('#send_signature_invitation') 16980 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 16981 .on('click', function () { 16982 //console.log('enter_email_dialog', 5976); 16983 var customer_email = $('#customer_email').html(); 16984 var $email_input = $('<input />', { 16985 type: 'text', 16986 name: 'email', 16987 id: 'email', 16988 class: 'text medium', 16989 }).val(customer_email); 16990 $('<div />', { style: 'text-align:left;' }) 16991 .append( 16992 $('<p />').html('Syötä sähköpostiosoite minne allekirjoituskutsu lähetetään'), 16993 $email_input 16994 ) 16995 .dialog({ 16996 width: 320, 16997 autoOpen: true, 16998 modal: true, 16999 resizable: false, 17000 draggable: false, 17001 beforeClose: function (event, ui) { 17002 event.stopPropagation(); 17003 }, 17004 title: 'Lähetä allekirjoituskutsu sähköpostiin', 17005 buttons: { 17006 Lähetä: function () { 17007 $(this).dialog('close'); 17008 email = $email_input.val(); 17009 pages.iv_laskutus_ja_reskontra.send_signature_invitation(part_payment_id, email); 17010 }, 17011 Peruuta: function () { 17012 $(this).dialog('close'); 17013 }, 17014 }, 17015 }); 17016 }); 17017 17018 $('#send_customer_acceptance_invitation') 17019 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 17020 .on('click', function () { 17021 //console.log('enter_email_dialog', 5976); 17022 var customer_email = $('#customer_email').html(); 17023 var $email_input = $('<input />', { 17024 type: 'text', 17025 name: 'email', 17026 id: 'email', 17027 class: 'text medium', 17028 }).val(customer_email); 17029 17030 var customer_phone = $('#customer_phone').html(); 17031 var $phone_input = $('<input />', { 17032 type: 'text', 17033 name: 'email', 17034 id: 'email', 17035 class: 'text medium', 17036 }).val(customer_phone); 17037 17038 $('<div />', { style: 'text-align:left;' }) 17039 .append( 17040 $('<p />').html( 17041 'Sähköposti ja puhelinnumero, minne linkki maksusopimuksen ja tiliehtojen hyväksyntään lähetetään' 17042 ), 17043 $('<label />', { text: 'Sähköposti' }), 17044 $email_input, 17045 $('<label />', { text: 'Puhelinnumero' }), 17046 $phone_input 17047 ) 17048 .dialog({ 17049 width: 320, 17050 autoOpen: true, 17051 modal: true, 17052 resizable: false, 17053 draggable: false, 17054 beforeClose: function (event, ui) { 17055 event.stopPropagation(); 17056 }, 17057 title: 'Lähetä maksusopimus/tiliehdot hyväksyttäväksi', 17058 buttons: { 17059 Lähetä: function () { 17060 $(this).dialog('close'); 17061 pages.iv_laskutus_ja_reskontra.send_customer_acceptance_invitation( 17062 part_payment_id, 17063 $email_input.val(), 17064 $phone_input.val() 17065 ); 17066 }, 17067 Peruuta: function () { 17068 $(this).dialog('close'); 17069 }, 17070 }, 17071 }); 17072 }); 17073 17074 $('#get_application_pdf') 17075 .button({ icons: { primary: 'ui-icon-document' } }) 17076 .on('click', function () { 17077 window.open('osamaksu/get_contract_pdf/' + part_payment_id); 17078 }); 17079 17080 $('#get_arvato_account_terms_pdf') 17081 .button({ icons: { primary: 'ui-icon-document' } }) 17082 .on('click', function () { 17083 window.open('osamaksu/get_arvato_account_terms_pdf/' + part_payment_id); 17084 }); 17085 17086 /* 17087 $('#send_towing_record_pdf_by_email').button({icons:{primary:'ui-icon-mail-closed'}}).on('click',function(){ 17088 kuormakirjat.send_towing_record_by_email(towing_record_id); 17089 }); 17090 */ 17091 17092 /* 17093 $('#send_receipt_by_email').button({icons:{primary:'ui-icon-mail-closed'}}).on('click',function(){ 17094 kuormakirjat.send_receipt_by_email(towing_record_id); 17095 }); 17096 */ 17097 }, 17098 17099 refresh_part_payment_dialog_and_datatable: function (part_payment_id) { 17100 //Refresh the datatable 17101 if (pages.iv_laskutus_ja_reskontra.$part_payments_datatable != null) { 17102 pages.iv_laskutus_ja_reskontra.$part_payments_datatable.fnClearTable(0); 17103 pages.iv_laskutus_ja_reskontra.$part_payments_datatable.fnDraw(); 17104 } 17105 17106 //Refresh the invoice dialog 17107 global.show_ajax_loader(global.$dialog); 17108 global.$dialog.load('/osamaksu/get_part_payment_dialog/' + part_payment_id + '/'); 17109 }, 17110 17111 show_direct_payment: function (direct_payment_id) { 17112 global.$dialog = $('<div />', {}); 17113 var $dialog = global.$dialog; 17114 17115 $.ajax({ 17116 processData: false, 17117 dataType: 'html', 17118 type: 'GET', 17119 url: 'ajax/get_direct_payment_dialog/' + direct_payment_id + '/', 17120 beforeSend: function (request) { 17121 $dialog.dialog({ 17122 width: 800, 17123 height: 600, 17124 modal: true, 17125 resizable: false, 17126 title: 'Korttimaksun tiedot', 17127 close: function () { 17128 $dialog.dialog('destroy'); 17129 }, 17130 }); 17131 global.show_ajax_loader($dialog); 17132 }, 17133 success: function (response) { 17134 $dialog.html(response); 17135 }, 17136 }); 17137 }, //show_direct_payment 17138 17139 init_direct_payment_dialog: function (directPaymentId) { 17140 $('#creditPayments').on('click', 'a.show_direct_payment', function (e) { 17141 e.preventDefault(); 17142 var id = $(e.target).attr('href'); 17143 pages.reskontra.show_direct_payment(id); 17144 }); 17145 $('#print_receipt_pdf') 17146 .button({ icons: { primary: 'ui-icon-document' } }) 17147 .on('click', function () {
17148 var pdfUrl = '/reskontra/directPayment/' + directPaymentId + '/pdf'; 17149 window.open(pdfUrl); 17150 }); 17151 $('#download_direct_payment_receipt') 17152 .button({ icons: { primary: 'ui-icon-document' } }) 17153 .on('click', function () { 17154 var paymentId = $(this).data('direct-payment-id'); 17155 var receiptUrl = '/payment_devices/tuloste/' + paymentId; 17156 window.open(receiptUrl); 17157 }); 17158 $('#confirm_online_payment') 17159 .button({ icons: { primary: 'ui-icon-document' } }) 17160 .on('click', function () { 17161 if(window.onlinePaymentDt){ 17162 var paymentId = $(this).data('direct-payment-id'); 17163 var type = $(this).data('conf-type'); 17164 window.onlinePaymentDt.openConfirmOnlinePayment(paymentId, type); 17165 } 17166 }); 17167 $('#get_payment_terminal_details') 17168 .button({ icons: { primary: 'ui-icon-document' } }) 17169 .on('click', function () { 17170 var transactionId = $(this).data('pt-transaction-id'); 17171 17172 var dialog = $('<div />', {}).dialog({ 17173 autoOpen: true, 17174 modal: true, 17175 width: 500, 17176 position: { 17177 top: 50, 17178 }, 17179 hide: { 17180 effect: 'fade', 17181 speed: 3000, 17182 }, 17183 resizable: true, 17184 title: 'Maksupäätetapahtuman tiedot', 17185 draggable: true, 17186 buttons: { 17187 Sulje: function () { 17188 dialog.dialog('close'); 17189 }, 17190 }, 17191 }); 17192 dialog.html('<p>Ladataan maksupäätetapahtuman tietoja...</p>'); 17193 jQuery 17194 .ajax({ 17195 type: 'POST', 17196 url: '/payment_devices/getPTTransaction', 17197 data: { 17198 transactionId: transactionId, 17199 }, 17200 }) 17201 .then(function (data) { 17202 var dialogHtml = ''; 17203 if (data.transaction_status === 'success') { 17204 var merchantReceipt = JSON.parse(data.merchant_receipt); 17205 var dateString = data.transaction_time; 17206 var yy = 20 + dateString.substring(0, 2), 17207 mm = dateString.substring(2, 4), 17208 dd = dateString.substring(4, 6), 17209 hh = dateString.substring(6, 8), 17210 MM = dateString.substring(8, 10); 17211 17212 var transactionTime = dd + '.' + mm + '.' + yy + ' ' + hh + ':' + MM; 17213 var transactionType = data.transaction_type === 'Purchase' ? 'Maksu' : 'Hyvitys'; 17214 dialogHtml = 17215 '<pre><code>' + 17216 'Tapahtumatyyppi: ' + 17217 transactionType + 17218 '\n' + 17219 'Maksupääte: ' + 17220 data.terminal_name + 17221 ' (' + 17222 data.terminal_id + 17223 ')\n' + 17224 'Tapahtuma luotu: ' + 17225 transactionTime + 17226 '\n' + 17227 'Kortin lukutapa: ' + 17228 data.card_reading_method + 17229 '\n' + 17230 merchantReceipt.text + 17231 '</code></pre>'; 17232 } else { 17233 dialogHtml = 17234 'Maksupääte tapahtuman tietoja ei voitu hakea, maksupäätetapahtuma keskeneräinen'; 17235 } 17236 dialog.html(dialogHtml); 17237 }) 17238 .fail(function (err) { 17239 console.log(err); 17240 dialog.html('<p>Maksupäätetapahtuman haku epäonnistui</p>'); 17241 }); 17242 }); 17243 }, // init_direct_payment_dialog 17244 17245 accept_for_money_transfer: function (part_payment_id) { 17246 $.ajax({ 17247 dataType: 'json', 17248 type: 'POST', 17249 data: { part_payment_id: part_payment_id }, 17250 url: '/osamaksu/accept_for_money_transfer/', 17251 17252 beforeSend: function (request) { 17253 global.showLoadingDialog('Hyväksytään osamaksusopimusta tilitettäväksi...'); 17254 }, 17255 success: function (responseJSON) { 17256 global.close_loading_dialog(); 17257 global.show_message(responseJSON); 17258 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17259 }, 17260 error: function (data) { 17261 global.show_message($.parseJSON(data.responseText)); 17262 global.close_loading_dialog(); 17263 }, 17264 }); 17265 }, 17266 17267 create_down_payment_invoice: function (part_payment_id) { 17268 $.ajax({ 17269 dataType: 'json', 17270 type: 'POST', 17271 data: { part_payment_id: part_payment_id, invoice_type: 'down_payment' }, 17272 url: '/osamaksu/create_invoice/', 17273 17274 beforeSend: function (request) { 17275 global.showLoadingDialog('Luodaan käsirahalaskua...'); 17276 }, 17277 success: function (responseJSON) { 17278 global.close_loading_dialog(); 17279 global.show_message(responseJSON); 17280 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17281 }, 17282 error: function (data) { 17283 global.show_message($.parseJSON(data.responseText)); 17284 global.close_loading_dialog(); 17285 }, 17286 }); 17287 }, 17288 17289 create_part_payment_invoice: function (part_payment_id) { 17290 $.ajax({ 17291 dataType: 'json', 17292 type: 'POST', 17293 data: { part_payment_id: part_payment_id, invoice_type: 'part_payment' }, 17294 url: '/osamaksu/create_invoice/', 17295 17296 beforeSend: function (request) { 17297 global.showLoadingDialog('Luodaan tililaskua...'); 17298 }, 17299 success: function (responseJSON) { 17300 global.close_loading_dialog(); 17301 global.show_message(responseJSON); 17302 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17303 }, 17304 error: function (data) { 17305 global.show_message($.parseJSON(data.responseText)); 17306 global.close_loading_dialog(); 17307 }, 17308 }); 17309 }, 17310 17311 cancel_part_payment_contract: function (part_payment_id, cancel_reason) { 17312 //Do ajax request 17313 $.ajax({ 17314 dataType: 'json', 17315 type: 'POST', 17316 url: 'osamaksu/cancel_contract/', 17317 data: { part_payment_id: part_payment_id, cancel_reason: cancel_reason }, 17318 17319 beforeSend: function (request) { 17320 global.showLoadingDialog('Perutaan osamaksusopimusta'); 17321 }, 17322 success: function (responseJSON) { 17323 global.close_loading_dialog(); 17324 global.show_message(responseJSON); 17325 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17326 }, 17327 error: function (data) { 17328 global.show_message($.parseJSON(data.responseText)); 17329 global.close_loading_dialog(); 17330 }, 17331 }); 17332 }, 17333 17334 convert_part_payment_contract_to_invoice: function (partPaymentId, addCancellationFee) { 17335 //Do ajax request 17336 $.ajax({ 17337 dataType: 'json', 17338 type: 'POST', 17339 url: 'osamaksu/convert_to_invoice/', 17340 data: { part_payment_id: partPaymentId, add_cancellation_fee: addCancellationFee }, 17341 17342 beforeSend: function (request) { 17343 global.showLoadingDialog('Muunnetaan osamaksusopimusta'); 17344 }, 17345 success: function (responseJSON) { 17346 global.close_loading_dialog(); 17347 global.show_message(responseJSON); 17348 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(partPaymentId); 17349 }, 17350 error: function (data) { 17351 global.show_message($.parseJSON(data.responseText)); 17352 global.close_loading_dialog(); 17353 }, 17354 }); 17355 }, 17356 17357 delete_part_payment_contract: function (part_payment_id) { 17358 //Do ajax request 17359 $.ajax({ 17360 dataType: 'json', 17361 type: 'POST', 17362 url: 'osamaksu/delete_contract/', 17363 data: { part_payment_id: part_payment_id }, 17364 17365 beforeSend: function (request) { 17366 global.showLoadingDialog('Poistetaan osamaksusopimusta'); 17367 }, 17368 success: function (responseJSON) { 17369 global.close_loading_dialog(); 17370 global.show_message(responseJSON); 17371 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17372 }, 17373 error: function (data) { 17374 global.show_message($.parseJSON(data.responseText)); 17375 global.close_loading_dialog(); 17376 }, 17377 }); 17378 }, 17379 17380 decline_part_payment_contract: function (part_payment_id, decline_reason) { 17381 //Do ajax request 17382 $.ajax({ 17383 dataType: 'json', 17384 type: 'POST', 17385 url: 'osamaksu/decline_contract/', 17386 data: { part_payment_id: part_payment_id, decline_reason: decline_reason }, 17387 17388 beforeSend: function (request) { 17389 global.showLoadingDialog('Hylätään osamaksusopimusta'); 17390 }, 17391 success: function (responseJSON) { 17392 global.close_loading_dialog(); 17393 global.show_message(responseJSON); 17394 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17395 }, 17396 error: function (data) { 17397 global.show_message($.parseJSON(data.responseText)); 17398 global.close_loading_dialog(); 17399 }, 17400 }); 17401 }, 17402 17403 approve_part_payment_application: function (part_payment_id) { 17404 //Do ajax request 17405 17406 $.ajax({ 17407 dataType: 'json', 17408 type: 'POST', 17409 url: 'osamaksu/approve_application/', 17410 data: { part_payment_id: part_payment_id }, 17411 17412 beforeSend: function (request) { 17413 global.showLoadingDialog('Merkitään osamaksua hyväksytyksi'); 17414 }, 17415 success: function (responseJSON) { 17416 global.close_loading_dialog(); 17417 global.show_message(responseJSON); 17418 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17419 }, 17420 error: function (data) { 17421 global.show_message($.parseJSON(data.responseText)); 17422 global.close_loading_dialog(); 17423 }, 17424 }); 17425 17426 //refresh dialog 17427 }, 17428 17429 approve_and_send_signature_invitation: function (part_payment_id, email) { 17430 //Do ajax request 17431 $.ajax({ 17432 dataType: 'json', 17433 type: 'POST', 17434 url: '/osamaksu/approve_and_send_signature_invitation/', 17435 data: { part_payment_id: part_payment_id, email: email }, 17436 17437 beforeSend: function (request) { 17438 global.showLoadingDialog('Hyväksytään sopimusta ja lähetetään allekirjoituskutsua'); 17439 }, 17440 success: function (responseJSON) { 17441 global.close_loading_dialog(); 17442 global.show_message(responseJSON); 17443 pages.iv_laskutus_ja_reskontra.refresh_part_payment_dialog_and_datatable(part_payment_id); 17444 }, 17445 error: function (data) { 17446 global.show_message($.parseJSON(data.responseText)); 17447 global.close_loading_dialog(); 17448 }, 17449 }); 17450 }, 17451 17452 send_signature_invitation: function (part_payment_id, email) { 17453 //Do ajax request 17454 $.ajax({ 17455 dataType: 'json', 17456 type: 'POST', 17457 url: '/osamaksu/send_signature_invitation/', 17458 data: { part_payment_id: part_payment_id, email: email }, 17459 17460 beforeSend: function (request) { 17461 global.showLoadingDialog('Lähetetään allekirjoituskutsua'); 17462 }, 17463 success: function (responseJSON) { 17464 global.close_loading_dialog(); 17465 global.show_message(responseJSON); 17466 }, 17467 error: function (data) { 17468 global.show_message($.parseJSON(data.responseText)); 17469 global.close_loading_dialog(); 17470 }, 17471 }); 17472 }, 17473 17474 send_customer_acceptance_invitation: function (part_payment_id, email, phone) { 17475 //Do ajax request 17476 $.ajax({ 17477 dataType: 'json', 17478 type: 'POST', 17479 url: '/osamaksu/send_customer_acceptance_invitation/', 17480 data: { 17481 part_payment_id: part_payment_id, 17482 email: email, 17483 phone: phone, 17484 }, 17485 beforeSend: function (request) { 17486 global.showLoadingDialog('Lähetetään hyväksyntäpyyntöä'); 17487 }, 17488 success: function (responseJSON) { 17489 global.close_loading_dialog(); 17490 global.show_message(responseJSON); 17491 }, 17492 error: function (data) { 17493 global.show_message($.parseJSON(data.responseText)); 17494 global.close_loading_dialog(); 17495 }, 17496 }); 17497 }, 17498 17499 show_invoice: function (invoice_id, open_sum) { 17500 LaskutusJaReskontra.showInvoiceDialog({ 17501 invoiceId: invoice_id, 17502 }); 17503 17504 /* 17505 var $dialog = global.$dialog; 17506 17507 if($dialog.hasClass('ui-dialog-content')){ 17508 $dialog.dialog('destroy'); 17509 } 17510 17511 $.ajax( { 17512 "processData":false, 17513 "dataType": 'html', 17514 "type": "GET", 17515 "url": "ajax/get_invoice_html/" + invoice_id + '/', 17516 "beforeSend":function(request){ 17517 $dialog.dialog({ 17518 width:800, 17519 height:600, 17520 modal:true, 17521 resizable:false, 17522 title:'Laskun tiedot', 17523 close: function(){ 17524 $dialog.dialog('destroy'); 17525 } 17526 }); 17527 global.show_ajax_loader($dialog); 17528 }, 17529 "success": function(response){ 17530 $dialog.html(response); 17531 17532 $(this).delegate(':button','click',function(){ 17533 $(this).data({'invoice_id': invoice_id, 'open_sum':open_sum}); 17534 }); 17535 } 17536 }); 17537 */ 17538 }, //show_invoice 17539 17540 copy_invoice: function (invoice_id) { 17541 $('<div></div>') 17542 .html('Haluatko siirtyä luomaan uuden laskun, käyttäen tätä laskua pohjana?') 17543 .dialog({ 17544 autoOpen: true, 17545 modal: true, 17546 resizable: false, 17547 draggable: false, 17548 title: 'Kopioi lasku', 17549 beforeClose: function (event, ui) { 17550 event.stopPropagation(); 17551 }, 17552 buttons: { 17553 Peruuta: function () { 17554 $(this).dialog('close'); 17555 }, 17556 'Siirry laskun luontiin': function () { 17557 $(this).dialog('close'); 17558 17559 window.location = '/lasku/kopioi/' + invoice_id; 17560 }, 17561 }, 17562 }); 17563 }, //copy_invoice 17564 17565 confirm_delete_draft: function (invoice_id) { 17566 $('<div></div>') 17567 .html('Haluatko varmasti poistaa laskun luonnoksen') 17568 .dialog({ 17569 autoOpen: true, 17570 modal: true, 17571 resizable: false, 17572 draggable: false, 17573 title: 'Poista laskun luonnos', 17574 beforeClose: function (event, ui) { 17575 event.stopPropagation(); 17576 }, 17577 close: function () { 17578 $(this).dialog('destroy'); 17579 $(this).remove(); 17580 }, 17581 buttons: { 17582 Peruuta: function () { 17583 $(this).dialog('close'); 17584 }, 17585 Poista: function () { 17586 $(this).dialog('close'); 17587 pages.iv_laskutus_ja_reskontra.delete_draft(invoice_id); 17588 }, 17589 }, 17590 }); 17591 }, //confirm_delete_draft 17592 17593 delete_draft: function (invoice_id) { 17594 //global.$dialog = $('</div />'); 17595 var $dialog = global.$dialog; 17596 17597 if ($dialog.hasClass('ui-dialog-content')) { 17598 $dialog.dialog('close'); 17599 } 17600 17601 //console.log("delete_draft"); 17602 17603 $.ajax({ 17604 processData: false, 17605 dataType: 'json', 17606 type: 'GET', 17607 url: '/ajax/delete_invoice_draft/' + invoice_id + '/', 17608 beforeSend: function (request) { 17609 global.showLoadingDialog('Poistetaan lasku...'); 17610 }, 17611 success: function (responseJSON) { 17612 global.close_loading_dialog(); 17613 global.show_message(responseJSON); 17614 17615 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 17616 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 17617 17618 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 17619 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 17620 }, 17621 }); 17622 }, //delete_draft 17623 17624 showAddDirectPaymentDialog: function (id, openAmount) { 17625 //Define the URL and success function for the refund payment case 17626 var $dialog = $('#add_direct_payment_dialog'); 17627 17628 if (!$dialog.length) { 17629 $dialog = pages.iv_laskutus_ja_reskontra.createDirectPaymentDialog(); 17630 $dialog.find('input#paid_date').datepicker($.datepicker.regional.fi); 17631 } 17632 17633 //Set date and open amount values 17634 $dialog.find('input#paid_date').datepicker('setDate', new Date()); 17635 $dialog.find('input#amount').val(openAmount); 17636
17636 $dialog.find('input#id').val(id); 17637 17638 $dialog.dialog('open'); 17639 }, 17640 17641 createDirectPaymentDialog: function () { 17642 var d = new Date(), 17643 url = '/iv_laskutus_ja_reskontra/addPaymentToDirectPayment/', 17644 $dialog = $('<div></div>', { id: 'add_direct_payment_dialog' }).append( 17645 $('<form />', { id: 'add_payment_form' }).append( 17646 $('<fieldset />', { class: '', style: '' }) 17647 .append('<p>Syötä tilityksen summa ja päivämäärä</p>') 17648 .append( 17649 $('<ol />') 17650 .append($('<input type="hidden" name="id" id="id" value="" />')) 17651 .append( 17652 $('<li />') 17653 .append($('<label for="amount">Summa:</label>')) 17654 .append( 17655 $('<input type="text" name="amount" id="amount" class="text small" />') 17656 ) 17657 .append(' €') 17658 ) 17659 .append( 17660 $('<li />') 17661 .append($('<label id="paid_date_label" for="paid_date">Päivämäärä:</label>')) 17662 .append( 17663 $( 17664 '<input type="text" class="text small" id="paid_date" name="paid_date" />' 17665 ) 17666 ) 17667 ) 17668 .append( 17669 $('<li />').append( 17670 $( 17671 '<button type="submit" class="btn btn-default">Tallenna' + 17672 ' tilitys</button>' 17673 ).button() 17674 ) 17675 ) 17676 ) 17677 ) 17678 ); 17679 17680 $dialog.find('form#add_payment_form').submit(function () { 17681 var data = _.object( 17682 $dialog 17683 .find('#add_payment_form') 17684 .serializeArray() 17685 .map(function (v) { 17686 return [v.name, v.value]; 17687 }) 17688 ); 17689 17690 $.ajax({ 17691 type: 'POST', 17692 url: url.concat(data.id), 17693 data: data, 17694 beforeSend: function (request) { 17695 global.showLoadingDialog('Tallennetaan tilitystä...'); 17696 }, 17697 }) 17698 .done(function (data) { 17699 global.close_loading_dialog(); 17700 global.show_message(data); 17701 $dialog.dialog('close'); 17702 17703 //Refresh the datatable 17704 pages.iv_laskutus_ja_reskontra.$datatable_direct_payments.fnClearTable(0); 17705 pages.iv_laskutus_ja_reskontra.$datatable_direct_payments.fnDraw(); 17706 }) 17707 .fail(function (data) { 17708 global.show_message($.parseJSON(data.responseText)); 17709 global.close_loading_dialog(); 17710 }); 17711 17712 return false; 17713 }); 17714 17715 $dialog.dialog({ 17716 width: 400, 17717 //height:200, 17718 autoOpen: false, 17719 modal: true, 17720 resizable: false, 17721 draggable: false, 17722 beforeClose: function (event, ui) { 17723 event.stopPropagation(); 17724 }, 17725 title: 'Lisää tilitys', 17726 buttons: { 17727 Peruuta: function () { 17728 $(this).dialog('close'); 17729 }, 17730 }, 17731 }); 17732 17733 return $dialog; 17734 }, 17735 17736 show_add_payment_dialog: function (id, open_sum, target_type) { 17737 //console.log('show_add_payment_dialog'); 17738 17739 var d = new Date(); 17740 17741 //Define the URL and success function for the invoice payment case 17742 if (target_type == 'invoice') {
17743 var url = '/ajax/add_invoice_payment/' + id; 17744 var success_callback = function (responseJSON, statusText, xhr, $form) { 17745 global.close_loading_dialog(); 17746 global.show_message(responseJSON); 17747 $add_payment_dialog.dialog('close'); 17748 17749 //Refresh the datatables 17750 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 17751 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 17752 17753 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 17754 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 17755 }; 17756 } 17757 17758 //Define the URL and success function for the refund payment case 17759 if (target_type == 'refund') { 17760 var url = '/ajax/add_refund_payment/' + id; 17761 var success_callback = function (responseJSON, statusText, xhr, $form) { 17762 global.close_loading_dialog(); 17763 global.show_message(responseJSON); 17764 $add_payment_dialog.dialog('close'); 17765 17766 //Refresh the datatable 17767 pages.iv_laskutus_ja_reskontra.$datatable_refunds.fnReloadAjax(); 17768 }; 17769 } 17770 17771 $add_payment_dialog = $('<div></div>') 17772 .append( 17773 $('<form />', { id: 'add_payment_form', method: 'post', action: url }) 17774 .append( 17775 $('<fieldset />', { class: 'fs-invisible', style: '' }) 17776 .append( 17777 '<p>Syötä maksusuorituksen summa euroissa ja lisää suorituksen päivämäärä</p>' 17778 ) 17779 .append( 17780 $('<ol />') 17781 .append( 17782 $('<li />') 17783 .append($('<label for="amount">Summa:</label>')) 17784 .append( 17785 $( 17786 '<input type="text" name="amount" id="amount" value="' + 17787 open_sum + 17788 '" class="text small" />' 17789 ) 17790 ) 17791 .append(' €') 17792 ) 17793 .append( 17794 $('<li />') 17795 .append($('<label id="created_label" for="created">Päivämäärä:</label>')) 17796 .append( 17797 $( 17798 '<input type="text" class="text small" id="created" name="created" value="' + 17799 d.getDate() + 17800 '.' + 17801 (d.getMonth() + 1) + 17802 '.' + 17803 d.getFullYear() + 17804 '" />' 17805 ).datepicker($.datepicker.regional.fi) 17806 ) 17807 ) 17808 .append( 17809 $('<li />').append( 17810 $('<button type="submit">Tallenna maksusuoritus</button>').button() 17811 ) 17812 ) 17813 ) 17814 ) 17815 .submit(function () { 17816 $(this).ajaxSubmit({ 17817 dataType: 'json', 17818 beforeSubmit: function () { 17819 global.showLoadingDialog('Tallennetaan maksusuoritusta...'); 17820 }, 17821 success: success_callback, 17822 }); 17823 return false; 17824 }) 17825 ) 17826 .dialog({ 17827 width: 400, 17828 //height:200, 17829 autoOpen: true, 17830 modal: true, 17831 resizable: false, 17832 draggable: false, 17833 beforeClose: function (event, ui) { 17834 event.stopPropagation(); 17835 }, 17836 close: function () { 17837 $(this).dialog('destroy'); 17838 $(this).remove(); 17839 }, 17840 title: 'Lisää maksusuoritus', 17841 buttons: { 17842 Peruuta: function () { 17843 $(this).dialog('close'); 17844 }, 17845 }, 17846 }); 17847 }, //show_add_payment_dialog 17848 add_log_item: function (invoice_id) { 17849 $('<div></div>') 17850 .append( 17851 $('<label />', { 17852 id: '', 17853 for: 'notifyInnovoice', 17854 style: 'font-weight:bold; width:100%;margin-bottom: 0;', 17855 }).html('Tyyppi'), 17856 $('<select/>', { 17857 id: 'notifyInnovoice', 17858 class: 'btn-sm', 17859 name: 'notify', 17860 style: 'font-weight: 500; line-height: 1.5; margin-bottom: 10px;', 17861 }).append( 17862 $('<option />', { value: '' }).html('Valitse'), 17863 $('<option />', { value: '1' }).html('Viesti Innovoicen asiakaspalveluun'), 17864 $('<option />', { value: '0' }).html('Oma muistiinpano') 17865 ), 17866 $('<label />', { style: 'width:auto;' }) 17867 .html('Viesti') 17868 .append($('<textarea />', { style: 'width:320px; height:72px;', name: 'log_event' })) 17869 .append('<br />') 17870 .append('<br />') 17871 ) 17872 .dialog({ 17873 autoOpen: true, 17874 modal: true, 17875 resizable: false, 17876 draggable: false, 17877 width: 380, 17878 title: 'Lisää muistiinpano', 17879 beforeClose: function (event, ui) { 17880 event.stopPropagation(); 17881 }, 17882 close: function () { 17883 $(this).dialog('destroy'); 17884 $(this).remove(); 17885 }, 17886 buttons: { 17887 Peruuta: function () { 17888 $(this).dialog('close'); 17889 }, 17890 Tallenna: function () { 17891 global.showLoadingDialog('Viestiä tallennetaan...'); 17892 var message = $(this).find('textarea[name=log_event]').val(); 17893 var notify = $('select#notifyInnovoice').val(); 17894 if (notify === '') { 17895 global.close_loading_dialog(); 17896 global.show_message({ 17897 type: 'error', 17898 title: 'Virhe', 17899 text: 'Valitse viestin tyyppi.', 17900 }); 17901 return; 17902 } 17903 var data = { id: invoice_id, message: message, notify: notify }; 17904 $(this).dialog('close'); 17905 $.ajax({ 17906 url: 'logger/makeLogEntry/', 17907 type: 'post', 17908 data: data, 17909 success: function (resp) { 17910 global.close_loading_dialog(); 17911 global.show_message({ 17912 type: 'success', 17913 title: 'Valmis', 17914 text: 'Muistiinpano lisätty onnistuneesti.', 17915 }); 17916 }, 17917 }); 17918 }, 17919 }, 17920 }); 17921 $('button').addClass('btn btn-default'); 17922 }, 17923 17924 confirm_mark_payments: function (selected_payments) { 17925 $('<div></div>') 17926 .html('Haluatko varmasti merkitä valitut laskut maksetuiksi') 17927 .dialog({ 17928 autoOpen: true, 17929 modal: true, 17930 resizable: false, 17931 draggable: false, 17932 title: 'Merkitse laskut maksetuiksi', 17933 beforeClose: function (event, ui) { 17934 event.stopPropagation(); 17935 }, 17936 buttons: { 17937 Kyllä: function () { 17938 $(this).dialog('close'); 17939 pages.iv_laskutus_ja_reskontra.mark_payments_paid(selected_payments); 17940 }, 17941 Peruuta: function () { 17942 $(this).dialog('close'); 17943 }, 17944 }, 17945 }); 17946 }, //confirm_mark_payments 17947 /** 17948 * General confirmation window. functions passed in must be anonymous. see params explanation 17949 * @param {String} title Window title 17950 * @param {String} message Window message 17951 * @param {function} onConfirm function is ran when modal confirmed -- () => { exampleFunction(exampleData) } 17952 * @param {function} onCancel function is ran when modal canceled-- () => { exampleFunction(exampleData) } 17953 */ 17954 confirm_action: function (title, message, onConfirm, onCancel) { 17955 onCancel = onCancel || false; 17956 17957 $('<div></div>') 17958 .html(message) 17959 .dialog({ 17960 autoOpen: true, 17961 modal: true, 17962 resizable: false, 17963 draggable: false, 17964 title: title, 17965 beforeClose: function (event, ui) { 17966 event.stopPropagation(); 17967 }, 17968 buttons: { 17969 Kyllä: function () { 17970 $(this).dialog('close'); 17971 onConfirm(); 17972 }, 17973 Peruuta: function () { 17974 $(this).dialog('close'); 17975 if (onCancel) { 17976 onCancel(); 17977 } 17978 }, 17979 }, 17980 }); 17981 }, 17982 17983 mark_payments_paid: function (payments) { 17984 global.showLoadingDialog('Merkitään tilityksiä maksetuiksi...'); 17985 17986 $.post( 17987 'iv_laskutus_ja_reskontra/ajax_mark_payments_paid', 17988 { 'payments[]': payments }, 17989 function (responseJSON) { 17990 global.close_loading_dialog(); 17991 global.show_message(responseJSON); 17992 pages.iv_laskutus_ja_reskontra.$datatable_paid_payments.fnReloadAjax(); 17993 pages.iv_laskutus_ja_reskontra.$datatable_open_payments.fnReloadAjax(); 17994 }, 17995 'json' 17996 ); 17997 }, //mark_payments_paid 17998 17999 show_upload_gothia_payment_file_dialog: function () { 18000 $upload_file_dialog = $('<div></div>') 18001 .append( 18002 $('<form />', { 18003 enctype: 'multipart/form-data', 18004 id: 'upload_gothia_payment_file_form', 18005 method: 'post', 18006 action: '/iv_laskutus_ja_reskontra/upload_gothia_payment_file/', 18007 }) 18008 .append( 18009 $('<fieldset />', { class: 'fs-invisible', style: '' }) 18010 .append('<p>Valitse Gothian tilitystiedosto</p>') 18011 .append( 18012 $('<ol />') 18013 .append( 18014 $('<li />').append( 18015 $( 18016 '<input type="file" name="gothia_payment_file" id="gothia_payment_file" />'
18017 ) 18018 ) 18019 ) 18020 .append( 18021 $('<li />').append( 18022 $('<button type="submit">Luo tiedostosta tilitys</button>').button() 18023 ) 18024 ) 18025 ) 18026 ) 18027 .submit(function () { 18028 $(this).ajaxSubmit({ 18029 dataType: 'json', 18030 iframe: true, 18031 beforeSubmit: function () { 18032 global.showLoadingDialog('Luodaan tilitystä...'); 18033 }, 18034 success: function (responseJSON, statusText, xhr, $form) { 18035 global.close_loading_dialog(); 18036 global.show_message(responseJSON); 18037 18038 if (responseJSON.type === 'success') { 18039 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnClearTable(0); 18040 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnDraw(); 18041 $upload_file_dialog.dialog('destroy'); 18042 } 18043 }, 18044 }); 18045 return false; 18046 }) 18047 ) 18048 .dialog({ 18049 width: 400, 18050 //height:200, 18051 autoOpen: true, 18052 modal: true, 18053 resizable: false, 18054 draggable: false, 18055 beforeClose: function (event, ui) { 18056 event.stopPropagation(); 18057 }, 18058 title: 'Syötä Gothian tilitystiedosto', 18059 buttons: { 18060 Peruuta: function () { 18061 $(this).dialog('close'); 18062 }, 18063 }, 18064 }); 18065 }, 18066 18067 show_money_transfer: function (id, moneyTransferDate, type) { 18068 global.$dialog = $('<div />', {}); 18069 var $dialog = global.$dialog; 18070 18071 if ($dialog.hasClass('ui-dialog-content')) { 18072 $dialog.dialog('destroy'); 18073 } 18074 18075 dialogs.url = 'ajax/get_money_transfer_html/' + id + '/' + type; 18076 18077 $.ajax({ 18078 processData: false, 18079 dataType: 'html', 18080 type: 'GET', 18081 url: dialogs.url, 18082 beforeSend: function (request) { 18083 $dialog.dialog({ 18084 width: 800, 18085 height: 500, 18086 modal: true, 18087 resizable: false, 18088 title: 'Tilityksen tiedot '.concat(moneyTransferDate), 18089 close: function () { 18090 $dialog.dialog('destroy'); 18091 }, 18092 }); 18093 global.show_ajax_loader($dialog); 18094 }, 18095 success: function (response) { 18096 $dialog.html(response); 18097 /* 18098 $(this).delegate(':button','click',function(){ 18099 $(this).data({'invoice_id': invoice_id, 'open_sum':open_sum}); 18100 }); 18101 */ 18102 }, 18103 }); 18104 }, //show_invoice 18105 18106 execute_accepted_money_transfers: function (money_transfer_id) { 18107 var $dialog = $('<div />', { style: 'text-align:left;' }), 18108 $loadingDialog = $( 18109 '<div><p style="margin: 0 auto; width: 66px; padding-top:38px;"><img src="/assets/images/ajax_loading.gif" width="66" height="66" /></p></div>' 18110 ); 18111 18112 $form = $('<form />', { id: 'sign_money_transfer_form' }) 18113 .append( 18114 $('<p />').html('Allekirjoita eräsiirto antamalla varmenteen avainfraasi'), 18115 $('<input />', { 18116 type: 'password', 18117 name: 'passphrase', 18118 id: 'passphrase', 18119 class: 'text medium', 18120 }) 18121 ) 18122 .submit(function () { 18123 $(this).ajaxSubmit({ 18124 data: { money_transfer_id: money_transfer_id }, 18125 url: '/tilitykset/execute_accepted_money_transfers', 18126 type: 'POST', 18127 dataType: 'json', 18128 beforeSubmit: function () { 18129 global.showLoadingDialog('Suoritetaan eräsiirtoa pankkiin...'); 18130 }, 18131 success: function (responseJSON) { 18132 global.close_loading_dialog(); 18133 global.show_message(responseJSON); 18134 18135 if (responseJSON.type === 'success' || responseJSON.type === 'info') { 18136 //Refresh the datatable and the dialog close the dialog 18137 $dialog.dialog('destroy'); 18138 dialogs.refresh(); 18139 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnClearTable(0); 18140 pages.iv_laskutus_ja_reskontra.$datatable_money_transfers.fnDraw(); 18141 } 18142 }, 18143 error: function (response) { 18144 global.close_loading_dialog(); 18145 18146 try { 18147 global.show_message(JSON.parse(response.responseText)); 18148 } catch (exception) { 18149 global.show_message({ 18150 type: 'error', 18151 text: 'Odottamaton virhe tapahtui palvelimella. Virhesanoma tallennettu palvelimen lokiin.', 18152 }); 18153 } 18154 }, 18155 }); 18156 18157 return false;
18158 }); 18159 18160 $dialog.append($form).dialog({ 18161 width: 320, 18162 autoOpen: true, 18163 modal: true, 18164 resizable: false, 18165 draggable: false, 18166 beforeClose: function (event, ui) { 18167 event.stopPropagation(); 18168 }, 18169 title: 'Allekirjoita pankin eräsiirto', 18170 buttons: { 18171 Peruuta: function () { 18172 $(this).dialog('close'); 18173 }, 18174 'Hyväksy eräsiirto': function () { 18175 $(this).find('#sign_money_transfer_form').submit(); 18176 }, 18177 }, 18178 }); 18179 }, //execute_accepted_money_transfers 18180 tryActionRemittance: function (data) { 18181 var inputData = JSON.parse(data); 18182 $.ajax({ 18183 dataType: 'json', 18184 type: 'POST', 18185 url: inputData.url, 18186 data: { 18187 remittance_id: inputData.remittance_id, 18188 updated: inputData.updated, 18189 }, 18190 beforeSend: function (request) { 18191 global.showLoadingDialog('Lähetetään hyväksyntäpyyntöä'); 18192 }, 18193 success: function (responseJSON) { 18194 global.close_loading_dialog(); 18195 global.show_message(responseJSON); 18196 18197 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnClearTable(0); 18198 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnDraw(); 18199 }, 18200 error: function (data) { 18201 global.show_message($.parseJSON(data.responseText)); 18202 global.close_loading_dialog(); 18203 if (data.status === 409) { 18204 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnClearTable(0); 18205 pages.iv_laskutus_ja_reskontra.$datatable_remittances.fnDraw(); 18206 } 18207 }, 18208 }); 18209 }, 18210 }, //iv_laskutus_ja_reskontra 18211 18212 iv_tapahtumaloki: { 18213 $datatable: '', 18214 18215 init: function () { 18216 $('#get_transactions') 18217 .button({ icons: { primary: 'ui-icon-search' } }) 18218 .on('click', function () { 18219 pages.iv_tapahtumaloki.$datatable.fnReloadAjax(); 18220 }); 18221 18222 $('#transactions_tabs').tabs(); 18223 18224 $('#transactions_filter_form select').change(function (e) { 18225 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 18226 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 18227 setTimeout(function () { 18228 pages.iv_tapahtumaloki.$datatable.fnClearTable(0); 18229 pages.iv_tapahtumaloki.$datatable.fnDraw(); 18230 }, 1); 18231 }); 18232 18233 $('#admin_transactions_dt').on('click', 'a.show_transaction_log', function (e) { 18234 e.preventDefault(); 18235 18236 var transactionId = $(e.target).attr('href'); 18237 var action = $(e.target).attr('class'); 18238 18239 switch (action) { 18240 case 'show_transaction_log': 18241 pages.iv_tapahtumaloki.show_transaction_log(transactionId); 18242 break; 18243 } 18244 }); 18245 18246 pages.iv_tapahtumaloki.$datatable = $('#admin_transactions_dt').dataTable({ 18247 oLanguage: global.dataTablesLanguage, 18248 sPaginationType: 'full_numbers', 18249 iDisplayLength: 25, 18250 bAutoWidth: false, 18251 bJQueryUI: true, 18252 bFilter: true, 18253 bInfo: true, 18254 bPaginate: true, 18255 bProcessing: true, 18256 bServerSide: true, 18257 sAjaxSource: 'tapahtumaloki/datatable/', 18258 aoColumns: [ 18259 /** ID **/ { bVisible: false, bSearchable: false }, 18260 /** Yritys **/ { bVisible: true, bSearchable: false }, 18261 /** Tapahtumatunnus **/ { bVisible: true, bSearchable: true }, 18262 /** Asiakas **/ { bVisible: true, bSearchable: false, bSortable: false }, 18263 /** Päiväys **/ { sType: 'date-eu', bVisible: true, bSearchable: false }, 18264 /** Käyttöliittymä **/ { bVisible: true, bSearchable: false }, 18265 /** Tyyppi **/ { bVisible: true, bSearchable: false }, 18266 /** Tila **/ { bVisible: true, bSearchable: false }, 18267 ], 18268 aaSorting: [[4, 'desc']], 18269 18270 fnServerParams: function (aoData) { 18271 var month = $('#transactions_filter_form select[name=month] option:selected').attr( 18272 'value' 18273 ); 18274 var year = $('#transactions_filter_form select[name=year] option:selected').attr('value'); 18275 var company = $('#transactions_filter_form select[name=company] option:selected').attr( 18276 'value' 18277 ); 18278 18279 aoData.push({ name: 'month', value: month }); 18280 aoData.push({ name: 'year', value: year }); 18281 aoData.push({ name: 'company', value: company }); 18282 }, 18283 18284 //Called before each row is shown 18285 fnRowCallback: function (nRow, aData, iDisplayIndex) { 18286 var transaction_id = aData[0]; 18287 var transaction_key = aData[2]; 18288 //Add the transaction id to every rows data object 18289 $(nRow).data({ transaction_id: transaction_id }); 18290 18291 $('td:eq(1)', nRow).html( 18292 '<a href="' + 18293 transaction_id + 18294 '" class="show_transaction_log" >' + 18295 transaction_key + 18296 '</a>' 18297 ); 18298 return nRow; 18299 }, 18300 }); 18301 $('select[name=company]').each(function () { 18302 global.renderCompaniesFilterOptions(this); 18303 }); 18304 }, 18305 18306 show_transaction_log: function (transactionId) { 18307 var $dialog = $('<div />', { style: 'text-align:left;' }); 18308 18309 if (transactionId.length > 0) { 18310 $.ajax({ 18311 processData: false, 18312 dataType: 'html', 18313 type: 'GET', 18314 url: 'tapahtumaloki/get_transaction_log_html/' + transactionId, 18315 beforeSend: function (request) { 18316 $dialog.dialog({ 18317 width: 650, 18318 height: 350, 18319 title: 'Tapahtumaloki', 18320 close: function () { 18321 $dialog.dialog('destroy'); 18322 }, 18323 }); 18324 global.show_ajax_loader($dialog); 18325 }, 18326 success: function (response) { 18327 $dialog.html(response); 18328 }, 18329 }); 18330 } 18331 }, // show_transaction_log 18332 }, //iv_tapahtumaloki 18333 18334 iv_sms_loki: { 18335 $datatable: '', 18336 18337 init: function () { 18338 $('#sms_log_tabs').tabs(); 18339 $('#get_sms_log') 18340 .button({ icons: { primary: 'ui-icon-search' } }) 18341 .on('click', function () { 18342 pages.iv_sms_loki.$datatable.fnReloadAjax(); 18343 }); 18344 18345 pages.iv_sms_loki.$datatable = $('table#sms_log_dt').dataTable({ 18346 oLanguage: global.dataTablesLanguage, 18347 sPaginationType: 'full_numbers', 18348 iDisplayLength: 25, 18349 bAutoWidth: false, 18350 bJQueryUI: true, 18351 bFilter: true, 18352 bInfo: true, 18353 bPaginate: true, 18354 bProcessing: true,
18355 bServerSide: false, 18356 sAjaxSource: 'ajax/get_sms_log_json/', 18357 aoColumns: [ 18358 /** ID **/ { bVisible: false }, 18359 /** Aika **/ { bSortable: false }, 18360 /** Välittäjä **/ { bSortable: false }, 18361 /** Lähettäjän numero **/ null, 18362 /** Yritys **/ null, 18363 /** Auton nro. **/ { bSortable: false }, 18364 /** Lähetetty viesti **/ { bSortable: false }, 18365 /** Palvelun vastaus **/ { bSortable: false }, 18366 ], 18367 aaSorting: [[0, 'desc']], 18368 fnServerData: function (sSource, aoData, fnCallback) { 18369 /* Add some extra data to the sender */ 18370 var month = $('#ac-tab-log').find('select[name=month] option:selected').attr('value'); 18371 var year = $('#ac-tab-log').find('select[name=year] option:selected').attr('value'); 18372 sSource += year + '/' + month + '/'; 18373 18374 $.getJSON(sSource, null, function (json) { 18375 $('span#month_year').html(json.month + ', ' + json.year); 18376 fnCallback(json); 18377 }); 18378 }, 18379 }); // $datatable 18380 }, //iv_sms_loki 18381 }, 18382 18383 iv_henkilorekisteri: { 18384 $datatable: '', 18385 18386 init: function () { 18387 $('#customer_registry_tabs').tabs(); 18388 18389 $('#create_customer_person') 18390 .button({ icons: { primary: 'ui-icon-plusthick' } }) 18391 .on('click', function () { 18392 pages.iv_henkilorekisteri.show_customer_card(); 18393 }); 18394 18395 $('#customer_registry_dt').delegate( 18396 '#customer_registry_dt a.show_customer_card', 18397 'click', 18398 function (e) { 18399 e.preventDefault(); 18400 var customer_id = $(e.target).attr('href'); 18401 var action = $(e.target).attr('class'); 18402 18403 switch (action) { 18404 case 'show_customer_card': 18405 pages.iv_henkilorekisteri.show_customer_card(customer_id); 18406 break; 18407 } 18408 } 18409 ); 18410 18411 pages.iv_henkilorekisteri.$datatable = $('#customer_registry_dt').dataTable({ 18412 oLanguage: global.dataTablesLanguage, 18413 sPaginationType: 'full_numbers', 18414 bPaginate: false, 18415 bAutoWidth: false, 18416 bJQueryUI: true, 18417 bProcessing: true, 18418 bServerSide: false, 18419 sAjaxSource: 'iv_henkilorekisteri/ajax_get_customers_json/', 18420 aoColumns: [ 18421 /** user_id **/ { bVisible: false }, 18422 /** Nimi **/ null, 18423 /** HETU **/ null, 18424 /** Osoite **/ null, 18425 /** Kaupunki **/ null, 18426 /** Puhelinnumero **/ null, 18427 /** Sähköposti **/ null, 18428 /** Laskun lähetystapa **/ null, 18429 /** Ei luottotark. **/ null, 18430 ], 18431 aaSorting: [[5, 'asc']], 18432 fnServerData: function (sSource, aoData, fnCallback) { 18433 $.getJSON(sSource, null, function (json) { 18434 /* Do whatever additional processing you want on the callback, then tell DataTables */ 18435 fnCallback(json); 18436 }); 18437 }, 18438 //Called before each row is shown 18439 fnRowCallback: function (nRow, aData, iDisplayIndex) { 18440 var user_id = aData[0]; 18441 var customer_name = aData[1]; 18442 18443 $('td:eq(0)', nRow).html( 18444 '<a href="' + user_id + '" class="show_customer_card" >' + customer_name + '</a>' 18445 ); 18446 return nRow; 18447 }, 18448 }); //datatables 18449 }, //init 18450 18451 init_customer_card: function (id) { 18452 //var id = $('#id').val(); 18453 $('#customer_card_tabs').tabs(); 18454 18455 $('button:submit').button({ text: true, icons: { primary: 'ui-icon-disk' } }); 18456 $('button#delete_customer').button({ text: true, icons: { primary: 'ui-icon-trash' } }); 18457 18458 $('#customer_card_form').submit(function () { 18459 $(this).ajaxSubmit({ 18460 dataType: 'json', 18461 //show the loading message 18462 beforeSubmit: function () { 18463 global.show_loading_dialog('Tallennetaan tietoja...'); 18464 }, 18465 success: function (responseJSON, statusText, xhr, $form) { 18466 global.close_loading_dialog(); 18467 global.show_message(responseJSON); 18468 18469 if (responseJSON.type === 'success') { 18470 //Refresh the datatable and close the dialog 18471 if ($form.find('#id').val() === '') { 18472 global.$dialog.dialog('destroy'); 18473 } 18474 pages.iv_henkilorekisteri.$datatable.fnReloadAjax(); 18475 } 18476 }, 18477 }); 18478 return false;
18479 }); 18480 }, 18481 18482 show_customer_card: function (user_id) { 18483 var $dialog = global.$dialog; 18484 18485 if ($dialog.hasClass('ui-dialog-content')) { 18486 $dialog.dialog('destroy'); 18487 } 18488 18489 var url = '/iv_henkilorekisteri/ajax_get_customer_card/'; 18490 18491 if (typeof user_id !== 'undefined') { 18492 url += user_id + '/'; 18493 } 18494 18495 $dialog.dialog({ 18496 width: 800, 18497 height: 550, 18498 modal: true, 18499 resizable: false, 18500 title: 'Henkilökortti', 18501 open: function () { 18502 global.show_ajax_loader($dialog); 18503 18504 $.get(url, function (data) { 18505 $dialog.html(data); 18506 }); 18507 }, 18508 close: function () { 18509 $dialog.dialog('destroy'); 18510 }, 18511 }); 18512 }, // show_customer_card 18513 }, // iv_henkilorekisteri 18514 18515 etusivu: { 18516 init: function () { 18517 $('#create_invoice_btn') 18518 .button({ icons: { primary: 'ui-icon-plusthick' } }) 18519 .on('click', function (e) { 18520 var url = $(e.target).attr('name'); 18521 window.location = url; 18522 }); 18523 18524 $('#latest_transactions').on('click', 'a.show_transaction_log', {}, function (e) { 18525 global.$dialog = $('#dialog'); 18526 e.preventDefault(); 18527 18528 var transactionId = $(e.target).attr('href'); 18529 var action = $(e.target).attr('class'); 18530 18531 var n = transactionId.lastIndexOf('/'); 18532 18533 transactionId = transactionId.substring(n + 1); 18534 18535 switch (action) { 18536 case 'show_transaction_log': 18537 pages.iv_tapahtumaloki.show_transaction_log(transactionId); 18538 break; 18539 } 18540 }); 18541 18542 $('#latest_invoices').on('click', 'a.show_invoice, a.show_invoice_log', {}, function (e) { 18543 global.$dialog = $('#dialog'); 18544 18545 e.preventDefault(); 18546 18547 var invoice_id = $(e.target).attr('href'); 18548 var action = $(e.target).attr('class'); 18549 18550 var n = invoice_id.lastIndexOf('/'); 18551 invoice_id = invoice_id.substring(n + 1); 18552 18553 switch (action) { 18554 case 'show_invoice': 18555 pages.iv_laskutus_ja_reskontra.show_invoice(invoice_id); 18556 break; 18557 case 'show_invoice_log': 18558 pages.iv_laskutus_ja_reskontra.show_invoice_log(invoice_id); 18559 break; 18560 } 18561 }); 18562 18563 $('#user_manual') 18564 .button({ icons: { primary: 'ui-icon-document' } }) 18565 .on('click', function () { 18566 window.open('http://www.innotaxi.fi/ohjeet/', 'user_manual'); 18567 }); 18568 18569 $( 18570 '#recent_events table tr:odd, #recent_logons table tr:odd, #recent_invoices table tr:odd, #recent_sms_logs table tr:odd' 18571 ).each(function () { 18572 $(this).addClass('odd'); 18573 }); 18574 18575 $('#recent_events tr, #recent_logons tr, #recent_invoices tr, #recent_sms_logs tr').hover( 18576 function () { 18577 $(this).addClass('hover'); 18578 }, 18579 function () { 18580 $(this).removeClass('hover'); 18581 } 18582 ); 18583 }, 18584 18585 init_online_agreement: function () { 18586 $('#accept_online_agreement').button({ icons: { primary: 'ui-icon-check' } }); 18587 18588 $('#agreement').change(function () { 18589 if ($('#agreement').is(':checked')) { 18590 $('#accept_online_agreement').button('enable'); 18591 } else { 18592 $('#accept_online_agreement').button('disable'); 18593 } 18594 }); 18595 }, 18596 18597 get_open_transactions: function ($wrapper) { 18598 //Refresh open transactions 18599 $.getJSON('/ajax/get_open_transactions_json/', function (responseJSON) { 18600 if (responseJSON.aaData.length > 0) { 18601 $tbody = $('<tbody />', {}); 18602 18603 $.each(responseJSON.aaData, function (index, transaction) { 18604 //console.log(transaction); 18605 18606 $tbody.append( 18607 $('<tr />').append( 18608 $('<td />', { class: 'ui-helper-hidden' }).html(transaction.id), 18609 $('<td />').html(transaction.date), 18610 $('<td />').html(transaction.time), 18611 $('<td />').html(transaction.customer_name), 18612 $('<td />').html(transaction.type), 18613 $('<td />').html(transaction.credit_decision), 18614 $('<td />') 18615 .html( 18616 $('<a />', { 18617 href: '/lasku/avoin/' + transaction.id, 18618 class: 'resume_transaction', 18619 }).html('Laskuta') 18620 ) 18621 .append(' ') 18622 .append( 18623 $('<a />', { 18624 href: '/ajax/close_transaction/' + transaction.id, 18625 class: 'close_transaction', 18626 }).html('Sulje') 18627 ) 18628 ) 18629 ); 18630 }); 18631 18632 $html = $('<table />', { 18633 cellspacing: '0', 18634 cellpadding: '0', 18635 border: '0', 18636 id: 'open_transactions_table', 18637 }).append( 18638 $('<thead />', {}).append( 18639 $('<tr />').append( 18640 $('<th />', { class: 'ui-helper-hidden' }).html('ID'), 18641 $('<th />').html('Pvm'), 18642 $('<th />').html('Klo'), 18643 $('<th />').html('Asiakas'), 18644 $('<th />').html('Tapahtuma'), 18645 $('<th />').html('Luottopäätös'), 18646 $('<th />', { width: '90px' }).html('') 18647 ) 18648 ), 18649 $tbody 18650 ); 18651 } else { 18652 $html = $('<p />', { style: 'padding-top:20px; margin:0; font-size:16px;' }).html( 18653 'Ei avoimia tapahtumia' 18654 ); 18655 } 18656 18657 $wrapper.html($html); 18658 //console.log(responseJSON); 18659 }); 18660 }, 18661 18662 show_customer_info: function (person_info, credit_info) { 18663 //Set the person info 18664 $receiver_wrapper = $('#person_info').find('table tbody'); 18665 18666 $receiver_wrapper 18667 .find('tr.name') 18668 .find('td.val') 18669 .html(person_info.lastname + ' ' + person_info.firstname); 18670 $receiver_wrapper 18671 .find('tr.address') 18672 .find('td.val') 18673 .html(person_info.address + '<br />' + person_info.zipcode + ' ' + person_info.city); 18674 18675 //$receiver_wrapper.find('input[name=\'person[customer_id]\']').val(person_info.id); 18676 18677 //$receiver_wrapper.find('input[name=\'person[gothia_cust_no]\']').val(person_info.gothia_cust_no
18677); 18678 18679 //$receiver_wrapper.find('input[name=\'person[ssn]\']').val(person_info.ssn); 18680 18681 //Set the credit check info 18682 //$receiver_wrapper.find('input[name=rating]').val(credit_info.rating); 18683 18684 //console.log($('#credit_info')); 18685 18686 $('#credit_info').show().find('.output').html(''); 18687 $('#person_info').show(); 18688 $('#financing_limit').hide(); 18689 18690 switch (credit_info.decision) { 18691 case 1: 18692 case 3: 18693 case 4: 18694 $('#credit_decision').addClass('credit_green').removeClass('credit_red'); 18695 $('#credit_decision').html('Puoltava'); 18696 //$('#credit_decision_reason').css('font-weight', 'bold').show().html(credit_info.response_message); 18697 $('#credit_info').find('.output').show().html(credit_info.response_message); 18698 18699 if (credit_info.financing_limit) { 18700 $('#financing_limit') 18701 .show() 18702 .find('.output') 18703 .addClass('credit_green') 18704 .html(('' + (+credit_info.financing_limit).toFixed(2)).replace('.', ',')); 18705 } 18706 break; 18707 case 2: 18708 $('#credit_decision').addClass('credit_red').removeClass('credit_green'); 18709 $('#credit_decision').html('Kielteinen'); 18710 $('#credit_info').find('.output').show().html(credit_info.response_message); 18711 break; 18712 default: 18713 $('#credit_decision').removeClass('credit_red').removeClass('credit_green'); 18714 $('#credit_decision').html(''); 18715 $('#credit_info').find('.output').show().html(credit_info.response_message); 18716 break; 18717 } 18718 18719 //Show the btn 18720 $('#create_invoice').show(); 18721 }, 18722 }, //etusivu 18723 18724 raportit: { 18725 init: function () { 18726 $('#report_tabs').tabs(); 18727 $('body').delegate('#report_tabs', 'tabsshow', function (ev, ui) { 18728 var rex = /^[^#]*#/; 18729 var hash = ui.tab.href.replace(rex, ''); 18730 window.location.hash = '#'.concat(hash); 18731 }); 18732 18733 $('#reports tr:odd').each(function () { 18734 $(this).addClass('odd'); 18735 }); 18736 18737 $('#reports tr').hover( 18738 function () { 18739 $(this).addClass('hover'); 18740 }, 18741 function () { 18742 $(this).removeClass('hover'); 18743 } 18744 ); 18745 18746 $('select[name=company]').each(function () { 18747 global.renderCompaniesFilterOptions(this); 18748 }); 18749 18750 $('#get_iv_reports') 18751 .button({}) 18752 .on('click', function (e) { 18753 $form = $(e.target).parents('form'); 18754 18755 //console.log($form.length); 18756 18757 var month = $form.find('select[name=month]').val(), 18758 year = $form.find('select[name=year]').val(), 18759 report_type = $form.find('.report_type:checked').val(); 18760 18761 window.location = location.pathname + '/' + report_type + '/' + year + '/' + month + '/'; 18762 }); 18763 18764 $('#get_client_reports') 18765 .button({}) 18766 .on('click', function (e) { 18767 $form = $(e.target).parents('form'); 18768 18769 var company = $form.find('select[name=company]').val(), 18770 month = $form.find('select[name=month]').val(), 18771 year = $form.find('select[name=year]').val(), 18772 report_type = $form.find('.report_type:checked').val(); 18773 18774 window.location = 18775 location.pathname + '/' + report_type + '/' + company + '/' + year + '/' + month + '/'; 18776 }); 18777 }, 18778 }, 18779 18780 reskontra: { 18781 $datatable: null, 18782 recurring_invoicing: null, 18783 $part_payments_datatable: null, 18784 $money_transfers_dt: null, 18785 $direct_payments_dt: null, 18786 $corporate_chain_invoices_dt: null, 18787 dataTableParams: { 18788 invoice: null, 18789 directPayments: null, 18790 partPayments: null, 18791 }, 18792 18793 init: function (opts) { 18794 var showClientCompanies = opts && opts.showClientCompanies === 1 ? true : false; 18795 var d_from = new Date(); 18796 d_from.setDate(1); 18797 var d_to = new Date(); 18798 var $date_from = $( 18799 '<input type="text" class="text small" id="date_from" name="date_from" value="' + 18800 d_from.getDate() + 18801 '.' + 18802 (d_from.getMonth() + 1) + 18803 '.' + 18804 d_from.getFullYear() + 18805 '" />' 18806 ).datepicker($.datepicker.regional.fi); 18807 var $date_to = $( 18808 '<input type="text" class="text small" id="date_to" name="date_to" value="' + 18809 d_to.getDate() + 18810 '.' + 18811 (d_to.getMonth() + 1) + 18812 '.' + 18813 d_to.getFullYear() + 18814 '" />' 18815 ).datepicker($.datepicker.regional.fi); 18816 18817 [ 18818 'input#filter-invoice-start-date', 18819 'input#filter-invoice-end-date', 18820 'input#filter-dp-start-date',
18821 'input#filter-dp-end-date', 18822 'input#filter-part-payment-start-date', 18823 'input#filter-part-payment-end-date', 18824 'input#filter-corporate-chain-start-date', 18825 'input#filter-corporate-chain-end-date', 18826 'input#filter-money-transfers-start-date', 18827 'input#filter-money-transfers-end-date', 18828 ].forEach(function (input) { 18829 if($(input).length === 0){ 18830 return; 18831 } 18832 $(input).datepicker({ 18833 showButtonPanel: true, 18834 language: 'fi-FI', 18835 weekStart: 1, 18836 todayHighlight: true, 18837 startDate: '-120m', 18838 autoclose: true, 18839 clearBtn: true, 18840 format: 'dd.mm.yyyy', 18841 forceParse: true, 18842 assumeNearbyYear: true, 18843 }); 18844 // console.log('DATEPICKER INITED: ', input); 18845 }); 18846 18847 $('#reskontra_tabs').tabs(); 18848 18849 $('#corporate-chain-get_invoices') 18850 .button({ icons: { primary: 'ui-icon-search' } }) 18851 .on('click', function () { 18852 pages.reskontra.$corporate_chain_invoices_dt.fnClearTable(0); 18853 pages.reskontra.$corporate_chain_invoices_dt.fnDraw(); 18854 }); 18855 18856 $('#new_invoice_person') 18857 .button({ icons: { primary: 'ui-icon-plusthick' } }) 18858 .on('click', function () { 18859 //pages.reskontra.show_invoice_dialog('person'); 18860 window.location = '/lasku/kuluttajalasku/'; 18861 }); 18862 18863 $('#new_invoice') 18864 .button({ icons: { primary: null, secondary: 'ui-icon-triangle-1-s' } }) 18865 .wrap($('<div />', { style: 'float:left;' })) 18866 .wrap($('<div />', {})) 18867 .parent() 18868 .parent() 18869 .append( 18870 $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }).append( 18871 $('<li />', {}).append( 18872 $('<a />', { href: '/lasku/kuluttajalasku/' }) 18873 .on('click', function () { 18874 window.location = '/lasku/kuluttajalasku/'; 18875 }) 18876 .text('Kuluttajalle') 18877 ), 18878 $('<li />', {}).append( 18879 $('<a />', { href: '/lasku/yrityslasku/' }) 18880 .on('click', function () { 18881 window.location = '/lasku/yrityslasku/'; 18882 }) 18883 .text('Yritykselle') 18884 ), 18885 $('<li />', {}).append( 18886 $('<a />', { href: '/lasku/vakuutusyhtio/' }) 18887 .on('click', function () { 18888 window.location = '/lasku/vakuutusyhtio/'; 18889 }) 18890 .text('Vakuutusyhtiölle') 18891 ) 18892 ) 18893 ) 18894 .parent() 18895 .parent() 18896 .find('#new_invoice') 18897 .on('click', function () { 18898 console.log('#new_invoice'); 18899 18900 //pages.reskontra.show_invoice_dialog('company'); 18901 //window.location = '/lasku/yrityslasku/'; 18902 var $menu = $(this).parent().next(); 18903 18904 if ($menu.is(':visible')) { 18905 $menu.hide(); 18906 } else { 18907 $menu.show().position({ 18908 my: 'left top', 18909 at: 'left bottom', 18910 of: this, 18911 }); 18912 } 18913 18914 var menu = $(this).parent().next(); 18915 $(document).one('click', function () { 18916 menu.hide(); 18917 }); 18918 return false; 18919 }) 18920 .parent() 18921 .buttonset() 18922 .next() 18923 .hide() 18924 .menu(); 18925 18926 $('#new_report') 18927 .button({ icons: { primary: null, secondary: 'ui-icon-triangle-1-s' } }) 18928 .wrap($('<div />', { style: 'float:left;' })) 18929 .wrap($('<div />', {})) 18930 .parent() 18931 .parent() 18932 .append( 18933 $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }).append( 18934 $('<li />', {}).append( 18935 $('<a />', { href: '/' }) 18936 .on('click', function (e) { 18937 //window.location = '/lasku/kuluttajalasku/'; 18938 e.preventDefault(); 18939 window.FivaldiReport.reportModal.openDialog(); 18940 }) 18941 .text('Fivaldi-kirjanpitoraportti') 18942 ), 18943 $('<li />', {}).append( 18944 $('<a />', { href: '/' }) 18945 .on('click', function (e) { 18946 e.preventDefault(); 18947 window.InvoiceReport.reportModal.openDialog(); 18948 }) 18949 .text('Myynnit') 18950 ), 18951 $('<li />', {}).append( 18952 $('<a />', { href: '/' }) 18953 .on('click', function (e) { 18954 e.preventDefault(); 18955 pages.reskontra.showCreateOpenInvoicesReportDialog(); 18956 }) 18957 .text('Avoimet laskut') 18958 ), 18959 $('<li />', {}).append( 18960 $('<a />', { href: '/' }) 18961 .on('click', function (e) { 18962 e.preventDefault(); 18963 window.SATReport.reportModal.openDialog(); 18964 }) 18965 .text('SAT-raportti') 18966 ), 18967 $('<li />', {}).append( 18968 $('<a />', { href: '/' }) 18969 .on('click', function (e) { 18970 e.preventDefault(); 18971 window.CreditLossReport.reportModal.openDialog(); 18972 }) 18973 .text('Luottotappiot') 18974 ) 18975 ) 18976 ) 18977 .parent() 18978 .parent()
18979 .find('#new_report') 18980 .on('click', function () { 18981 console.log('#new_report'); 18982 18983 //pages.reskontra.show_invoice_dialog('company'); 18984 //window.location = '/lasku/yrityslasku/'; 18985 var $menu = $(this).parent().next(); 18986 18987 if ($menu.is(':visible')) { 18988 $menu.hide(); 18989 } else { 18990 $menu.show().position({ 18991 my: 'left top', 18992 at: 'left bottom', 18993 of: this, 18994 }); 18995 } 18996 18997 var menu = $(this).parent().next(); 18998 $(document).one('click', function () { 18999 menu.hide(); 19000 }); 19001 return false; 19002 }) 19003 .parent() 19004 .buttonset() 19005 .next() 19006 .hide() 19007 .menu(); 19008 19009 $('#close_previous_accounting_period').on('click', function () { 19010 console.log('close previous accounting period'); 19011 19012 var $closeButton = $(this); 19013 19014 $('<div></div>') 19015 .html('<p>Haluatko varmasti sulkea edellisen kirjanpitokauden?</p>') 19016 .dialog({ 19017 autoOpen: true, 19018 modal: true, 19019 resizable: false, 19020 draggable: false, 19021 title: 'Sulje edellinen kirjanpitokausi', 19022 beforeClose: function (event, ui) { 19023 event.stopPropagation(); 19024 }, 19025 buttons: { 19026 Peruuta: function () { 19027 $(this).dialog('close'); 19028 }, 19029 'Sulje kirjanpitokausi': function () { 19030 pages.reskontra.close_previous_accounting_period($(this), $closeButton); 19031 }, 19032 }, 19033 }); 19034 }); 19035 19036 $('#new_invoice_company') 19037 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19038 .on('click', function () { 19039 //pages.reskontra.show_invoice_dialog('company'); 19040 window.location = '/lasku/yrityslasku/'; 19041 }); 19042 19043 $('#new_configurable_report') 19044 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19045 .click(function () { 19046 window.InvoiceReport.reportModal.openDialog(); 19047 }), 19048 $('#new_pos_payment') 19049 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19050 .click(function () { 19051 window.location.href = '/innokassa/add'; 19052 }), 19053 $('#new_invoice_report') 19054 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19055 .on('click', function () { 19056 pages.reskontra.createInvoiceReport(); 19057 }); 19058 19059 $('#new_direct_payments_report') 19060 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19061 .on('click', function () { 19062 var $createReportDialog = $('<div></div>') 19063 .append( 19064 $('<form />', { 19065 id: 'create_direct_payments_report', 19066 target: '_blank', 19067 method: 'post', 19068 }).append( 19069 $('<span />', { class: 'ui-helper-hidden-accessible' }).append('<input />', { 19070 type: 'text', 19071 }), 19072 $('<fieldset />', { class: 'fs-invisible', style: '' }).append( 19073 $('<ol />').append( 19074 $('<li />', { style: 'padding:7px 0;' }).append( 19075 $('<label />', { id: 'date_from_label', style: 'width:130px;' }).html( 19076 'Kassaraportti ajalta' 19077 ), 19078 $date_from, 19079 ' - ', 19080 $date_to 19081 ), 19082 $('<li />', { style: 'padding:7px 0;' }).append( 19083 $('<label />', { 19084 id: '', 19085 style: 'font-weight:bold; width:130px; height:40px;', 19086 }).html('Maksutapa'), 19087 $('<select/>', { name: 'filters[payment_type]' }).append( 19088 $('<option />', { value: 'all' }).html('Kaikki'), 19089 $('<option />', { value: 'cash' }).html('Käteismaksu'), 19090 $('<option />', { value: 'card' }).html('Korttimaksu'), 19091 $('<option />', { value: 'cash_on_delivery' }).html('Jälkivaatimus') 19092 ) 19093 ) 19094 ) 19095 ) 19096 ) 19097 ) 19098 .dialog({ 19099 width: 550, 19100 autoOpen: true, 19101 modal: true, 19102 resizable: false, 19103 draggable: false, 19104 beforeClose: function (event, ui) { 19105 event.stopPropagation(); 19106 }, 19107 title: 'Luo kassaraportti', 19108 buttons: { 19109 Peruuta: function () { 19110 $(this).dialog('close'); 19111 }, 19112 'Luo PDF': function () { 19113 $createReportDialog 19114 .find('form') 19115 .attr('action', '/reskontra/create_direct_payments_report/pdf') 19116 .submit(); 19117 // $createReportDialog.find('form') 19118 }, 19119 /* 19120 'Luo CSV': function() { 19121 $createReportDialog 19122 .find('form') 19123 .attr('action', '/reskontra/create_direct_payments_report/csv') 19124 .submit(); 19125 }, 19126 19127 */ 19128 }, 19129 }); 19130 }); 19131 19132 $('#new_invoice_from_registry') 19133 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19134 .on('click', function () { 19135 window.location = '/lasku/asiakasrekisterista/'; 19136 }); 19137 19138 $('#new_invoice_insurance_company') 19139 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19140 .on('click', function () { 19141 window.location = '/lasku/vakuutusyhtio/'; 19142 }); 19143 19144 $('#new_part_payment') 19145 .button({ icons: { primary: 'ui-icon-plusthick' } }) 19146 .on('click', function () { 19147 window.location = '/osamaksu/'; 19148 }); 19149 19150 $('button#export_invoice_csv').on('click', function (event) { 19151 event.preventDefault(); 19152 19153 pages.reskontra.getDatatableCsv(pages.reskontra.dataTableParams.invoice, 'invoice', 'button#export_invoice_csv'); 19154 }); 19155 19156 $('button#export_part_payment_csv').on('click', function (event) { 19157 event.preventDefault(); 19158 19159 pages.reskontra.getDatatableCsv(pages.reskontra.dataTableParams.partPayments, 'partPayment', 'button#export_part_payment_csv'); 19160 }); 19161 19162 $('button#export_direct_payment_csv').on('click', function (event) { 19163 event.preventDefault(); 19164 19165 pages.reskontra.getDatatableCsv(pages.reskontra.dataTableParams.directPayments, 'directPayment', 'button#export_direct_payment_csv'); 19166 }); 19167 19168 $('#corporate-chain-invoices_filter_form.extended').delegate( 19169 'input:checkbox', 19170 'change', 19171 function () { 19172 var filter = $(this).attr('name'), 19173 is_checked = $(this).is(':checked'); 19174 19175 if (filter != 'all' && is_checked) { 19176 $('#corporate-chain-invoices_filter_form') 19177 .find('input[name=all]') 19178 .prop('checked', false); 19179 } 19180 19181 if (filter == 'all' && is_checked) { 19182 $('#corporate-chain-invoices_filter_form')
19183 .find('input:checkbox:checked') 19184 .each(function (index, elem) { 19185 if ($(elem).attr('name') != 'all') { 19186 $(elem).prop('checked', false); 19187 } 19188 }); 19189 } 19190 } 19191 ); 19192 19193 $( 19194 '#corporate-chain-invoices_filter_form input:checkbox, #corporate-chain-invoices_filter_form select' 19195 ).change(function (e) { 19196 var filters = []; 19197 19198 $('#corporate-chain-invoices_filter_form input:checkbox:checked').each(function () { 19199 filters.push($(this).attr('name')); 19200 }); 19201 if(filters.length === 0){ 19202 return; 19203 } 19204 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 19205 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 19206 setTimeout(function () { 19207 pages.reskontra.$corporate_chain_invoices_dt.fnClearTable(0); 19208 pages.reskontra.$corporate_chain_invoices_dt.fnDraw(); 19209 }, 1); 19210 }); 19211 19212 $('#invoices_filter_form.extended').delegate('input:checkbox', 'change', function () { 19213 var filter = $(this).attr('name'), 19214 is_checked = $(this).is(':checked'); 19215 19216 if (filter != 'all' && is_checked) { 19217 $('#invoices_filter_form').find('input[name=all]').prop('checked', false); 19218 } 19219 19220 if (filter == 'all' && is_checked) { 19221 $('#invoices_filter_form') 19222 .find('input:checkbox:checked') 19223 .each(function (index, elem) { 19224 if ($(elem).attr('name') != 'all') { 19225 $(elem).prop('checked', false); 19226 } 19227 }); 19228 } 19229 }); 19230 19231 $('#invoices_dt').on('click', 'a.show_invoice, a.show_invoice_log', function (e) { 19232 e.preventDefault(); 19233 19234 var invoice_id = $(e.target).attr('href'); 19235 var action = $(e.target).attr('class'); 19236 19237 var n = invoice_id.lastIndexOf('/'); 19238 19239 invoice_id = invoice_id.substring(n + 1); 19240 19241 switch (action) { 19242 case 'show_invoice': 19243 pages.reskontra.show_invoice(invoice_id); 19244 break; 19245 case 'show_invoice_log': 19246 pages.reskontra.show_invoice_log(invoice_id); 19247 break; 19248 } 19249 }); 19250 19251 19252 $('#corporate-chain-invoices_dt').on( 19253 'click', 19254 'a.show_invoice, a.show_invoice_log', 19255 function (e) { 19256 e.preventDefault(); 19257 19258 var invoice_id = $(e.target).attr('href'); 19259 var action = $(e.target).attr('class'); 19260 19261 var n = invoice_id.lastIndexOf('/'); 19262 19263 invoice_id = invoice_id.substring(n + 1); 19264 19265 switch (action) { 19266 case 'show_invoice': 19267 pages.reskontra.show_invoice(invoice_id); 19268 break; 19269 case 'show_invoice_log': 19270 pages.reskontra.show_invoice_log(invoice_id); 19271 break; 19272 } 19273 } 19274 ); 19275 19276 $('#money_transfers_dt').on('click', 'a.show_money_transfer_item', function (e) { 19277 e.preventDefault(); 19278 var money_transfer_item_url = $(e.target).attr('href'); 19279 var action = $(e.target).attr('class'); 19280 var parts = money_transfer_item_url.split('/'); 19281 19282 switch (action) { 19283 case 'show_money_transfer_item': 19284 pages.reskontra.show_money_transfer_item(parts[1], parts[0]); 19285 break; 19286 } 19287 }); 19288 19289 $('#direct_payments_dt').on( 19290 'click', 19291 'a.show_add_payment_dialog, a.show_account_card, a.show_direct_payment_log, a.reskontra_show_job_order, a.show_direct_payment, a.show_pos_payment, a.show_freight', 19292 19293 function (e) { 19294 console.log('here'); 19295 e.preventDefault(); 19296 var id = $(e.target).attr('href'); 19297 var action = $(e.target).attr('class'); 19298 var companyId = $(e.target).attr('data-companyId'); 19299 var openAmount = $(e.target).attr('data-openAmount'); 19300 19301 switch (action) { 19302 case 'show_add_payment_dialog': 19303 pages.reskontra.showAddDirectPaymentDialog(id, openAmount); 19304 break; 19305 case 'show_account_card': 19306 window.AccountCard.show(companyId); 19307 break; 19308 case 'reskontra_show_job_order': 19309 window.openDialog(id); 19310 break; 19311 case 'show_direct_payment_log': 19312 global.show_log(id); 19313 break; 19314 case 'show_direct_payment': 19315 pages.reskontra.show_direct_payment(id); 19316 break; 19317 case 'show_pos_payment': 19318 document.location.href = '/innokassa/edit/' + id; 19319 break; 19320 case 'show_freight': 19321 // @ai:claude same-window navigation for freight links; href already holds the full /innorahti/edit/{id} path 19322 document.location.href = id; 19323 break; 19324 } 19325 } 19326 ); 19327 19328 var showStationField = 19329 window.App.company.mod_company_group && window.App.company.company_group_admin; 19330 19331 19332 if($('#toistuva_laskutus').length !== 0){ 19333 pages.reskontra.recurring_invoicing = new recurringInvoicing({ 19334 showStation: showStationField, 19335 isAdmin: false, 19336 controller: '/reskontra', 19337 invoiceEndpoint: '/reskontra/invoicesDataTable/' 19338 }); 19339
19340 pages.reskontra.recurring_invoicing.init(); 19341 19342 } 19343 //If there is part_payments datatable init it 19344 if ($('#part_payments_dt').size()) { 19345 $('#part_payments_dt').on('click', 'a', function (e) { 19346 e.preventDefault(); 19347 19348 var id = $(e.target).attr('href'); 19349 var action = $(e.target).attr('class'); 19350 19351 switch (action) { 19352 case 'show_part_payment_log': 19353 global.show_log(id); 19354 break; 19355 case 'show_part_payment': 19356 pages.reskontra.show_part_payment(id); 19357 break; 19358 case 'show_invoice': 19359 pages.reskontra.show_invoice(id); 19360 break; 19361 case 'show_invoice_log': 19362 pages.reskontra.show_invoice_log(id); 19363 break; 19364 } 19365 }); 19366 19367 $('#part_payments_filter_form').find('select[name="company[]"]').on('changed.bs.select', function (e, clickedIndex, isSelected) { 19368 var $select = $(this); 19369 var selectedValues = $select.val() ? $select.val() : []; 19370 19371 if (selectedValues.includes('all') && selectedValues.length > 1) { 19372 if ($select.find('option').eq(clickedIndex).val() === 'all') { 19373 selectedValues = ['all']; 19374 } else { 19375 selectedValues = selectedValues.filter(function(company){ return company !== 'all'}); 19376 } 19377 $select.selectpicker('val', selectedValues); 19378 } 19379 19380 }); 19381 19382 //If company group admin, we want to show the company field in datatable 19383 19384 pages.reskontra.$part_payments_datatable = $('#part_payments_dt').dataTable({ 19385 oLanguage: global.dataTablesLanguage, 19386 sPaginationType: 'full_numbers', 19387 bPaginate: true, 19388 bAutoWidth: false, 19389 bJQueryUI: true, 19390 bFilter: true, 19391 bInfo: true, 19392 bProcessing: true, 19393 bServerSide: true, 19394 sAjaxSource: 'osamaksu/get_part_payments/', 19395 aoColumns: [ 19396 /** SopimusNr **/ null, 19397 /** Yritys **/ { bVisible: false, bSearchable: false }, 19398 /** Toimipiste **/ { bVisible: showStationField, bSortable: false, bSearchable: false }, 19399 /** Luotonhakija **/ null, 19400 /** Summa **/ null, 19401 /** Sopimuspvm **/ { sType: 'date-eu' }, 19402 /** Käsirahan eräpäivä **/ { bVisible: false, bSearchable: false }, 19403 /** Toimituspvm **/ { sType: 'date-eu' }, 19404 /** Rahoituspvm **/ { bVisible: false, bSearchable: false }, 19405 /** Sopimuksen tila **/ null, 19406 /** Käsirahan tila **/ { bVisible: false, bSearchable: false }, 19407 /** Käsirahalasku ID **/ { bVisible: false, bSearchable: false }, 19408 /** Tililasku ID **/ { bVisible: false, bSearchable: false }, 19409 /** Käsirahalasku **/ { bVisible: false, bSearchable: false }, 19410 /** Tililasku **/ { bVisible: false, bSearchable: false }, 19411 ], 19412 aaSorting: [[0, 'desc']], 19413 19414 fnServerParams: function (aoData) { 19415 var month = $('#osamaksusopimukset') 19416 .find('select[name=month] option:selected') 19417 .attr('value'); 19418 var year = $('#osamaksusopimukset') 19419 .find('select[name=year] option:selected') 19420 .attr('value'); 19421 19422 var selectedCompanies = $('#part_payments_filter_form select[name="company[]"]').val() ? $('#part_payments_filter_form select[name="company[]"]').val() : []; 19423 19424 if (selectedCompanies.includes('all')){ 19425 selectedCompanies = selectedCompanies.filter(function (company) { return company !== 'all'}); 19426 } 19427 19428 company = selectedCompanies.includes('all') ? 'all' : selectedCompanies; 19429 19430 var startDate; 19431 var endDate; 19432 if ($('input#filter-part-payment-start-date').length > 0) { 19433 startDate = $('input#filter-part-payment-start-date')[0].value; 19434 endDate = $('input#filter-part-payment-end-date')[0].value; 19435 } 19436 19437 var filters = []; 19438 19439 $('#part_payments_filter_form input:checkbox:checked').each(function () { 19440 filters.push($(this).attr('name')); 19441 }); 19442 19443 // filters.push('part_payments'); 19444 19445 aoData.push({ name: 'month', value: month }); 19446 aoData.push({ name: 'year', value: year }); 19447 aoData.push({ name: 'company', value: company }); 19448 aoData.push({ name: 'startDate', value: startDate }); 19449 aoData.push({ name: 'endDate', value: endDate }); 19450 aoData.push({ name: 'filters', value: filters }); 19451 19452 $('#export_part_payment_csv').html(global.$mini_loader).attr('disabled', true); 19453 pages.reskontra.dataTableParams.partPayments = aoData; 19454 }, 19455 19456 fnInfoCallback: function (oSettings, iStart, iEnd, iMax, iTotal, sPre) { 19457 19458 var responseJson = JSON.parse(oSettings.jqXHR.responseText); 19459 var sums = responseJson.iSumma; 19460 if (typeof sums !== 'undefined') { 19461 return (
19462 'Näytetään rivit ' + 19463 iStart + 19464 ' - ' + 19465 iEnd + 19466 ' / ' + 19467 iTotal + 19468 ', summa: ' + 19469 sums.sumTotal 19470 ); 19471 } 19472 return 'Näytetään rivit ' + iStart + ' - ' + iEnd + ' / ' + iTotal; 19473 }, 19474 19475 fnDrawCallback: function(){ 19476 $('#export_part_payment_csv').html('Vie Csv-tiedostoon').attr('disabled', false); 19477 }, 19478 19479 //Called before each row is shown 19480 fnRowCallback: function (nRow, aData, iDisplayIndex) { 19481 var part_payment_id = aData[0]; 19482 var part_payment_status = aData[9]; 19483 var down_payment_status = aData[10]; 19484 19485 var down_payment_invoice_id = aData[11]; 19486 var part_payment_invoice_id = aData[12]; 19487 19488 var down_payment_invoice_no = aData[13]; 19489 var part_payment_invoice_no = aData[14]; 19490 //var open_sum = aData[8]; 19491 //var row_class = aData[12]; 19492 //var status = aData[11]; 19493 19494 //Add the transaction id to every rows data object 19495 //$(nRow).addClass(row_class); 19496 $('td:eq(0)', nRow).html( 19497 '<a href="' + 19498 part_payment_id + 19499 '" class="show_part_payment" >' + 19500 part_payment_id + 19501 '</a>' 19502 ); 19503 $('td:eq(' + (5 + showStationField) + ')', nRow).html(
19504 '<a href="/logs/getLogHtml/part_payment/' + 19505 part_payment_id + 19506 '" name="global" class="show_part_payment_log" >' + 19507 part_payment_status + 19508 '</a>' 19509 ); 19510 19511 if (part_payment_invoice_id == null) { 19512 $('td:eq(' + (9 + showStationField) + ')', nRow).html(''); 19513 } else { 19514 $('td:eq(' + (9 + showStationField) + ')', nRow).html( 19515 '<a href="' + 19516 part_payment_invoice_id + 19517 '" class="show_invoice" >' + 19518 part_payment_invoice_no + 19519 '</a>' 19520 ); 19521 } 19522 19523 if (down_payment_invoice_id == null) { 19524 $('td:eq(' + (6 + showStationField) + ')', nRow).html(''); 19525 $('td:eq(' + (7 + showStationField) + ')', nRow).html(''); 19526 } else { 19527 $('td:eq(' + (6 + showStationField) + ')', nRow).html( 19528 '<a href="' + 19529 down_payment_invoice_id + 19530 '" class="show_invoice_log" >' + 19531 down_payment_status + 19532 '</a>' 19533 ); 19534 $('td:eq(' + (7 + showStationField) + ')', nRow) 19535 .addClass('status') 19536 .html( 19537 '<a href="' + 19538 down_payment_invoice_id + 19539 '" class="show_invoice" >' + 19540 down_payment_invoice_no + 19541 '</a>' 19542 ); 19543 } 19544 19545 return nRow; 19546 }, 19547 }); 19548 19549 $('#part_payments_filter_form input:checkbox, #part_payments_filter_form select').change( 19550 function (e) { 19551 var filters = []; 19552 19553 $('#part_payments_filter_form input:checkbox:checked').each(function () { 19554 filters.push($(this).attr('name')); 19555 }); 19556 if(filters.length === 0){ 19557 return; 19558 } 19559 19560 setTimeout(function () { 19561 pages.reskontra.$part_payments_datatable.fnClearTable(0); 19562 pages.reskontra.$part_payments_datatable.fnDraw(); 19563 }, 1); 19564 19565 } 19566 ); 19567 } 19568 19569 function isCorrectDateFormat(input) { 19570 return /^([0-9]|[0-9]{2})[./]([0-9]|[0-9]{2})[./]([0-9]{4})$/.test(input); 19571 } 19572 19573 $('#invoices_filter_form input:checkbox, #invoices_filter_form select').change(function (e) { 19574 var filters = []; 19575 19576 $('#invoices_filter_form input:checkbox:checked').each(function () { 19577 filters.push($(this).attr('name')); 19578 }); 19579 if(filters.length === 0){ 19580 return; 19581 } 19582 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 19583 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 19584 setTimeout(function () { 19585 pages.reskontra.$datatable.fnClearTable(0); 19586 pages.reskontra.$datatable.fnDraw(); 19587 }, 1); 19588 }); 19589 19590 $('.input-group.date .input-group-addon.open-calendar').on('click', function (e) { 19591 e.preventDefault(); 19592 $(this).parent().children().first().trigger('focus'); 19593 }); 19594 $('.input-group.date .input-group-addon.delete-date').on('click', function (e) { 19595 e.preventDefault(); 19596 $(this).parent().children().first().datepicker('update', ''); 19597 $(this).parent().children().first().trigger('changeDate'); 19598 }); 19599 $('input#filter-invoice-start-date, input#filter-invoice-end-date').each(function () { 19600 $(this).on('change changeDate clearDate blur', function (e) { 19601 var d = e.target.value; 19602 if (/^[0-9]{6}$/.test(d)) { 19603 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 19604 $(this).trigger('changeDate'); 19605 $(this).trigger('blur'); 19606 $(this).datepicker('hide'); 19607 return; 19608 } 19609 if (/^[0-9]{8}$/.test(d)) { 19610 $(this).datepicker( 19611 'update', 19612 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 19613 ); 19614 $(this).trigger('changeDate'); 19615 $(this).trigger('blur'); 19616 $(this).datepicker('hide'); 19617 return; 19618 } 19619 if (!!d && !isCorrectDateFormat(d)) { 19620 if (e.type === 'blur') { 19621 $(this).datepicker('update', ''); 19622 } 19623 return; 19624 } 19625 if (e.type === 'changeDate') { 19626 setTimeout(function () { 19627 pages.reskontra.$datatable.fnClearTable(0); 19628 pages.reskontra.$datatable.fnDraw(); 19629 }, 1); 19630 } 19631 }); 19632 });
19633 $('input#filter-dp-end-date, input#filter-dp-start-date').each(function () { 19634 $(this).on('change changeDate blur', function (e) { 19635 var d = e.target.value; 19636 if (/^[0-9]{6}$/.test(d)) { 19637 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 19638 $(this).trigger('changeDate'); 19639 $(this).trigger('blur'); 19640 $(this).datepicker('hide'); 19641 return; 19642 } 19643 if (/^[0-9]{8}$/.test(d)) { 19644 $(this).datepicker( 19645 'update', 19646 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 19647 ); 19648 $(this).trigger('changeDate'); 19649 $(this).trigger('blur'); 19650 $(this).datepicker('hide'); 19651 return; 19652 } 19653 if (!!e.target.value && !isCorrectDateFormat(d)) { 19654 if (e.type === 'blur') { 19655 $(this).datepicker('update', ''); 19656 } 19657 return; 19658 } 19659 if (e.type === 'changeDate') { 19660 setTimeout(function () { 19661 pages.reskontra.$direct_payments_dt.fnClearTable(0); 19662 pages.reskontra.$direct_payments_dt.fnDraw(); 19663 }, 1); 19664 } 19665 }); 19666 }); 19667 $('input#filter-part-payment-end-date, input#filter-part-payment-start-date').each( 19668 function () { 19669 $(this).on('change changeDate blur', function (e) { 19670 var d = e.target.value; 19671 if (/^[0-9]{6}$/.test(d)) { 19672 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 19673 $(this).trigger('changeDate'); 19674 $(this).trigger('blur'); 19675 $(this).datepicker('hide'); 19676 return; 19677 } 19678 if (/^[0-9]{8}$/.test(d)) { 19679 $(this).datepicker( 19680 'update', 19681 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 19682 ); 19683 $(this).trigger('changeDate'); 19684 $(this).trigger('blur'); 19685 $(this).datepicker('hide'); 19686 return; 19687 } 19688 if (!!e.target.value && !isCorrectDateFormat(d)) { 19689 if (e.type === 'blur') { 19690 $(this).datepicker('update', ''); 19691 } 19692 return; 19693 } 19694 if (e.type === 'changeDate') { 19695 setTimeout(function () { 19696 pages.reskontra.$part_payments_datatable.fnClearTable(0); 19697 pages.reskontra.$part_payments_datatable.fnDraw(); 19698 }, 1); 19699 } 19700 }); 19701 } 19702 ); 19703 $('input#filter-money-transfers-end-date, input#filter-money-transfers-start-date').each( 19704 function () { 19705 $(this).on('change changeDate blur', function (e) { 19706 var d = e.target.value; 19707 if (/^[0-9]{6}$/.test(d)) { 19708 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 19709 $(this).trigger('changeDate'); 19710 $(this).trigger('blur'); 19711 $(this).datepicker('hide'); 19712 return; 19713 } 19714 if (/^[0-9]{8}$/.test(d)) { 19715 $(this).datepicker( 19716 'update', 19717 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 19718 ); 19719 $(this).trigger('changeDate'); 19720 $(this).trigger('blur'); 19721 $(this).datepicker('hide'); 19722 return; 19723 } 19724 if (!!e.target.value && !isCorrectDateFormat(d)) { 19725 if (e.type === 'blur') { 19726 $(this).datepicker('update', ''); 19727 } 19728 return; 19729 } 19730 if (e.type === 'changeDate') { 19731 setTimeout(function () { 19732 pages.reskontra.$money_transfers_dt.fnClearTable(0); 19733 pages.reskontra.$money_transfers_dt.fnDraw(); 19734 }, 1); 19735 } 19736 }); 19737 } 19738 ); 19739 $('input#filter-corporate-chain-end-date, input#filter-corporate-chain-start-date').each( 19740 function () { 19741 $(this).on('change changeDate blur', function (e) { 19742 var d = e.target.value; 19743 if (/^[0-9]{6}$/.test(d)) { 19744 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 19745 $(this).trigger('changeDate'); 19746 $(this).trigger('blur'); 19747 $(this).datepicker('hide'); 19748 return; 19749 } 19750 if (/^[0-9]{8}$/.test(d)) { 19751 $(this).datepicker( 19752 'update', 19753 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 19754 ); 19755 $(this).trigger('changeDate'); 19756 $(this).trigger('blur'); 19757 $(this).datepicker('hide'); 19758 return; 19759 } 19760 if (!!e.target.value && !isCorrectDateFormat(d)) { 19761 if (e.type === 'blur') { 19762 $(this).datepicker('update', ''); 19763 } 19764 return; 19765 } 19766 if (e.type === 'changeDate') { 19767 setTimeout(function () { 19768 pages.reskontra.$corporate_chain_invoices_dt.fnClearTable(0); 19769 pages.reskontra.$corporate_chain_invoices_dt.fnDraw(); 19770 }, 1); 19771 } 19772 }); 19773 } 19774 ); 19775 19776 $('#invoices_filter_form').find('select[name="company[]"]').on('changed.bs.select', function (e, clickedIndex, isSelected) { 19777 var $select = $(this); 19778 var selectedValues = $select.val() ? $select.val() : []; 19779 19780 if (selectedValues.includes('all') && selectedValues.length > 1) { 19781 if (isSelected && $select.find('option').eq(clickedIndex).val() === 'all') { 19782 selectedValues = ['all']; 19783 } else { 19784 selectedValues = selectedValues.filter(function(company) {return company !== 'all'}); 19785 } 19786 $select.selectpicker('val', selectedValues); 19787 } 19788 }); 19789
19790 pages.reskontra.$datatable = $('#invoices_dt').dataTable({ 19791 oSearch: {"sSearch": intialSearch}, 19792 oLanguage: global.dataTablesLanguage, 19793 sPaginationType: 'full_numbers', 19794 bPaginate: true, 19795 iDisplayLength: 25, 19796 bAutoWidth: false, 19797 bJQueryUI: true, 19798 bFilter: true, 19799 bInfo: true, 19800 bProcessing: true, 19801 bServerSide: true, 19802 sAjaxSource: 'reskontra/invoicesDataTable/', 19803 aoColumns: [ 19804 /** id **/ { bVisible: false, bSortable: true, bSearchable: true }, 19805 /** invoice_number **/ { bVisible: true, bSortable: false, bSearchable: true }, 19806 /** reference_nr **/ { bVisible: false, bSortable: false, bSearchable: true }, 19807 /** company **/ { bVisible: false, bSortable: false, bSearchable: false }, 19808 /** station **/ { bVisible: showStationField, bSortable: false, bSearchable: false }, 19809 /** receiver **/ null, 19810 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 19811 /** delivery_date **/ { sType: 'date-eu' }, 19812 /** due_date **/ { sType: 'date-eu' }, 19813 /** sum **/ { bSortable: false, bSearchable: false }, 19814 /** open_amount **/ { bVisible: true, bSortable: false, bSearchable: false }, 19815 /** is_financed **/ { bVisible: false, bSortable: false, bSearchable: false }, 19816 /** our_reference **/ null, 19817 /** status **/ null, 19818 /** status_class **/ { bVisible: false }, 19819 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 19820 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 19821 ], 19822 aaSorting: [[0, 'desc']], 19823 19824 fnServerParams: function (aoData) { 19825 var month = $('#invoices_filter_form select[name="month"] option:selected').attr('value'); 19826 var year = $('#invoices_filter_form select[name="year"] option:selected').attr('value'); 19827 var startDate; 19828 var endDate; 19829 if ($('input#filter-invoice-start-date').length > 0) { 19830 startDate = $('input#filter-invoice-start-date')[0].value; 19831 endDate = $('input#filter-invoice-end-date')[0].value; 19832 } 19833 19834 var filters = []; 19835 var selectedCompanies = $('#invoices_filter_form select[name="company[]"]').val() ? $('#invoices_filter_form select[name="company[]"]').val() : []; 19836 19837 if (selectedCompanies.includes('all') && selectedCompanies.length > 1){ 19838 selectedCompanies = selectedCompanies.filter(function(company){return company !== 'all'}); 19839 } 19840 19841 company = selectedCompanies.includes('all') ? 'all' : selectedCompanies; 19842 19843 $('#invoices_filter_form input:checkbox:checked').each(function () { 19844 filters.push($(this).attr('name')); 19845 }); 19846 19847 aoData.push({ name: 'month', value: month }); 19848 aoData.push({ name: 'year', value: year }); 19849 aoData.push({ name: 'company', value: company }); 19850 aoData.push({ name: 'startDate', value: startDate }); 19851 aoData.push({ name: 'endDate', value: endDate }); 19852 aoData.push({ name: 'filters', value: filters }); 19853 19854 $('#export_invoice_csv').attr('disabled', true); 19855 $('#export_invoice_csv').html(global.$mini_loader); 19856 pages.reskontra.dataTableParams.invoice = aoData; 19857 }, 19858 19859 fnInfoCallback: function (oSettings, iStart, iEnd, iMax, iTotal, sPre) { 19860 19861 var responseJson = JSON.parse(oSettings.jqXHR.responseText); 19862 var sums = responseJson.iSumma; 19863 if (typeof sums !== 'undefined') { 19864 return ( 19865 'Näytetään rivit ' + 19866 iStart + 19867 ' - ' + 19868 iEnd + 19869 ' / ' + 19870 iTotal + 19871 ', summa: ' + 19872 sums.amountToPay + 19873 ', avoinna: ' + 19874 sums.openAmount 19875 ); 19876 } 19877 return 'Näytetään rivit ' + iStart + ' - ' + iEnd + ' / ' + iTotal; 19878 }, 19879 19880 fnDrawCallback: function () {
19881 var month = $('#invoices_filter_form select.month option:selected').html(); 19882 var year = $('#invoices_filter_form select.year option:selected').html(); 19883 $('#ac-tab-invoices span.month_year').html(month + ', ' + year); 19884 $('#export_invoice_csv').html('Vie Csv-tiedostoon').attr('disabled', false); 19885 }, 19886 19887 //Called before each row is shown 19888 fnRowCallback: function (nRow, aData, iDisplayIndex) { 19889 var invoiceId = aData[0]; 19890 var invoiceNumber = aData[1]; 19891 var rowClass = aData[14]; 19892 var status = aData[13]; 19893 19894 //Add the transaction id to every rows data object 19895 //$(nRow).data({"invoice_id":invoice_id}); 19896 $(nRow).addClass(rowClass); 19897 19898 $('td:eq(0)', nRow).html( 19899 '<a href="' + invoiceId + '" class="show_invoice" >' + invoiceNumber + '</a>' 19900 ); 19901 19902 //Status column is 8:th in case the station col is visible 19903 $('td:eq(' + (7 + showStationField) + ')', nRow) 19904 .addClass('status') 19905 .html('<a href="' + invoiceId + '" class="show_invoice_log" >' + status + '</a>'); 19906 19907 return nRow; 19908 }, 19909 }); 19910 19911 pages.reskontra.$corporate_chain_invoices_dt = $('#corporate-chain-invoices_dt').dataTable({ 19912 oLanguage: global.dataTablesLanguage, 19913 sPaginationType: 'full_numbers', 19914 bPaginate: true, 19915 iDisplayLength: 10, 19916 bAutoWidth: false, 19917 bJQueryUI: true, 19918 bFilter: true, 19919 bInfo: true, 19920 bProcessing: true, 19921 bServerSide: true, 19922 sAjaxSource: 'reskontra/invoicesDataTable/', 19923 aoColumns: [ 19924 /** invoice_id **/ null, 19925 /** gothia_invoice_number **/ { bVisible: false, bSortable: false, bSearchable: true }, 19926 /** reference_nr **/ { bVisible: false, bSortable: false, bSearchable: true }, 19927 /** company **/ { bVisible: true, bSortable: false, bSearchable: false }, 19928 /** Toimipiste **/ { bVisible: false, bSortable: false, bSearchable: false }, 19929 /** receiver **/ null, 19930 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 19931 /** date **/ { sType: 'date-eu' }, 19932 /** due_date **/ { sType: 'date-eu' }, 19933 /** sum **/ { bSortable: false, bSearchable: false }, 19934 /** open_sum **/ { bVisible: true, bSortable: false, bSearchable: false }, 19935 /** rahoitettu **/ { bVisible: false, bSortable: false, bSearchable: false }, 19936 /** our_reference **/ null, 19937 /** status **/ null, 19938 /** status_class **/ { bVisible: false }, 19939 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 19940 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 19941 ], 19942 aaSorting: [[0, 'desc']], 19943 19944 fnServerParams: function (aoData) { 19945 var month = $('#corporate-chain-invoices_filter_form select.month option:selected').attr( 19946 'value' 19947 ) || 'all'; 19948 var year = $('#corporate-chain-invoices_filter_form select.year option:selected').attr( 19949 'value' 19950 ) || 'all'; 19951 19952 var startDate; 19953 var endDate; 19954 if ($('input#filter-corporate-chain-start-date').length > 0) { 19955 startDate = $('input#filter-corporate-chain-start-date')[0].value; 19956 endDate = $('input#filter-corporate-chain-end-date')[0].value; 19957 } 19958 19959 var filters = []; 19960 19961 filters.push('corporate_chain_invoices'); 19962 19963 $('#corporate-chain-invoices_filter_form input:checkbox:checked').each(function () { 19964 filters.push($(this).attr('name')); 19965 }); 19966 19967 aoData.push({ name: 'month', value: month }); 19968 aoData.push({ name: 'year', value: year }); 19969 aoData.push({ name: 'startDate', value: startDate }); 19970 aoData.push({ name: 'endDate', value: endDate }); 19971 aoData.push({ name: 'filters', value: filters }); 19972 }, 19973 19974 fnDrawCallback: function () { 19975 var month = $( 19976 '#corporate-chain-invoices_filter_form select.month option:selected' 19977 ).html(); 19978 var year = $('#corporate-chain-invoices_filter_form select.year option:selected').html(); 19979 $('#ac-tab-invoices span.month_year').html(month + ', ' + year); 19980 }, 19981 19982 //Called before each row is shown 19983 fnRowCallback: function (nRow, aData, iDisplayIndex) { 19984 var invoice_id = aData[0]; 19985 var rowClass = aData[14]; 19986 var status = aData[13]; 19987 19988 //Add the transaction id to every rows data object 19989 //$(nRow).data({"invoice_id":invoice_id}); 19990 $(nRow).addClass(rowClass); 19991 19992 $('td:eq(0)', nRow).html( 19993 '<a href="' + invoice_id + '" class="show_invoice" >' + invoice_id + '</a>' 19994 ); 19995 $('td:eq(8)', nRow) 19996 .addClass('status') 19997 .html('<a href="' + invoice_id + '" class="show_invoice_log" >' + status + '</a>'); 19998 19999 return nRow; 20000 }, 20001 }); 20002 20003 pages.reskontra.$money_transfers_dt = $('#money_transfers_dt').dataTable({ 20004 oLanguage: global.dataTablesLanguage, 20005 sPaginationType: 'full_numbers', 20006 bPaginate: true, 20007 bAutoWidth: false, 20008 bJQueryUI: true, 20009 bFilter: true, 20010 bInfo: true, 20011 bProcessing: true,
20012 bServerSide: true, 20013 sAjaxSource: 'reskontra/moneyTransferItemsDataTable/', 20014 aoColumns: [ 20015 /** ID **/ { bVisible: false }, 20016 /** company_id **/ { bVisible: false }, 20017 /** Toimipiste **/ { bVisible: showStationField, bSortable: false, bSearchable: false }, 20018 /** date **/ { sType: 'date-eu' }, 20019 /** source */ null, 20020 /** paid_invoice **/ null, 20021 /** service_charges **/ null, 20022 /** money_transfer **/ null, 20023 /** reference_number **/ null, 20024 /** show_money_transfer_item **/ { bVisible: true, bSortable: false, bSearchable: false }, 20025 ], 20026 aaSorting: [[3, 'desc']], 20027 20028 fnServerParams: function (aoData) { 20029 /* Add some extra data to the sender */ 20030 var month = $('#money_transfers_filter_form select.month option:selected').attr('value') || 'all'; 20031 var year = $('#money_transfers_filter_form select.year option:selected').attr('value') || 'all'; 20032 var company = $('#money_transfers_filter_form select[name="company"] option:selected').attr('value'); 20033 var source = $('#money_transfers_filter_form select.source option:selected').attr('value') || 'all'; 20034 20035 var startDate; 20036 var endDate; 20037 if ($('input#filter-money-transfers-start-date').length > 0) { 20038 startDate = $('input#filter-money-transfers-start-date')[0].value; 20039 endDate = $('input#filter-money-transfers-end-date')[0].value; 20040 } 20041 20042 aoData.push({ name: 'company', value: company }); 20043 aoData.push({ name: 'month', value: month }); 20044 aoData.push({ name: 'year', value: year }); 20045 aoData.push({ name: 'source', value: source }); 20046 aoData.push({ name: 'startDate', value: startDate }); 20047 aoData.push({ name: 'endDate', value: endDate }); 20048 20049 }, 20050 20051 //Called before each row is shown 20052 fnRowCallback: function (nRow, aData, iDisplayIndex) { 20053 var money_transfer_item_id = aData[0], 20054 company_id = aData[1], 20055 paid_invoices = aData[5], 20056 service_charges = aData[6], 20057 money_transferred = aData[7]; 20058 source = aData[4]; 20059 20060 var colShift = showStationField ? 1 : 0; 20061 20062 $('td:eq('+ (6 + colShift) +')', nRow).html( 20063 '<a href="' + source + '/' + money_transfer_item_id + '" class="show_money_transfer_item" >Näytä tiedot</a>' 20064 ); 20065 20066 return nRow; 20067 }, 20068 }); 20069 20070 $('#money_transfers_filter_form select').on('change', function (e) { 20071 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 20072 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 20073 setTimeout(function () { 20074 pages.reskontra.$money_transfers_dt.fnClearTable(0); 20075 pages.reskontra.$money_transfers_dt.fnDraw(); 20076 }, 1); 20077 }); 20078 20079 $('#direct_payments_filter_form').find('select[name="company[]"]').on('changed.bs.select', function (e, clickedIndex, isSelected) { 20080 var $select = $(this); 20081 var selectedValues = $select.val() ? $select.val() : []; 20082 20083 if (selectedValues.includes('all') && selectedValues.length > 1) { 20084 if (isSelected && $select.find('option').eq(clickedIndex).val() === 'all') { 20085 selectedValues = ['all']; 20086 } else { 20087 selectedValues = selectedValues.filter(function(company){return company !== 'all'}); 20088 } 20089 $select.selectpicker('val', selectedValues); 20090 } 20091 }); 20092 20093 pages.reskontra.$direct_payments_dt = $('#direct_payments_dt').dataTable({ 20094 oLanguage: global.dataTablesLanguage, 20095 sPaginationType: 'full_numbers', 20096 bAutoWidth: false, 20097 bJQueryUI: true, 20098 bFilter: true, 20099 bInfo: true, 20100 bPaginate: true, 20101 bProcessing: true, 20102 bServerSide: true, 20103 sAjaxSource: 'reskontra/directPaymentsDataTable/', 20104 aoColumns: [ 20105 /** ID **/ { bVisible: false }, 20106 /** Yritys ID **/ { bVisible: false }, 20107 /** Yritys **/ { bVisible: false }, 20108 /** Maksunumero **/ { bVisible: false }, 20109 /** TyömääräysId **/ { bVisible: false }, 20110 /** Työmääräysnumero **/ { bVisible: false }, 20111 /** KuormakirjaId **/ { bVisible: false }, 20112 /** Kuormakirjanumero **/ { bVisible: false }, 20113 /** Työ **/ { bSortable: false }, 20114 /** Toimipiste **/ { bVisible: showStationField, bSortable: false, bSearchable: false }, 20115 /** Pvm **/ null, 20116 /** Tyyppi **/ null, 20117 /** Maksaja / Viiteemme **/ { bVisible: showStationField }, 20118 /** Työn suorittaja **/ null, 20119 /** Summa **/ { bSortable: false }, 20120 /** Tilitetty **/ { bVisible: true, bSortable: false }, 20121 /** Avoinna **/ { bVisible: true, bSortable: false }, 20122 /** Tilakoodi **/ { bVisible: false }, 20123 /** Tila **/ { bSortable: 'status' }, 20124 /** Maksun päivä **/ { bVisible: false }, 20125 /** Työmääräys numero **/ { bVisible: false }, 20126 /** Työ tyyppi **/ { bVisible: false, bSearchable: false }, 20127 /** external payment id **/ { bVisible: false }, 20128 /** freight id **/ { bVisible: false }, 20129 ], 20130 aaSorting: [[0, 'desc']], 20131 20132 fnServerParams: function (aoData) { 20133 var filters = [], 20134 payment_type; 20135
20136 var month = 20137 $('#direct_payments_filter_form select.month option:selected').attr('value') || 'all'; 20138 var year = 20139 $('#direct_payments_filter_form select.year option:selected').attr('value') || 'all'; 20140 20141 var selectedCompanies = $('#direct_payments_filter_form select[name="company[]"]').val() ? $('#direct_payments_filter_form select[name="company[]"]').val() : []; 20142 20143 if (selectedCompanies.includes('all') && selectedCompanies.length > 1){ 20144 selectedCompanies = selectedCompanies.filter(function(company){return company !== 'all'}); 20145 } 20146 20147 company = selectedCompanies.includes('all') ? 'all' : selectedCompanies; 20148 20149 $('#direct_payments_filter_form input:checkbox:checked').each(function () { 20150 filters.push($(this).attr('name')); 20151 }); 20152 var startDate; 20153 var endDate; 20154 if ($('input#filter-dp-start-date').length > 0) { 20155 startDate = $('input#filter-dp-start-date')[0].value; 20156 endDate = $('input#filter-dp-end-date')[0].value; 20157 } 20158 20159 //If no checkbox filter in UI, open both and paid statuses to filters 20160 if ($('#direct_payments_filter_form input:checkbox').length < 1) { 20161 filters.push('paid'); 20162 filters.push('open'); 20163 } 20164 20165 payment_type = $('#direct_payments_filter_form') 20166 .find('select[name=payment_type] option:selected') 20167 .attr('value'); 20168 20169 filters.push(payment_type); 20170 20171 aoData.push({ name: 'filters', value: filters }); 20172 aoData.push({ name: 'company', value: company }); 20173 aoData.push({ name: 'month', value: month }); 20174 aoData.push({ name: 'year', value: year }); 20175 aoData.push({ name: 'endDate', value: endDate }); 20176 aoData.push({ name: 'startDate', value: startDate }); 20177 20178 $('#export_direct_payment_csv').html(global.$mini_loader).attr('disabled', true); 20179 pages.reskontra.dataTableParams.directPayments = aoData; 20180 }, 20181 20182 fnInfoCallback: function (oSettings, iStart, iEnd, iMax, iTotal, sPre) { 20183 20184 var responseJson = JSON.parse(oSettings.jqXHR.responseText); 20185 var sums = responseJson.iSumma; 20186 if (typeof sums !== 'undefined') { 20187 return ( 20188 'Näytetään rivit ' + 20189 iStart + 20190 ' - ' + 20191 iEnd + 20192 ' / ' + 20193 iTotal + 20194 ', summa: ' + 20195 sums.amountToPay + 20196 ', avoinna: ' + 20197 sums.openAmount 20198 ); 20199 } 20200 return 'Näytetään rivit ' + iStart + ' - ' + iEnd + ' / ' + iTotal; 20201 }, 20202 20203 fnDrawCallback: function(){ 20204 $('#export_direct_payment_csv').html('Vie Csv-tiedostoon').attr('disabled', false); 20205 }, 20206 20207 //Called before each row is shown 20208 fnRowCallback: function (nRow, aData, iDisplayIndex) { 20209 var id = aData[0], 20210 companyId = aData[1], 20211 companyName = aData[2], 20212 ourReference = aData[3], 20213 jobOrderId = aData[4], 20214 towingRecordId = aData[6], 20215 towingRecordNo = aData[7], 20216 paymentType = aData[11], 20217 amountToPay = aData[14], 20218 moneyTrasferred = aData[15], 20219 openAmount = aData[16], 20220 status = aData[18], 20221 entityNumber = aData[20], 20222 jobType = aData[21]; 20223 posId = aData[22]; 20224 extPaymentId = aData[23]; 20225 freightId = aData[24]; 20226 20227 var colShift = showStationField ? 1 : 0; 20228 20229 if (towingRecordId) { 20230 if (jobType === 'towing_record') { 20231 $('td:eq(0)', nRow).html( 20232 '<a href="kuormakirjat/get_towing_record_html/' + 20233 towingRecordId + 20234 '" name="kuormakirjat" class="show_towing_record" >' + 20235 towingRecordNo + 20236 '</a>' 20237 ); 20238 } 20239 } else if (extPaymentId) { 20240 $('td:eq(0)', nRow).html(extPaymentId.toString()); 20241 } else { 20242 if (jobType === 'pos') { 20243 $('td:eq(0)', nRow).html( 20244 '<a class="show_pos_payment" href="' + posId + '">' + ourReference + '</a>' 20245 ); 20246 } 20247 20248 if (jobType === 'job_order') { 20249 var jobOrderReference = ourReference.split('/'); 20250 jobOrderType = jobOrderReference[1]; 20251 if (jobOrderType !== ' RAH') { 20252 $('td:eq(0)', nRow).html( 20253 '<a href="' + 20254 jobOrderId.toString() + 20255 '" class="reskontra_show_job_order" >' + 20256 entityNumber.toString() + 20257 '</a>' 20258 ); 20259 } else { 20260 $('td:eq(0)', nRow).html(entityNumber.toString()); 20261 } 20262 } 20263 20264 if (jobType === 'freight') { 20265 $('td:eq(0)', nRow).html( 20266 '<a href="/innorahti/edit/' + 20267 freightId + 20268 '" class="show_freight" >' + 20269 entityNumber.toString() + 20270 '</a>' 20271 ); 20272 } 20273 } 20274 20275 if (paymentType === 'Korttimaksu') { 20276 $('td:eq(' + (2 + colShift) + ')', nRow).html( 20277 '<a href="' + id + '" class="show_direct_payment" >' + paymentType + '</a>' 20278 ); 20279 } 20280 20281 if(showStationField){ourReference 20282 $('td:eq(4)', nRow).html(ourReference); 20283 } 20284 20285 colShift += showStationField ? 1 : 0; 20286 20287 $('td:eq(' + (5 + colShift) + ')', nRow).html( 20288 '<a href="' + 20289 id + 20290 '" class="show_add_payment_dialog" data-moneyTransferred="' + 20291 moneyTrasferred + 20292 '" >' + 20293 moneyTrasferred + 20294 '</a>' 20295 ); 20296 20297 $('td:eq(' + (6 + colShift) + ')', nRow).html(openAmount); 20298 $('td:eq(' + (7 + colShift) + ')', nRow).html(
20299 '<a href="/logs/getLogHtml/direct_payment/' + 20300 id + 20301 '" class="show_direct_payment_log" name="global" >' + 20302 status + 20303 '</a>' 20304 ); 20305 20306 return nRow; 20307 }, 20308 }); 20309 20310 $('#direct_payments_filter_form input:checkbox, #direct_payments_filter_form select').on( 20311 'change', 20312 function (e) { 20313 // Timeout used here to prevent sending checked checkboxes when swithing from any filter -> all 20314 // If fnDraw() is called when swithcing checkboxes, previous filter will override all filter 20315 setTimeout(function () { 20316 pages.reskontra.$direct_payments_dt.fnClearTable(0); 20317 pages.reskontra.$direct_payments_dt.fnDraw(); 20318 }, 1); 20319 } 20320 ); 20321 20322 /* 20323 $('#direct_payments_recopart_dt').on( 20324 'click', 20325 'a.s, a.show_account_card, a.show_invoice_log,' + 20326 ' a.show_towing_record, a.show_log', 20327 function(e) { 20328 e.preventDefault(); 20329 20330 var id = $(e.target).attr('href'); 20331 var action = $(e.target).attr('class'); 20332 var companyId = $(e.target).attr('data-companyId'); 20333 var openAmount = $(e.target).attr('data-openAmount'); 20334 20335 switch (action) { 20336 case 'show_add_payment_dialog': 20337 pages.iv_laskutus_ja_reskontra.showAddDirectPaymentDialog(id, openAmount); 20338 break; 20339 case 'show_account_card': 20340 window.AccountCard.show(companyId); 20341 break; 20342 case 'show_towing_record': 20343 global.showJob(id); 20344 break; 20345 case 'show_log': 20346 global.show_log(id); 20347 break; 20348 } 20349 } 20350 ); 20351 */ 20352 20353 pages.reskontra.$direct_payments_recopart_dt = $('#direct_payments_recopart_dt').dataTable({ 20354 oLanguage: global.dataTablesLanguage, 20355 sPaginationType: 'full_numbers', 20356 bAutoWidth: false, 20357 bJQueryUI: true, 20358 bFilter: true, 20359 bInfo: true, 20360 bPaginate: true, 20361 bProcessing: true, 20362 bServerSide: true, 20363 sAjaxSource: 'reskontra/recopartDirectPaymentsDataTable/', 20364 aoColumns: [ 20365 /** ID **/ { bVisible: false }, 20366 /** Yritys ID **/ { bVisible: false }, 20367 /** Yritys **/ { bVisible: false }, 20368 /** Pvm **/ null, 20369 /** Maksunumero **/ { bVisible: true }, 20370 /** Tyyppi **/ null, 20371 /** Maksaja **/ { bVisible: true }, 20372 /** Oma viite **/ { bVisible: true }, 20373 /** Summa **/ null, 20374 /** external_order_id **/ { bVisible: false }, 20375 /** external_payment_id **/ { bVisible: false }, 20376 /** external_payment_reference **/ { bVisible: false }, 20377 ], 20378 aaSorting: [[0, 'desc']], 20379 20380 fnServerParams: function (aoData) { 20381 var filters = [], 20382 payment_type; 20383 20384 $('#direct_payments_recopart_filter_form input:checkbox:checked').each(function () { 20385 filters.push($(this).attr('name')); 20386 }); 20387 20388 payment_type = $('#direct_payments_recopart_filter_form') 20389 .find('select[name=payment_type] option:selected') 20390 .attr('value'); 20391 20392 filters.push(payment_type); 20393 20394 aoData.push({ name: 'filters', value: filters }); 20395 }, 20396 20397 //Called before each row is shown 20398 fnRowCallback: function (nRow, aData, iDisplayIndex) { 20399 var id = aData[0], 20400 companyId = aData[1], 20401 companyName = aData[2], 20402 ourReference = aData[3], 20403 amountToPay = aData[13]; 20404 20405 $('td:eq(0)', nRow).html( 20406 $('<a />', { 20407 href: 'reskontra/directPayment/' + id + '/', 20408 name: 'DirectPaymentDialog', 20409 class: 'show', 20410 }).html(id) 20411 ); 20412 20413 return nRow; 20414 }, 20415 }); 20416 20417 $('#direct_payments_recopart_filter_form').delegate('input, select', 'change', function (e) { 20418 pages.reskontra.$direct_payments_recopart_dt.fnClearTable(0); 20419 pages.reskontra.$direct_payments_recopart_dt.fnDraw(); 20420 }); 20421 }, // init 20422 20423 insert_invoice_to_ledger: function(invoice_id) { 20424 var $dialog = $('<div />', { style: 'text-align:left;' }) 20425 .html( 20426 'Haluatko varmasti lähettää laskun reskontrattavaksi? HUOM! Asiakkaalle ei toimiteta laskua' 20427 ) 20428 .dialog({ 20429 autoOpen: true, 20430 modal: true, 20431 resizable: false, 20432 draggable: false, 20433 title: 'Lähetä lasku reskontraan', 20434 beforeClose: function (event, ui) { 20435 event.stopPropagation(); 20436 }, 20437 buttons: { 20438 Peruuta: function () { 20439 $dialog.dialog('close'); 20440 }, 20441 'Lähetä lasku': function () { 20442 $.ajax({ 20443 dataType: 'json', 20444 type: 'POST', 20445 url: '/reskontra/insert_invoice_to_ledger/' + invoice_id, 20446 beforeSend: function(request) { 20447 global.showLoadingDialog('Lähetetään laskua...'); 20448 }, 20449 success: function (responseJSON) { 20450 if (responseJSON.type == 'success') { 20451 20452 if (pages.reskontra.$datatable != null) { 20453 pages.reskontra.$datatable.fnClearTable(0); 20454 pages.reskontra.$datatable.fnDraw(); 20455 } 20456 20457 LaskutusJaReskontra.showInvoiceDialog({ 20458 invoiceId: invoice_id, 20459 }); 20460 } 20461 20462 global.show_message(responseJSON); 20463 global.close_loading_dialog(); 20464 20465 $dialog.dialog('close'); 20466 }, 20467 error: function (response) { 20468 global.close_loading_dialog(); 20469 global.show_message($.parseJSON(response.responseText)); 20470 }, 20471 }); 20472 }, 20473 }, 20474 }); 20475 }, 20476 20477 showAddDirectPaymentDialog: function (id, openAmount) { 20478 //Define the URL and success function for the refund payment case 20479 var $dialog = $('#add_direct_payment_dialog'); 20480 20481 if (!$dialog.length) { 20482 $dialog = pages.reskontra.createDirectPaymentDialog(); 20483 $dialog.find('input#paid_date').datepicker($.datepicker.regional.fi); 20484 } 20485 20486 //Set date and open amount values 20487 $dialog.find('input#paid_date').datepicker('setDate', new Date()); 20488 $dialog.find('input#amount').val(openAmount); 20489 $dialog.find('input#id').val(id); 20490 20491 $dialog.dialog('open'); 20492 }, 20493 20494 showAddManualReminderDialog: function (invoiceId, recipientEmail) { 20495 var defaultReminderText = 'Kirjanpitomme mukaan tämä lasku on maksamatta. '; 20496 var textAreaStyle = 'width:320px; height:72px; font-weight: 500; line-height: 1.5;'; 20497 var textArea = $('<textarea />', { style: textAreaStyle, name: 'reminder_message' }); 20498 var sendMethodEl = 20499 '<div style="width: 100%;"><label>Toimitustapa: <select id="reminder_send_method" style="font-weight: 500; line-height: 1.5;" name="send_method"><option value="mail">Postitse</option><option value="email">Sähköpostitse</option></select></label></div>'; 20500 var recipientEl = 20501 '<div id="reminder_recipient_field" style="display: none;"><label style="width: 100%;">Vastaanottajan sähköpostiosoite: <input style="width: 200px;" type="text" name="recipient" value="' + 20502 recipientEmail + 20503 '"></div></div>'; 20504 $('<div></div>') 20505 .append( 20506 $('<label />', { style: 'width:auto;' }) 20507 .html('Muistutusteksti') 20508 .append(textArea) 20509 .append('<br />') 20510 .append(sendMethodEl) 20511 .append('<br />') 20512 .append(recipientEl) 20513 ) 20514 .dialog({ 20515 autoOpen: true, 20516 modal: true, 20517 resizable: false, 20518 draggable: false, 20519 width: 380, 20520 title: 'Lähetä maksumuistutus', 20521 open: function (event, ui) { 20522 $(textArea).val(defaultReminderText); 20523 $('#reminder_send_method').on('change', function (el) { 20524 if ($(this).val() == 'email') { 20525 $('#reminder_recipient_field').show(); 20526 } else { 20527 $('#reminder_recipient_field').hide(); 20528 } 20529 }); 20530 }, 20531 beforeClose: function (event, ui) { 20532 event.stopPropagation(); 20533 }, 20534 close: function () { 20535 $(this).dialog('destroy'); 20536 $(this).remove(); 20537 }, 20538 buttons: { 20539 Peruuta: function () { 20540 $(this).dialog('close'); 20541 }, 20542 'Lähetä muistutus': function () { 20543 var sendDialog = this; 20544 global.showLoadingDialog('Viestiä lähetetään...'); 20545 var message = $(this).find('textarea[name=reminder_message]').val(); 20546 if (message.length > 400) { 20547 global.close_loading_dialog(); 20548 global.show_message({ 20549 type: 'error', 20550 title: 'Virhe', 20551 text: 'Muistutusteksti ei saa olla yli 400 merkkiä pitkä.', 20552 }); 20553 return; 20554 } 20555 var sendMethod = $('#reminder_send_method').val(); 20556 var recipient = $('#reminder_recipient_field input').val(); 20557 var data = { 20558 invoiceId: invoiceId, 20559 message: message, 20560 sendMethod: sendMethod, 20561 recipient: recipient, 20562 }; 20563 var url = '/reskontra/takeManualOverDueAction/'; 20564 $.ajax({ 20565 url: url, 20566 type: 'post', 20567 data: data, 20568 success: function (resp) { 20569 $(sendDialog).dialog('close'); 20570 global.close_loading_dialog(); 20571 global.show_message({ 20572 type: 'success', 20573 title: 'Valmis', 20574 text: 'Maksumuistutus lähetetty.', 20575 }); 20576 pages.reskontra.$datatable.fnClearTable(0); 20577 pages.reskontra.$datatable.fnDraw(); 20578 }, 20579 error: function (response) { 20580 global.close_loading_dialog(); 20581 var error = JSON.parse(response.responseText); 20582 global.show_message(error); 20583 }, 20584 }); 20585 }, 20586 }, 20587 }); 20588 $('button').addClass('btn btn-default'); 20589 }, 20590 20591 showCreateOpenInvoicesReportDialog: function () { 20592 var dateTo = new Date(); 20593 dateTo.setDate(1); 20594 20595 var $createReportDialog = $('<div />') 20596 .append( 20597 $('<form method="post" action="/raportit/createOpenInvoicesReport/csv"/>').append( 20598 $('<label />', { id: 'date_to_label', style: 'width:auto; float:none;' }).html( 20599 'Hae avoimet laskut päivämäärällä' 20600 ), 20601 $( 20602 '<input type="text" class="text small" id="date_to" name="open_until_date" value="' + 20603 dateTo.getDate() + 20604 '.' + 20605 (dateTo.getMonth() + 1) + 20606 '.' + 20607 dateTo.getFullYear() + 20608 '" />' 20609 ).datepicker() 20610 ) 20611 ) 20612 .dialog({ 20613 width: 400, 20614 autoOpen: true, 20615 modal: true, 20616 resizable: false, 20617 draggable: false, 20618 beforeClose: function (event, ui) { 20619 event.stopPropagation(); 20620 }, 20621 title: 'Luo raportti avoimista laskuista', 20622 buttons: { 20623 Peruuta: function () { 20624 $(this).dialog('close'); 20625 }, 20626 'Luo raportti': function () { 20627 console.log($createReportDialog.find('form')); 20628 $createReportDialog.find('form').submit(); 20629 //pages.reskontra.createOpenInvoicesReport($(this).find('input[name=date_to]').val()); 20630 }, 20631 }, 20632 }); 20633 }, 20634 20635 createOpenInvoicesReport: function (endDate) { 20636 var data = { 20637 endDate: endDate, 20638 }; 20639 20640 $.ajax({ 20641 data: data, 20642 dataType: 'json', 20643 type: 'POST', 20644 url: '/raportit/createOpenInvoicesReport/csv', 20645 beforeSend: function (request) { 20646 $dialog.dialog({ 20647 width: 400, 20648 height: 200, 20649 title: 'Haku käynnissä', 20650 close: function (e) { 20651 e.stopPropagation(); 20652 $dialog.dialog('destroy').remove(); 20653 }, 20654 }); 20655 }, 20656 success: function (responseJSON) { 20657 self.data = responseJSON; 20658 20659 console.log(responseJSON); 20660 20661 // self.close(); 20662 $dialog.dialog({ 20663 width: 400, 20664 height: 200, 20665 title: self.data.title || '', 20666 close: function (e) { 20667 e.stopPropagation(); 20668 // $dialog.dialog('destroy').remove(); 20669 }, 20670 buttons: { 20671 OK: function (e) { 20672 e.stopPropagation(); 20673 // $dialog.dialog('destroy').remove(); 20674 self.dialog.dialog('close'); 20675 }, 20676 }, 20677 }); 20678 $dialog.html('<p>' + self.data.text + '</p>'); 20679 console.log('data haettu onnistuneesti', responseJSON); 20680 // $dialog.dialog('close'); 20681 // DO SOMETHING WITH THE DATA 20682 if (typeof callback == 'function') { 20683 callback(); 20684 } 20685 }, 20686 error: function (response) { 20687 $dialog.html('<p>Tietojen haku epäonnistui</p>'); 20688 console.log('Error!:', response); 20689 var error = JSON.parse(response.responseText); 20690 global.show_message(error); 20691 $dialog.dialog('close'); 20692 }, 20693 }); 20694 }, 20695 20696 createDirectPaymentDialog: function () { 20697 var d = new Date(), 20698 url = '/reskontra/addPaymentToDirectPayment/', 20699 $dialog = $('<div></div>', { id: 'add_direct_payment_dialog' }).append( 20700 $('<form />', { id: 'add_payment_form' }).append( 20701 $('<fieldset />', { class: '', style: '' }) 20702 .append('<p>Syötä tilityksen summa ja päivämäärä</p>') 20703 .append( 20704 $('<ol />') 20705 .append($('<input type="hidden" name="id" id="id" value="" />')) 20706 .append( 20707 $('<li />') 20708 .append($('<label for="amount">Summa:</label>')) 20709 .append( 20710 $('<input type="text" name="amount" id="amount" class="text small" />') 20711 ) 20712 .append(' €') 20713 ) 20714 .append( 20715 $('<li />') 20716 .append($('<label id="paid_date_label" for="paid_date">Päivämäärä:</label>')) 20717 .append( 20718 $( 20719 '<input type="text" class="text small" id="paid_date" name="paid_date" />' 20720 ) 20721 ) 20722 ) 20723 .append( 20724 $('<li />').append( 20725 $('<button type="submit">Tallenna tilitys</button>').button() 20726 ) 20727 ) 20728 ) 20729 ) 20730 ); 20731 20732 $dialog.find('form#add_payment_form').submit(function () { 20733 var data = _.object( 20734 $dialog 20735 .find('#add_payment_form') 20736 .serializeArray() 20737 .map(function (v) {
20738 return [v.name, v.value]; 20739 }) 20740 ); 20741 20742 $.ajax({ 20743 type: 'POST', 20744 url: url.concat(data.id), 20745 data: data, 20746 beforeSend: function (request) { 20747 global.show_loading_dialog('Tallennetaan tilitystä...'); 20748 }, 20749 }) 20750 .done(function (data) { 20751 global.close_loading_dialog(); 20752 global.show_message(data); 20753 $dialog.dialog('close'); 20754 20755 //Refresh the datatable 20756 pages.reskontra.$direct_payments_dt.fnClearTable(0); 20757 pages.reskontra.$direct_payments_dt.fnDraw(); 20758 }) 20759 .fail(function (data) { 20760 global.show_message($.parseJSON(data.responseText)); 20761 global.close_loading_dialog(); 20762 }); 20763 20764 return false; 20765 }); 20766 20767 $dialog.dialog({ 20768 width: 400, 20769 //height:200, 20770 autoOpen: false, 20771 modal: true, 20772 resizable: false, 20773 draggable: false, 20774 beforeClose: function (event, ui) { 20775 event.stopPropagation(); 20776 }, 20777 title: 'Lisää tilitys', 20778 buttons: { 20779 Peruuta: function () { 20780 $(this).dialog('close'); 20781 }, 20782 }, 20783 }); 20784 20785 return $dialog; 20786 }, 20787 20788 init_show_invoice: function (invoice) { 20789 var invoice_id = invoice.id; 20790 var open_sum = invoice.open_sum; 20791 var invoice_items = invoice.items; 20792 var jobOrderId = invoice.jobOrderId || false; 20793 var towingRecordId = invoice.invoice.towing_record_id || false; 20794 var recipientEmail = invoice.email; 20795 20796 var sendInvoiceMethods = function () { 20797 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 20798 $list.append( 20799 $('<li />', {}).append( 20800 $('<a />', { href: '' }) 20801 .on('click', function (e) { 20802 e.preventDefault(); 20803 pages.reskontra.send_invoice_by_mail(invoice.id); 20804 }) 20805 .text('Posti') 20806 ), 20807 $('<li />', {}).append( 20808 $('<a />', { href: '' }) 20809 .on('click', function (e) { 20810 e.preventDefault(); 20811 pages.reskontra.send_invoice_by_email(invoice.id, invoice.email); 20812 }) 20813 .text('Sähköposti') 20814 ), 20815 $('<li />', {}).append( 20816 $('<a />', { href: '' }) 20817 .on('click', function (e) { 20818 e.preventDefault(); 20819 pages.reskontra.send_invoice_by_sms(invoice.id); 20820 }) 20821 .text('Tekstiviesti') 20822 ) 20823 ); 20824 if (invoice.invoice.customer_type !== 'person') { 20825 $list.append( 20826 $('<li />', {}).append( 20827 $('<a />', { href: '' }) 20828 .on('click', function (e) { 20829 e.preventDefault(); 20830 20831 var errorMessage = pages.reskontra.checkInvoiceStatusBeforeSendEinvoice(invoice); 20832 if (errorMessage) { 20833 $('<div>' + errorMessage + '</div>').dialog({ 20834 modal: true, 20835 buttons: { 20836 Ok: function() { 20837 $(this).dialog('close'); 20838 } 20839 } 20840 }); 20841 return; 20842 } 20843 20844 pages.reskontra.send_invoice_by_e_invoice(invoice.id); 20845 }) 20846 .text('Verkkolasku') 20847 )); 20848 } 20849 20850 //For AK company group admins 20851 if (window.App.user.access_level >= 10) { 20852 $list.append( 20853 $('<li />', {}).append( 20854 $('<a />', { href: '' }) 20855 .on('click', function (e) { 20856 e.preventDefault(); 20857 pages.reskontra.insert_invoice_to_ledger(invoice.id); 20858 }) 20859 .text('Muuta avoimeksi (ei toimitusta)') 20860 )); 20861 } 20862 return $list; 20863 }; 20864 20865 // Lähetä heti action 20866 $('#send_invoice') 20867 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 20868 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 20869 .wrap($('<div />', { style: 'float:left;' })) 20870 .wrap($('<div />', {})) 20871 .parent() 20872 .parent() 20873 .append(sendInvoiceMethods()) 20874 .parent() 20875 .parent() 20876 .find('#send_invoice') 20877 .on('click', function () { 20878 var $menu = $(this).parent().next(); 20879 20880 if ($menu.is(':visible')) { 20881 $menu.hide(); 20882 } else { 20883 $('.ui-menu').hide(); 20884 $menu.show().position({ 20885 my: 'left top', 20886 at: 'left bottom', 20887 of: this, 20888 }); 20889 } 20890 20891 var menu = $(this).parent().next(); 20892 $(document).one('click', function () { 20893 menu.hide(); 20894 }); 20895 return false;
20896 }) 20897 .parent() 20898 .buttonset() 20899 .next() 20900 .hide() 20901 .menu(); 20902 20903 // Lataa lasku options 20904 var downloadInvoiceMethods = function () { 20905 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 20906 if (invoice.invoice.status !== '0') { 20907 $list.append( 20908 $('<li />', {}).append( 20909 $('<a />', { href: '' }) 20910 .on('click', function (e) { 20911 e.preventDefault(); 20912 window.LaskutusJaReskontra.invoiceDialog.insertInvoiceToArvatoIfRequiredAndPrintPdf(); 20913 }) 20914 .text('Laskukopio') 20915 ) 20916 ) 20917 } 20918 if (invoice.invoice.status === '20' && invoice.creditInvoices.length > 0) { 20919 $list.append( 20920 $('<li />', {}).append( 20921 $('<a />', { href: '' }) 20922 .on('click', function (e) { 20923 e.preventDefault(); 20924 20925 $('<div />', { 20926 title: 'Valitse hyvityslasku', 20927 id: 'credit-invoice-dialog' 20928 }) 20929 .append( 20930 $('<div />', {}).append( 20931 invoice.creditInvoices.map(function(creditInvoice, index) { 20932 return $('<div />', { 20933 }).append( 20934 $('<br />'), 20935 $('<input />', { 20936 type: 'radio', 20937 name: 'credit-invoice', 20938 id: 'credit-invoice-' + index, 20939 value: creditInvoice.id, 20940 checked: index === 0 20941 }), 20942 $('<label />', { 20943 for: 'credit-invoice-' + index, 20944 text: creditInvoice.invoice_number, 20945 style: 'display:inline; float:none;', 20946 }) 20947 ); 20948 }) 20949 ) 20950 ) 20951 .dialog({ 20952 modal: true, 20953 width: 300, 20954 buttons: { 20955 'Peruuta': function() { 20956 $(this).dialog('close'); 20957 }, 20958 'Lataa': function() { 20959 var selectedId = $('input[name="credit-invoice"]:checked').val(); 20960 if (selectedId) { 20961 window.open('/lasku/pdf/'.concat(selectedId)); 20962 return false; 20963 } 20964 } 20965 } 20966 }); 20967 }) 20968 .text('Hyvityslasku') 20969 ) 20970 ) 20971 } 20972 $list.append( 20973 $('<li />', {}).append( 20974 $('<a />', { href: '' }) 20975 .on('click', function (e) { 20976 e.preventDefault(); 20977 var receiptUrl = '/reskontra/kuitti/' + invoice_id, 20978 w = window.open(); 20979 20980 w.location = receiptUrl; 20981 }) 20982 .text('Laskulähete') 20983 ) 20984 ); 20985 return $list; 20986 }; 20987 20988 var sendCreditInvoiceCopyMethods = function () { 20989 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 20990 $list.append( 20991 $('<li />', {}).append( 20992 $('<a />', { href: '' }) 20993 .on('click', function (e) { 20994 e.preventDefault(); 20995 20996 if (!invoice.creditInvoices || invoice.creditInvoices.length === 0) { 20997 global.show_message({ type: 'error', text: 'Ei hyvityslaskuja saatavilla' }); 20998 return; 20999 } 21000 21001 $('<div />', { 21002 title: 'Valitse hyvityslasku', 21003 id: 'credit-invoice-dialog' 21004 }) 21005 .append( 21006 $('<div />', { 21007 }).append( 21008 invoice.creditInvoices.map(function(creditInvoice, index) { 21009 return $('<div />', { 21010 }).append( 21011 $('<br />'), 21012 $('<input />', { 21013 type: 'radio', 21014 name: 'credit-invoice', 21015 id: 'credit-invoice-' + index, 21016 value: creditInvoice.id, 21017 checked: index === 0 21018 }), 21019 $('<label />', { 21020 for: 'credit-invoice-' + index, 21021 text: creditInvoice.invoice_number, 21022 style: 'display:inline; float:none;', 21023 }) 21024 ); 21025 }) 21026 ) 21027 ) 21028 .dialog({ 21029 modal: true, 21030 width: 300, 21031 buttons: { 21032 'Peruuta': function() { 21033 $(this).dialog('close'); 21034 }, 21035 'Lähetä': function() { 21036 var selectedId = $('input[name="credit-invoice"]:checked').val(); 21037 21038 if (selectedId) { 21039 $.ajax({ 21040 dataType: 'json', 21041 type: 'POST', 21042 url: '/reskontra/send_invoice_copy_by_mail/' + selectedId, 21043 beforeSend: function () { 21044 global.showLoadingDialog('Lähetetään hyvityslaskua...'); 21045 } 21046 }).done(function () { 21047 global.show_message({ type: 'success', text: 'Hyvityslasku lähetetty!' }) 21048 21049 setTimeout(function () { 21050 $(this).dialog('close') 21051 }, 100) 21052 21053 }).error(function (response) { 21054 global.show_message(JSON.parse(response.responseText)); 21055 }).always(function () { 21056 global.close_loading_dialog(); 21057 }) 21058 $(this).dialog('close'); 21059 21060 } else { 21061 global.show_message({ type: 'error', text: 'Valitse hyvityslasku' }); 21062 } 21063 $(this).dialog('close'); 21064 } 21065 } 21066 }); 21067 21068 }) 21069 .text('Posti') 21070 ), 21071 $('<li />', {}).append( 21072 $('<a />', { href: '' }) 21073 .on('click', function (e) { 21074 e.preventDefault(); 21075 21076 if (!invoice.creditInvoices || invoice.creditInvoices.length === 0) { 21077 global.show_message({ type: 'error', text: 'Ei hyvityslaskuja saatavilla' }); 21078 return; 21079 } 21080 21081 $('<div />', { 21082 title: 'Valitse hyvityslasku', 21083 id: 'credit-invoice-dialog' 21084 }) 21085 .append( 21086 $('<div />', { 21087 }).append( 21088 invoice.creditInvoices.map(function(creditInvoice, index) { 21089 return $('<div />', { 21090 }).append( 21091 $('<br />'), 21092 $('<input />', { 21093 type: 'radio', 21094 name: 'credit-invoice', 21095 id: 'credit-invoice-' + index, 21096 value: creditInvoice.id, 21097 checked: index === 0 21098 }), 21099 $('<label />', { 21100 for: 'credit-invoice-' + index, 21101 text: creditInvoice.invoice_number, 21102 style: 'display:inline; float:none;', 21103 }) 21104 ); 21105 }) 21106 ), 21107 $('<div />', { 21108 style: 'margin-top: 15px;' 21109 }).append( 21110 $('<label />', { 21111 for: 'send-to-email', 21112 text: 'Sähköposti:', 21113 style: 'display: block; margin-bottom: 5px;' 21114 }), 21115 $('<input />', { 21116 type: 'email', 21117 id: 'send-to-email', 21118 name: 'send-to-email', 21119 value: invoice.email, 21120 style: 'width: 100%;' 21121 }) 21122 ) 21123 ) 21124 .dialog({ 21125 modal: true, 21126 width: 300, 21127 buttons: { 21128 'Peruuta': function() { 21129 $(this).dialog('close'); 21130 }, 21131 'Lähetä': function() { 21132 var selectedId = $('input[name="credit-invoice"]:checked').val(); 21133 var email = $('#send-to-email').val(); 21134 21135 if (!selectedId) { 21136 global.show_message({ type: 'error', text: 'Valitse hyvityslasku' }); 21137 return; 21138 } 21139 21140 if (!email) { 21141 global.show_message({ type: 'error', text: 'Anna sähköpostiosoite' }); 21142 return; 21143 } 21144 21145 $.ajax({ 21146 dataType: 'json', 21147 type: 'POST', 21148 url: '/reskontra/send_invoice_copy_by_email/' + selectedId, 21149 data: { 21150 send_to_email: email 21151 }, 21152 beforeSend: function () { 21153 global.showLoadingDialog('Lähetetään hyvityslaskua...'); 21154 } 21155 }).done(function () { 21156 global.show_message({ type: 'success', text: 'Hyvityslasku lähetetty!' }) 21157 21158 setTimeout(function () { 21159 $(this).dialog('close') 21160 }, 100) 21161 21162 }).error(function (response) { 21163 global.show_message(JSON.parse(response.responseText)); 21164 }).always(function () { 21165 global.close_loading_dialog(); 21166 }) 21167 $(this).dialog('close'); 21168 } 21169 } 21170 }); 21171 }) 21172 .text('Sähköposti') 21173 ), 21174 $('<li />', {}).append( 21175 $('<a />', { href: '' }) 21176 .on('click', function (e) { 21177 e.preventDefault(); 21178 21179 if (!invoice.creditInvoices || invoice.creditInvoices.length === 0) { 21180 global.show_message({ type: 'error', text: 'Ei hyvityslaskuja saatavilla' }); 21181 return; 21182 } 21183 21184 $('<div />', { 21185 title: 'Valitse hyvityslasku', 21186 id: 'credit-invoice-dialog' 21187 }) 21188 .append( 21189 $('<div />', { 21190 }).append( 21191 invoice.creditInvoices.map(function(creditInvoice, index) { 21192 return $('<div />', { 21193 }).append( 21194 $('<br />'), 21195 $('<input />', { 21196 type: 'radio', 21197 name: 'credit-invoice', 21198 id: 'credit-invoice-' + index, 21199 value: creditInvoice.id, 21200 checked: index === 0 21201 }), 21202 $('<label />', { 21203 for: 'credit-invoice-' + index, 21204 text: creditInvoice.invoice_number, 21205 style: 'display:inline; float:none;', 21206 }) 21207 ); 21208 }) 21209 ), 21210 $('<div />', { 21211 style: 'margin-top: 15px;' 21212 }).append( 21213 $('<label />', { 21214 for: 'phone-number', 21215 text: 'Puhelinnumero:', 21216 style: 'display: block; margin-bottom: 5px;' 21217 }), 21218 $('<input />', { 21219 type: 'text', 21220 id: 'phone-number', 21221 name: 'phone-number', 21222 style: 'width: 100%;' 21223 }) 21224 ) 21225 ) 21226 .dialog({ 21227 modal: true, 21228 width: 300, 21229 buttons: { 21230 'Peruuta': function() { 21231 $(this).dialog('close'); 21232 }, 21233 'Lähetä': function() { 21234 var selectedId = $('input[name="credit-invoice"]:checked').val(); 21235 var phoneNumber = $('#phone-number').val(); 21236 21237 if (!selectedId) { 21238 global.show_message({ type: 'error', text: 'Valitse hyvityslasku' }); 21239 return; 21240 } 21241 21242 if (!phoneNumber) { 21243 global.show_message({ type: 'error', text: 'Syötä puhelinnumero' }); 21244 return; 21245 } 21246 21247 $.ajax({ 21248 dataType: 'json', 21249 type: 'POST', 21250 url: '/reskontra/send_invoice_copy_by_sms/' + selectedId, 21251 data: { 21252 phone: phoneNumber 21253 }, 21254 beforeSend: function () { 21255 global.showLoadingDialog('Lähetetään hyvityslaskua...'); 21256 } 21257 }).done(function () { 21258 global.show_message({ type: 'success', text: 'Hyvityslasku lähetetty!' }) 21259 21260 setTimeout(function () { 21261 $(this).dialog('close') 21262 }, 100) 21263 21264 }).error(function (response) { 21265 global.show_message(JSON.parse(response.responseText)); 21266 }).always(function () { 21267 global.close_loading_dialog(); 21268 }) 21269 $(this).dialog('close'); 21270 } 21271 } 21272 }); 21273 }) 21274 .text('Tekstiviesti') 21275 ) 21276 ); 21277 21278 if (invoice.invoice.customer_type !== 'person') { 21279 $list.append( 21280 $('<li />', {}).append( 21281 $('<a />', { href: '' }) 21282 .on('click', function (e) { 21283 e.preventDefault(); 21284 21285 if (!invoice.creditInvoices || invoice.creditInvoices.length === 0) { 21286 global.show_message({ type: 'error', text: 'Ei hyvityslaskuja saatavilla' }); 21287 return; 21288 } 21289 21290 $('<div />', { 21291 title: 'Valitse hyvityslasku', 21292 id: 'credit-invoice-dialog' 21293 }) 21294 .append( 21295 $('<div />', { 21296 }).append( 21297 invoice.creditInvoices.map(function(creditInvoice, index) { 21298 return $('<div />', { 21299 }).append( 21300 $('<br />'), 21301 $('<input />', { 21302 type: 'radio', 21303 name: 'credit-invoice', 21304 id: 'credit-invoice-' + index, 21305 value: creditInvoice.id, 21306 checked: index === 0 21307 }), 21308 $('<label />', { 21309 for: 'credit-invoice-' + index, 21310 text: creditInvoice.invoice_number, 21311 style: 'display:inline; float:none;', 21312 }) 21313 ); 21314 }) 21315 ) 21316 ) 21317 .dialog({ 21318 modal: true, 21319 width: 300, 21320
21320 buttons: { 21321 'Peruuta': function() { 21322 $(this).dialog('close'); 21323 }, 21324 'Lähetä': function() { 21325 var selectedId = $('input[name="credit-invoice"]:checked').val(); 21326 pages.reskontra.send_invoice_by_e_invoice(selectedId); 21327 } 21328 } 21329 }); 21330 }) 21331 .text('Verkkolasku') 21332 )); 21333 } 21334 21335 return $list; 21336 }; 21337 21338 $('#send_credit_invoice') 21339 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21340 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 21341 .wrap($('<div />', { style: 'float:left;' })) 21342 .wrap($('<div />', {})) 21343 .parent() 21344 .parent() 21345 .append(sendCreditInvoiceCopyMethods()) 21346 .parent() 21347 .parent() 21348 .find('#send_credit_invoice') 21349 .on('click', function () { 21350 var $menu = $(this).parent().next(); 21351 21352 if ($menu.is(':visible')) { 21353 $menu.hide(); 21354 } else { 21355 $('.ui-menu').hide(); 21356 $menu.show().position({ 21357 my: 'left top', 21358 at: 'left bottom', 21359 of: this, 21360 }); 21361 } 21362 21363 var menu = $(this).parent().next(); 21364 $(document).one('click', function () { 21365 menu.hide(); 21366 }); 21367 return false; 21368 }) 21369 .parent() 21370 .buttonset() 21371 .next() 21372 .hide() 21373 .menu(); 21374 21375 // Lataa lasku action 21376 $('#download_invoice') 21377 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21378 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 21379 .wrap($('<div />', { style: 'float:left;' })) 21380 .wrap($('<div />', {})) 21381 .parent() 21382 .parent() 21383 .append(downloadInvoiceMethods()) 21384 .parent() 21385 .parent() 21386 .find('#download_invoice') 21387 .on('click', function () { 21388 var $menu = $(this).parent().next(); 21389 21390 if ($menu.is(':visible')) { 21391 $menu.hide(); 21392 } else { 21393 $('.ui-menu').hide(); 21394 $menu.show().position({ 21395 my: 'left top', 21396 at: 'left bottom', 21397 of: this, 21398 }); 21399 } 21400 21401 var menu = $(this).parent().next(); 21402 $(document).one('click', function () { 21403 menu.hide(); 21404 }); 21405 return false; 21406 }) 21407 .parent() 21408 .buttonset() 21409 .next() 21410 .hide() 21411 .menu(); 21412 21413 var functionsMethods = function () { 21414 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 21415 $list.append( 21416 $('<li />', {}).append( 21417 $('<a />', { href: '' }) 21418 .on('click', function (e) { 21419 e.preventDefault(); 21420 pages.reskontra.add_log_item(invoice_id); 21421 }) 21422 .text('Muistiinpano') 21423 ) 21424 ); 21425 21426 if (!invoice.jobOrderId && !invoice.invoice.towing_record_id) { 21427 $list.append( 21428 $('<li />', {}).append( 21429 $('<a />', { href: '' }) 21430 .on('click', function (e) { 21431 e.preventDefault(); 21432 pages.reskontra.copy_invoice(invoice_id); 21433 }) 21434 .text('Kopioi lasku') 21435 )) 21436 } 21437 21438 if ( 21439 invoice.invoice.status !== '0' && 21440 invoice.invoice.status !== '7' && 21441 invoice.invoice.status !== '20' && 21442 invoice.invoice.status !== '30' && 21443 invoice.invoice.status !== '40' && 21444 invoice.invoice.status !== '50' 21445 ) { 21446 $list.append( 21447 $('<li />', {}).append( 21448 $('<a />', { href: '' }) 21449 .on('click', function (e) { 21450 e.preventDefault(); 21451 21452 var errorMessage = pages.reskontra.checkInvoiceStatusBeforeChangeDueDate(invoice); 21453 if (errorMessage) { 21454 $('<div>' + errorMessage + '</div>').dialog({ 21455 modal: true, 21456 buttons: { 21457 Ok: function() { 21458 $(this).dialog('close'); 21459 } 21460 } 21461 }); 21462 return; 21463 } 21464 window.LaskutusJaReskontra.invoiceDialog.postponeDueDateDialog.show( 21465 $('#due_date').text() 21466 ); 21467 21468 }) 21469 .text('Siirrä eräpäivää') 21470 ) 21471 ); 21472 } 21473 21474 if ( 21475 invoice.invoice.status !== '0' && 21476 invoice.invoice.status !== '7' && 21477 invoice.invoice.status !== '20' && 21478 invoice.invoice.status !== '30' && 21479 invoice.invoice.ledger_service !== 'innovoice' 21480 ) { 21481 $list.append( 21482 $('<li />', {}).append( 21483 $('<a />', { href: '' }) 21484 .on('click', function (e) { 21485 e.preventDefault(); 21486 pages.reskontra.paid_to_customer(invoice); 21487 }) 21488 .text('Asiakas maksoi tililleni') 21489 ) 21490 ); 21491 } 21492 21493 return $list; 21494 }; 21495 21496 // Toiminnot action 21497 $('#functions') 21498 .button({ icons: { primary: 'ui-icon-triangle-1-s' } }) 21499 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 21500 .wrap($('<div />', { style: 'float:left;' })) 21501 .wrap($('<div />', {})) 21502 .parent() 21503 .parent() 21504 .append(functionsMethods()) 21505 .parent() 21506 .parent() 21507 .find('#functions') 21508 .on('click', function (e) { 21509 e.stopPropagation(); 21510 21511 $('.menu').hide(); 21512 21513 var $menu = $(this).parent().next(); 21514 21515 if ($menu.is(':visible')) { 21516 $menu.hide(); 21517 } else { 21518 $('.ui-menu').hide(); 21519 $menu.show().position({ 21520 my: 'left top', 21521 at: 'left bottom', 21522 of: this, 21523 }); 21524 } 21525 21526 var menu = $(this).parent().next(); 21527 $(document).one('click', function () { 21528 menu.hide(); 21529 }); 21530 21531 $(document).one('click', function () { 21532 $menu.hide(); 21533 }); 21534 return false;
21535 }) 21536 .parent() 21537 .buttonset() 21538 .next() 21539 .hide() 21540 .menu(); 21541 21542 var customerAddCreditnoteMethods = function () { 21543 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 21544 var jobOrderId = invoice.jobOrderId; 21545 var towingRecordId = invoice.invoice.towing_record_id; 21546 21547 $list.append( 21548 $('<li />', {}).append( 21549 $('<a />', { href: '' }) 21550 .on('click', function (e) { 21551 e.preventDefault(); 21552 $('<div />', { 21553 title: 'Hyvitä koko lasku', 21554 id: 'credit-invoice-dialog' 21555 }).html('Siirry ' + (jobOrderId ? 'työmääräykseen' : towingRecordId ? 'kuormakirjaan' : '')).dialog({ 21556 modal: true, 21557 width: 300, 21558 buttons: { 21559 'Peruuta': function() { 21560 $(this).dialog('close'); 21561 }, 21562 'Siirry': function() { 21563 if (jobOrderId) { 21564 document.location.assign('/innokorjaamo/edit/' + jobOrderId); 21565 } else if (towingRecordId) { 21566 document.location.assign('/kuormakirja/edit/' + towingRecordId); 21567 } 21568 } 21569 } 21570 }); 21571 }) 21572 .text('Hyvitä koko lasku') 21573 ), 21574 $('<li />', {}).append( 21575 $('<a />', { href: '' }) 21576 .on('click', function (e) { 21577 e.preventDefault(); 21578 $('<div />', { 21579 title: 'Osahyvitys', 21580 id: 'credit-invoice-dialog' 21581 }) 21582 .append($('<div />', { 21583 style: 'margin-bottom: 15px; ' 21584 }).append( 21585 $('<label />', { 21586 text: 'Hyvitettävä summa (sis. ALV)', 21587 style: 'width: auto;' 21588 }), 21589 $('<input />', { 21590 type: 'text', 21591 id: 'credit-amount', 21592 class: 'form-control' 21593 }), 21594 $('<label />', { 21595 text: 'Hyvityksen syy, lisätiedot tms.', 21596 style: 'width: auto; margin-top: 10px;' 21597 }), 21598 $('<textarea />', { 21599 id: 'credit-reason', 21600 class: 'form-control' 21601 }) 21602 )) 21603 .dialog({ 21604 modal: true, 21605 width: 400, 21606 buttons: { 21607 'Peruuta': function() { 21608 $(this).dialog('close'); 21609 }, 21610 'Lähetä hyvityspyyntö': function() { 21611 var creditAmount = $('#credit-amount').val(); 21612 var creditReason = $('#credit-reason').val(); 21613 21614 var data = { 21615 id: invoice_id, 21616 creditType: 'partial', 21617 otherAmount: creditAmount, 21618 message: creditReason 21619 } 21620 21621 $.ajax({ 21622 dataType: 'json', 21623 type: 'POST', 21624 url: '/logger/addRequestForCrediting/', 21625 data: data, 21626 beforeSend: function () { 21627 global.showLoadingDialog('Luodaan hyvitystä...'); 21628 } 21629 }).done(function () { 21630 global.show_message({ type: 'success', text: 'Hyvityspyyntö lähetetty asiakaspalveluun!' }) 21631 21632 setTimeout(function () { 21633 $(this).dialog('close') 21634 }, 100) 21635 21636 }).error(function (response) { 21637 global.show_message(JSON.parse(response.responseText)); 21638 }).always(function () { 21639 global.close_loading_dialog(); 21640 }) 21641 $(this).dialog('close'); 21642 } 21643 } 21644 }); 21645 }) 21646 .text('Osahyvitys') 21647 ) 21648 ); 21649 21650 if ((invoice.jobOrderId || invoice.invoice.towing_record_id) && (invoice.invoice.status === '11' || invoice.invoice.status === '13')) { 21651 $list.append( 21652 $('<li />', {}).append( 21653 $('<a />', { href: '' }) 21654 .on('click', function (e) { 21655 e.preventDefault(); 21656 pages.reskontra.credit_debt_collection_fees(invoice_id); 21657 }) 21658 .text('Hyvitä muistutuskulut laskulta') 21659 ) 21660 ) 21661 } 21662 return $list; 21663 }; 21664 21665 if (!invoice.jobOrderId && !invoice.invoice.towing_record_id) { 21666 $('#customer_add_creditnote') 21667 .button({ icons: { primary: 'ui-icon-pencil' } }) 21668 .on('click', function () { 21669 window.LaskutusJaReskontra.invoiceDialog.showCustomerCreditInvoiceDialog(); 21670 }); 21671 } else { 21672 $('#customer_add_creditnote') 21673 .button({ icons: { primary: 'ui-icon-triangle-1-s' } }) 21674 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 21675 .wrap($('<div />', { style: 'float:left;' })) 21676 .wrap($('<div />', {})) 21677 .parent() 21678 .parent()
21679 .append(customerAddCreditnoteMethods()) 21680 .parent() 21681 .parent() 21682 .find('#customer_add_creditnote') 21683 .on('click', function (e) { 21684 e.stopPropagation(); 21685 21686 $('.menu').hide(); 21687 21688 var $menu = $(this).parent().next(); 21689 21690 if ($menu.is(':visible')) { 21691 $menu.hide(); 21692 } else { 21693 $('.ui-menu').hide(); 21694 $menu.show().position({ 21695 my: 'left top', 21696 at: 'left bottom', 21697 of: this, 21698 }); 21699 } 21700 21701 var menu = $(this).parent().next(); 21702 $(document).one('click', function () { 21703 menu.hide(); 21704 }); 21705 21706 $(document).one('click', function () { 21707 $menu.hide(); 21708 }); 21709 return false; 21710 }) 21711 .parent() 21712 .buttonset() 21713 .next() 21714 .hide() 21715 .menu(); 21716 } 21717 21718 //console.log('init_show_invoice', 7175); 21719 $('#add_credit_line') 21720 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21721 .addClass('btn btn-default') 21722 .on('click', function () { 21723 pages.reskontra.show_add_credit_line_dialog(invoice_id, invoice_items); 21724 }); 21725 21726 $('#copy_invoice') 21727 .button({ icons: { primary: 'ui-icon-copy' } }) 21728 .on('click', function () { 21729 pages.reskontra.copy_invoice(invoice_id); 21730 }); 21731 21732 $('#delete_draft') 21733 .button({ icons: { primary: 'ui-icon-trash' } }) 21734 .on('click', function () { 21735 pages.reskontra.confirm_delete_draft(invoice_id); 21736 }); 21737 21738 $('#add_payment') 21739 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21740 .click(function () { 21741 pages.reskontra.show_add_payment_dialog(invoice_id, open_sum, 'invoice'); 21742 }); 21743 21744 $('#add_refund_payment') 21745 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21746 .click(function () { 21747 console.log('add_refund_payment'); 21748 pages.reskontra.show_add_refund_payment_dialog(invoice_id, open_sum, 'invoice'); 21749 }); 21750 21751 $('#start_debt_collection') 21752 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21753 .on('click', function () { 21754 console.log('start_debt_collection'); 21755 pages.reskontra.confirm_debt_collection(invoice_id); 21756 }); 21757 21758 var invoiceCopyDeliveryMethods = function () { 21759 var $list = $('<ul />', { style: 'position:absolute; z-index:99; font-size:13px;' }); 21760 21761 $list.append( 21762 $('<li />', {}).append( 21763 $('<a />', { href: '' }) 21764 .on('click', function (e) { 21765 e.preventDefault(); 21766 pages.reskontra.send_invoice_copy_by_mail(invoice.id); 21767 }) 21768 .text('Posti') 21769 ), 21770 $('<li />', {}).append( 21771 $('<a />', { href: '' }) 21772 .on('click', function (e) { 21773 e.preventDefault(); 21774 pages.reskontra.send_invoice_copy_by_email(invoice.id, invoice.email); 21775 }) 21776 .text('Sähköposti') 21777 ), 21778 $('<li />', {}).append( 21779 $('<a />', { href: '' }) 21780 .on('click', function (e) { 21781 e.preventDefault(); 21782 pages.reskontra.send_invoice_copy_by_sms(invoice.id); 21783 }) 21784 .text('Tekstiviesti') 21785 ) 21786 ); 21787 21788 if (invoice.invoice.customer_type !== 'person') { 21789 var disableEditing = 21790 invoice.isAutoliitto || invoice.isSos || invoice.isInsuranceCompany ? true : false; 21791 $list.append( 21792 $('<li />', {}).append( 21793 $('<a />', { href: '' }) 21794 .on('click', function (e) { 21795 e.preventDefault(); 21796 21797 var errorMessage = pages.reskontra.checkInvoiceStatusBeforeSendEinvoice(invoice); 21798 if (errorMessage) { 21799 $('<div>' + errorMessage + '</div>').dialog({ 21800 modal: true, 21801 buttons: { 21802 Ok: function() { 21803 $(this).dialog('close'); 21804 } 21805 } 21806 }); 21807 return; 21808 } 21809 21810 pages.reskontra.send_invoice_copy_by_e_invoice( 21811 invoice.id, 21812 disableEditing, 21813 invoice.eInvoiceAddress, 21814 invoice.eInvoiceOperator, 21815 invoice.eInvoiceOperators 21816 ); 21817 }) 21818 .text('Verkkolasku') 21819 ) 21820 ); 21821 } 21822 return $list; 21823 }; 21824 21825 $('#send_invoice_copy') 21826 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21827 .append('<span class="ui-icon ui-icon-triangle-1-s" style="float: right; margin-left: 5px;"></span>') 21828 .wrap($('<div />', { style: 'float:left;' })) 21829 .wrap($('<div />', {})) 21830 .parent() 21831 .parent() 21832 .append(invoiceCopyDeliveryMethods()) 21833 .parent() 21834 .parent() 21835 .find('#send_invoice_copy') 21836 .on('click',function() { 21837 var $menu = $(this) 21838 .parent() 21839 .next(); 21840 21841 if ($menu.is(':visible')) { 21842 $menu.hide(); 21843 } else { 21844 $('.ui-menu').hide(); 21845 $menu.show().position({ 21846 my: 'left top', 21847 at: 'left bottom', 21848 of: this, 21849 }); 21850 } 21851 21852 var menu = $(this) 21853 .parent() 21854 .next(); 21855 $(document).one('click', function() { 21856 menu.hide(); 21857 }); 21858 return false;
21859 }) 21860 .parent() 21861 .buttonset() 21862 .next() 21863 .hide() 21864 .menu(); 21865 21866 $('#send_by_email') 21867 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21868 .on('click', function () { 21869 //console.log("button clicked", 6427); 21870 pages.reskontra.enter_email_dialog(invoice_id); 21871 }); 21872 21873 $('#show_invoice_interest') 21874 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21875 .on('click',function() { 21876 21877 function onSuccess(resp, target){ 21878 if(resp.data){ 21879 21880 var remainingFee = resp.data.remainingFee === 0 || resp.data.remainingFee ? resp.data.remainingFee : null; 21881 var remainingInterest = resp.data.remainingInterest === 0 || resp.data.remainingInterest ? resp.data.remainingInterest : null; 21882 21883 if(remainingInterest !== null && remainingInterest !== null){ 21884 var partialData = { 21885 'Maksamattomat_kulut': remainingFee, 21886 'Maksamattomat_korot': remainingInterest 21887 } 21888 21889 var dataString = JSON.stringify(partialData, null, 4); 21890 dataString = dataString.replace(/[}{]/g, ''); 21891 target.html('<pre>'+dataString+'</pre><span>Mikäli haluatte hyvittää perinnästä aiheutuneet kulut/korot, jätä viesti asiakaspalveluumme (Muistiinpano)</span>'); 21892 } else { 21893 target.html('Laskun tietoja ei löytynyt'); 21894 } 21895 }else{ 21896 target.html('Laskun tietoja ei löytynyt'); 21897 } 21898 } 21899 21900 function onError(response, target){ 21901 global.close_loading_dialog(); 21902 try { 21903 target.html(JSON.parse(response.responseText)); 21904 }catch (exception){ 21905 target.html('Odottamaton virhe tapahtui palvelimella. Virhesanoma tallennettu palvelimen lokiin.'); 21906 } 21907 } 21908 LaskutusJaReskontra.invoiceDialog.showAccumulatedInterest(onSuccess, onError); 21909 }); 21910 21911 $('#send_invoice_copy_by_email') 21912 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21913 .on('click', function () { 21914 pages.reskontra.send_invoice_copy_by_email(invoice.id, invoice.email); 21915 }); 21916 21917 $('#send_invoice_copy_by_sms') 21918 .button({ icons: { primary: 'ui-icon-mail-closed' } }) 21919 .on('click', function () { 21920 pages.iv_laskutus_ja_reskontra.send_invoice_copy_by_sms( 21921 invoice.invoice.id, 21922 invoice.invoice.phone 21923 ); 21924 }); 21925 21926 $('#send_manual_reminder') 21927 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21928 .on('click', function () { 21929 console.log(invoice); 21930 pages.reskontra.showAddManualReminderDialog(invoice_id, recipientEmail); 21931 }); 21932 21933 $('#add_log_item') 21934 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21935 .on('click', function () { 21936 pages.iv_laskutus_ja_reskontra.add_log_item(invoice_id); 21937 }); 21938 21939 $('#show_invoice_pdf') 21940 .button({ icons: { primary: 'ui-icon-document' } }) 21941 .on('click', function () { 21942 var receiptUrl = '/lasku/pdf/' + invoice_id, 21943 w = window.open(); 21944 w.location = receiptUrl; 21945 }); 21946 21947 $('#show_invoice .show_invoice_log').on('click', function (e) { 21948 e.preventDefault(); 21949 var invoice_id = $(this).attr('href'); 21950 pages.reskontra.show_invoice_log(invoice_id); 21951 }); 21952 21953 $('#print-pdf') 21954 .button({ icons: { primary: 'ui-icon-print' } }) 21955 .wrap($('<div />', { style: 'float:left; margin-right: 5px;' })) 21956 .on('click', function () { 21957 window.LaskutusJaReskontra.invoiceDialog.insertInvoiceToArvatoIfRequiredAndPrintPdf(); 21958 }); 21959 21960 $('#request_for_crediting') 21961 .button({ icons: { primary: 'ui-icon-cancel' } }) 21962 .on('click', function () { 21963 window.LaskutusJaReskontra.invoiceDialog.showRequestForCreditingDialog(); 21964 }); 21965 21966 $('#edit_invoice') 21967 .button({ icons: { primary: 'ui-icon-pencil' } }) 21968 .on('click', function () { 21969 pages.reskontra.edit_invoice(invoice_id); 21970 }); 21971 21972 $('#show_invoice a.show_invoice').on('click', function (e) { 21973 e.preventDefault(); 21974 var invoice_id = $(this).attr('href'); 21975 pages.reskontra.show_invoice(invoice_id); 21976 }); 21977 21978 $('#print_receipt') 21979 .button({ icons: { primary: 'ui-icon-print' } }) 21980 .on('click', function () { 21981 var receiptUrl = '/lasku/kuitti/' + invoice_id; 21982 21983 window.open(receiptUrl); 21984 }); 21985 21986 $('#show-credit-invoice-dialog') 21987 .button({ icons: { primary: 'ui-icon-plusthick' } }) 21988 .on('click', function () { 21989 window.LaskutusJaReskontra.invoiceDialog.showCreditInvoiceDialog(); 21990 }); 21991 21992 $('#go_to_job_order') 21993 .button({ icons: { primary: 'ui-icon-arrowthick-1-e' } }) 21994 .click(function () { 21995 document.location.assign('/innokorjaamo/edit/' + jobOrderId); 21996 }); 21997 21998 $('#go_to_towing_record') 21999 .button({ icons: { primary: 'ui-icon-arrowthick-1-e' }}) 22000 .click(function () { 22001 document.location.assign('/kuormakirja/edit/' + towingRecordId); 22002 }) 22003 22004 $('#update_due_date') 22005 .button({ icons: { primary: 'ui-icon-calendar' } }) 22006 .click(function () { 22007 window.LaskutusJaReskontra.invoiceDialog.postponeDueDateDialog.show( 22008 $('#due_date').text() 22009 ); 22010 }); 22011 22012 $('#add-credit-loss') 22013 .button({ icons: { primary: 'ui-icon-plusthick' } }) 22014 .click(function () { 22015 window.LaskutusJaReskontra.invoiceDialog.confirmAddCreditLoss(); 22016 }); 22017 }, //init_show_invoice 22018 22019 checkInvoiceStatusBeforeChangeDueDate: function (invoice) { 22020 22021 if (window.App.user.access_level >= 100) { 22022 return null; 22023 } 22024 switch (invoice.invoice.status){ 22025 case '2': 22026 case '6': 22027 return 'Eräpäivää ei voi siirtää, lasku on rahoitettu' 22028 case '11': 22029 return 'Eräpäivää ei voi siirtää, lasku on muistutuksessa' 22030 case '13': 22031 return 'Eräpäivää ei voi siirtää, lasku on perinnässä' 22032 case '30': 22033 return 'Eräpäivää ei voi siirtää.' 22034 case '40': 22035 case '50': 22036 if (invoice.invoice.ledger_service === 'kredinor') { 22037 return 'Eräpäivää ei voi siirtää, lasku on maksettu.' 22038 } else if (invoice.invoice.ledger_service === 'riverty') { 22039 return 'Eräpäivää ei voi siirtää, lasku on rahoitettu.' 22040 } 22041 return 'Eräpäivää ei voi siirtää.' 22042 default: 22043 return null 22044 } 22045 }, 22046 22047 checkInvoiceStatusBeforeSendEinvoice: function (invoice) { 22048 switch (invoice.invoice.status) { 22049 case '7': 22050 case '40': 22051 case '50': 22052 var dueDate = new Date(invoice.invoice.due_date); 22053 var currentDate = new Date(); 22054 22055 if (dueDate < currentDate) { 22056 return 'Verkkolaskua ei voi lähettää, lasku on erääntynyt.'; 22057 } 22058 break; 22059 case '10': 22060 case '11': 22061 case '13': 22062 case '30': 22063 return 'Verkkolaskua ei voi lähettää, lasku on erääntynyt.'; 22064 default: 22065 return null; 22066 } 22067 }, 22068 22069 checkInvoiceStatusBeforePaidToCustomer: function (invoice) { 22070 switch (invoice.invoice.status){ 22071 case '40': 22072 case '50': 22073 if (invoice.invoice.ledger_service === 'kredinor') { 22074 return 'Lasku on jo maksettu, et voi merkitä tätä maksetuksi tilillenne.' 22075 } else if (invoice.invoice.ledger_service === 'riverty') { 22076 return null; 22077 } 22078 return null; 22079 default: 22080 return null 22081 } 22082 }, 22083 22084 createInvoiceReport: function () { 22085 var customers = [ 22086 '<option value="insurance_companies_and_display_in_custom_registry">Vakuutusyhtiöt ja asiakasrekisteri</option>', 22087 '<option value="insurance_companies">Vakuutusyhtiöt</option>', 22088 '<option value="display_in_customer_registry">Asiakasrekisterissä olevat</option>', 22089 '<option value="hansel">Hansel</option>', 22090 '<option value="all">Kaikki</option>', 22091 ]; 22092 var d_from = new Date(); 22093 d_from.setDate(1); 22094 var d_to = new Date(); 22095 var $date_from = $( 22096 '<input type="text" class="text small" id="date_from" name="date_from" value="' + 22097 d_from.getDate() + 22098 '.' + 22099 (d_from.getMonth() + 1) + 22100 '.' + 22101 d_from.getFullYear() + 22102 '" />' 22103 ).datepicker($.datepicker.regional.fi); 22104 var $date_to = $( 22105 '<input type="text" class="text small" id="date_to" name="date_to" value="' + 22106 d_to.getDate() + 22107 '.' + 22108 (d_to.getMonth() + 1) + 22109 '.' + 22110 d_to.getFullYear() + 22111 '" />' 22112 ).datepicker($.datepicker.regional.fi); 22113 22114 var $createReportDialog = $('<div></div>') 22115 .append( 22116 $('<form />', { 22117 id: 'create_invoice_report', 22118 target: '_blank', 22119 method: 'post', 22120 action: '/reskontra/create_invoice_report', 22121 }).append( 22122 $('<span />', { class: 'ui-helper-hidden-accessible' }).append('<input />', { 22123 type: 'text', 22124 }), 22125 $('<fieldset />', { class: 'fs-invisible', style: '' }).append( 22126 $('<ol />').append( 22127 $('<li />', { style: 'padding:7px 0;' }).append( 22128 $('<label />', { id: 'date_from_label', style: 'width:130px;' }).html( 22129 'Laskut ajalta' 22130 ), 22131 $date_from, 22132 ' - ', 22133 $date_to 22134 ), 22135 22136 $('<li />', { style: 'padding:7px 0;' }).append( 22137 $('<label />', { 22138 id: '', 22139 style: 'font-weight:bold; width:130px; height:40px;', 22140 }).html('Asiakkaat'), 22141 $('<select/>', { name: 'filters[customers]' }
22141).append(customers.join('')) 22142 ), 22143 $('<li />', { style: 'padding:7px 0;' }).append( 22144 $('<label />', { 22145 id: '', 22146 style: 'font-weight:bold; width:130px; height:40px;', 22147 }).html('Erittele laskut'), 22148 $('<select/>', { name: 'grouping', id: 'grouping' }).append( 22149 $('<option />', { value: 'by_customer_summarized' }).html( 22150 'Asiakkaittain - Summat' 22151 ), 22152 $('<option />', { value: 'by_customer' }).html('Asiakkaittain - Laskuerittely'), 22153 $('<option />', { value: 'by_delivery_date' }).html( 22154 'Luontipäivän mukaan - Laskuerittely' 22155 ), 22156 $('<option />', { value: 'all' }).html('Kaikki yhdessä - Laskuerittely') 22157 ) 22158 ), 22159 22160 $('<li />', { style: 'padding:7px 0;' }).append( 22161 $('<label />', { style: 'font-weight:bold; width:130px; height:40px;' }).html( 22162 'Näytä laskut' 22163 ), 22164 $('<input />', { 22165 id: 'status_open', 22166 type: 'checkbox', 22167 name: 'filters[status][]', 22168 value: 'open', 22169 checked: 'checked', 22170 }), 22171 $('<label />', { 22172 for: 'status_open', 22173 style: 'font-weight:normal; display:inline; float:none; width:auto;', 22174 }).html('Avoimet'), 22175 $('<input />', { 22176 id: 'status_paid', 22177 type: 'checkbox', 22178 name: 'filters[status][]', 22179 value: 'paid', 22180 checked: 'checked', 22181 }), 22182 $('<label />', { 22183 for: 'status_paid', 22184 style: 'font-weight:normal; display:inline; float:none; width:auto;', 22185 }).html('Tilitetyt'), 22186 $('<input />', { 22187 id: 'status_credited', 22188 type: 'checkbox', 22189 name: 'filters[status][]', 22190 value: 'credited', 22191 checked: 'checked', 22192 }), 22193 $('<label />', { 22194 for: 'status_credited', 22195 style: 'font-weight:normal; display:inline; float:none; width:auto;', 22196 }).html('Hyvitetyt') 22197 ), 22198 22199 $('<li />', { style: 'padding:7px 0;' }).append( 22200 $('<label />', { 22201 id: '', 22202 style: 'font-weight:bold; width:130px; height:40px;', 22203 }).html('Raportin muoto'), 22204 $('<select/>', { name: 'printer', id: 'printer' }).append( 22205 $('<option />', { value: 'csv' }).html('CSV'), 22206 $('<option />', { value: 'pdf' }).html('PDF') 22207 ) 22208 ) 22209 ) 22210 ) 22211 ) 22212 ) 22213 .dialog({ 22214 width: 550, 22215 autoOpen: true, 22216 modal: true, 22217 resizable: false, 22218 draggable: false, 22219 beforeClose: function (event, ui) { 22220 event.stopPropagation(); 22221 }, 22222 title: 'Luo raportti laskuista', 22223 buttons: { 22224 Peruuta: function () { 22225 $(this).dialog('close'); 22226 }, 22227 'Luo raportti': function () { 22228 $createReportDialog.find('form').submit(); 22229 }, 22230 }, 22231 }); 22232 }, 22233 22234 init_show_money_transfer_item: function() {}, 22235 22236 send_invoice_by_mail: function (invoice_id) { 22237 $dialog = $('<div />', { style: 'text-align:left;' }) 22238 .html('Haluatko varmasti lähettää lasku postitse?') 22239 .dialog({ 22240 autoOpen: true, 22241 modal: true, 22242 resizable: false, 22243 draggable: false, 22244 title: 'Lähetä lasku postitse', 22245 beforeClose: function (event, ui) { 22246 event.stopPropagation(); 22247 }, 22248 buttons: { 22249 Peruuta: function () { 22250 $dialog.dialog('close'); 22251 }, 22252 'Lähetä lasku': function () { 22253 $.ajax({ 22254 dataType: 'json', 22255 type: 'POST', 22256 url: '/reskontra/send_invoice_by_mail/' + invoice_id, 22257 beforeSend: function (request) { 22258 global.showLoadingDialog('Lähetetään laskua...'); 22259 }, 22260 success: function (responseJSON) { 22261 if (responseJSON.type == 'success') { 22262 //Refresh the datatables 22263 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 22264 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 22265 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 22266 } 22267 22268 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 22269 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 22270 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 22271 } 22272 22273 if (pages.reskontra.$datatable != null) { 22274 pages.reskontra.$datatable.fnClearTable(0); 22275 pages.reskontra.$datatable.fnDraw(); 22276 } 22277 22278 LaskutusJaReskontra.showInvoiceDialog({ 22279 invoiceId: invoice_id, 22280 }); 22281 } 22282 22283 global.show_message(responseJSON); 22284 global.close_loading_dialog(); 22285 22286 $dialog.dialog('close'); 22287 }, 22288 error: function (response) { 22289 global.close_loading_dialog(); 22290 global.show_message($.parseJSON(response.responseText)); 22291 }, 22292 }); 22293 }, 22294 }, 22295 }); 22296 }, 22297 22298 send_invoice_by_sms: function (invoiceId, phone) { 22299 var $form = $('<form />').append( 22300 $('<p />').html('Anna puhelinnumero'), 22301 $('<input />', { type: 'text', name: 'toSms', id: 'toSms', class: 'text medium' }).val( 22302 phone 22303 ) 22304 ); 22305 22306 $form.submit(function (e) { 22307 e.preventDefault(); 22308 var phone = document.getElementById('toSms').value; 22309 var data = { 22310 phone: phone, 22311 }; 22312 22313 global.showLoadingDialog('Lähetetään lasku...'); 22314 22315 $.ajax({ 22316 url: '/reskontra/send_invoice_by_sms/' + invoiceId, 22317 dataType: 'json', 22318 type: 'POST', 22319 data: data, 22320 }) 22321 .done(function (responseJSON) { 22322 $dialog.dialog('close'); 22323 global.show_message(responseJSON); 22324 global.close_loading_dialog(); 22325 }) 22326 .fail(function (response) { 22327 var responseJSON = $.parseJSON(response.responseText); 22328 global.close_loading_dialog(); 22329 global.show_message(responseJSON); 22330 }); 22331 }); 22332 22333 var $dialog = $('<div />', { style: 'text-align:left;' }) 22334 .append($form) 22335 .dialog({ 22336 width: 320, 22337 autoOpen: true, 22338 modal: true, 22339 resizable: false, 22340 draggable: false, 22341 beforeClose: function (event, ui) { 22342 event.stopPropagation(); 22343 }, 22344 close: function () { 22345 $(this).dialog('destroy'); 22346 $(this).remove(); 22347 }, 22348 title: 'Lähetä lasku sms viestinä', 22349 buttons: { 22350 Peruuta: function () { 22351 $(this).dialog('close'); 22352 }, 22353 'Lähetä lasku': function () { 22354 $form.submit(); 22355 }, 22356 }, 22357 }); 22358 }, 22359 22360 send_invoice_by_email: function (invoice_id, email) { 22361 var $form = $('<form />', { 22362 method: 'POST', 22363 action: '/reskontra/send_invoice_by_email/' + invoice_id, 22364 }).append( 22365 $('<p />').html('Anna sähköpostiosoite minne lasku lähetetään'), 22366 $('<input />', { 22367 type: 'text', 22368 name: 'send_to_email', 22369 id: 'send_to_email', 22370 class: 'text medium', 22371 }).val(email) 22372 ); 22373 22374 $form.submit(function (e) { 22375 e.preventDefault(); 22376 22377 $form.ajaxSubmit({ 22378 dataType: 'json', 22379 type: 'POST', 22380 22381 beforeSend: function (request) { 22382 global.showLoadingDialog('Lähetetään laskua...'); 22383 }, 22384 success: function (responseJSON) { 22385 if (responseJSON.type == 'success') { 22386 $dialog.dialog('close'); 22387 22388 //Refresh the datatables 22389 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 22390 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 22391 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 22392 } 22393 22394 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 22395 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 22396 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 22397 } 22398 22399 if (pages.reskontra.$datatable != null) { 22400 pages.reskontra.$datatable.fnClearTable(0); 22401 pages.reskontra.$datatable.fnDraw(); 22402 } 22403 22404 LaskutusJaReskontra.showInvoiceDialog({ 22405 invoiceId: invoice_id, 22406 }); 22407 } 22408 22409 global.show_message(responseJSON); 22410 global.close_loading_dialog(); 22411 }, 22412 error: function (response) { 22413 global.close_loading_dialog(); 22414 global.show_message($.parseJSON(response.responseText)); 22415 }, 22416 }); 22417 }); 22418 22419 var $dialog = $('<div />', { style: 'text-align:left;' }) 22420 .append($form) 22421 .dialog({ 22422 width: 320, 22423 autoOpen: true, 22424 modal: true, 22425 resizable: false, 22426 draggable: false, 22427 beforeClose: function (event, ui) { 22428 event.stopPropagation(); 22429 }, 22430 title: 'Lähetä lasku sähköpostitse', 22431 buttons: { 22432 Peruuta: function () { 22433 $(this).dialog('close'); 22434 }, 22435 'Lähetä lasku': function () { 22436 $form.submit(); 22437 }, 22438 }, 22439 }); 22440 }, 22441 22442 send_invoice_by_e_invoice: function (invoice_id) { 22443 $dialog = $('<div />', { style: 'text-align:left;' }) 22444 .html('Haluatko varmasti lähettää laskun verkkolaskuna?') 22445 .dialog({ 22446 autoOpen: true, 22447 modal: true, 22448 resizable: false, 22449 draggable: false, 22450 title: 'Lähetä lasku verkkolaskuna', 22451 beforeClose: function (event, ui) { 22452 event.stopPropagation(); 22453 }, 22454 buttons: { 22455 Peruuta: function () { 22456 $dialog.dialog('close'); 22457 }, 22458 'Lähetä lasku': function () { 22459 $.ajax({ 22460 dataType: 'json', 22461 type: 'POST', 22462 url: '/reskontra/send_invoice_by_e_invoice/' + invoice_id, 22463 beforeSend: function (request) { 22464 global.showLoadingDialog('Lähetetään laskua...'); 22465 }, 22466 success: function (responseJSON) { 22467 if (responseJSON.type == 'success') { 22468 //Refresh the datatables 22469 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 22470 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 22471 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 22472 } 22473 22474 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 22475 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 22476 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 22477 } 22478 22479 if (pages.reskontra.$datatable != null) { 22480 pages.reskontra.$datatable.fnClearTable(0); 22481 pages.reskontra.$datatable.fnDraw(); 22482 } 22483 22484 LaskutusJaReskontra.showInvoiceDialog({ 22485 invoiceId: invoice_id, 22486 }); 22487 } 22488 22489 global.show_message(responseJSON); 22490 global.close_loading_dialog(); 22491 22492 $dialog.dialog('close'); 22493 }, 22494 error: function (response) { 22495 global.close_loading_dialog(); 22496 global.show_message($.parseJSON(response.responseText)); 22497 }, 22498 }); 22499 }, 22500 }, 22501 }); 22502 }, 22503 22504 credit_debt_collection_fees: function (invoice_id) { 22505 var $dialog = $('<div></div>') 22506 .append( 22507 $('<p />', {}).append( 22508 $('<br />'), 22509 $('<input />', { 22510 type: 'radio', 22511 id: 'removeFees', 22512 name: 'actionNoteType', 22513 value: 'removeFees', 22514 }), 22515 $('<label />', { 22516 for: 'removeFees', 22517 text: 'Hyvitä muistutus- ja perintäkulut', 22518 style: 'display:inline; float:none;', 22519 }), 22520 $('<br />'), 22521 $('<input />', { 22522 type: 'radio', 22523 id: 'removeFeesAndInterests', 22524 name: 'actionNoteType', 22525 value: 'removeFeesAndInterests', 22526 checked: true, 22527 }), 22528 $('<label />', { 22529 for: 'removeFeesAndInterests', 22530 text: 'Hyvitä muistutus- ja perintäkulut + korot', 22531 style: 'display:inline; float:none;', 22532 }), 22533 $('<div>', { 22534 style: 'margin-top: 15px;' 22535 }).append( 22536 $('<label>', { 22537 text: 'Viesti:', 22538 style: 'display: block; margin-bottom: 5px; font-weight: bold;' 22539 }), 22540 $('<textarea>', { 22541 id: 'message', 22542 style: 'width: 100%; height: 80px; resize: vertical;' 22543 }) 22544 ) 22545 ) 22546 ) 22547 .dialog({ 22548 autoOpen: true, 22549 modal: true, 22550 resizable: false, 22551 draggable: true, 22552 title: 'Hyvitä muistutus- ja perintäkulut / korot', 22553 width: 400, 22554 beforeClose: function (e) { 22555 e.stopPropagation(); 22556 }, 22557 buttons: { 22558 'Sulje': function () { 22559 $(this).dialog('close'); 22560 }, 22561 'Hyvitä': function () { 22562 var creditType = $dialog.find('input[name="actionNoteType"]:checked').val(); 22563 var message = $dialog.find('#message').val(); 22564 global.showLoadingDialog('Hyvitetään muistutuskulut laskulta...'); 22565 $.ajax({ 22566 url: '/reskontra/credit_debt_collection_fees/', 22567 type: 'post', 22568 data: { 22569 invoice_id: invoice_id, 22570 actionNoteType: creditType, 22571 message: message 22572 }, 22573 success: function (responseJSON) { 22574 global.close_loading_dialog(); 22575 global.show_message(responseJSON); 22576 $dialog.dialog('close'); 22577 }, 22578 error: function (response) { 22579 global.close_loading_dialog(); 22580 global.show_message($.parseJSON(response.responseText)); 22581 } 22582 }); 22583 }, 22584 }, 22585 }); 22586 }, 22587 22588 paid_to_customer: function (invoice) { 22589 var $dialog = $('<div></div>') 22590 .append($('<div />', { 22591 style: 'margin-bottom: 15px; ' 22592 }).append( 22593 $('<label />', { 22594 text: 'Maksettu summa', 22595 style: 'width: auto;' 22596 }), 22597 $('<input />', { 22598 type: 'text', 22599 id: 'amount', 22600 class: 'form-control', 22601 value: invoice.invoiceTotals.openAmount 22602 }), 22603 $('<label />', { 22604 text: 'Maksettu päivämäärä', 22605 style: 'width: auto;' 22606 }), 22607 $('<input />', { 22608 type: 'date', 22609 id: 'paidDate', 22610 class: 'form-control', 22611 value: new Date().toISOString().split('T')[0] 22612
22612 }) 22613 )) 22614 .dialog({ 22615 autoOpen: true, 22616 modal: true, 22617 resizable: false, 22618 draggable: true, 22619 title: 'Asiakas maksoi tililleni', 22620 beforeClose: function (event, ui) { 22621 event.stopPropagation(); 22622 }, 22623 buttons: { 22624 'Sulje': function () { 22625 $(this).dialog('close'); 22626 }, 22627 'Tallenna': function (e) { 22628 e.preventDefault(); 22629 22630 var errorMessage = pages.reskontra.checkInvoiceStatusBeforePaidToCustomer(invoice); 22631 if (errorMessage) { 22632 $('<div>' + errorMessage + '</div>').dialog({ 22633 modal: true, 22634 buttons: { 22635 Ok: function() { 22636 $(this).dialog('close'); 22637 } 22638 } 22639 }); 22640 return; 22641 } 22642 22643 var amount = $(this).find('#amount').val(); 22644 var paidDate = $(this).find('#paidDate').val(); 22645 var data = { 22646 invoiceId: invoice.id, 22647 amount: amount, 22648 paidDate: paidDate 22649 }; 22650 $.ajax({ 22651 url: '/reskontra/paid_to_customer/', 22652 type: 'post', 22653 data: data, 22654 success: function (responseJSON) { 22655 if (responseJSON.type == 'success') { 22656 22657 LaskutusJaReskontra.showInvoiceDialog({ 22658 invoiceId: invoice.id, 22659 }); 22660 } 22661 22662 global.show_message(responseJSON); 22663 global.close_loading_dialog(); 22664 $dialog.dialog('close'); 22665 }, 22666 error: function (response) { 22667 global.close_loading_dialog(); 22668 global.show_message($.parseJSON(response.responseText)); 22669 } 22670 }); 22671 }, 22672 }, 22673 }); 22674 }, 22675 22676 add_log_item: function (invoice_id) { 22677 $('<div></div>') 22678 .append( 22679 $('<label />', { 22680 id: '', 22681 for: 'notifyInnovoice', 22682 style: 'font-weight:bold; width:100%;margin-bottom: 0;', 22683 }).html('Tyyppi'), 22684 $('<select/>', { 22685 id: 'notifyInnovoice', 22686 class: 'btn-sm', 22687 name: 'notify', 22688 style: 'font-weight: 500; line-height: 1.5; margin-bottom: 10px;', 22689 }).append( 22690 $('<option />', { value: '' }).html('Valitse'), 22691 $('<option />', { value: '1' }).html('Viesti Innovoicen asiakaspalveluun'), 22692 $('<option />', { value: '0' }).html('Oma muistiinpano') 22693 ), 22694 $('<label />', { style: 'width:auto;' }) 22695 .html('Viesti') 22696 .append($('<textarea />', { style: 'width:320px; height:72px;', name: 'log_event' })) 22697 .append('<br />') 22698 .append('<br />') 22699 ) 22700 .dialog({ 22701 autoOpen: true, 22702 modal: true, 22703 resizable: false, 22704 draggable: false, 22705 width: 380, 22706 title: 'Lisää muistiinpano', 22707 beforeClose: function (event, ui) { 22708 event.stopPropagation(); 22709 }, 22710 close: function () { 22711 $(this).dialog('destroy'); 22712 $(this).remove(); 22713 }, 22714 buttons: { 22715 Peruuta: function () { 22716 $(this).dialog('close'); 22717 }, 22718 Tallenna: function () { 22719 global.showLoadingDialog('Viestiä tallennetaan...'); 22720 var message = $(this).find('textarea[name=log_event]').val(); 22721 var notify = $('select#notifyInnovoice').val(); 22722 if (notify === '') { 22723 global.close_loading_dialog(); 22724 global.show_message({ 22725 type: 'error', 22726 title: 'Virhe', 22727 text: 'Valitse viestin tyyppi.', 22728 }); 22729 return; 22730 } 22731 var data = { id: invoice_id, message: message, notify: notify }; 22732 $(this).dialog('close'); 22733 $.ajax({ 22734 url: 'logger/makeLogEntry/', 22735 type: 'post', 22736 data: data, 22737 success: function (resp) { 22738 global.close_loading_dialog(); 22739 global.show_message({ 22740 type: 'success', 22741 title: 'Valmis', 22742 text: 'Muistiinpano lisätty onnistuneesti.', 22743 }); 22744 }, 22745 }); 22746 }, 22747 }, 22748 }); 22749 $('button').addClass('btn btn-default'); 22750 }, 22751 22752 copy_invoice: function (invoice_id) { 22753 $('<div></div>') 22754 .html('Haluatko siirtyä luomaan uuden laskun, käyttäen tätä laskua pohjana?') 22755 .dialog({ 22756 autoOpen: true, 22757 modal: true, 22758 resizable: false, 22759 draggable: false, 22760 title: 'Kopioi lasku', 22761 beforeClose: function (event, ui) { 22762 event.stopPropagation(); 22763 }, 22764 buttons: { 22765 Peruuta: function () { 22766 $(this).dialog('close'); 22767 }, 22768 'Siirry laskun luontiin': function () { 22769 $(this).dialog('close'); 22770 22771 window.location = '/lasku/kopioi/' + invoice_id; 22772 }, 22773 }, 22774 }); 22775 }, //copy_invoice 22776 22777 print_receipt: function (invoice_id) { 22778 $('<div></div>') 22779 .html('Haluatko varmasti tulostaa laskun lähete?') 22780 .dialog({ 22781 autoOpen: true, 22782 modal: true, 22783 resizable: false, 22784 draggable: false, 22785 title: 'Tulosta laskun lähete', 22786 beforeClose: function (event, ui) { 22787 event.stopPropagation(); 22788 }, 22789 buttons: { 22790 Peruuta: function () { 22791 $(this).dialog('close'); 22792 }, 22793 'Tulosta laskun lähete': function () { 22794 $(this).dialog('close'); 22795 var receiptUrl = '/lasku/kuitti/' + invoice_id; 22796 22797 window.open(receiptUrl); 22798 }, 22799 }, 22800 }); 22801 }, 22802 22803 close_previous_accounting_period: function ( 22804 $confirmDialog, 22805 $closePreviousAccountingPeriodButton 22806 ) { 22807 global.show_loading_dialog('Suljetaan kirjanpitokautta'); 22808 22809 $.ajax({ 22810 url: '/reskontra/close_previous_accounting_period/', 22811 dataType: 'json', 22812 type: 'POST', 22813 }) 22814 .done(function (responseJSON) { 22815 $confirmDialog.dialog('close'); 22816 $closePreviousAccountingPeriodButton.effect('highlight', {}, 500).fadeOut(); 22817 global.show_message(responseJSON); 22818 global.close_loading_dialog(); 22819 }) 22820 .fail(function (response) { 22821 var responseJSON = $.parseJSON(response.responseText); 22822 22823 // console.log('fail:', response); 22824 // console.log($.parseJSON(response.responseText)); 22825 global.close_loading_dialog(); 22826 global.show_message(responseJSON); 22827 }); 22828 }, 22829 22830 confirm_delete_draft: function (invoice_id) { 22831 $('<div></div>') 22832 .html('Haluatko varmasti poistaa laskun luonnoksen') 22833 .dialog({ 22834 autoOpen: true, 22835 modal: true, 22836 resizable: false, 22837 draggable: false, 22838 title: 'Poista laskun luonnos', 22839 beforeClose: function (event, ui) { 22840 event.stopPropagation(); 22841 }, 22842 close: function () { 22843 $(this).dialog('destroy'); 22844 }, 22845 buttons: { 22846 Peruuta: function () { 22847 $(this).dialog('close'); 22848 }, 22849 Poista: function () { 22850 $(this).dialog('close'); 22851 pages.reskontra.delete_draft(invoice_id); 22852 }, 22853 }, 22854 }); 22855 }, //confirm_delete_draft 22856 confirm_debt_collection: function (invoice_id) { 22857 var opts = { 22858 type: 'POST', 22859 url: '/reskontra/startDebtCollection/' + invoice_id, 22860 } 22861 var $dialog = $('<div></div>'); 22862 $dialog.html('Haluatko varmasti siirtää laskun perintään') 22863 .dialog({ 22864 autoOpen: true, 22865 modal: true, 22866 resizable: false, 22867 draggable: false, 22868 title: 'Poista laskun luonnos', 22869 beforeClose: function (event, ui) { 22870 event.stopPropagation(); 22871 }, 22872 close: function () { 22873 $(this).dialog('destroy'); 22874 }, 22875 buttons: { 22876 Peruuta: function () { 22877 $(this).dialog('destroy'); 22878 }, 22879 "Siirrä perintään": function () { 22880 global.showLoadingDialog('Siirretään laskua...'); 22881 22882 $.ajax(opts).done(function(responseJSON){ 22883 global.show_message(responseJSON); 22884 }).fail(function(err){ 22885 global.show_message(JSON.parse(err.responseText)); 22886 pages.reskontra.$datatable.fnClearTable(0); 22887 pages.reskontra.$datatable.fnDraw(); 22888 }).always(function(){ 22889 global.close_loading_dialog(); 22890 $dialog.dialog('close'); 22891 }) 22892 }, 22893 }, 22894 }); 22895 }, //confirm_delete_draft 22896 show_add_payment_dialog: function (id, open_sum, target_type) { 22897 var d = new Date();
22898 var url = '/reskontra/addInvoicePayment/' + id; 22899 22900 $add_payment_dialog = $('<div></div>') 22901 .append( 22902 $('<form />', { id: 'add_payment_form', method: 'post', action: url }) 22903 .append( 22904 $('<fieldset />', { class: 'fs-invisible', style: '' }) 22905 .append( 22906 '<p>Syötä maksusuorituksen summa euroissa ja lisää suorituksen päivämäärä</p>' 22907 ) 22908 .append( 22909 $('<ol />') 22910 .append( 22911 $('<li />') 22912 .append($('<label for="amount">Summa:</label>')) 22913 .append( 22914 $( 22915 '<input type="text" name="amount" id="amount" value="' + 22916 open_sum + 22917 '" class="text small" />' 22918 ) 22919 ) 22920 .append(' €') 22921 ) 22922 .append( 22923 $('<li />') 22924 .append($('<label id="created_label" for="created">Päivämäärä:</label>')) 22925 .append( 22926 $( 22927 '<input type="text" class="text small" id="created" name="created" value="' + 22928 d.getDate() + 22929 '.' + 22930 (d.getMonth() + 1) + 22931 '.' + 22932 d.getFullYear() + 22933 '" />' 22934 ).datepicker($.datepicker.regional.fi) 22935 ) 22936 ) 22937 .append( 22938 $('<li />').append( 22939 $('<button type="submit">Tallenna maksusuoritus</button>').button() 22940 ) 22941 ) 22942 ) 22943 ) 22944 .submit(function () { 22945 $(this).ajaxSubmit({ 22946 dataType: 'json', 22947 beforeSubmit: function () { 22948 global.showLoadingDialog('Tallennetaan maksusuoritusta...'); 22949 }, 22950 success: function (responseJSON) { 22951 global.show_message(responseJSON); 22952 global.close_loading_dialog(); 22953 22954 $add_payment_dialog.dialog('close'); 22955 22956 //Refresh the datatables 22957 pages.reskontra.$datatable.fnClearTable(0); 22958 pages.reskontra.$datatable.fnDraw(); 22959 }, 22960 error: function (response) { 22961 global.close_loading_dialog(); 22962 global.show_message($.parseJSON(response.responseText)); 22963 }, 22964 }); 22965 return false; 22966 }) 22967 ) 22968 .dialog({ 22969 width: 400, 22970 //height:200, 22971 autoOpen: true, 22972 modal: true, 22973 resizable: false, 22974 draggable: false, 22975 beforeClose: function (event, ui) { 22976 event.stopPropagation(); 22977 }, 22978 close: function () { 22979 $(this).dialog('destroy'); 22980 $(this).remove(); 22981 }, 22982 title: 'Lisää maksusuoritus', 22983 buttons: { 22984 Peruuta: function () { 22985 $(this).dialog('close'); 22986 }, 22987 }, 22988 }); 22989 }, //show_add_payment_dialog 22990 show_add_refund_payment_dialog: function (id, open_sum, target_type) { 22991 var d = new Date(); 22992 var url = '/reskontra/addRefundPayment/' + id; 22993 22994 $add_payment_dialog = $('<div></div>') 22995 .append( 22996 $('<form />', { id: 'add_payment_form', method: 'post', action: url }) 22997 .append( 22998 $('<fieldset />', { class: 'fs-invisible', style: '' }) 22999 .append('<p>Tarkista palautettu summa ja anna palautuksen päivämäärä</p>') 23000 .append( 23001 $('<ol />') 23002 .append( 23003 $('<li />') 23004 .append($('<label for="amount">Summa:</label>')) 23005 .append( 23006 $( 23007 '<input type="text" name="amount" id="amount" value="' + 23008 open_sum + 23009 '" class="text small" />' 23010 ) 23011 ) 23012 .append(' €') 23013 ) 23014 .append( 23015 $('<li />') 23016 .append($('<label id="created_label" for="refundDate">Päivämäärä:</label>')) 23017 .append( 23018 $( 23019 '<input type="text" class="text small" id="created" name="refundDate" value="' + 23020 d.getDate() + 23021 '.' + 23022 (d.getMonth() + 1) + 23023 '.' + 23024 d.getFullYear() + 23025 '" />' 23026 ).datepicker($.datepicker.regional.fi) 23027 ) 23028 ) 23029 .append( 23030 $('<li />').append( 23031 $('<button type="submit">Merkitse palautetuksi</button>').button() 23032 ) 23033 ) 23034 ) 23035 ) 23036 .submit(function () { 23037 $(this).ajaxSubmit({ 23038 dataType: 'json', 23039 beforeSubmit: function () { 23040 global.showLoadingDialog('Tallennetaan palautusta...'); 23041 }, 23042 success: function (responseJSON) { 23043 window.LaskutusJaReskontra.invoiceDialog.refresh(); 23044 23045 global.show_message(responseJSON); 23046 global.close_loading_dialog(); 23047 23048 $add_payment_dialog.dialog('close'); 23049 23050 //Refresh the datatables 23051 pages.reskontra.$datatable.fnClearTable(0); 23052 pages.reskontra.$datatable.fnDraw(); 23053 }, 23054 error: function (response) { 23055 global.close_loading_dialog(); 23056 global.show_message($.parseJSON(response.responseText)); 23057 }, 23058 }); 23059 return false;
23060 }) 23061 ) 23062 .dialog({ 23063 width: 400, 23064 //height:200, 23065 autoOpen: true, 23066 modal: true, 23067 resizable: false, 23068 draggable: false, 23069 beforeClose: function (event, ui) { 23070 event.stopPropagation(); 23071 }, 23072 close: function () { 23073 $(this).dialog('destroy'); 23074 $(this).remove(); 23075 }, 23076 title: 'Merkitse palautus', 23077 buttons: { 23078 Peruuta: function () { 23079 $(this).dialog('close'); 23080 }, 23081 }, 23082 }); 23083 }, //show_add_payment_dialog 23084 enter_email_dialog: function (invoice_id) { 23085 var $form = $('<form />', { 23086 method: 'POST', 23087 action: '/reskontra/send_by_email/' + invoice_id, 23088 }).append( 23089 $('<p />').html('Anna sähköpostiosoite minne lasku lähetetään'), 23090 $('<input />', { 23091 type: 'text', 23092 name: 'send_to_email', 23093 id: 'send_to_email', 23094 class: 'text medium', 23095 }) 23096 ); 23097 23098 var $dialog = $('<div />', { style: 'text-align:left;' }) 23099 .append($form) 23100 .dialog({ 23101 width: 320, 23102 autoOpen: true, 23103 modal: true, 23104 resizable: false, 23105 draggable: false, 23106 beforeClose: function (event, ui) { 23107 event.stopPropagation(); 23108 }, 23109 title: 'Lähetä lasku sähköpostitse', 23110 buttons: { 23111 Peruuta: function () { 23112 $(this).dialog('close'); 23113 }, 23114 'Lähetä lasku': function () { 23115 $form.ajaxSubmit({ 23116 type: 'post', 23117 dataType: 'json', 23118 //show the loading message 23119 beforeSubmit: function () { 23120 global.show_loading_dialog('Lähetetään laskua...'); 23121 }, 23122 23123 success: function (responseJSON, statusText, xhr, $form) { 23124 if (responseJSON.type == 'success') { 23125 pages.reskontra.$datatable.fnReloadAjax(); 23126 } 23127 23128 global.show_message(responseJSON); 23129 global.close_loading_dialog(); 23130 $dialog.dialog('close'); 23131 }, 23132 error: function (data) { 23133 global.close_loading_dialog(); 23134 }, 23135 }); //ajaxSubmit 23136 }, 23137 }, 23138 }); 23139 }, //enter_email_dialog 23140 23141 send_invoice_copy_by_mail: function (invoice_id) { 23142 $dialog = $('<div />', { style: 'text-align:left;' }) 23143 .html('Haluatko varmasti lähettää laskukopion postitse?') 23144 .dialog({ 23145 autoOpen: true, 23146 modal: true, 23147 resizable: false, 23148 draggable: false, 23149 title: 'Lähetä laskukopio postitse', 23150 beforeClose: function (event, ui) { 23151 event.stopPropagation(); 23152 }, 23153 buttons: { 23154 Peruuta: function () { 23155 $dialog.dialog('close'); 23156 }, 23157 'Lähetä laskukopio': function () { 23158 $.ajax({ 23159 dataType: 'json', 23160 type: 'POST', 23161 url: '/reskontra/send_invoice_copy_by_mail/', 23162 data: { invoiceId: invoice_id }, 23163 beforeSend: function (request) { 23164 global.showLoadingDialog('Lähetetään laskukopiota...'); 23165 }, 23166 success: function (responseJSON) { 23167 if (responseJSON.type == 'success') { 23168 //Refresh the datatables 23169 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 23170 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 23171 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 23172 } 23173 23174 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 23175 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 23176 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 23177 } 23178 23179 LaskutusJaReskontra.showInvoiceDialog({ 23180 invoiceId: invoice_id, 23181 }); 23182 } 23183 23184 global.show_message(responseJSON); 23185 global.close_loading_dialog(); 23186 23187 $dialog.dialog('close'); 23188 }, 23189 error: function (response) { 23190 global.close_loading_dialog(); 23191 global.show_message($.parseJSON(response.responseText)); 23192 }, 23193 }); 23194 }, 23195 }, 23196 }); 23197 }, //send_invoice_copy_by_mail 23198 23199 send_invoice_copy_by_email: function (invoice_id, email) { 23200 var $form = $('<form />').append( 23201 $('<p />').html('Anna sähköpostiosoite'), 23202 $('<input />', { type: 'text', name: 'toEmail', id: 'toEmail', class: 'text medium' }).val( 23203 email 23204 ) 23205 ); 23206 23207 $form.submit(function (e) { 23208 //Get the data from the form element 23209 var data = _.object( 23210 $form.serializeArray().map(function (v) {
23211 return [v.name, v.value]; 23212 }) 23213 ); 23214 23215 //Add some extra data 23216 _.extend(data, { invoiceId: invoice_id }); 23217 23218 e.preventDefault(); 23219 23220 global.show_loading_dialog('Lähetetään laskukopiota...'); 23221 23222 $.ajax({ 23223 url: '/reskontra/send_invoice_copy_by_email/', 23224 dataType: 'json', 23225 type: 'POST', 23226 data: data, 23227 }) 23228 .done(function (responseJSON) { 23229 $dialog.dialog('destroy'); 23230 global.show_message(responseJSON); 23231 global.close_loading_dialog(); 23232 $dialog.remove(); 23233 }) 23234 .fail(function (response) { 23235 var responseJSON = $.parseJSON(response.responseText); 23236 23237 global.close_loading_dialog(); 23238 global.show_message(responseJSON); 23239 }); 23240 }); 23241 23242 var $dialog = $('<div />', { style: 'text-align:left;' }) 23243 .append($form) 23244 .dialog({ 23245 width: 320, 23246 autoOpen: true, 23247 modal: true, 23248 resizable: false, 23249 draggable: false, 23250 beforeClose: function (event, ui) { 23251 event.stopPropagation(); 23252 }, 23253 close: function () { 23254 $(this).dialog('destroy'); 23255 $dialog.remove(); 23256 }, 23257 title: 'Lähetä laskukopio sähköpostitse', 23258 buttons: { 23259 Peruuta: function () { 23260 $(this).dialog('destroy'); 23261 $dialog.remove(); 23262 }, 23263 'Lähetä lasku': function () { 23264 $form.submit(); 23265 }, 23266 }, 23267 }); 23268 }, //send_invoice_copy_by_email 23269 23270 send_invoice_copy_by_sms: function (invoiceId, phone) { 23271 var $form = $('<form />').append( 23272 $('<p />').html('Anna puhelinnumero'), 23273 $('<input />', { type: 'text', name: 'toSms', id: 'toSms', class: 'text medium' }).val( 23274 phone 23275 ) 23276 ); 23277 23278 $form.submit(function (e) { 23279 e.preventDefault(); 23280 var phone = document.getElementById('toSms').value; 23281 var data = { 23282 phone: phone, 23283 invoiceId: invoiceId, 23284 }; 23285 23286 global.showLoadingDialog('Lähetetään laskukopiota...'); 23287 23288 $.ajax({ 23289 url: '/reskontra/send_invoice_copy_by_sms/', 23290 dataType: 'json', 23291 type: 'POST', 23292 data: data, 23293 }) 23294 .done(function (responseJSON) { 23295 $dialog.dialog('close'); 23296 global.show_message(responseJSON); 23297 global.close_loading_dialog(); 23298 }) 23299 .fail(function (response) { 23300 var responseJSON = $.parseJSON(response.responseText); 23301 global.close_loading_dialog(); 23302 global.show_message(responseJSON); 23303 }); 23304 }); 23305 23306 var $dialog = $('<div />', { style: 'text-align:left;' }) 23307 .append($form) 23308 .dialog({ 23309 width: 320, 23310 autoOpen: true, 23311 modal: true, 23312 resizable: false, 23313 draggable: false, 23314 beforeClose: function (event, ui) { 23315 event.stopPropagation(); 23316 }, 23317 close: function () { 23318 $(this).dialog('destroy'); 23319 $(this).remove(); 23320 }, 23321 title: 'Lähetä laskukopio sms viestinä', 23322 buttons: { 23323 Peruuta: function () { 23324 $(this).dialog('close'); 23325 }, 23326 'Lähetä lasku': function () { 23327 $form.submit(); 23328 }, 23329 }, 23330 }); 23331 }, 23332 23333 send_invoice_copy_by_e_invoice: function ( 23334 invoice_id, 23335 disableEditing, 23336 eInvoiceAddress, 23337 eInvoiceOperator, 23338 eInvoiceOperators 23339 ) { 23340 var selectEl = $('<select />', { 23341 type: 'text', 23342 name: 'eInvoiceOperator', 23343 id: 'eInvoiceOperator', 23344 class: 'form-control input-sm', 23345 }); 23346 $.each(eInvoiceOperators, function (i, obj) { 23347 $(selectEl).append('<option value=' + obj.code + '>' + obj.name + '</option>'); 23348 }); 23349 selectEl.val(eInvoiceOperator); 23350 selectEl.prop('disabled', disableEditing); 23351 23352 var eInvoiceInputField = $('<input />', { 23353 type: 'text', 23354 name: 'eInvoiceAddress', 23355 id: 'eInvoiceAddress', 23356 class: 'text medium', 23357 }).val(eInvoiceAddress); 23358 eInvoiceInputField.prop('disabled', disableEditing); 23359 23360 var $form = $('<form />').append( 23361 $('<label />').html('Verkkolaskuosoite'), 23362 eInvoiceInputField, 23363 $('<label />').html('Operaattori'), 23364 selectEl 23365 ); 23366 if (disableEditing) { 23367 $form.append( 23368 $('<input />', { type: 'hidden', name: 'eInvoiceAddress', id: 'eInvoiceAddress' }).val( 23369 eInvoiceAddress 23370 ), 23371 $('<input />', { type: 'hidden', name: 'eInvoiceOperator', id: 'eInvoiceOperator' }).val( 23372 eInvoiceOperator 23373 ) 23374 ); 23375 } 23376 $form.submit(function (e) { 23377 //Get the data from the form element 23378 var data = _.object( 23379 $form.serializeArray().map(function (v) {
23380 return [v.name, v.value]; 23381 }) 23382 ); 23383 23384 //Add some extra data 23385 _.extend(data, { invoiceId: invoice_id }); 23386 23387 e.preventDefault(); 23388 23389 $.ajax({ 23390 dataType: 'json', 23391 type: 'POST', 23392 url: '/reskontra/send_invoice_copy_by_e_invoice/', 23393 data: data, 23394 beforeSend: function (request) { 23395 global.showLoadingDialog('Lähetetään laskukopiota...'); 23396 }, 23397 success: function (responseJSON) { 23398 if (responseJSON.type == 'success') { 23399 //Refresh the datatables 23400 if (pages.iv_laskutus_ja_reskontra.$datatable_iv != null) { 23401 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnClearTable(0); 23402 pages.iv_laskutus_ja_reskontra.$datatable_iv.fnDraw(); 23403 } 23404 23405 if (pages.iv_laskutus_ja_reskontra.$datatable != null) { 23406 pages.iv_laskutus_ja_reskontra.$datatable.fnClearTable(0); 23407 pages.iv_laskutus_ja_reskontra.$datatable.fnDraw(); 23408 } 23409 23410 LaskutusJaReskontra.showInvoiceDialog({ 23411 invoiceId: invoice_id, 23412 }); 23413 } 23414 23415 global.show_message(responseJSON); 23416 global.close_loading_dialog(); 23417 23418 $dialog.dialog('close'); 23419 }, 23420 error: function (response) { 23421 global.close_loading_dialog(); 23422 global.show_message($.parseJSON(response.responseText)); 23423 }, 23424 }); 23425 }); 23426 23427 $dialog = $('<div />', { style: 'text-align:left;' }) 23428 .append($form) 23429 .dialog({ 23430 autoOpen: true, 23431 modal: true, 23432 resizable: false, 23433 draggable: false, 23434 title: 'Lähetä laskukopio verkkolaskuna', 23435 beforeClose: function (event, ui) { 23436 event.stopPropagation(); 23437 }, 23438 buttons: { 23439 Peruuta: function () { 23440 $dialog.dialog('close'); 23441 }, 23442 'Lähetä laskukopio': function () { 23443 $form.submit(); 23444 }, 23445 }, 23446 }); 23447 }, //send_invoice_copy_by_e_invoice 23448 23449 getDatatableCsv: function(params, table, selector){ 23450 23451 var data = '?' + params.map(function (item) { 23452 return item.name + '=' + encodeURIComponent(item.value); 23453 }).join('&'); 23454 var url = 'reskontra/exportDataTable/' + data + '&table=' + table; 23455 $.ajax({ 23456 type: 'GET', 23457 contentType: 'application/csv', 23458 url: url, 23459 beforeSend: function(){ 23460 $(selector).html(global.$mini_loader).attr('focus', false).attr('disabled', true); 23461 }, 23462 success: function(response){ 23463 if(response){ 23464 23465 // var csvContent = "data:text/csv;charset=utf-8," + response; 23466 var blob = new Blob([response], { type: 'text/csv' }); 23467 var url = window.URL.createObjectURL(blob); 23468 var a = document.createElement('a'); 23469 a.setAttribute('href', url); 23470 a.setAttribute('download', table + '_datatable_' + Date.now() + '.csv'); 23471 a.click(); 23472 a.remove(); 23473 // var encodedUri = encodeURI(csvContent); 23474 // window.location.href = encodedUri; 23475 } 23476 }, 23477 error: function(error){ 23478 global.show_message(JSON.parse(error.responseText)); 23479 }, 23480 complete: function(){ 23481 $(selector).text('Vie Csv-tiedostoon').attr('disabled', false); 23482 } 23483 }); 23484 }, 23485 23486 delete_draft: function (invoice_id) { 23487 var $dialog = global.$dialog; 23488 23489 if ($dialog.hasClass('ui-dialog-content')) { 23490 $dialog.dialog('close'); 23491 } 23492 23493 $.ajax({ 23494 processData: false, 23495 dataType: 'json', 23496 type: 'GET', 23497 url: 'ajax/delete_invoice_draft/' + invoice_id + '/', 23498 beforeSend: function (request) { 23499 global.show_loading_dialog('Poistetaan lasku...'); 23500 }, 23501 success: function (responseJSON) { 23502 global.close_loading_dialog(); 23503 global.show_message(responseJSON); 23504 23505 if (pages.reskontra.$datatable != null) { 23506 pages.reskontra.$datatable.fnClearTable(0); 23507 pages.reskontra.$datatable.fnDraw(); 23508 } 23509 23510 if (kuormakirjat.$datatable !== null) { 23511 kuormakirjat.$datatable.fnReloadAjax(); 23512 } 23513 }, 23514 }); 23515 }, //delete_draft 23516 23517 show_invoice_dialog: function (customer_type) { 23518 var $dialog = global.getGlobalDialogAndEmptyIfHasContent(); 23519 var url = 'reskontra/ajax_get_create_invoice/' + customer_type + '/'; 23520 23521 dialogs.url = url; 23522 23523 if ($dialog.hasClass('ui-dialog-content')) { 23524 $dialog.dialog('destroy'); 23525 } 23526 23527 $dialog.dialog({ 23528 autoOpen: true, 23529 width: 860, 23530 height: 600, 23531 title: 'Luo lasku', 23532 modal: true, 23533 resizable: false, 23534 open: function () { 23535 global.show_ajax_loader($dialog); 23536 23537 $.get(url, function (html) { 23538 $dialog.html(html); 23539 }); 23540 }, 23541 close: function () { 23542 $(this).dialog('destroy'); 23543 }, 23544 }); 23545 }, 23546 23547 show_edit_invoice_dialog: function () {}, 23548 23549 show_invoice_log: function (invoice_id) { 23550 global.$dialog = $('<div />'); 23551 var $dialog = global.$dialog; 23552 23553 if (invoice_id.length > 0) { 23554 $.ajax({ 23555 processData: false, 23556 dataType: 'html', 23557 type: 'GET', 23558 url: 'reskontra/get_invoice_log_html/' + invoice_id + '/', 23559 beforeSend: function (request) { 23560 $dialog.dialog({ 23561 width: 650, 23562 height: 450, 23563 title: 'Laskun tapahtumaloki', 23564 buttons: { 23565 'Lisää muistiinpano': function () { 23566 pages.iv_laskutus_ja_reskontra.add_log_item(invoice_id); 23567 }, 23568 }, 23569 close: function (e) { 23570 e.stopPropagation(); 23571 $dialog.dialog('destroy'); 23572 $dialog.remove(); 23573 }, 23574 }); 23575 global.show_ajax_loader($dialog); 23576 }, 23577 success: function (response) { 23578 $dialog.html(response); 23579 $('.invoiceLogTabs').tabs(); 23580 //Add special click handler to show towing record popup
23580instead of redirecting user to towing record page 23581 $dialog.on('click', 'a.show_towing_record', function (e) { 23582 e.preventDefault(); 23583 $dialog.dialog('destroy'); 23584 $dialog.remove(); 23585 var url = $(this).data('url'); 23586 kuormakirjat.show_towing_record(url); 23587 }); 23588 }, 23589 }); 23590 } 23591 }, //show_invoice_log 23592 23593 show_invoice: function (invoice_id, open_sum) { 23594 if (window.LaskutusJaReskontra && window.LaskutusJaReskontra.invoiceDialog) { 23595 window.LaskutusJaReskontra.showInvoiceDialog({ 23596 invoiceId: invoice_id, 23597 }); 23598 } else { 23599 var $dialog = $('#dialog'); 23600 23601 if ($dialog.hasClass('ui-dialog-content')) { 23602 $dialog.dialog('close'); 23603 } 23604 23605 $.ajax({ 23606 processData: false, 23607 dataType: 'html', 23608 type: 'GET', 23609 url: 'ajax/get_invoice_html/' + invoice_id + '/', 23610 beforeSend: function (request) { 23611 $dialog.dialog({ 23612 width: 800, 23613 height: 600, 23614 modal: true, 23615 resizable: false, 23616 title: 'Laskun tiedot', 23617 close: function () { 23618 $dialog.dialog('close'); 23619 }, 23620 }); 23621 global.show_ajax_loader($dialog); 23622 }, 23623 success: function (response) { 23624 $dialog.html(response); 23625 23626 $(this).delegate(':button', 'click', function () { 23627 $(this).data({ invoice_id: invoice_id, open_sum: open_sum }); 23628 }); 23629 }, 23630 }); 23631 } 23632 }, //show_invoice 23633 23634 show_invoice_2: function (url) { 23635 var $dialog = global.getGlobalDialogAndEmptyIfHasContent(); 23636 // console.log('new has content',$dialog.hasClass('ui-dialog-content')) 23637 // if ($dialog.hasClass('ui-dialog-content')) { 23638 // $dialog.dialog('destroy'); 23639 // } 23640 23641 //console.log('show_invoice_2'); 23642 23643 $.ajax({ 23644 processData: false, 23645 dataType: 'html', 23646 type: 'GET', 23647 url: url, 23648 beforeSend: function (request) { 23649 $dialog.dialog({ 23650 width: 800, 23651 height: 600, 23652 modal: true, 23653 resizable: false, 23654 title: 'Laskun tiedot', 23655 }); 23656 global.show_ajax_loader($dialog); 23657 }, 23658 success: function (response) { 23659 $dialog.html(response); 23660 }, 23661 }); 23662 }, //show_invoice 23663 23664 show_invoice_by: function (id, get_by) { 23665 var $dialog = global.$dialog; 23666 23667 if ($dialog.hasClass('ui-dialog-content')) { 23668 $dialog.dialog('destroy'); 23669 } 23670 23671 $.ajax({ 23672 processData: false, 23673 dataType: 'html', 23674 type: 'GET', 23675 url: 'ajax/get_invoice/' + id + '/' + get_by + '/', 23676 beforeSend: function (request) { 23677 $dialog.dialog({ 23678 width: 650, 23679 height: 450, 23680 title: 'Laskun tiedot', 23681 modal: true, 23682 resizable: false, 23683 }); 23684 global.show_ajax_loader($dialog); 23685 }, 23686 success: function (response) { 23687 $dialog.html(response); 23688 var invoice_id = $dialog.find('#invoice_id').val(); 23689 var open_sum = $dialog.find('#open_sum').val(); 23690 23691 $dialog.delegate(':button', 'click', function () { 23692 $(this).data({ invoice_id: invoice_id, open_sum: open_sum }); 23693 }); 23694 }, 23695 }); 23696 }, //show_invoice_by 23697 23698 show_money_transfer_item: function(money_transfer_item_id, source) { 23699 var $dialog = global.$dialog; 23700 23701 if ($dialog.hasClass('ui-dialog-content')) { 23702 $dialog.dialog('destroy'); 23703 } 23704 23705 $.ajax({ 23706 processData: false, 23707 dataType: 'html', 23708 type: 'GET', 23709 url: 'ajax/get_money_transfer_item/' + money_transfer_item_id + '/' + source, 23710 beforeSend: function(request) { 23711 $dialog.dialog({ 23712 width: 800, 23713 height: 600, 23714 modal: true, 23715 resizable: false, 23716 title: 'Tilityksen tiedot', 23717 }); 23718 global.show_ajax_loader($dialog); 23719 }, 23720 success: function (response) { 23721 $dialog.html(response); 23722 }, 23723 }); 23724 }, //show_invoice 23725 23726 show_part_payment: function (part_payment_id) { 23727 var $dialog = global.$dialog; 23728 23729 $.ajax({ 23730 processData: false, 23731 dataType: 'html', 23732 type: 'GET', 23733 url: 'osamaksu/get_part_payment_dialog/' + part_payment_id + '/', 23734 beforeSend: function (request) { 23735 $dialog.dialog({ 23736 width: 800, 23737 height: 600, 23738 modal: true, 23739 resizable: false, 23740 title: 'Osamaksusopimuksen tiedot', 23741 }); 23742 global.show_ajax_loader($dialog); 23743 }, 23744 success: function (response) { 23745 $dialog.html(response); 23746 }, 23747 }); 23748 }, //show_part_payment 23749 23750 init_part_payment_dialog: function (part_payment_id) { 23751 $('#confirm_financing') 23752 .button({ icons: { primary: 'ui-icon-check' } }) 23753 .on('click', function () { 23754 $('<div></div>') 23755 .html( 23756 'Haluatko varmasti merkitä osamaksusopimuksen rahoituksen ehdot täyttyneeksi? Kun rahoituksen ehdot ovat täyttyneet, on mahdollista luoda tililasku osamaksusopimuksesta' 23757 ) 23758 .dialog({ 23759 autoOpen: true, 23760 modal: true, 23761 resizable: false, 23762 draggable: false, 23763 title: 'Merkitse rahoituksen ehdot täyttyneeksi', 23764 beforeClose: function (event, ui) { 23765 event.stopPropagation(); 23766 }, 23767 buttons: { 23768 Peruuta: function () { 23769 $(this).dialog('close'); 23770 }, 23771 Merkitse: function () { 23772 $(this).dialog('close'); 23773 pages.iv_laskutus_ja_reskontra.mark_as_confirmed_for_financing(part_payment_id); 23774 }, 23775 }, 23776 }); 23777 }); 23778 }, 23779 23780 show_direct_payment: function (direct_payment_id, title) { 23781 var $dialog = global.$dialog; 23782 23783 $.ajax({ 23784 processData: false, 23785 dataType: 'html', 23786 type: 'GET', 23787 url: 'ajax/get_direct_payment_dialog/' + direct_payment_id + '/', 23788 beforeSend: function (request) { 23789 $dialog.dialog({ 23790 width: 800, 23791 height: 600, 23792 modal: true, 23793 resizable: false,
23794 title: title ? title : 'Korttimaksun tiedot', 23795 }); 23796 global.show_ajax_loader($dialog); 23797 }, 23798 success: function (response) { 23799 $dialog.html(response); 23800 }, 23801 }); 23802 }, //show_direct_payment 23803 23804 init_direct_payment_dialog: function () { 23805 $('#creditPayments').on('click', 'a.show_direct_payment', function (e) { 23806 e.preventDefault(); 23807 var id = $(e.target).attr('href'); 23808 pages.reskontra.show_direct_payment(id); 23809 }); 23810 $('#get_payment_terminal_details') 23811 .button({ icons: { primary: 'ui-icon-document' } }) 23812 .on('click', function () { 23813 var transactionId = $(this).data('pt-transaction-id'); 23814 23815 var dialog = $('<div />', {}).dialog({ 23816 autoOpen: true, 23817 modal: true, 23818 width: 500, 23819 position: { 23820 top: 50, 23821 }, 23822 hide: { 23823 effect: 'fade', 23824 speed: 3000, 23825 }, 23826 resizable: true, 23827 title: 'Maksupäätetapahtuman tiedot', 23828 draggable: true, 23829 buttons: { 23830 Sulje: function () { 23831 dialog.dialog('close'); 23832 }, 23833 }, 23834 }); 23835 dialog.html('<p>Ladataan maksupäätetapahtuman tietoja...</p>'); 23836 jQuery 23837 .ajax({ 23838 type: 'POST', 23839 url: '/payment_devices/getPTTransaction', 23840 data: { 23841 transactionId: transactionId, 23842 }, 23843 }) 23844 .then(function (data) { 23845 var dialogHtml = ''; 23846 if (data.transaction_status === 'success') { 23847 var merchantReceipt = JSON.parse(data.merchant_receipt); 23848 var dateString = data.transaction_time; 23849 var yy = 20 + dateString.substring(0, 2), 23850 mm = dateString.substring(2, 4), 23851 dd = dateString.substring(4, 6), 23852 hh = dateString.substring(6, 8), 23853 MM = dateString.substring(8, 10); 23854 23855 var transactionTime = dd + '.' + mm + '.' + yy + ' ' + hh + ':' + MM; 23856 var transactionType = data.transaction_type === 'Purchase' ? 'Maksu' : 'Hyvitys'; 23857 dialogHtml = 23858 '<pre><code>' + 23859 'Tapahtumatyyppi: ' + 23860 transactionType + 23861 '\n' + 23862 'Maksupääte: ' + 23863 data.terminal_name + 23864 ' (' + 23865 data.terminal_id + 23866 ')\n' + 23867 'Tapahtuma luotu: ' + 23868 transactionTime + 23869 '\n' + 23870 'Kortin lukutapa: ' + 23871 data.card_reading_method + 23872 '\n' + 23873 merchantReceipt.text + 23874 '</code></pre>'; 23875 } else { 23876 dialogHtml = 23877 'Maksupäätetapahtuma keskeneräinen, viimeistele maksutapahtuma työmääräyksellä'; 23878 } 23879 dialog.html(dialogHtml); 23880 }) 23881 .fail(function (err) { 23882 console.log(err); 23883 dialog.html('<p>Maksupäätetapahtuman haku epäonnistui</p>'); 23884 }); 23885 }); 23886 }, // init_direct_payment_dialog 23887 23888 createSATReportDialog: function () { 23889 23890 const html = pages.reskontra.getReportDialog(); 23891 23892 var SATReportDialog = $('<div>').html(html).dialog({ 23893 dialogClass: 'SATReportDialog', 23894 width: 400, 23895 height: 300, 23896 autoOpen: false, 23897 modal: true, 23898 resizable: false, 23899 draggable: false, 23900 title: 'Luo raportti', 23901 beforeclose: function (event, ui) { 23902 event.stopPropagation(); 23903 }, 23904 buttons: { 23905 Peruuta: function () { 23906 $(this).dialog('close'); 23907 }, 23908 'Luo raportti': function () { 23909 var data = pages.reskontra.SATReportData(); 23910 pages.reskontra.createSATReport(data); 23911 }, 23912 }, 23913 }); 23914 23915 SATReportDialog.dialog('open'); 23916 }, 23917 23918 23919 23920 getReportDialog: function (dialog) { 23921 23922 const div = document.createElement('div'); 23923 23924 const select = document.createElement('select'); 23925 const option = document.createElement('option'); 23926 option.textContent = 'valitse'; 23927 option.value = ""; 23928 select.appendChild(option); 23929 div.appendChild(select); 23930 23931 return div; 23932 }, 23933 23934 }, //reskontra 23935 23936 innovoice_ledger: { 23937 $datatable: null, 23938 $ledger_payment_totals_dt: null, 23939 $ledger_payments_dt: null, 23940 paymentsVM: new LedgerPaymentsDialogVm(), 23941 23942 init: function (opts) { 23943 $('#ledger_payments_filter_form select').selectmenu({ 23944 style: 'popup', 23945 width: 200, 23946 menuWidth: 200, 23947 }); 23948 23949 $('#ledger_payment_totals_filter_form') 23950 .button({ icons: { primary: 'ui-icon-search' } }) 23951 .on('change', function () { 23952 pages.innovoice_ledger.$ledger_payment_totals_dt.fnClearTable(0); 23953 pages.innovoice_ledger.$ledger_payment_totals_dt.fnDraw(); 23954 }); 23955 23956 $('#ledger_payments_filter_form input:checkbox').on('change', function (e) {
23957 // Timeout needed for filters to set before reRender 23958 setTimeout(function () { 23959 pages.innovoice_ledger.$ledger_payments_dt.fnClearTable(0); 23960 pages.innovoice_ledger.$ledger_payments_dt.fnDraw(); 23961 }, 1); 23962 }); 23963 23964 $('#get_ledger_payments') 23965 .button({ icons: { primary: 'ui-icon-search' } }) 23966 .on('click', function () { 23967 pages.innovoice_ledger.$ledger_payments_dt.fnClearTable(0); 23968 pages.innovoice_ledger.$ledger_payments_dt.fnDraw(); 23969 }); 23970 23971 $('#ledger_payments_filter_form input:checkbox').on('change', function (e) { 23972 var filter = $(this).attr('name'); 23973 var isChecked = $(this).is(':checked'); 23974 if (filter == 'all' && isChecked) { 23975 $('#ledger_payments_filter_form') 23976 .find('input:checkbox:checked') 23977 .each(function (ind, elem) { 23978 if ($(elem).attr('name') != 'all') { 23979 $(elem).prop('checked', false); 23980 } 23981 }); 23982 } 23983 23984 if (filter != 'all' && isChecked) { 23985 $('#ledger_payments_filter_form').find('input[name=all]').prop('checked', false); 23986 } 23987 }); 23988 23989 $('#ledger_payment_totals_dt').on('click', 'a.show_ledger_payment_report', function (e) { 23990 e.preventDefault(); 23991 var param = $(e.target).attr('href'); 23992 var action = $(e.target).attr('class'); 23993 var isHandled = $(e.target).attr('data-handled'); 23994 23995 switch (action) { 23996 case 'show_ledger_payment_report': 23997 pages.innovoice_ledger.paymentsVM.show_ledger_payment_report(param, isHandled); 23998 break; 23999 } 24000 }); 24001 24002 $('#ledger_payments_dt').on( 24003 'click', 24004 'a.show_ledger_payment, a.show_ledger_payment_invoice', 24005 function (e) { 24006 e.preventDefault(); 24007 24008 var id = $(e.target).attr('href'); 24009 var action = $(e.target).attr('class'); 24010 24011 switch (action) { 24012 case 'show_ledger_payment': 24013 pages.innovoice_ledger.paymentsVM.show_ledger_payment(id); 24014 break; 24015 case 'show_ledger_payment_invoice': 24016 pages.reskontra.show_invoice(id); 24017 break; 24018 } 24019 } 24020 ); 24021 //if ($('#ledger_payment_totals_dt').size()) { 24022 // on click of <a> --> id = href and action = class 24023 24024 pages.innovoice_ledger.$ledger_payment_totals_dt = $('#ledger_payment_totals_dt').dataTable({ 24025 oLanguage: global.dataTablesLanguage, 24026 sPaginationType: 'full_numbers', 24027 bPaginate: true, 24028 iDisplayLength: 10, 24029 bAutoWidth: false, 24030 bJQueryUI: true, 24031 bFilter: true, 24032 bInfo: true, 24033 bProcessing: true, 24034 bServerSide: true, 24035 sAjaxSource: 'innovoice_ledger_payments/get_payment_totals_data/', 24036 aoColumns: [ 24037 /** payment_date **/ { bVisible: true, bSortable: true, bSearchable: false }, 24038 /** Määrä **/ { bVisible: true, bSortable: false, bSearchable: false }, 24039 /** Määrä alisuorituksia **/ { bVisible: true, bSortable: false, bSearchable: false }, 24040 /** Määrä ylisuorituksia**/ { bVisible: true, bSortable: false, bSearchable: false }, 24041 /** Summa **/ { bVisible: true, bSortable: false, bSearchable: false }, 24042 /** Allokoitu **/ { bVisible: true, bSortable: false, bSearchable: false }, 24043 /** Allokoimattomat **/ { bVisible: true, bSortable: false, bSearchable: false }, 24044 /** Korkotuotto **/ { bVisible: true, bSortable: false, bSearchable: false }, 24045 /** Palautukset **/ { bVisible: true, bSortable: false, bSearchable: false }, 24046 /** KÃSITELTY **/ { bVisible: true, bSortable: false, bSearchable: false }, 24047 ], 24048 aaSorting: [[0, 'desc']], 24049 24050 fnServerParams: function (aoData) { 24051 var month = $('#ledger_payment_totals_filter_form select.month option:selected').attr( 24052 'value' 24053 ); 24054 var year = $('#ledger_payment_totals_filter_form select.year option:selected').attr( 24055 'value' 24056 ); 24057 var handledStatus = $( 24058 '#ledger_payment_totals_filter_form select.handled option:selected' 24059 ).attr('value'); 24060 24061 // filters.push('corporate_chain_invoices'); 24062 // $('#corporate-chain-invoices_filter_form input:checkbox:checked').each(function() { 24063 // filters.push($(this).attr('name')); 24064 // }); 24065 24066 aoData.push({ name: 'month', value: month }); 24067 aoData.push({ name: 'year', value: year }); 24068 aoData.push({ name: 'handledStatus', value: handledStatus }); 24069 }, 24070 24071 // fnDrawCallback: function() {
24072 // var month = $('#ledger_payment_totals_filter_form select.month option:selected').html(); 24073 // var year = $('#ledger_payment_totals_filter_form select.year option:selected').html(); 24074 // $('#maksusuoritukset span.month_year').html(month + ', ' + year); 24075 // }, 24076 24077 //Called before each row is shown 24078 fnRowCallback: function (nRow, aData, iDisplayIndex) { 24079 var date = aData[0]; 24080 var total = aData[1]; 24081 var totalUnderpaid = aData[2]; 24082 var totalOverpaid = aData[3]; 24083 var sum = parseFloat(aData[4]); 24084 var alloc = parseFloat(aData[5]); 24085 var unalloc = parseFloat(aData[6]); 24086 var intrest = parseFloat(aData[7]); 24087 var refunds = parseFloat(aData[8]); 24088 var dateHandled = parseInt(aData[9]); 24089 24090 var tick = ''; 24091 24092 if (unalloc > 0) { 24093 $(nRow).addClass('danger'); 24094 } else if (totalOverpaid > 0 || totalUnderpaid > 0) { 24095 $(nRow).addClass('warning'); 24096 } 24097 24098 if (!!dateHandled) { 24099 tick = 24100 '<span class="glyphicon glyphicon-ok" style="display:block; text-align:center;"></span>'; 24101 } 24102 24103 $('td:eq(0)', nRow).html( 24104 '<a href="' + 24105 date + 24106 '" data-handled="' + 24107 dateHandled + 24108 '" class="show_ledger_payment_report" >' + 24109 date + 24110 '</a>' 24111 ); 24112 $('td:eq(4)', nRow).html('<span>' + sum.toFixed(2).replace('.', ',') + '</span>'); 24113 $('td:eq(5)', nRow).html('<span>' + alloc.toFixed(2).replace('.', ',') + '</span>'); 24114 $('td:eq(6)', nRow).html('<span>' + unalloc.toFixed(2).replace('.', ',') + '</span>'); 24115 $('td:eq(7)', nRow).html('<span>' + intrest.toFixed(2).replace('.', ',') + '</span>'); 24116 $('td:eq(8)', nRow).html('<span>' + refunds.toFixed(2).replace('.', ',') + '</span>'); 24117 $('td:eq(9)', nRow).html(tick); 24118 24119 return nRow; 24120 }, 24121 }); 24122 24123 pages.innovoice_ledger.$ledger_payments_dt = $('#ledger_payments_dt').dataTable({ 24124 oLanguage: global.dataTablesLanguage, 24125 sPaginationType: 'full_numbers', 24126 bPaginate: true, 24127 iDisplayLength: 10, 24128 bAutoWidth: false, 24129 bJQueryUI: true, 24130 bFilter: true, 24131 bInfo: true, 24132 bProcessing: true, 24133 bServerSide: true, 24134 sAjaxSource: 'innovoice_ledger_payments/get_payments_data/', 24135 aoColumns: [ 24136 /* 'id' */ { bVisible: true, bSearchable: true, bSortable: true }, 24137 /* 'entryDate' */ { bVisible: true, bSearchable: true, bSortable: true }, 24138 /* 'statusDescription' */ { bVisible: true, bSearchable: false, bSortable: false }, 24139 /* 'amount' */ { bVisible: true, bSearchable: false, bSortable: true }, 24140 /* 'ref_no' */ { bVisible: true, bSearchable: true, bSortable: true }, 24141 /* 'invoiceNumber' */ { bVisible: true, bSearchable: true, bSortable: true }, 24142 /* 'payer_name' */ { bVisible: true, bSearchable: true, bSortable: true }, 24143 /* 'allocated_at' */ { bVisible: true, bSearchable: false, bSortable: true }, 24144 /* 'refunded_at' */ { bVisible: true, bSearchable: false, bSortable: true }, 24145 /* 'invoice_id' */ { bVisible: false, bSearchable: false, bSortable: false }, 24146 /* 'type' */ { bVisible: false, bSearchable: false, bSortable: false }, 24147 /* 'original_payment_id' */ { bVisible: false, bSearchable: true, bSortable: false }, 24148 ], 24149 aaSorting: [[0, 'desc']], 24150 24151 fnServerParams: function (aoData) { 24152 var month = $('#ledger_payments_filter_form select.month option:selected').attr('value'); 24153 var year = $('#ledger_payments_filter_form select.year option:selected').attr('value'); 24154 24155 var filters = []; 24156 24157 filters.push('ledger_payments'); 24158 24159 $('#ledger_payments_filter_form input:checkbox:checked').each(function () { 24160 filters.push($(this).attr('name')); 24161 }); 24162 24163 aoData.push({ name: 'month', value: month }); 24164 aoData.push({ name: 'year', value: year }); 24165 aoData.push({ name: 'filters', value: filters }); 24166 }, 24167 24168 fnDrawCallback: function () {
24169 var month = 24170 $('#ledger_payments_filter_form select.month option:selected').html() === 24171 '-- Kaikki kuukaudet --' 24172 ? 'Kaikki' 24173 : $('#ledger_payments_filter_form select.month option:selected').html(); 24174 var year = 24175 $('#ledger_payments_filter_form select.year option:selected').html() === 24176 '-- Kaikki vuodet --' 24177 ? 'Kaikki' 24178 : $('#ledger_payments_filter_form select.year option:selected').html(); 24179 $('#maksusuoritukset span.month_year').html(month + ', ' + year); 24180 }, 24181 24182 //Called before each row is shown 24183 fnRowCallback: function (nRow, aData, iDisplayIndex) { 24184 var id = aData[0]; 24185 var entryDate = aData[1]; 24186 var status = aData[2]; 24187 var amount = aData[3]; 24188 var ref_no = aData[4]; 24189 var invoice_no = aData[5] ? aData[5] : ''; 24190 var refund = aData[8]; 24191 var invoiceId = aData[9] ? aData[9] : ''; 24192 var type = aData[10]; 24193 var originalPaymentId = aData[11]; 24194 var isInterest = ''; 24195 if (parseInt(type) === 2) { 24196 isInterest = ' (Korko)'; 24197 } 24198 24199 var displayId = originalPaymentId ? originalPaymentId : id; 24200 24201 $('td:eq(0)', nRow).html( 24202 '<a href="' + id + '" class="show_ledger_payment" >' + displayId + '</a>' 24203 ); 24204 $('td:eq(2)', nRow).html('<span>' + status + isInterest + '</span>'); 24205 $('td:eq(3)', nRow).html('<span>' + amount + '</span>'); 24206 $('td:eq(5)', nRow).html( 24207 '<a href="' + 24208 invoiceId + 24209 '" class="show_ledger_payment_invoice" >' + 24210 invoice_no + 24211 '</a>' 24212 ); 24213 24214 return nRow; 24215 }, 24216 }); 24217 }, 24218 }, 24219 24220 tools: { 24221 cache: {}, 24222 lastXhr: '', 24223 $datatable: '', 24224 24225 init: function () { 24226 $('#tools_tabs').tabs(); 24227 }, 24228 init_stats: function () { 24229 $('#stats_tabs').tabs(); 24230 }, 24231 }, 24232 24233 omat_tiedot: { 24234 init: function (user_id) { 24235 $('#omat_tiedot_tabs').tabs(); 24236 $('body').delegate('#omat_tiedot_tabs', 'tabsshow', function (ev, ui) { 24237 var rex = /^[^#]*#/; 24238 var hash = ui.tab.href.replace(rex, ''); 24239 window.location.hash = '#'.concat(hash); 24240 }); 24241 24242 if ($('#company_users_tabs').length) { 24243 $('#company_users_tabs').tabs(); 24244 $('body').delegate('#company_users_tabs', 'tabsshow', function (ev, ui) { 24245 var rex = /^[^#]*#/; 24246 var hash = ui.tab.href.replace(rex, ''); 24247 window.location.hash = '#'.concat(hash); 24248 }); 24249 } 24250 24251 $('#change_password') 24252 .button({}) 24253 .on('click', function () { 24254 pages.omat_tiedot.change_password(user_id); 24255 }); 24256 24257 $('button.save').button({ icons: { primary: 'ui-icon-disk' } }); 24258 $('button#download_gdpr_disclaimer') 24259 .button({ icons: { primary: 'ui-icon-document' } }) 24260 .on('click', function () { 24261 w = window.open(); 24262 w.location = 'omat_tiedot/tietosuojaseloste/'; 24263 }); 24264 24265 $('#add_phone') 24266 .button({ icons: { primary: 'ui-icon-plusthick' }, text: true }) 24267 .on('click', function () { 24268 pages.omat_tiedot.add_phone(); 24269 }); 24270 24271 $('.remove_phone') 24272 .button({ icons: { primary: 'ui-icon-trash' }, text: true }) 24273 .on('click', function () { 24274 pages.omat_tiedot.remove_phone($(this)); 24275 }); 24276 24277 $('#omat_tiedot_form') 24278 .find('button[type=submit]') 24279 .on('click', function (e) { 24280 e.preventDefault(); 24281 24282 var $form = $('#omat_tiedot_form'); 24283 24284 console.log('omat_tiedot_form clicked'); 24285 24286 if (!pages.omat_tiedot.validateSave($form)) { 24287 return false; 24288 } 24289 24290 $form.ajaxSubmit({ 24291 type: 'post', 24292 dataType: 'json', 24293 //show the loading message 24294 beforeSubmit: function () { 24295 global.show_loading_dialog('Päivitetään tietoja...'); 24296 }, 24297 success: function (responseJSON, statusText, xhr, $form) { 24298 24299 console.log('response', responseJSON) 24300 24301 if (responseJSON.type === 'success') { 24302 global.show_message(responseJSON); 24303 global.close_loading_dialog(); 24304 24305 if (typeof changeSmsInterfaceUI === "function") { 24306 changeSmsInterfaceUI(responseJSON.data); 24307 } 24308 24309 if (typeof updateNewlyAddedUsers === "function") { 24310 updateNewlyAddedUsers(responseJSON.data); 24311 } 24312 24313 } else { 24314 global.show_message(responseJSON); 24315 global.close_loading_dialog(); 24316 } 24317 }, 24318 error: function (data) { 24319 global.close_loading_dialog(); 24320 global.show_message($.parseJSON(data.responseText)); 24321 }, 24322 }); 24323 }); 24324 24325 /* 24326 $('#omat_tiedot_form').validate({ 24327 debug: true, 24328 ignore: ':button', 24329 24330 errorPlacement: function(error, element) {}, 24331 24332 invalidHandler: function() { 24333 var msgJSON = {}; 24334 msgJSON.text = 'Ole hyvä ja täytä kaikki pakolliset kentät'; 24335 msgJSON.type = 'error'; 24336 global.show_message(msgJSON); 24337 }, 24338 24339 submitHandler: function(form) {
24340 $(form).ajaxSubmit({ 24341 type: 'post', 24342 dataType: 'json', 24343 //show the loading message 24344 beforeSubmit: function() { 24345 global.show_loading_dialog('Päivitetään tietoja...'); 24346 }, 24347 24348 success: function(responseJSON, statusText, xhr, $form) { 24349 if (responseJSON.type === 'success') { 24350 global.show_message(responseJSON); 24351 global.close_loading_dialog(); 24352 } else { 24353 global.show_message(responseJSON); 24354 global.close_loading_dialog(); 24355 } 24356 }, 24357 error: function(data) { 24358 global.close_loading_dialog(); 24359 global.show_message($.parseJSON(data.responseText)); 24360 }, 24361 }); 24362 return false; 24363 }, 24364 }); 24365 24366 */ 24367 24368 $('button#change_bank_account_number') 24369 .on('click', function () { 24370 $('div#bank-account-dialog').dialog({ 24371 autoOpen: true, 24372 modal: true, 24373 width: 350, 24374 height: 240, 24375 position: { 24376 top: 50, 24377 }, 24378 hide: { 24379 effect: 'fade', 24380 speed: 3000, 24381 }, 24382 resizable: true, 24383 draggable: true, 24384 title: 'Vaihda tilinumero', 24385 buttons: { 24386 Peruuta: function () { 24387 $(this).dialog('close'); 24388 }, 24389 Siirry: function () { 24390 pages.omat_tiedot.sendKycForm(); 24391 }, 24392 }, 24393 }); 24394 }); 24395 24396 $('button#sign_kredinor_contracts').button({ icons: { primary: 'ui-icon-pencil' } }).on('click',function () { 24397 pages.omat_tiedot.signKredinorContracts(); 24398 }); 24399 $('button#edit_kyc_form') 24400 .button({ icons: { primary: 'ui-icon-pencil' } }) 24401 .on('click', function () { 24402 pages.omat_tiedot.sendKycForm('edit_form'); 24403 }) 24404 24405 $('button#edit_contact_person') 24406 .button({ icons: { primary: 'ui-icon-pencil' } }) 24407 .on('click', function () { 24408 24409 $('div#contact-person-dialog').dialog({ 24410 autoOpen: true, 24411 modal: true, 24412 width: 350, 24413 height: 240, 24414 hide: { 24415 effect: 'fade', 24416 speed: 3000, 24417 }, 24418 resizable: true, 24419 draggable: true, 24420 title: 'Muokkaa sopimusyhteyshenkilöä', 24421 buttons: { 24422 Peruuta: function () { 24423 $(this).dialog('close'); 24424 }, 24425 Siirry: function () { 24426 pages.omat_tiedot.sendKycForm('edit_contact_person'); 24427 }, 24428 }, 24429 }); 24430 }); 24431 }, 24432 24433 change_password: function (user_id) { 24434 var $form = $('<form />', { 24435 method: 'POST', 24436 action: '/omat_tiedot/change_password/' + user_id, 24437 }).append( 24438 $('<fieldset />', { class: 'fs-invisible' }).append( 24439 $('<ol />', {}).append( 24440 $('<li />', {}).append( 24441 $('<label />', {}).html('Nykyinen salasanasi'), 24442 $('<input />', { 24443 type: 'password', 24444 name: 'old_password', 24445 id: 'old_password', 24446 class: 'text medium', 24447 }) 24448 ), 24449 24450 $('<li />', {}).append( 24451 $('<label />', {}).html('Uusi salasana'), 24452 $('<input />', { 24453 type: 'password', 24454 name: 'new_password', 24455 id: 'new_password', 24456 class: 'text medium', 24457 }) 24458 ), 24459 24460 $('<li />', {}).append( 24461 $('<label />', {}).html('Vahvista uusi salasana'), 24462 $('<input />', { 24463 type: 'password', 24464 name: 'confirm_password', 24465 id: 'confirm_password', 24466 class: 'text medium', 24467 }) 24468 ) 24469 ) 24470 ) 24471 ); 24472 24473 var $dialog = $('<div />', { style: 'text-align:left;' }) 24474 .append($form) 24475 .dialog({ 24476 width: 400, 24477 autoOpen: true, 24478 modal: true, 24479 resizable: false, 24480 draggable: false, 24481 beforeClose: function (event, ui) { 24482 event.stopPropagation(); 24483 }, 24484 title: 'Salasanan vaihto', 24485 buttons: { 24486 Peruuta: function () { 24487 $(this).dialog('close'); 24488 }, 24489 'Vaihda salasana': function () { 24490 $form.ajaxSubmit({ 24491 type: 'post', 24492 dataType: 'json', 24493 //show the loading message 24494 beforeSubmit: function () { 24495 global.show_loading_dialog('Vaihdetaan salasanaa...'); 24496 }, 24497 24498 success: function (responseJSON, statusText, xhr, $form) { 24499 $dialog.dialog('close'); 24500 global.show_message(responseJSON); 24501 global.close_loading_dialog(); 24502 }, 24503 error: function (data) { 24504 global.show_message($.parseJSON(data.responseText)); 24505 global.close_loading_dialog(); 24506 }, 24507 }); //ajaxSubmit 24508 }, 24509 }, 24510 }); 24511 }, //change_password 24512 24513 add_car: function ($cars) { 24514 $num = $cars.find('tbody tr').size(); 24515 var company_id = $cars 24516 .parents('.company')
24517 .find('input:hidden') 24518 .filter('[name=company_id]') 24519 .val(); 24520 24521 if (typeof company_id == 'undefined') { 24522 var new_id = $cars.parents('.company').data('new_id'); 24523 company_id = 'new_' + new_id; 24524 } 24525 24526 $remove_btn = $( 24527 '<button type="button" class="remove_car" style="float:right;">Poista</button>' 24528 ) 24529 .button({ icons: { primary: 'ui-icon-trash' }, text: true }) 24530 .on('click', function (e) { 24531 e.stopPropagation(); 24532 $wrapper = $(this).parent().parent(); 24533 $('<div />') 24534 .html( 24535 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen auton?</p>' 24536 ) 24537 .dialog({ 24538 resizable: false, 24539 height: 180, 24540 width: 340, 24541 title: 'Poista auto', 24542 modal: true, 24543 buttons: { 24544 Ei: function () { 24545 $(this).dialog('close'); 24546 }, 24547 Kyllä: function () { 24548 $(this).dialog('close'); 24549 24550 $wrapper.hide('highlight', function () { 24551 $(this).remove(); 24552 }); 24553 }, 24554 }, 24555 }); 24556 }); 24557 24558 $car_data = $('<tr />', { class: 'car', style: 'width:900px;' }).append( 24559 $('<td />').append( 24560 '<input type="text" name="cars[' + 24561 company_id + 24562 '][new_' + 24563 $num + 24564 '][phone]" id="cars[' + 24565 $num + 24566 '][phone]" class="text medium-small required" />' 24567 ), 24568 $('<td />').append( 24569 '<input type="text" name="cars[' + 24570 company_id + 24571 '][new_' + 24572 $num + 24573 '][car_nr]" id="cars[' + 24574 $num + 24575 '][car_nr]" class="text small required" />' 24576 ), 24577 $('<td />').append( 24578 '<input type="text" name="cars[' + 24579 company_id + 24580 '][new_' + 24581 $num + 24582 '][stationary_position]" id="cars[' + 24583 $num + 24584 '][stationary_position]" class="text small required" />' 24585 ), 24586 $('<td />', {}).append($remove_btn) 24587 ); 24588 24589 $cars.prepend($car_data); 24590 }, //add_car 24591 24592 add_phone: function () { 24593 $num = $('#phones tbody tr').size(); 24594 24595 $remove_btn = $('<button />', { type: 'button' }) 24596 .html('Poista') 24597 .button({ icons: { primary: 'ui-icon-trash' }, text: true }) 24598 .on('click', function (e) { 24599 e.stopPropagation(); 24600 pages.omat_tiedot.remove_phone(e.target); 24601 }); 24602 24603 $phone_data = $('<tr />', { class: 'phone', style: 'width:900px;' }).append( 24604 $('<td />').append( 24605 '<input type="text" name="sms_interface[' + 24606 ($num + 10) + 24607 '][msisdn]" id="sms_interface[' + 24608 ($num + 10) + 24609 '][msisdn]" class="text small required" />' 24610 ), 24611 $('<td />').append( 24612 '<input type="text" name="sms_interface[' + 24613 ($num + 10) + 24614 '][sales_person]" id="sms_interface[' + 24615 ($num + 10) + 24616 '][sales_person]" class="text small" />' 24617 ), 24618 $('<td />').append( 24619 '<input type="text" name="sms_interface[' + 24620 ($num + 10) + 24621 '][product]" id="sms_interface[' + 24622 ($num + 10) + 24623 '][product]" class="text medium-small" />' 24624 ), 24625 $('<td />', {}).append($remove_btn) 24626 ); 24627 24628 //$phone_data.append(); 24629 $('#phones').prepend($phone_data); 24630 }, 24631 24632 add_company: function () { 24633 var $userinfo = $('#companies .company').eq(0), 24634 contact_info = [], 24635 $num = 0; 24636 24637 if (typeof $userinfo[0] !== 'undefined') { 24638 var $input_fields = $userinfo.find('input'); 24639 contact_info.contact_person = $input_fields.filter('[name*=contact_person]').val(); 24640 contact_info.contact_phone = $input_fields.filter('[name*=phone]').val(); 24641 contact_info.contact_address = $input_fields.filter('[name*=address]').val(); 24642 contact_info.contact_zipcode = $input_fields.filter('[name*=zipcode]').val(); 24643 contact_info.contact_city = $input_fields.filter('[name*=city]').val(); 24644 } 24645 24646 $num = '' + $('#companies .company').size(); 24647 24648 if (typeof contact_info.contact_person === 'undefined') { 24649 contact_info.contact_person = ''; 24650 contact_info.contact_phone = ''; 24651 contact_info.contact_address = ''; 24652 contact_info.contact_zipcode = ''; 24653 contact_info.contact_city = ''; 24654 } 24655 24656 $remove_company_btn = $('<button />', { 24657 type: 'button', 24658 style: 'float:right; padding:0px 5px;', 24659 }) 24660 .html('Poista yritys') 24661 .button({ icons: { primary: 'ui-icon-trash' }, text: true }) 24662 .on('click', function (e) { 24663 e.stopPropagation(); 24664 $wrapper = $(this).parents('.company'); 24665 24666 $('<div />', {}) 24667 .html( 24668 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen yrityksen?</p>' 24669 ) 24670 .dialog({ 24671 resizable: false, 24672 height: 200, 24673 width: 300, 24674 title: 'Poista yritys', 24675 modal: true, 24676 buttons: { 24677 Ei: function () { 24678 $(this).dialog('close'); 24679 }, 24680 Kyllä: function () { 24681 $(this).dialog('close'); 24682 24683 $wrapper.hide('highlight', function () { 24684 $(this).remove(); 24685 }); 24686 }, 24687 }, 24688 }); 24689 }); 24690 24691 $company_data = $('<div />', { class: 'company' }).append( 24692 $('<fieldset />', {}) 24693 .append( 24694 $('<legend>Yritys</legend>'), 24695 $('<div />', { class: 'buttons', style: 'display:block; float:right; ' }), 24696 $('<div />', { style: 'width:280px; float:left;' }).append( 24697 $('<ol />').append( 24698 $('<li><label for="company_name">Yrityksen nimi:</label></li>').append( 24699 $( 24700 '<input type="text" name="company[new_' + 24701 $num + 24702 '][company_name]" id="company[new_' + 24703 $num + 24704 '][company_name]" class="text medium-small required" />' 24705 ) 24706 ), 24707 $('<li><label for="business_id">Y-tunnus:</label></li>').append( 24708 '<input type="text" name="company[new_' + 24709 $num + 24710 '][business_id]" id="compamy[new_' + 24711 $num + 24712 '][business_id]" class="text medium-small required" />' 24713 ), 24714 $('<li><label for="iban">IBAN:</label>').append( 24715 '<input type="text" name="company[new_' + 24716 $num + 24717 '][iban]" id="company[new_' + 24718 $num + 24719 '][iban]" class="text medium-small" />' 24720 ), 24721 $('<li><label for="bic">BIC:</label></li>').append( 24722 '<input type="text" name="company[new_' + 24723 $num + 24724 '][bic]" id="company[new_' + 24725 $num + 24726 '][bic]" class="text medium-small" />' 24727 ) 24728 ) 24729 ) 24730 ) 24731 .append( 24732 $('<div />', { class: 'right', style: 'float:left;' }).append( 24733 $('<ol />').append( 24734 $('<li><label for="contact_person">Yhteyshenkilö:</label></li>').append( 24735 '<input type="text" name="company[new_' + 24736 $num + 24737 '][contact_person]" id="company[new_' + 24738 $num + 24739 '][contact_person]" class="text medium-small required" value="' + 24740 contact_info.contact_person + 24741 '" />' 24742 ), 24743 $('<li><label for="phone">Puhelin:</label></li>').append( 24744 '<input type="text" name="company[new_' + 24745 $num + 24746 '][phone]" id="company[new_' + 24747 $num + 24748 '][phone]" class="text medium-small" value="' + 24749 contact_info.contact_phone + 24750 '" />' 24751 ), 24752 $('<li><label for="address">Osoite:</label>').append( 24753 '<input type="text" name="company[new_' + 24754 $num + 24755 '][address]" id="company[new_' + 24756 $num + 24757 '][address]" class="text medium-small required" value="' + 24758 contact_info.contact_address + 24759 '" />' 24760 ), 24761 $('<li><label for="zipcode">Postinumero:</label></li>').append( 24762 '<input type="text" name="company[new_' + 24763 $num + 24764 '][zipcode]" id="company[new_' + 24765 $num + 24766 '][zipcode]" class="text medium-small required" value="' + 24767 contact_info.contact_zipcode + 24768 '"/>' 24769 ), 24770 $('<li><label for="city">Kaupunki:</label></li>').append( 24771 '<input type="text" name="company[new_' + 24772 $num + 24773 '][city]" id="company[new_' + 24774 $num + 24775 '][city]" class="text medium-small required" value="' + 24776 contact_info.contact_city + 24777 '" />' 24778 ), 24779 $( 24780 '<label for="company_id"><input type="hidden" name="company[new_' + 24781 $num + 24782 '][id]" id="company[new_' + 24783 $num +
24784 '][id]" value="0" /></label>' 24785 ), 24786 $( 24787 '<label for="company_id"><input type="hidden" name="company[new_' + 24788 $num + 24789 '][new_id]" id="company[new_' + 24790 $num + 24791 '][new_id]" value="new_' + 24792 $num + 24793 '" /></label>' 24794 ) 24795 ) 24796 ) 24797 ) 24798 .append( 24799 $('<div />', { style: 'clear:both;' }) 24800 .append( 24801 $('<h3 />', { style: 'margin:0; padding:0;' }).html('Autot'), 24802 $('<table />', { id: 'cars', style: 'width:680px;' }).append( 24803 $('<thead />').append( 24804 $('<tr />').append( 24805 $('<th />').html('Autopuhelimen nro.'), 24806 $('<th />').html('Rekisterinumero'), 24807 $('<th />').html('Järjestysnumero'), 24808 $('<th />').html('Asemapaikka') 24809 ) 24810 ) 24811 ) 24812 ) 24813 .append( 24814 $('<button />', { 24815 type: 'button', 24816 style: 'margin:0px 10px 10px 10px;', 24817 class: 'add_car', 24818 }) 24819 .html('Lisää auto') 24820 .button({ icons: { primary: 'ui-icon-plusthick' } }) 24821 .on('click', function (e) { 24822 $btn = $(e.currentTarget); 24823 dialogs.account_card.innotaxi.add_car($btn.parent().find('#cars')); 24824 }) 24825 ) 24826 ) 24827 ); 24828 24829 //<button type="button" style="margin:0px 10px 10px 10px;" id="add_car">Lisää uusi auto</button> 24830 24831 $('#companies').prepend($company_data.data({ new_id: $num })); 24832 $remove_company_btn.prependTo($company_data.find('div.buttons')); 24833 24834 $company_data.find('.add_car').trigger('click'); 24835 24836 $('#companies').delegate('[id*="company_name"]', 'keyup', function () { 24837 $(this).parents('fieldset').find('legend').html($(this).val()); 24838 }); 24839 }, //add_company 24840 24841 remove_phone: function (btn) { 24842 $wrapper = $(btn).parent().parent(); 24843 24844 $('<div />') 24845 .html( 24846 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen puhelimen?</p>' 24847 ) 24848 .dialog({ 24849 resizable: false, 24850 height: 180, 24851 width: 340, 24852 title: 'Poista SMS-käyttöliittymä', 24853 modal: true, 24854 buttons: { 24855 Ei: function () { 24856 $(this).dialog('close'); 24857 }, 24858 Kyllä: function () { 24859 $(this).dialog('close'); 24860 24861 var sms_interface_id = $wrapper.find('input:hidden').filter('[name*=id]').val(); 24862 24863 if (sms_interface_id != '' && typeof sms_interface_id != 'undefined') { 24864 $.ajax({ 24865 url: 'ajax/delete_sms_interface/' + sms_interface_id + '/', 24866 type: 'post', 24867 dataType: 'json', 24868 success: function (responseJSON, textStatus, jqXHR) { 24869 if (responseJSON.type == 'success') { 24870 $wrapper.hide('highlight', function () { 24871 $(this).remove(); 24872 }); 24873 } else { 24874 global.show_message(responseJSON); 24875 } 24876 }, 24877 }); 24878 } else { 24879 $wrapper.hide('highlight', function () { 24880 $(this).remove(); 24881 }); 24882 } 24883 }, 24884 }, 24885 }); 24886 }, 24887 24888 remove_car: function (btn) { 24889 $wrapper = $(btn).parent().parent(); 24890 24891 $('<div />') 24892 .html( 24893 '<p style="font-weight:bold;"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; "></span>Haluatko varmasti poistaa kyseisen auton?</p>' 24894 ) 24895 .dialog({ 24896 resizable: false, 24897 height: 180, 24898 width: 340, 24899 title: 'Poista Auto', 24900 modal: true, 24901 buttons: { 24902 Ei: function () { 24903 $(this).dialog('close'); 24904 }, 24905 Kyllä: function () { 24906 $(this).dialog('close'); 24907
24908 var car_id = $wrapper.find('input:hidden').filter('[name*=id]').val(); 24909 24910 if (car_id !== '' && typeof car_id !== 'undefined') { 24911 $.ajax({ 24912 url: 'ajax/delete_car/' + car_id + '/', 24913 type: 'post', 24914 dataType: 'json', 24915 success: function (responseJSON, textStatus, jqXHR) { 24916 if (responseJSON.type === 'success') { 24917 $wrapper.hide('highlight', function () { 24918 $(this).remove(); 24919 }); 24920 } else { 24921 global.show_message(responseJSON); 24922 } 24923 }, 24924 }); 24925 } else { 24926 $wrapper.hide('highlight', function () { 24927 $(this).remove(); 24928 }); 24929 } 24930 }, 24931 }, 24932 }); 24933 }, 24934 24935 validateSave: function ($form) { 24936 var msgJSON = {}, 24937 errors = []; 24938 msgJSON.text = 'Ole hyvä ja täytä kaikki pakolliset kentät'; 24939 msgJSON.type = 'error'; 24940 24941 // Validate required fields on current page 24942 // Get all fields that have required class on it 24943 var $inputs = $form.find('fieldset:enabled input.required').not(':disabled'); 24944 24945 $inputs.each(function (index, elem) { 24946 if ($(elem).val() === '') { 24947 $(elem).addClass('error'); 24948 24949 console.log('Field caused validation errors:', index, elem); 24950 errors.push('Ole hyvä ja täytä kaikki pakolliset tiedot'); 24951 } else { 24952 if ($(elem).hasClass('error')) { 24953 $(elem).removeClass('error'); 24954 } 24955 } 24956 }); 24957 24958 if (errors.length > 0) { 24959 global.show_message(msgJSON); 24960 return false; 24961 } 24962 24963 return true; 24964 }, 24965 24966 sendKycForm: function (type) { 24967 type = type || 'edit_bank_account'; 24968 $.ajax({ 24969 url: '/omat_tiedot/send_kyc_form', 24970 data: { type: type }, 24971 type: 'POST', 24972 dataType: 'application/json', 24973 beforeSend: function () { 24974 global.show_loading_dialog('Lähetetään...'); 24975 }, 24976 success: function () { 24977 global.close_loading_dialog(); 24978 }, 24979 error: function () { 24980 global.close_loading_dialog(); 24981 }, 24982 complete: function (response) { 24983 console.log('complete response', JSON.parse(response.responseText).text); 24984 var json = JSON.parse(response.responseText); 24985 24986 switch (json.type) { 24987 case 'success': 24988 console.log('url', json.data.url); 24989 $('.info-text').fadeOut(); 24990 //$('.response-text').text(json.text); 24991 //$('.response-text').fadeIn(); 24992 window.location.href = json.data.url; 24993 $('.ui-dialog .ui-dialog-buttonpane').find('button:last').hide(); 24994 $('.ui-dialog .ui-dialog-buttonpane').find('button:first').text('Sulje'); 24995 break; 24996 case 'error': 24997 global.show_message(json); 24998 break; 24999 } 25000 }, 25001 }); 25002 }, 25003 25004 signKredinorContracts: function() { 25005 $.ajax({ 25006 url: '/omat_tiedot/sign_contract', 25007 type: 'GET', 25008 dataType: 'application/json', 25009 beforeSend: function () { 25010 global.show_loading_dialog('Siirrytään allekirjoitukseen...'); 25011 }, 25012 success: function(){ 25013 global.close_loading_dialog(); 25014 }, 25015 error: function(){ 25016 global.close_loading_dialog(); 25017 }, 25018 complete: function (response) { 25019 console.log('signKredinorContracts response', JSON.parse(response.responseText).text); 25020 var json = JSON.parse(response.responseText); 25021 25022 switch (json.type) { 25023 case 'success': 25024 console.log('url', json.data.url); 25025 $('.info-text').fadeOut(); 25026 //$('.response-text').text(json.text); 25027 //$('.response-text').fadeIn(); 25028 window.location.href = json.data.url; 25029 $('.ui-dialog .ui-dialog-buttonpane').find('button:last').hide(); 25030 $('.ui-dialog .ui-dialog-buttonpane').find('button:first').text('Sulje'); 25031 break; 25032 case 'error': 25033 global.show_message(json); 25034 break; 25035 } 25036 } 25037 }); 25038 } 25039 } 25040}; //pages 25041 25042var dialogs = { 25043 url: '', 25044 25045 refresh: function () { 25046 global.show_ajax_loader(global.$dialog); 25047 $.get(dialogs.url, function (data) { 25048 global.$dialog.html(data); 25049 }); 25050 }, 25051}; 25052 25053global.addressFormatting = function (text) { 25054 var newText = text; 25055 //array of find replaces 25056 var findreps = [ 25057 { find: /^([^\:]+) \: /g, rep: '<span class="ui-selectmenu-item-header">$1</span>' }, 25058 { find: /([^\|><]+) \| /g, rep: '<span class="ui-selectmenu-item-content">$1</span>' }, 25059 { find: /([^\|><\(\)]+) (\()/g, rep: '<span class="ui-selectmenu-item-content">$1</span>$2' }, 25060 { find: /([^\|><\(\)]+)$/g, rep: '<span class="ui-selectmenu-item-content">$1</span>' }, 25061 { find: /(\([^\|><]+\))$/g, rep: '<span class="ui-selectmenu-item-footer">$1</span>' }, 25062 ]; 25063 25064 for (var i in findreps) { 25065 newText = newText.replace(findreps[i].find, findreps[i].rep); 25066 } 25067 return newText; 25068}; 25069 25070var lasku = lasku || {}; 25071lasku.asiakasrekisterista = lasku.asiakasrekisterista || {}; 25072 25073lasku.asiakasrekisterista.init = function () { 25074 $('#search_from_customer_registry_form').submit(function () { 25075 var customer_type = $('#change_customer_type')
25076 .find('input:radio[name=customer_type]:checked') 25077 .val(), 25078 customer_id; 25079 25080 //if customer type is 0 = person, 1 = company 25081 if (customer_type == 0) { 25082 customer_id = $('#person_list option:selected').val(); 25083 } 25084 25085 if (customer_type == 1) { 25086 customer_id = $('#company_list option:selected').val(); 25087 } 25088 25089 customer_data = lasku.asiakasrekisterista.get_customer_data(customer_id); 25090 return false; 25091 }); 25092 25093 $('#change_customer_type') 25094 .find('input:radio[name=customer_type]') 25095 .change(function (e) { 25096 if ($(e.target).val() == 0) { 25097 $('#person').show(); 25098 $('#company').hide(); 25099 } 25100 25101 if ($(e.target).val() == 1) { 25102 $('#person').hide(); 25103 $('#company').show(); 25104 } 25105 }); 25106 25107 $('#person_list').selectmenu({ 25108 width: 200, 25109 menuWidth: 350, 25110 format: global.addressFormatting, 25111 style: 'dropdown', 25112 maxHeight: 300, 25113 }); 25114 25115 $('#company_list').selectmenu({ 25116 width: 200, 25117 menuWidth: 350, 25118 format: global.addressFormatting, 25119 style: 'dropdown', 25120 maxHeight: 300, 25121 }); 25122 25123 $('#get_customer_data').button({ icons: { primary: 'ui-icon-search' } }); 25124}; 25125 25126lasku.asiakasrekisterista.get_customer_data = function (customer_id) { 25127 //console.log('lasku.asiakasrekisterista.get_customer_data'); 25128 25129 //console.log($('#person_list').find('option:selected').val()); 25130 /* 25131 var customer_type = $('#change_customer_type').find('input:radio[name=customer_type]:checked').val(), customer_id; 25132 25133 //if customer type is 0 = person, 1 = company 25134 if(customer_type == 0){ 25135 customer_id = $('#person_list option:selected').val(); 25136 } 25137 25138 if(customer_type == 1){ 25139 customer_id = $('#company_list option:selected').val(); 25140 } 25141 */ 25142 25143 $.getJSON('ajax/get_customer_json/' + customer_id, function (data, textStatus, jqXHR) { 25144 var customer_info; 25145 25146 if (customer_type == 0) { 25147 $('.company').remove(); 25148 $('#company_info').hide(); 25149 $customer_info = $('#person_info'); 25150 $customer_info.find("input[name='customer[firstname]']").val(data.firstname); 25151 $customer_info.find("input[name='customer[lastname]']").val(data.lastname); 25152 $customer_info.find("input[name='customer[ssn]']").val(data.ssn); 25153 } 25154 25155 if (customer_type == 1) { 25156 $('.person').remove(); 25157 $('#person_info').hide(); 25158 $customer_info = $('#company_info'); 25159 $customer_info.find("input[name='customer[company_name]']").val(data.company_name); 25160 $customer_info.find("input[name='customer[business_id]']").val(data.business_id); 25161 25162 $payment_terms_select = $("select[name='customer[payment_terms]']") 25163 .selectmenu() 25164 .selectmenu('value', data.payment_terms); 25165 //$payment_terms_option = $payment_terms_select.find('option[value='+ data.payment_terms +']'); 25166 // $('select[name=set_payment_terms] option[value='+ data.payment_terms +']').attr('selected', 'selected'); 25167 25168 //console.log($('select[name=customer_payment_terms]').selectmenu("value")); 25169 //console.log($('select[name=set_payment_terms]').selectmenu("value")); 25170 //console.log($payment_terms_option); 25171 25172 //If the given payment_terms is not selectable, set it to payment_terms = 14; 25173 // index = $payment_terms_option.index() == -1? 1 : $payment_terms_option.index(); 25174 // $payment_terms_select.selectmenu('index', index); 25175 //console.log(index); 25176 25177 //$('#set_payment_terms').selectmenu('value', index); 25178 //pages.lasku.set_payment_terms(data.payment_terms); 25179 // pages.lasku.set_payment_terms(data.payment_terms); 25180 } 25181 25182 $('#receiver').show(); 25183 $customer_info.show(); 25184 $customer_info.find("input[name='customer[address]']").val(data.address); 25185 $customer_info.find("input[name='customer[zipcode]']").val(data.zipcode); 25186 $customer_info.find("input[name='customer[city]']").val(data.city); 25187 $customer_info.find("input[name='customer[email]']").val(data.email); 25188 $customer_info.find("input[name='customer[id]']").val(data.id); 25189 25190 //console.log('delivery_by:', delivery_by); 25191 25192 if (data.delivery_by == 'mail' || data.delivery_by == 'gothia') { 25193 $customer_info.find('td.delivery').find('input[value=gothia]').attr('checked', 'checked'); 25194 } 25195 25196 if (data.delivery_by == 'email') { 25197 $customer_info.find('td.delivery').find('input[value=email]').attr('checked', 'checked'); 25198 } 25199 }); 25200}; 25201 25202pages.laskutus = { 25203 init: function (data) { 25204 $('#laskutus-tabs').tabs(); 25205 var upload = document.getElementById('upload-material'); 25206 $('#upload-material').change(function () { 25207 console.log('Change'); 25208 }); 25209 upload.addEventListener('change', function () { 25210 var fileName = upload.files[0].name; 25211 $('#file-name').text(fileName).css('display', 'block'); 25212 $('#parse_invoice_material').css('display', 'inline'); 25213 }); 25214 $('#upload_invoice_material') 25215 .button({ icons: { primary: 'ui-icon-plus' } }) 25216 .on('click', function () { 25217 $('#upload-material').trigger('click'); 25218 }); 25219 $('#parse_invoice_material') 25220 .button({ icons: { primary: 'ui-icon-arrowthickstop-1-s' } }) 25221 .on('click', function () {
25222 console.log('send to server...'); 25223 $('#parse_invoice_material').find('span.ui-button-text').text('Odota. Ladataan...'); 25224 $('#parse_invoice_material').attr('disabled', 'disabled'); 25225 $('#upload-to-server').submit(); 25226 }); 25227 window.batchData = data; 25228 }, 25229}; 25230 25231;var recurringInvoicing = function({showStation, isAdmin, controller, invoiceEndpoint}){ 25232 25233 var self = this; 25234 25235 self.isAdmin = isAdmin; 25236 self.recurringInvoiceId = 0; 25237 self.showStationField = showStation; 25238 self.controller = controller; 25239 self.invoiceEndpoint = invoiceEndpoint; 25240 25241 $('body').append('<div id="recurring_popup"><div/>'); 25242 self.dialog = $('#recurring_popup'); 25243 25244 $('body').append('<div id="recurring_extra_popup"><div/>'); 25245 self.extraDialog = $('#recurring_extra_popup'); 25246 25247 self.dialogOpen = function(title, width, height){ 25248 self.dialog.html(global.$ajax_loader).dialog({ 25249 autoOpen: true, 25250 modal: true, 25251 hide: { 25252 effect: 'fade', 25253 speed: 3000, 25254 }, 25255 width: width ? width : 'auto', 25256 height: height ? height : 'auto', 25257 resizable: true, 25258 title: title, 25259 draggable: true, 25260 close: function(){ 25261 $(this).dialog('close'); 25262 } 25263 }); 25264 } 25265 25266 self.dialogReplaceHtml = function(html){ 25267 self.dialog.dialog().html(html); 25268 } 25269 self.dialogStartLoading = function(){ 25270 self.dialog.dialog().html(global.$ajax_loader); 25271 } 25272 25273 self.extraDialogOpen = function(title, width, height){ 25274 self.extraDialog.html(global.$ajax_loader).dialog({ 25275 autoOpen: true, 25276 modal: true, 25277 hide: { 25278 effect: 'fade', 25279 speed: 3000, 25280 }, 25281 width: width ? width : 'auto', 25282 height: height ? height : 'auto', 25283 resizable: false, 25284 title: title, 25285 draggable: true, 25286 close: function(){ 25287 $(this).dialog('close'); 25288 } 25289 }); 25290 } 25291 25292 self.extraDialogReplaceHtml = function(html){ 25293 self.extraDialog.dialog().html(html); 25294 } 25295 self.extraDialogStartLoading = function(){ 25296 self.extraDialog.dialog().html(global.$ajax_loader); 25297 } 25298 25299 self.loadStatusDialog = function(id){ 25300 self.extraDialogOpen('Loki', 540, 450); 25301 $.ajax({ 25302 type: 'GET', 25303 url: '/reskontra/getRecurringInvoiceLog/' + id, 25304 }).done(function(response){ 25305 self.extraDialogReplaceHtml(response.data.html); 25306 }).fail(function(error){ 25307 var msg = JSON.parse(error.responseText); 25308 self.extraDialogReplaceHtml('<span>' + msg.text + '<span/>'); 25309 self.extraDialogClose(4000); 25310 }) 25311 } 25312 self.loadDateFixDialog = function(id){ 25313 self.dialogOpen('Muuta laskun päiväys', 520); 25314 $.ajax({ 25315 type: 'GET', 25316 url: '/reskontra/getRecurringDateFixDialog/' + id, 25317 }).done(function(response){ 25318 self.dialogReplaceHtml(response.data.html); 25319 }).fail(function(error){ 25320 var msg = JSON.parse(error.responseText); 25321 self.dialogReplaceHtml('<span>' + msg.text + '<span/>'); 25322 self.dialogClose(4000); 25323 }) 25324 } 25325 25326 self.loadEndDateDialog = function(id){ 25327 self.extraDialogOpen('Aseta päättymispäivä', 520); 25328 $.ajax({ 25329 type: 'GET', 25330 url: '/reskontra/getRecurringEndDateDialog/' + id, 25331 }).done(function(response){ 25332 self.extraDialogReplaceHtml(response.data.html); 25333 }).fail(function(error){ 25334 var msg = JSON.parse(error.responseText); 25335 self.extraDialogReplaceHtml('<span>' + msg.text + '<span/>'); 25336 self.extraDialogClose(3000); 25337 }) 25338 } 25339 25340 self.loadRecurringInvoiceDialog = function(id){ 25341 self.dialogOpen('Laskutuspohjan asetukset', 800, 600); 25342 $.ajax({ 25343 type: 'GET', 25344 url: 'reskontra/getRecurringInvoiceDialog/' + id, 25345 }).done(function(response){ 25346 self.dialogReplaceHtml(response.data.html); 25347 }).fail(function(error){ 25348 var msg = JSON.parse(error.responseText); 25349 self.dialogReplaceHtml('<span>' + msg.text + '<span/>'); 25350 self.dialogClose(4000); 25351 }) 25352 } 25353 25354 self.dialogClose = function(delay){ 25355 if(!self.dialog){ 25356 return; 25357 } 25358 if(!delay){ 25359 self.dialog.dialog('close'); 25360 } 25361 25362 setTimeout(function(){ 25363 self.dialog.dialog('close'); 25364 }, delay); 25365 } 25366 25367 self.extraDialogClose = function(delay){ 25368 if(!self.extraDialog){ 25369 return; 25370 } 25371 if(!delay){ 25372 self.extraDialog.dialog('close'); 25373 } 25374 25375 setTimeout(function(){ 25376 self.extraDialog.dialog('close'); 25377 }, delay); 25378 } 25379 25380 self.dt = $('#recurring_dt').dataTable({ 25381 oLanguage: global.dataTablesLanguage, 25382 sPaginationType: 'full_numbers', 25383 bPaginate: true, 25384 iDisplayLength: 10, 25385 bAutoWidth: false, 25386 bJQueryUI: true, 25387 bFilter: true, 25388 bInfo: true, 25389 bProcessing: true, 25390 bServerSide: true, 25391 sAjaxSource: 'reskontra/recurringDataTable/', 25392 aoColumns: [ 25393 /** id **/ { bVisible: true, bSortable: true, bSearchable: true }, 25394 /** customer_id **/ { bVisible: false, bSortable: false, bSearchable: false }, 25395 /** myyjä **/ { bVisible: self.isAdmin, bSortable: true, bSearchable: self.isAdmin }, 25396 /** asiakas **/ { bVisible: true, bSortable: true, bSearchable: true }, 25397 /** luotu **/ { bVisible: true, bSortable: false, bSearchable: false }, 25398 /** ed. lasku **/ { bVisible: true, bSortable: false, bSearchable: false }, 25399 /** seur. lasku **/ { bVisible: true, bSortable: false, bSearchable: false }, 25400 /** summa **/ { bVisible: true, bSortable: false, bSearchable: false }, 25401 /** viitteemme **/ { bVisible: true, bSortable: true, bSearchable: true }, 25402 /** laskutuskausi **/ { bVisible: true, bSearchable: false, bSortable: false }, 25403 /** laskutettu **/ { bVisible: true, bSearchable: false, bSortable: false }, 25404 /** tila **/ { bVisible: true, bSearchable: false, bSortable: false }, 25405 /** end_date **/ { bVisible: false, bSearchable: false, bSortable: false }, 25406 ], 25407 aaSorting: [[0, 'desc']], 25408 25409 fnServerParams: function (aoData) {
25410 // var month = $('#invoices_filter_form select[name="month"] option:selected').attr('value'); 25411 // var year = $('#invoices_filter_form select[name="year"] option:selected').attr('value'); 25412 var company = $('#invoices_filter_form select[name="company"] option:selected').attr( 25413 'value' 25414 ); 25415 var startDate; 25416 var endDate; 25417 if ($('input#filter-recurring-start-date').length > 0) { 25418 startDate = $('input#filter-recurring-start-date')[0].value; 25419 endDate = $('input#filter-recurring-end-date')[0].value; 25420 } 25421 25422 var filters = []; 25423 25424 $('#recurring_filter_form input:checkbox:checked').each(function () { 25425 filters.push($(this).attr('name')); 25426 }); 25427 25428 // aoData.push({ name: 'month', value: month }); 25429 // aoData.push({ name: 'year', value: year }); 25430 aoData.push({ name: 'company', value: company }); 25431 aoData.push({ name: 'startDate', value: startDate }); 25432 aoData.push({ name: 'endDate', value: endDate }); 25433 aoData.push({ name: 'filters', value: filters }); 25434 25435 }, 25436 25437 //Called before each row is shown 25438 fnRowCallback: function (nRow, aData, iDisplayIndex) { 25439 var id = aData[0]; 25440 // var customer_id = aData[1]; 25441 // var customer_name = aData[2]; 25442 var next_date = aData[6]; 25443 var recurrence = aData[9]; 25444 var status = aData[11]; 25445 var endDate = aData[12]; 25446 25447 $(nRow).attr('data-record-id', id); 25448 25449 $('td:eq(0)', nRow).html( 25450 '<a href="' + id + '" class="show_recurring_invoice" >' + id + '</a>' 25451 ); 25452 25453 var dateError = false; 25454 if(next_date){ 25455 var parts = next_date.split('.'); 25456 var dateError = Date.parse(parts[2]+'-'+ parts[1].padStart(2, '0') + '-' + parts[0].padStart(2, '0')+'T23:59:59.000Z') < Date.now(); 25457 } else { 25458 dateError = true; 25459 } 25460 25461 var dateCol = isAdmin ? 5 : 4; 25462 if(dateError && status == 'Käynnissä'){ 25463 $('td:eq('+dateCol+')', nRow).html( 25464 '<a href="' + id + '" class="show_date_error" >' + (next_date ? next_date : 'Virhe') + '</a>' 25465 ).addClass('warning'); 25466 } else { 25467 $('td:eq('+dateCol+')', nRow).removeClass('warning'); 25468 } 25469 var recurrenceCol = isAdmin ? 8 : 7; 25470 var recurrenceText = endDate ? recurrence + '<br>( päättyy ' + endDate + ' )' : recurrence; 25471 $('td:eq('+recurrenceCol+')', nRow) 25472 .html(recurrenceText); 25473 25474 var statusCol = isAdmin ? 10 : 9; 25475 25476 $('td:eq('+statusCol+')', nRow) 25477 .html('<a href="' + id + '" class="show_recurring_log" >' + status + '</a>'); 25478 25479 return nRow; 25480 }, 25481 }) 25482 25483 function getInvoiceColumns(isAdmin){ 25484 if(isAdmin){ 25485 return [ 25486 /** invoice_id **/ null, 25487 /** gothia_invoice_nr **/ { bVisible: false, bSearchable: true, bSortable: false }, 25488 /** ref_nr **/ { bVisible: false, bSearchable: true, bSortable: false }, 25489 /** Lähettäjä **/ null, 25490 /** Velallinen **/ null, 25491 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 25492 /** Päiväys **/ null, 25493 /** Eräpäivä **/ null, 25494 /** Summa **/ { bSearchable: false, bSortable: false }, 25495 /** Avoinna **/ { bSearchable: false, bSortable: false }, 25496 /** Rahoitettu **/ null, 25497 /** Viitteemme **/ null, 25498 /** Laskun **/ { bSearchable: false, bSortable: 'status' }, 25499 /** status **/ { bVisible: false, bSearchable: false, bSortable: false }, 25500 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 25501 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 25502 ] 25503 } else { 25504 return [ 25505 /** id **/ { bVisible: false, bSortable: true, bSearchable: true }, 25506 /** invoice_number **/ { bVisible: true, bSortable: false, bSearchable: true }, 25507 /** reference_nr **/ { bVisible: false, bSortable: false, bSearchable: true }, 25508 /** company **/ { bVisible: false, bSortable: false, bSearchable: false }, 25509 /** station **/ { bVisible: false, bSortable: false, bSearchable: false }, 25510 /** receiver **/ null, 25511 /** c/o **/ { bVisible: false, bSearchable: true, bSortable: false }, 25512 /** delivery_date **/ { sType: 'date-eu' }, 25513 /** due_date **/ { sType: 'date-eu' }, 25514 /** sum **/ { bSortable: false, bSearchable: false }, 25515 /** open_amount **/ { bVisible: true, bSortable: false, bSearchable: false }, 25516 /** is_financed **/ { bVisible: false, bSortable: false, bSearchable: false }, 25517 /** our_reference **/ null, 25518 /** status **/ null, 25519 /** status_class **/ { bVisible: false }, 25520 /** customer_id **/ { bVisible: false, bSearchable: false, bSortable: false }, 25521 /** customer_type **/ { bVisible: false, bSearchable: false, bSortable: false }, 25522 ] 25523 } 25524 } 25525 25526 function getRowCallbackFunction(){ 25527 var adminCallback = function (nRow, aData, iDisplayIndex) { 25528 var invoice_id = aData[0]; 25529 // var receiver = aData[4]; 25530 // var open_sum = aData[9]; 25531 var row_class = aData[13]; 25532 var status = aData[12]; 25533 // var company_id = aData[14]; 25534 // var customer_id = aData[15]; 25535 var ledger_service = aData[17]; 25536 // var company_name = aData[3]; 25537 $('td:eq(7)', nRow).html(ledger_service); 25538 25539 // Add the transaction id to every rows data object 25540 $(nRow).addClass(row_class); 25541 $('td:eq(0)', nRow).html( 25542 '<a href="' + invoice_id + '" class="show_invoice" >' + invoice_id + '</a>' 25543 ); 25544 25545 $('td:eq(9)', nRow) 25546 .addClass('status') 25547 .html('<a href="' + invoice_id + '" class="show_invoice_log" >' + status + '</a>'); 25548 25549 return nRow; 25550 } 25551 var defaultCallback = function (nRow, aData, iDisplayIndex) { 25552 var invoiceId = aData[0]; 25553 var invoiceNumber = aData[1]; 25554 var rowClass = aData[14]; 25555 var status = aData[13]; 25556 25557 $(nRow).addClass(rowClass); 25558 25559 $('td:eq(0)', nRow).html( 25560 '<a href="' + invoiceId + '" class="show_invoice" >' + invoiceNumber + '</a>' 25561 ); 25562 25563 //Status column is 8:th in case the station col is visible 25564 $('td:eq(' + (7 + self.showStationField) + ')', nRow) 25565 .addClass('status') 25566 .html('<a href="' + invoiceId + '" class="show_invoice_log" >' + status + '</a>'); 25567 25568 return nRow; 25569 } 25570 25571 return isAdmin ? adminCallback : defaultCallback; 25572 } 25573 25574 self.invoice_dt = $('#recurring_invoices_dt').dataTable({ 25575 oLanguage: global.dataTablesLanguage, 25576 sPaginationType: 'full_numbers', 25577 bPaginate: false, 25578 iDisplayLength: 100, 25579 bAutoWidth: false, 25580 bJQueryUI: true, 25581 bFilter: false, 25582 bInfo: false, 25583 sDom: 'rt', 25584 bProcessing: true, 25585 bServerSide: true, 25586 sAjaxSource: self.invoiceEndpoint, 25587 aoColumns: getInvoiceColumns(isAdmin), 25588 aaSorting: [[0, 'desc']], 25589 25590 fnServerParams: function (aoData) { 25591 aoData.push({ name: 'recurringInvoiceId', value: self.recurringInvoiceId }); 25592 aoData.push({ name: 'filters', value: ['all'] }); 25593 }, 25594 25595 fnInfoCallback: function (oSettings, iStart, iEnd, iMax, iTotal, sPre) { 25596 25597 var responseJson = JSON.parse(oSettings.jqXHR.responseText); 25598 if(responseJson.aaData.length === 0){ 25599 self.hide 25600 } 25601 var sums = responseJson.iSumma; 25602 if (typeof sums !== 'undefined') { 25603 return (
25604 'Näytetään rivit ' + 25605 iStart + 25606 ' - ' + 25607 iEnd + 25608 ' / ' + 25609 iTotal + 25610 ', summa: ' + 25611 sums.amountToPay + 25612 ', avoinna: ' + 25613 sums.openAmount 25614 ); 25615 } 25616 return 'Näytetään rivit ' + iStart + ' - ' + iEnd + ' / ' + iTotal; 25617 }, 25618 25619 //Called before each row is shown 25620 fnRowCallback: getRowCallbackFunction(), 25621 25622 }) 25623 25624 self.updateDt = function(){ 25625 self.dt.fnClearTable(0); 25626 self.dt.fnDraw(); 25627 } 25628 self.updateInvoiceDt = function(){ 25629 self.invoice_dt.fnClearTable(0); 25630 self.invoice_dt.fnDraw(); 25631 } 25632 self.hideInvoices = function(){ 25633 if($('#recurring_invoices_dt').hasClass('hide')){ 25634 return; 25635 } 25636 self.recurringInvoiceId = 0; 25637 self.updateInvoiceDt(); 25638 $('#recurring_invoices_dt').addClass('hide'); 25639 $('#recurring_invoices_dt_container .no-items').removeClass('hide'); 25640 } 25641 self.showInvoices = function(id){ 25642 self.recurringInvoiceId = id; 25643 self.updateInvoiceDt(); 25644 $('#recurring_invoices_dt').removeClass('hide'); 25645 $('#recurring_invoices_dt_container .no-items').addClass('hide'); 25646 } 25647 25648 self.init = function(){ 25649 25650 $('#recurring_invoices_dt').on('click', 'a.show_invoice, a.show_invoice_log', function (e) { 25651 e.preventDefault(); 25652 25653 var invoice_id = $(e.target).attr('href'); 25654 var action = $(e.target).attr('class'); 25655 25656 var n = invoice_id.lastIndexOf('/'); 25657 25658 invoice_id = invoice_id.substring(n + 1); 25659 25660 switch (action) { 25661 case 'show_invoice': 25662 pages.reskontra.show_invoice(invoice_id); 25663 break; 25664 case 'show_invoice_log': 25665 pages.reskontra.show_invoice_log(invoice_id); 25666 break; 25667 } 25668 }); 25669 25670 $('#recurring_filter_form input:checkbox, #recurring_filter_form select').on('change', 25671 function (e) { 25672 var filters = []; 25673 25674 $('#recurring_filter_form input:checkbox:checked').each(function () { 25675 filters.push($(this).attr('name')); 25676 }); 25677 if(filters.length === 0){ 25678 return; 25679 } 25680 if(self.recurringInvoiceId !== 0){} 25681 25682 self.hideInvoices(); 25683 self.dt.fnClearTable(0); 25684 self.dt.fnDraw(); 25685 } 25686 ); 25687 25688 $('#recurring_dt_filter').on('keypress', 25689 function (e) { 25690 self.hideInvoices(); 25691 } 25692 ); 25693 25694 $('#recurring_dt').on('click', 'td', function(){ 25695 var id = $(this).parent().attr('data-record-id'); 25696 25697 if(id === self.recurringInvoiceId){ 25698 return; 25699 } 25700 $('#recurring_dt tr').each(function(item){ 25701 $(this).removeClass('selected'); 25702 }) 25703 $(this).parent().addClass('selected'); 25704 self.showInvoices(id) 25705 }); 25706 25707 $('#recurring_dt').on( 25708 'click', 25709 'a.show_recurring_log, a.show_date_error, a.show_recurring_invoice', 25710 function (e) { 25711 e.preventDefault(); 25712 e.stopPropagation(); 25713 25714 var id = $(e.target).attr('href'); 25715 var action = $(e.target).attr('class'); 25716 25717 switch (action) { 25718 case 'show_recurring_log': 25719 self.loadStatusDialog(id); 25720 break; 25721 case 'show_date_error': 25722 self.loadDateFixDialog(id); 25723 break; 25724 case 'show_recurring_invoice': 25725 self.loadRecurringInvoiceDialog(id); 25726 break; 25727 } 25728 } 25729 ); 25730 25731 25732 } 25733 window.recurringInvoiceFunctions = { 25734 loadRecurringInvoiceDialog: function(id){ 25735 self.loadRecurringInvoiceDialog(id); 25736 }, 25737 loadEndDateDialog: function(id){ 25738 self.loadEndDateDialog(id); 25739 }, 25740 loadStatusDialog: function(id){ 25741 self.loadStatusDialog(id); 25742 }, 25743 dialogStartLoading: function(){ 25744 self.dialogStartLoading(); 25745 }, 25746 closeDialog: function(delay){ 25747 self.closeDialog(delay); 25748 }, 25749 dialogReplaceHtml: function(html){ 25750 self.dialogReplaceHtml(html); 25751 }, 25752 extraDialogClose: function(delay){ 25753 self.extraDialogClose(delay); 25754 }, 25755 extraDialogStartLoading: function(){ 25756 self.extraDialogStartLoading(); 25757 }, 25758 extraDialogReplaceHtml: function(html){ 25759 self.extraDialogReplaceHtml(html); 25760 }, 25761 updateDt: function(){ 25762 self.updateDt(); 25763 }, 25764 hideInvoices: function(){ 25765 self.hideInvoices(); 25766 } 25767 } 25768 25769} 25770 25771 25772;var PaymentLinkDataTable = function({isAdmin, isCompanyGroupAdmin}){ 25773 var self = this; 25774 self.isAdmin = isAdmin ? true : false;
25775 self.isCompanyGroupAdmin = isCompanyGroupAdmin ? true : false; 25776 25777 self.openJobOrder = function(id){ 25778 console.log('OPENING JOB ORDER') 25779 } 25780 25781 self.openTowingRecord = function(id){ 25782 console.log('OPENING TOWING ORDER') 25783 } 25784 25785 self.openLog = function(id){ 25786 25787 console.log('OPENING LOG') 25788 } 25789 25790 $('#payment_link_filter_form').find('select[name="company"]').on('changed.bs.select', function (e, clickedIndex, isSelected) { 25791 var $select = $(this); 25792 var selectedValues = $select.val() || []; 25793 25794 if (selectedValues.includes('all') && selectedValues.length > 1) { 25795 if (isSelected && $select.find('option').eq(clickedIndex).val() === 'all') { 25796 selectedValues = ['all']; 25797 } else { 25798 selectedValues = selectedValues.filter(company => company !== 'all'); 25799 } 25800 $select.selectpicker('val', selectedValues); 25801 } 25802 }); 25803 25804 self.dataTable = $('#payment_links_dt').dataTable({ 25805 oLanguage: global.dataTablesLanguage, 25806 sPaginationType: 'full_numbers', 25807 bPaginate: true, 25808 iDisplayLength: 10, 25809 bAutoWidth: false, 25810 bJQueryUI: true, 25811 bFilter: true, 25812 bInfo: true, 25813 bProcessing: true, 25814 bServerSide: true, 25815 sAjaxSource: 'reskontra/paymentLinksDataTable/', 25816 aoColumns: [ 25817 /** id **/ { bVisible: false, bSortable: true, bSearchable: true}, 25818 /** company_id **/ { bVisible: false, bSortable: false, bSearchable: false }, 25819 /** job_id **/ { bVisible: false, bSortable: false, bSearchable: true }, 25820 /** job_type **/ { bVisible: false, bSortable: false, bSearchable: false }, 25821 /** number **/ { bVisible: true, bSortable: true, bSearchable: true }, 25822 /** company_name **/ { bVisible: self.isAdmin, bSortable: false, bSearchable: false }, 25823 /** station_name **/ { bVisible: self.isCompanyGroupAdmin, bSortable: false, bSearchable: false }, 25824 /** created_date **/ { bVisible: true, bSortable: true, bSearchable: false }, 25825 /** confirmed_date **/ { bVisible: true, bSortable: true, bSearchable: false }, 25826 /** our_reference **/ { bVisible: true, bSortable: false, bSearchable: true }, 25827 /** debtor **/ { bVisible: true, bSortable: false, bSearchable: false }, 25828 /** operator **/ { bVisible: false, bSortable: false, bSearchable: false }, 25829 /** reference_number **/ { bVisible: true, bSortable: false, bSearchable: true }, 25830 /** amount_to_pay **/ { bVisible: true, bSortable: false, bSearchable: false }, 25831 /** status **/ { bVisible: false, bSortable: true, bSearchable: false }, 25832 /** status_description **/ { bVisible: true, bSortable: false, bSearchable: false } 25833 ], 25834 aaSorting: [[14, 'desc'], [0, 'desc']], 25835 25836 fnServerParams: function (aoData) { 25837 25838 var filters = []; 25839 var selectedCompanies = $('#payment_link_filter_form select[name="company"]').val() || []; 25840 25841 if(!Array.isArray(selectedCompanies)){ 25842 selectedCompanies = [selectedCompanies]; 25843 } 25844 25845 if (selectedCompanies.includes('all') && selectedCompanies.length > 1){ 25846 selectedCompanies = selectedCompanies.filter(company => company !== 'all'); 25847 } 25848 25849 company = selectedCompanies.includes('all') ? 'all' : selectedCompanies; 25850 25851 var jobType = $('#payment_link_filter_form select[name="job_type"] option:selected').attr( 25852 'value' 25853 ); 25854 var startDate; 25855 var endDate; 25856 if ($('input#filter-payment-link-start-date').length > 0) { 25857 startDate = $('input#filter-payment-link-start-date')[0].value; 25858 endDate = $('input#filter-payment-link-end-date')[0].value; 25859 } 25860 25861 $('#payment_link_filter_form input:checkbox:checked').each(function () { 25862 filters.push($(this).attr('name')); 25863 }); 25864 25865 aoData.push({ name: 'company', value: company }); 25866 aoData.push({ name: 'jobType', value: jobType }); 25867 aoData.push({ name: 'startDate', value: startDate }); 25868 aoData.push({ name: 'endDate', value: endDate }); 25869 aoData.push({ name: 'filters', value: filters }); 25870 25871 }, 25872 25873 //Called before each row is shown 25874 fnRowCallback: function (nRow, aData, iDisplayIndex) { 25875 var id = aData[0]; 25876 var company_id = aData[1]; 25877 var job_id = aData[2]; 25878 var job_type = aData[3]; 25879 var job_number = aData[4]; 25880 var company_name = aData[5]; 25881 var station_name = aData[6]; 25882 var created = aData[7]; 25883 var paid = aData[8]; 25884 var jobRef = aData[9]; 25885 var status = aData[14]; 25886 var status_description = aData[15]; 25887 25888 var statusClasses = { 25889 'link_expired': 'status-alert', 25890 'payment_non_trackable': 'status-alert', 25891 'payment_failed': 'status-alert', 25892 'link_sent': 'status-warning' 25893 } 25894 25895 var shiftCol = self.isCompanyGroupAdmin || self.isAdmin ? 1 : 0; 25896 25897 $(nRow).addClass(statusClasses[status]); 25898 25899 var jobHref = job_id; 25900 if (job_type === 'TOWING_ORDER') { 25901 jobHref = '/tilaus/' + job_id; 25902 } 25903 25904 $('td:eq(0)', nRow).html( 25905 '<a href="' + jobHref + '" class="open_job_record" data_type='+ job_type +' >' + job_number + '</a>' 25906 ); 25907 $('td:eq('+ (1 + shiftCol) +')', nRow).html(`<span>${created}</span>`); 25908 $('td:eq('+ (2 + shiftCol) +')', nRow).html(`<span>${paid}</span>`); 25909 $('td:eq('+ (3 + shiftCol) +')', nRow).html( 25910 '<a href="' + id + '" class="open_direct_payment" >' + jobRef + '</a>' 25911 ); 25912 $('td:eq('+ (7 + shiftCol) +')', nRow).html(
25913 '<a href="/logs/getLogHtml/direct_payment/' + id + '" class="open_log" >' + status_description + '</a>' 25914 ); 25915 25916 return nRow; 25917 }, 25918 }) 25919 25920 self.updateDt = function(){ 25921 setTimeout(function () { 25922 self.dataTable.fnClearTable(0); 25923 self.dataTable.fnDraw(); 25924 }, 1) 25925 } 25926 25927 25928 self.init = function(){ 25929 25930 $('#payment_links_dt').on('click', 'a.open_job_record, a.open_log, a.open_direct_payment', function (e) { 25931 e.preventDefault(); 25932 25933 var id = $(e.target).attr('href'); 25934 var action = $(e.target).attr('class'); 25935 25936 switch (action) { 25937 case 'open_job_record': 25938 var type = $(e.target).attr('data_type'); 25939 console.log(type, ' This is the type') 25940 if(type === 'JOB_ORDER'){ 25941 window.openDialog(id); 25942 } 25943 if(type === 'TOWING_RECORD'){ 25944 var url = 'kuormakirjat/get_towing_record_html/' + id; 25945 global.showJob(url); 25946 } 25947 if(type === 'TOWING_ORDER'){ 25948 window.location = id; 25949 } 25950 break; 25951 case 'open_log': 25952 global.show_log(id); 25953 break; 25954 case 'open_direct_payment': 25955 pages.reskontra.show_direct_payment(id, 'Maksun tiedot'); 25956 break; 25957 } 25958 }); 25959 25960 $('#payment_link_filter_form input:checkbox, #payment_link_filter_form select').on('change', 25961 function (e) { 25962 var filters = []; 25963 25964 $('#payment_link_filter_form input:checkbox:checked').each(function () { 25965 filters.push($(this).attr('name')); 25966 }); 25967 if(filters.length === 0){ 25968 return; 25969 } 25970 25971 self.updateDt(); 25972 } 25973 ); 25974 25975 [ 25976 'input#filter-payment-link-start-date', 25977 'input#filter-payment-link-end-date' 25978 ].forEach(function (input) { 25979 if($(input).length === 0){ 25980 return; 25981 } 25982 $(input).datepicker({ 25983 showButtonPanel: true, 25984 language: 'fi-FI', 25985 weekStart: 1, 25986 todayHighlight: true, 25987 startDate: '-120m', 25988 autoclose: true, 25989 clearBtn: true, 25990 format: 'dd.mm.yyyy', 25991 forceParse: true, 25992 assumeNearbyYear: true, 25993 }); 25994 }); 25995 25996 function isCorrectDateFormat(input) { 25997 return /^([0-9]|[0-9]{2})[./]([0-9]|[0-9]{2})[./]([0-9]{4})$/.test(input); 25998 } 25999 26000 $('input#filter-payment-link-end-date, input#filter-payment-link-start-date').each( 26001 function () { 26002 $(this).on('change changeDate blur', function (e) { 26003 var d = e.target.value; 26004 if (/^[0-9]{6}$/.test(d)) { 26005 $(this).datepicker('update', d[0] + d[1] + '.' + d[2] + d[3] + '.20' + d[4] + d[5]); 26006 $(this).trigger('changeDate'); 26007 $(this).trigger('blur'); 26008 $(this).datepicker('hide'); 26009 return; 26010 } 26011 if (/^[0-9]{8}$/.test(d)) { 26012 $(this).datepicker( 26013 'update', 26014 d[0] + d[1] + '.' + d[2] + d[3] + '.' + d[4] + d[5] + d[6] + d[7] 26015 ); 26016 $(this).trigger('changeDate'); 26017 $(this).trigger('blur'); 26018 $(this).datepicker('hide'); 26019 return; 26020 } 26021 if (!!e.target.value && !isCorrectDateFormat(d)) { 26022 if (e.type === 'blur') { 26023 $(this).datepicker('update', ''); 26024 } 26025 return; 26026 } 26027 if (e.type === 'changeDate') { 26028 setTimeout(function () { 26029 self.updateDt(); 26030 }, 1); 26031 } 26032 }); 26033 } 26034 ); 26035 } 26036 26037 self.confirmDateDialogHtml = `<div> 26038 <form id="confirm-online-payment-form"> 26039 <fieldset> 26040 <p>Syötä maksun päivämäärä</p> 26041 <ol> 26042 <li> 26043 <label id="paid_date_label" for="paid_date">Päivämäärä:</label> 26044 <input type="text" class="text small" id="paid_date" name="paid_date" /> 26045 </li> 26046 <li> 26047 <div style="margin-top: 2rem;"> 26048 <button id="submit-button" type="submit">Merkitse maksetuksi</button> 26049 </div> 26050 </li> 26051 </ol> 26052 </fieldset> 26053 </form> 26054 </div>`; 26055 26056 self.confirmDialogHtml = `<div> 26057 <form id="confirm-online-payment-form"> 26058 <fieldset> 26059 <p>Haluatko varmasti merkitä maksun maksetuksi</p> 26060 <ol> 26061 <li> 26062 <div style="margin-top: 2rem;"> 26063 <button id="submit-button" type="submit">Merkitse maksetuksi</button> 26064 </div> 26065 </li> 26066 </ol> 26067 </fieldset> 26068 </form> 26069 </div>`; 26070 26071 self.confirmDialogOptions = { 26072 width: 400, 26073 //height:200, 26074 autoOpen: true, 26075 modal: true, 26076 resizable: false, 26077 draggable: false, 26078 beforeClose: function (event, ui) { 26079 event.stopPropagation(); 26080 }, 26081 onclose: function(){ 26082 $(this).dialog('destroy'); 26083 }, 26084 title: 'Merkitse maksu', 26085 buttons: { 26086 Peruuta: function () { 26087 $(this).dialog('close'); 26088 }, 26089 }, 26090 }; 26091 26092 self.openConfirmOnlinePayment = function(paymentId, type) { 26093 if(type == 'confirmed'){ 26094 self.openVerifyOnlinePayment(paymentId) 26095 } else { 26096 self.openConfirmDateOnlinePayment(paymentId) 26097 } 26098 } 26099 26100 self.openConfirmDateOnlinePayment = function(paymentId) { 26101 26102 $dialog = $(self.confirmDateDialogHtml); 26103 26104 $dialog.find("input#paid_date").datepicker({ 26105 showButtonPanel: true, 26106 language: 'fi-FI', 26107 weekStart: 1, 26108 todayHighlight: true, 26109 startDate: '-12m', 26110 autoclose: true, 26111 clearBtn: true, 26112 format: 'dd.mm.yyyy', 26113 forceParse: true, 26114 assumeNearbyYear: true, 26115 endDate: '+0d' 26116 }); 26117 26118 $dialog.find('form#confirm-online-payment-form').on('submit', function (e) { 26119 e.preventDefault(); 26120 var data = _.object( 26121 $dialog 26122 .find('#confirm-online-payment-form') 26123 .serializeArray() 26124 .map(function (v) {
26125 return [v.name, v.value]; 26126 }) 26127 ); 26128 26129 self.callConfirmeEndpoint(paymentId, data, $dialog); 26130 26131 return false; 26132 }); 26133 26134 $dialog.dialog(self.confirmDialogOptions); 26135 } 26136 26137 self.openVerifyOnlinePayment = function(paymentId) { 26138 26139 $dialog = $(self.confirmDialogHtml); 26140 26141 $dialog.find('form#confirm-online-payment-form').on('submit', function (e) { 26142 e.preventDefault(); 26143 self.callConfirmeEndpoint(paymentId, {paid_date: null}, $dialog); 26144 26145 return false; 26146 }); 26147 26148 $dialog.dialog(self.confirmDialogOptions); 26149 } 26150 26151 self.callConfirmeEndpoint = function(paymentId, data, $dialog){ 26152 $.ajax({ 26153 type: 'POST', 26154 url: '/reskontra/confirmOnlinePayment/' + paymentId, 26155 data: data, 26156 beforeSend: function (request) { 26157 global.showLoadingDialog('Tallennetaan maksua...'); 26158 }, 26159 }) 26160 .done(function (data) { 26161 global.close_loading_dialog(); 26162 global.show_message(data); 26163 $dialog.dialog('close'); 26164 global.$dialog.dialog('close'); 26165 pages.reskontra.show_direct_payment(paymentId, 'Maksun tiedot'); 26166 //Refresh the datatable 26167 self.updateDt(); 26168 }) 26169 .fail(function (data) { 26170 global.show_message(JSON.parse(data.responseText)); 26171 global.close_loading_dialog(); 26172 }); 26173 } 26174} 26175 26176 26177;//Declare class properties and methods 26178var tuotteet = (function () { 26179 var self = this; 26180 26181 //Properties 26182 self.$dialog = $('<div />', {}); 26183 self.$items_datatable = null; 26184 self.$item_groups_datatable = null; 26185 self.itemDialog = null; 26186 self.itemGroupDialog = null; 26187 26188 //Define methods 26189 self.show_message = function (msgJSON, callback) { 26190 var icon = ''; 26191 var $message_dialog = ''; 26192 var timer; 26193 26194 switch (msgJSON.type) { 26195 case 'success': 26196 icon = 'ui-icon-circle-check'; 26197 break; 26198 case 'error': 26199 icon = 'ui-icon-circle-close'; 26200 break; 26201 case 'alert': 26202 icon = 'ui-icon-alert'; 26203 break; 26204 } 26205 26206 if ( 26207 (msgJSON.title === '' || typeof msgJSON.title === 'undefined') && 26208 msgJSON.type === 'error' 26209 ) { 26210 msgJSON.title = 'Virhe!'; 26211 } 26212 26213 $message_dialog = $('<div />', {}); 26214 $message_dialog.append($('<p />', {})).html(msgJSON.text); 26215 26216 if (msgJSON.type !== 'info') { 26217 $message_dialog.prepend( 26218 $('<span />', { class: 'ui-icon ' + icon, style: 'float:left; margin:0 7px 50px 0;' }) 26219 ); 26220 } 26221 26222 $message_dialog.dialog({ 26223 title: msgJSON.title, 26224 modal: true, 26225 buttons: { 26226 Ok: function () { 26227 $(this).dialog('close'); 26228 }, 26229 }, 26230 open: function () { 26231 if (msgJSON.type === 'success') { 26232 timer = setTimeout(function () { 26233 $message_dialog.dialog('widget').hide('highlight', {}, 1500, function () { 26234 $message_dialog.dialog('close'); 26235 }); 26236 }, 2000); 26237 } 26238 if (msgJSON.type === 'info') { 26239 } 26240 }, 26241 beforeClose: function () { 26242 clearTimeout(timer); 26243 }, 26244 close: function () { 26245 if (typeof callback !== 'undefined') { 26246 callback(); 26247 } 26248 }, 26249 }); 26250 }; 26251 26252 self.init = function (opts) { 26253 $('#items_tabs').tabs(); 26254 26255 $('#add_item') 26256 .button({ icons: { primary: 'ui-icon-plusthick' } }) 26257 .click(function () { 26258 window.ItemDialog.show(); 26259 }); 26260 26261 $('#add_item_group') 26262 .button({ icons: { primary: 'ui-icon-plusthick' } }) 26263 .click(function () { 26264 window.ItemGroupDialog.show(); 26265 }); 26266 26267 $('#upgrade_vat_pct') 26268 .button({ icons: { primary: 'ui-icon-document' } }) 26269 .click(function () { 26270 self.openVatUpgardeModal(); 26271 }); 26272 26273 $('#open_report_generator') 26274 .button({ icons: { primary: 'ui-icon-document' } }) 26275 .click(function () { 26276 self.reportGenerator(); 26277 }); 26278 26279 var aoColumns = [ 26280 /** id **/ { bVisible: false }, 26281 /** item_name **/ null, 26282 /** unitprice **/ null, 26283 /** vat **/ null, 26284 /** vat_included **/ null, 26285 /** unit **/ null, 26286 /** limited_usage **/ { bVisible: false }, 26287 /** is_tracked **/ { bVisible: false }, 26288 /** show_groups **/ null, 26289 ]; 26290 // Hide the limited usage column for everyone except car_tow companies 26291 if (opts.field_of_work == 'car_tow') { 26292 aoColumns = [ 26293 /** id **/ { bVisible: false }, 26294 /** item_name **/ null, 26295 /** unitprice **/ null, 26296 /** vat **/ null, 26297 /** vat_included **/ null, 26298 /** unit **/ null, 26299 /** limited_usage **/ null, 26300 /** is_tracked **/ { bVisible: false }, 26301 /** show_groups **/ null, 26302 ]; 26303 } 26304 26305 if (opts.innokorjaamo === '1') { 26306 aoColumns = [ 26307 /** id **/ { bVisible: false }, 26308 /** item_name **/ null, 26309 /** unitprice **/ null, 26310 /** vat **/ null, 26311 /** vat_included **/ null, 26312 /** unit **/ null, 26313 /** limited_usage **/ null, 26314 /** is_tracked **/ { bVisible: true }, 26315 /** show_groups **/ null, 26316 ]; 26317 } 26318
26319 self.$items_datatable = $('#items_dt').dataTable({ 26320 oLanguage: global.dataTablesLanguage, 26321 sPaginationType: 'full_numbers', 26322 iDisplayLength: 25, 26323 bAutoWidth: false, 26324 bJQueryUI: true, 26325 bFilter: true, 26326 bInfo: true, 26327 bPaginate: true, 26328 bProcessing: true, 26329 bServerSide: false, 26330 sAjaxSource: 'tuotteet/get_items_json/', 26331 aoColumns: aoColumns, 26332 aaSorting: [[1, 'asc']], 26333 26334 fnRowCallback: function (nRow, aData) { 26335 var id = aData[0]; 26336 var item_name = aData[1]; 26337 var is_owner = aData[19]; 26338 if (is_owner) { 26339 $('td:eq(0)', nRow).html( 26340 $('<a />', { 26341 href: 'tuotteet/item/' + id + '/', 26342 name: 'ItemDialog', 26343 class: 'show', 26344 }).html(item_name) 26345 ); 26346 $('td:last', nRow).html( 26347 $('<a />', { href: id + '/', name: 'tuotteet', class: 'edit_items_groups' }).html( 26348 'Näytä' 26349 ) 26350 ); 26351 } else { 26352 $('td:last', nRow).html('Näytä'); 26353 } 26354 return nRow; 26355 }, 26356 }); 26357 26358 self.$AK_items_datatable = $('#AK_items_dt').dataTable({ 26359 oLanguage: global.dataTablesLanguage, 26360 sPaginationType: 'full_numbers', 26361 iDisplayLength: 25, 26362 bAutoWidth: false, 26363 bJQueryUI: true, 26364 bFilter: true, 26365 bInfo: true, 26366 bPaginate: true, 26367 bProcessing: true, 26368 bServerSide: false, 26369 sAjaxSource: 'tuotteet/get_AK_items_json/', 26370 aoColumns: [ 26371 /** id **/ { bVisible: false }, 26372 /** item_name **/ null, 26373 /** unitprice **/ null, 26374 /** vat **/ null, 26375 /** vat_included **/ null, 26376 /** unit **/ null, 26377 /** limited_usage **/ { bVisible: false }, 26378 /** is_tracked **/ { bVisible: false }, 26379 /** show_groups **/ { bVisible: false }, 26380 ], 26381 aaSorting: [[1, 'asc']], 26382 fnRowCallback: function () {}, 26383 }); 26384 26385 self.$AK_item_groups_datatable = $('#AK_item_groups_dt').dataTable({ 26386 oLanguage: global.dataTablesLanguage, 26387 sPaginationType: 'full_numbers', 26388 iDisplayLength: 25, 26389 bAutoWidth: false, 26390 bJQueryUI: true, 26391 bFilter: true, 26392 bInfo: true, 26393 bPaginate: true, 26394 bProcessing: true, 26395 bServerSide: false, 26396 sAjaxSource: 'tuotteet/get_AK_item_groups_json/', 26397 aoColumns: [/** id **/ { bVisible: false }, /** group_name **/ null], 26398 26399 aaSorting: [[1, 'asc']], 26400 26401 //Called before each row is shown 26402 fnRowCallback: function (nRow, aData) { 26403 var id = aData[0], 26404 group_name = aData[1]; 26405 $('td:eq(0)', nRow).html( 26406 $('<a />', { href: id + '/', name: 'tuotteet', class: 'show_AK_item_group' }).html( 26407 group_name 26408 ) 26409 ); 26410 return nRow; 26411 }, 26412 }); 26413 26414 self.$item_inventory_datatable = $('#item_inventory_dt').dataTable({ 26415 oLanguage: global.dataTablesLanguage, 26416 sPaginationType: 'full_numbers', 26417 iDisplayLength: 25, 26418 bAutoWidth: false, 26419 bJQueryUI: true, 26420 bFilter: true, 26421 bInfo: true, 26422 bPaginate: true, 26423 bProcessing: true, 26424 bServerSide: false, 26425 sAjaxSource: 'tuotteet/inventory/', 26426 aoColumns: [ 26427 { sTitle: 'id', mDataProp: 'item_id', bVisible: false }, 26428 { sTitle: 'Tuote', mDataProp: 'name', bVisible: true }, 26429 { sTitle: 'Varattu', mDataProp: 'reserved', bVisible: true }, 26430 { sTitle: 'Vapaana', mDataProp: 'in_stock', bVisible: true }, 26431 { sTitle: 'Yhteensä', mDataProp: 'total', bVisible: true }, 26432 { sTitle: 'Arvo', mDataProp: 'stock_value', bVisible: true }, 26433 ], 26434 aaSorting: [[1, 'desc']], 26435 fnRowCallback: function (element, item, _index) { 26436 $('td:eq(0)', element).html( 26437 $('<a>', { href: item.item_id + '/', name: 'tuotteet', class: 'show_item_history' }).html( 26438 item.name 26439 ) 26440 ); 26441 return element; 26442 }, 26443 }); 26444 26445 self.$item_groups_datatable = $('#item_groups_dt').dataTable({ 26446 oLanguage: global.dataTablesLanguage, 26447 sPaginationType: 'full_numbers', 26448 iDisplayLength: 25, 26449 bAutoWidth: false, 26450 bJQueryUI: true, 26451 bFilter: true, 26452 bInfo: true, 26453 bPaginate: true, 26454 bProcessing: true, 26455 bServerSide: false, 26456 sAjaxSource: 'tuotteet/get_item_groups_json/', 26457 aoColumns: [/** id **/ { bVisible: false }, /** group_name **/ null], 26458 26459 aaSorting: [[1, 'asc']], 26460 26461 //Called before each row is shown 26462 fnRowCallback: function (nRow, aData) { 26463 var id = aData[0], 26464 group_name = aData[1]; 26465 $('td:eq(0)', nRow).html( 26466 $('<a />', { 26467 href: 'tuotteet/itemGroup/' + id + '/', 26468 name: 'ItemGroupDialog', 26469 class: 'show', 26470 }).html(group_name) 26471 ); 26472 return nRow; 26473 }, 26474 }); 26475 }; 26476 26477 self.show_item_history = function (itemId) { 26478 if (!itemId) { 26479 return; 26480 } 26481 var $dialog = self.$dialog; 26482 var url = '/tuotteet/history/'; 26483 var title = 'Tuotteen varastotilanne'; 26484 26485 if ($dialog.hasClass('ui-dialog-content')) { 26486 $dialog.dialog('destroy'); 26487 } 26488 26489 $dialog.dialog({ 26490 width: 800, 26491 height: 800, 26492 modal: true, 26493 resizable: false, 26494 title: title, 26495 open: function () { 26496 global.show_ajax_loader($dialog); 26497 $.get(url + itemId, function (html) { 26498 $dialog.html(html); 26499 }); 26500 }, 26501 beforeClose: function (event) { 26502 $('link.js-popup').remove(); 26503 $('style.js-popup').remove(); 26504 event.stopPropagation(); 26505 }, 26506 close: function () { 26507 $dialog.dialog('destroy'); 26508 }, 26509 }); 26510 }; 26511 26512 self.reportPdfGenerator = function ( 26513 year, 26514 month, 26515 type, 26516 product, 26517 layout, 26518 user_id, 26519 sales_aggregate 26520 ) { 26521 var url = window.location.href + '/get_report_pdf/'; 26522 // User lists, so we can easily add more filters int the future... 26523 url += year + '/' + month + '/?type[]=' + type; 26524 url += '&layout=' + layout; 26525 url += '&user_id=' + user_id; 26526 url += '&sales_aggregate=' + sales_aggregate; 26527 url += '&product[]=' + product; 26528 26529 window.open(url, '_blank'); 26530 }; 26531 26532 var processing = false;
26533 self.openVatUpgardeModal = function () { 26534 $dialog.dialog({ 26535 width: 600, 26536 height: 400, 26537 modal: true, 26538 resizable: false, 26539 title: 'Muuta tuotteiden 24% ALV kanta', 26540 open: function () { 26541 global.show_ajax_loader($dialog); 26542 var html = ` 26543 <p>Muuta kaikkien ALV24% tuotteiden arvonlisäveroksi ALV25,5%</p> 26544 <p>Huomaa tuotteen arvonlisäveroasetuksen vaikutus hintaan kun arvonlisäverokannan muutoksen yhtydessä</p> 26545 <p>Jos âHinta ei sis ALVâ pysyy tuotteen veroton hinta (ALV0) muuttumattomana ja maksettava verollinen hinta nousee. 26546 <br>Jos âHinta sis. ALVâ pienenee tuotteen veroton hinta (ALV0) ja maksettava verollinen hinta pysyy muuttumattomana. 26547 </p> 26548 `; 26549 $dialog.html(html); 26550 }, 26551 buttons: [ 26552 { 26553 text: 'Peruuta', 26554 click: function () { 26555 $(this).dialog('close'); 26556 }, 26557 }, 26558 { 26559 text: 'Muuta', 26560 click: function () { 26561 if (processing) { 26562 return; 26563 } 26564 processing = true; 26565 jQuery 26566 .ajax({ 26567 url: '/tuotteet/upgradeVatPercentage', 26568 }) 26569 .done(function (ok) { 26570 $dialog.html(ok.msg); 26571 self.refreshDataTables(); 26572 $('#upgrade_vat_pct').remove(); 26573 setTimeout(function () { 26574 $dialog.dialog('destroy'); 26575 }, 2500); 26576 }) 26577 .error(function (err) { 26578 $dialog.html(err.msg); 26579 setTimeout(function () { 26580 $dialog.dialog('destroy'); 26581 }, 2500); 26582 }) 26583 .always(function () { 26584 console.log('always'); 26585 processing = false; 26586 }); 26587 }, 26588 }, 26589 ], 26590 close: function () { 26591 $dialog.dialog('destroy'); 26592 }, 26593 }); 26594 }; 26595 26596 self.reportGenerator = function (year, month, type, product, layout, user_id, sales_aggregate) { 26597 user_id = user_id || 'all'; 26598 year = year || 0;
26599 month = month || 0; 26600 type = type || ''; 26601 product = product || ''; 26602 layout = layout || ''; 26603 sales_aggregate = sales_aggregate || 'separate'; 26604 var $dialog = self.$dialog; 26605 var url = window.location.href + '/report/'; 26606 var title = 'Varastoraportti'; 26607 26608 if ($dialog.hasClass('ui-dialog-content')) { 26609 $dialog.dialog('destroy'); 26610 } 26611 26612 $dialog.dialog({ 26613 width: 1000, 26614 height: 800, 26615 modal: true, 26616 resizable: false, 26617 title: title, 26618 open: function () { 26619 global.show_ajax_loader($dialog); 26620 // User lists, so we can easily add more filters int the future... 26621 url += year + '/' + month + '/?type[]=' + type; 26622 url += '&layout=' + layout; 26623 url += '&product[]=' + product; 26624 url += '&user_id=' + user_id; 26625 url += '&sales_aggregate=' + sales_aggregate; 26626 $.get(url, function (html) { 26627 $dialog.html(html); 26628 }); 26629 }, 26630 beforeClose: function (event) { 26631 $('link.js-popup').remove(); 26632 $('style.js-popup').remove(); 26633 event.stopPropagation(); 26634 }, 26635 close: function () { 26636 $dialog.dialog('destroy'); 26637 }, 26638 }); 26639 }; 26640 26641 self.show_AK_item_group = function (item_group_id) { 26642 var $dialog = self.$dialog; 26643 if ($dialog.hasClass('ui-dialog-content')) { 26644 $dialog.dialog('destroy'); 26645 } 26646 26647 var url = '/tuotteet/get_AK_item_group_html/' + item_group_id; 26648 26649 $dialog.dialog({ 26650 width: 500, 26651 height: 300, 26652 modal: true, 26653 resizable: false, 26654 open: function () { 26655 global.show_ajax_loader($dialog); 26656 26657 $.get(url, function (html) { 26658 $dialog.html(html); 26659 }); 26660 }, 26661 buttons: { 26662 Poistu: function () { 26663 $dialog.dialog('destroy'); 26664 }, 26665 }, 26666 }); 26667 }; 26668 26669 self.init_show_items_item_groups = function () { 26670 self.$dialog.find('#submit').button({ icons: { primary: 'ui-icon-disk' } }); 26671 26672 self.$dialog 26673 .find('#close') 26674 .button({ icons: { primary: 'ui-icon-close' } }) 26675 .click(function () { 26676 self.$dialog.dialog('close'); 26677 }); 26678 26679 self.$dialog.find('form').submit(function (e) { 26680 e.preventDefault(); 26681 26682 $(this).ajaxSubmit({ 26683 dataType: 'json', 26684 beforeSubmit: function () { 26685 global.show_loading_dialog('Tallennetaan...'); 26686 }, 26687 success: function (responseJSON) { 26688 global.close_loading_dialog(); 26689 global.show_message(responseJSON); 26690 }, 26691 error: function (response) { 26692 global.close_loading_dialog(); 26693 global.show_message(response.responseJSON); 26694 }, 26695 }); 26696 26697 return false; 26698 }); 26699 }; 26700 26701 self.delete_item = function (item_id) { 26702 //Show confirm 26703 var $deleteItemDialog = $('<div></div>') 26704 .html('Haluatko varmasti poistaa tuotteen? (Tuote poistuu myös ryhmistä joihin se kuuluu)') 26705 .dialog({ 26706 autoOpen: true, 26707 modal: true, 26708 resizable: false, 26709 draggable: false, 26710 title: 'Vahvista tuotteen poisto', 26711 beforeClose: function (event) { 26712 event.stopPropagation(); 26713 }, 26714 buttons: { 26715 Peruuta: function () { 26716 $(this).dialog('close'); 26717 }, 26718 Poista: function () { 26719 $(this).dialog('close'); 26720 26721 $.ajax({ 26722 processData: false, 26723 dataType: 'json', 26724 type: 'GET', 26725 url: '/tuotteet/delete_item/' + item_id + '/', 26726 beforeSend: function () { 26727 global.show_loading_dialog('Poistetaan tuotetta...'); 26728 }, 26729 success: function (responseJSON) { 26730 global.close_loading_dialog(); 26731 global.show_message(responseJSON); 26732 26733 if (self.$items_datatable != null) { 26734 self.$items_datatable.fnReloadAjax(); 26735 } 26736 26737 window.ItemDialog.close(); 26738 $deleteItemDialog.dialog('close'); 26739 }, 26740 }); 26741 }, 26742 }, 26743 }); 26744 }; 26745 26746 self.edit_items_groups = function (item_id) { 26747 var $dialog = self.$dialog; 26748 var url = '/tuotteet/get_items_item_groups_html/'; 26749 var title = ''; 26750 26751 if (typeof item_id !== 'undefined') { 26752 url += item_id; 26753 title = 'Valitse tuotteen ryhmät'; 26754 } else { 26755 title = 'Uusi tuotepaketti'; 26756 } 26757 26758 $dialog.dialog({ 26759 width: 600, 26760 modal: true, 26761 resizable: false, 26762 title: title, 26763 dialogClass: 'show-over-flow', 26764 open: function () { 26765 global.show_ajax_loader($dialog); 26766 26767 $.get(url, function (html) { 26768 $dialog.html(html); 26769 }); 26770 }, 26771 close: function () { 26772 $(this).dialog('destroy'); 26773 $(this).remove(); 26774 }, 26775 }); 26776 }; 26777 26778 self.delete_item_group = function (item_group_id) { 26779 $('<div></div>') 26780 .html( 26781 'Haluatko varmasti poistaa kyseisen tuotepaketin? (Tuotteet säilyvät tuoterekisterissä)' 26782 ) 26783 .dialog({ 26784 autoOpen: true, 26785 modal: true, 26786 resizable: false, 26787 draggable: false, 26788 title: 'Vahvista tuotepaketin poisto', 26789 beforeClose: function (event) { 26790 event.stopPropagation(); 26791 }, 26792 buttons: { 26793 Peruuta: function () { 26794 $(this).dialog('close'); 26795 }, 26796 Poista: function () { 26797 $(this).dialog('close'); 26798 26799 $.ajax({ 26800 processData: false, 26801 dataType: 'json', 26802 type: 'GET', 26803 url: '/tuotteet/delete_item_group/' + item_group_id + '/', 26804 beforeSend: function () { 26805 global.show_loading_dialog('Poistetaan tuotepakettia...'); 26806 }, 26807 success: function (responseJSON) { 26808 global.close_loading_dialog(); 26809 global.show_message(responseJSON); 26810 26811 if (self.$items_datatable != null) { 26812 self.$items_datatable.fnReloadAjax(); 26813 } 26814 26815 if (self.$item_groups_datatable != null) { 26816 self.$item_groups_datatable.fnReloadAjax(); 26817 } 26818 26819 window.ItemGroupDialog.close(); 26820 }, 26821 }); 26822 }, 26823 }, 26824 }); 26825 }; 26826 26827 self.refreshDataTables = function () { 26828 if (self.$items_datatable != null) { 26829 self.$items_datatable.fnReloadAjax(); 26830 } 26831 26832 if (self.$item_groups_datatable != null) { 26833 self.$item_groups_datatable.fnReloadAjax(); 26834 } 26835 }; 26836 26837 return self; 26838})(); 26839 26840;/** 26841 * Version 2.4.1 Copyright (C) 2013 26842 * Tested in IE 11, FF 28.0 and Chrome 33.0.1750.154 26843 * No official support for other browsers, but will TRY to accommodate challenges in other browsers. 26844 * Example: 26845 * Print Button: <div id="print_button">Print</div> 26846 * Print Area : <div class="PrintArea" id="MyId" class="MyClass"> ... html ... </div> 26847 * Javascript : <script> 26848 * $("div#print_button").click(function(){ 26849 * $("div.PrintArea").printArea( [OPTIONS] ); 26850 * }); 26851 * </script> 26852 * options are passed as json (example: {mode: "popup", popClose
26852: false}) 26853 * 26854 * {OPTIONS} | [type] | (default), values | Explanation 26855 * --------- | --------- | ---------------------- | ----------- 26856 * @mode | [string] | (iframe),popup | printable window is either iframe or browser popup 26857 * @popHt | [number] | (500) | popup window height 26858 * @popWd | [number] | (400) | popup window width 26859 * @popX | [number] | (500) | popup window screen X position 26860 * @popY | [number] | (500) | popup window screen Y position 26861 * @popTitle | [string] | ('') | popup window title element 26862 * @popClose | [boolean] | (false),true | popup window close after printing 26863 * @extraCss | [string] | ('') | comma separated list of extra css to include 26864 * @retainAttr | [string[]] | ["id","class","style"] | string array of attributes to retain for the containment area. (ie: id, style, class) 26865 * @standard | [string] | strict, loose, (html5) | Only for popup. For html 4.01, strict or loose document standard, or html 5 standard 26866 * @extraHead | [string] | ('') | comma separated list of extra elements to be appended to the head tag 26867 */ 26868(function($) { 26869 var counter = 0; 26870 var modes = { iframe : "iframe", popup : "popup" }; 26871 var standards = { strict : "strict", loose : "loose", html5 : "html5" }; 26872 var defaults = { mode : modes.iframe, 26873 standard : standards.html5, 26874 popHt : 500, 26875 popWd : 400, 26876 popX : 200, 26877 popY : 200, 26878 popTitle : '', 26879 popClose : false, 26880 extraCss : '', 26881 extraHead : '', 26882 retainAttr : ["id","class","style"] }; 26883 26884 var settings = {};//global settings 26885 26886 $.fn.printArea = function( options ) 26887 { 26888 $.extend( settings, defaults, options ); 26889 26890 counter++; 26891 var idPrefix = "printArea_"; 26892 $( "[id^=" + idPrefix + "]" ).remove(); 26893 26894 settings.id = idPrefix + counter; 26895 26896 var $printSource = $(this); 26897 26898 var PrintAreaWindow = PrintArea.getPrintWindow(); 26899 26900 PrintArea.write( PrintAreaWindow.doc, $printSource ); 26901 26902 setTimeout( function () { PrintArea.print( PrintAreaWindow ); }, 1000 ); 26903 }; 26904 26905 var PrintArea = { 26906 print : function( PAWindow ) { 26907 var paWindow = PAWindow.win; 26908 26909 $(PAWindow.doc).ready(function(){ 26910 paWindow.focus(); 26911 paWindow.print(); 26912 26913 if ( settings.mode == modes.popup && settings.popClose ) 26914 setTimeout(function() { paWindow.close(); }, 2000); 26915 }); 26916 }, 26917 write : function ( PADocument, $ele ) { 26918 PADocument.open(); 26919 PADocument.write( PrintArea.docType() + "<html>" + PrintArea.getHead() + PrintArea.getBody( $ele ) + "</html>" ); 26920 PADocument.close(); 26921 }, 26922 docType : function() { 26923 if ( settings.mode == modes.iframe ) return ""; 26924 26925 if ( settings.standard == standards.html5 ) return "<!DOCTYPE html>"; 26926 26927 var transitional = settings.standard == standards.loose ? " Transitional" : ""; 26928 var dtd = settings.standard == standards.loose ? "loose" : "strict"; 26929 26930 return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01' + transitional + '//EN" "http://www.w3.org/TR/html4/' + dtd + '.dtd">'; 26931 }, 26932 getHead : function() { 26933 var extraHead = ""; 26934 var links = ""; 26935 26936 if ( settings.extraHead ) settings.extraHead.replace( /([^,]+)/g, function(m){ extraHead += m }); 26937 26938 $(document).find("link") 26939 .filter(function(){ // Requirement: <link> element MUST have rel="stylesheet" to be considered in print document 26940 var relAttr = $(this).attr("rel"); 26941 return ($.type(relAttr) === 'undefined') == false && relAttr.toLowerCase() == 'stylesheet'; 26942 }) 26943 .filter(function(){ // Include if media is undefined, empty, print or all 26944 var mediaAttr = $(this).attr("media"); 26945 return $.type(mediaAttr) === 'undefined' || mediaAttr == "" || mediaAttr.toLowerCase() == 'print' || mediaAttr.toLowerCase() == 'all' 26946 }) 26947 .each(function(){ 26948 links += '<link type="text/css" rel="stylesheet" href="' + $(this).attr("href") + '" >'; 26949 });
26950 if ( settings.extraCss ) settings.extraCss.replace( /([^,\s]+)/g, function(m){ links += '<link type="text/css" rel="stylesheet" href="' + m + '">' }); 26951 26952 return "<head><title>" + settings.popTitle + "</title>" + extraHead + links + "</head>"; 26953 }, 26954 getBody : function ( elements ) { 26955 var htm = ""; 26956 var attrs = settings.retainAttr; 26957 elements.each(function() { 26958 var ele = PrintArea.getFormData( $(this) ); 26959 26960 var attributes = "" 26961 for ( var x = 0; x < attrs.length; x++ ) 26962 { 26963 var eleAttr = $(ele).attr( attrs[x] ); 26964 if ( eleAttr ) attributes += (attributes.length > 0 ? " ":"") + attrs[x] + "='" + eleAttr + "'"; 26965 } 26966 26967 htm += '<div ' + attributes + '>' + $(ele).html() + '</div>'; 26968 }); 26969 26970 return "<body>" + htm + "</body>"; 26971 }, 26972 getFormData : function ( ele ) { 26973 var copy = ele.clone(); 26974 var copiedInputs = $("input,select,textarea", copy); 26975 $("input,select,textarea", ele).each(function( i ){ 26976 var typeInput = $(this).attr("type"); 26977 if ($.type(typeInput) === 'undefined') typeInput = $(this).is("select") ? "select" : $(this).is("textarea") ? "textarea" : ""; 26978 var copiedInput = copiedInputs.eq( i ); 26979 26980 if ( typeInput == "radio" || typeInput == "checkbox" ) copiedInput.attr( "checked", $(this).is(":checked") ); 26981 else if ( typeInput == "text" || typeInput == "" ) copiedInput.attr( "value", $(this).val() ); 26982 else if ( typeInput == "select" ) 26983 $(this).find( "option" ).each( function( i ) { 26984 if ( $(this).is(":selected") ) $("option", copiedInput).eq( i ).attr( "selected", true ); 26985 }); 26986 else if ( typeInput == "textarea" ) copiedInput.text( $(this).val() ); 26987 }); 26988 return copy; 26989 }, 26990 getPrintWindow : function () { 26991 switch ( settings.mode ) 26992 { 26993 case modes.iframe : 26994 var f = new PrintArea.Iframe(); 26995 return { win : f.contentWindow || f, doc : f.doc }; 26996 case modes.popup : 26997 var p = new PrintArea.Popup(); 26998 return { win : p, doc : p.doc }; 26999 } 27000 }, 27001 Iframe : function () { 27002 var frameId = settings.id; 27003 var iframeStyle = 'border:0;position:absolute;width:0px;height:0px;right:0px;top:0px;'; 27004 var iframe; 27005 27006 try 27007 { 27008 iframe = document.createElement('iframe'); 27009 document.body.appendChild(iframe); 27010 $(iframe).attr({ style: iframeStyle, id: frameId, src: "#" + new Date().getTime() }); 27011 iframe.doc = null; 27012 iframe.doc = iframe.contentDocument ? iframe.contentDocument : ( iframe.contentWindow ? iframe.contentWindow.document : iframe.document); 27013 } 27014 catch( e ) { throw e + ". iframes may not be supported in this browser."; } 27015 27016 if ( iframe.doc == null ) throw "Cannot find document."; 27017 27018 return iframe; 27019 }, 27020 Popup : function () { 27021 var windowAttr = "location=yes,statusbar=no,directories=no,menubar=no,titlebar=no,toolbar=no,dependent=no"; 27022 windowAttr += ",width=" + settings.popWd + ",height=" + settings.popHt; 27023 windowAttr += ",resizable=yes,screenX=" + settings.popX + ",screenY=" + settings.popY + ",personalbar=no,scrollbars=yes"; 27024 27025 var newWin = window.open( "", "_blank", windowAttr ); 27026 27027 newWin.doc = newWin.document; 27028 27029 return newWin; 27030 } 27031 }; 27032})(jQuery); 27033 27034;/** 27035 * Functionality for ajax calls, used by app admin to update part payments. 27036 * @param {Object} opts [Holds the data for the partpayment about to be edited.] 27037 */ 27038var editPartPaymentData = function(opts) { 27039 var server = '/iv_laskutus_ja_reskontra/update_partpayment_data'; 27040 var serverRemove = '/iv_laskutus_ja_reskontra/remove_item'; 27041 var serverAdd = '/iv_laskutus_ja_reskontra/add_item'; 27042 var serverEdit = '/iv_laskutus_ja_reskontra/edit_item'; 27043 var options = { 27044 'partPaymentId': opts.partPaymentId, 27045 'customerId': opts.customerId 27046 }; 27047 27048 /** 27049 * General ajax changes. See serverside for the posibilities. 27050 */ 27051 $('.edit_osamaksu_data').editable(server, { 27052 submitdata: options, 27053 id: 'field', 27054 indicator : 'Tallennetaan...' 27055 }); 27056 27057 /** 27058 * Edit the signature type. Either pankkitunniste or by hand. 27059 * 27060 */ 27061 $('.edit_osamaksu_current_signature').editable(server, { 27062 data: "{'written':'Allekirjoituksella'," + 27063 "'tupas':'Pankkitunnisteilla'," + 27064 "'selected': '" + opts.signatureType + "'}", 27065 submitdata: options, 27066 type: 'select', 27067 id: 'field', 27068 submit : 'OK', 27069 indicator : 'Tallennetaan...' 27070 }); 27071 27072 /** 27073 * Edit a item in the partpayment. 27074 * @type Promise. 27075 */ 27076 $('.edit-partpayment-item').editable(function(value) { 27077 27078 var itemId = $(this).parent('tr').data('item'); 27079 var fieldInEdit = $(this).attr('id'); 27080 27081 var editedItemData = { 27082 itemId: itemId, 27083 value: value, 27084 field: fieldInEdit 27085 }; 27086 $.post(serverEdit, editedItemData, function() { 27087 }) 27088 .then(function(data) { 27089 $('a[href=' + opts.partPaymentId + ']').click(); 27090 }) 27091 .fail(function(e) { 27092 alert("Palvelimella tapahtui virhe!", e); 27093 }); 27094 }); 27095 27096 /** 27097 * Add a new item to the partpayment. 27098 * Defaults to an empty object in the database. 27099 * @type Promise. 27100 */ 27101 $('button#add-item').click(function() { 27102 var addToId = options.partPaymentId; 27103 var data = { addToPartPaymentId: addToId }; 27104 27105 $.post(serverAdd, data, function() { 27106 }) 27107 .then(function(data){ 27108 $('a[href=' + addToId + ']').click(); 27109 }) 27110 .fail(function(e) { 27111 alert("Palvelimella tapahtui virhe!", e); 27112 }); 27113 }); 27114 27115 27116 /** 27117 * Remove a item from the partpayment. 27118 * @type Promise. 27119 */ 27120 $('button.remove').click(function() { 27121 if (window.confirm("Haluatko varmasti poistaa kyseisen rivin?")) { 27122 27123 var row = $(this).parent().parent('tr'); 27124 var itemId = $(row).data('item'); 27125 var data = { rowToDelete: itemId }; 27126 27127 $.post(serverRemove, data, function() { 27128 }) 27129 .then(function(data) { 27130 var resp = JSON.parse(data); 27131 row.fadeOut(500); 27132 }) 27133 .fail(function(e) { 27134 alert("Palvelimella tapahtui virhe!", e); 27135 }); 27136 27137 } 27138 }); 27139 27140 /** 27141 * Edit downpayment and total sum. Updated fields 27142 * and refreshed the dialog on callback. 27143 */ 27144 $('.edit-osamaksu-sums').editable(server, { 27145 submitdata: options, 27146 id: 'field', 27147 indicator : 'Tallennetaan...', 27148 callback : function() { 27149 $('a[href=' + opts.partPaymentId + ']').click(); 27150 } 27151 }); 27152 27153 /** 27154 * @BETA-version (0.0.1) 27155 * Fixed on the Server. 27156 */ 27157 27158 $('.edit_osamaksu_payment_parts').editable(function(val, settings) { 27159 var partPaymentData = { 27160 partPaymentId: opts.partPaymentId, 27161 field: 'part_payment_maksuerat', 27162 value: val, 27163 }; 27164 $.post(server, partPaymentData, function() { 27165 }) 27166 .then(function(a,b,c) { 27167 $('a[href=' + opts.partPaymentId + ']').click(); 27168 }); 27169 27170 }, { 27171 data: "{'3':'3'," + 27172 "'6':'6'," + 27173 "'9':'9'," + 27174 "'12':'12'," + 27175 "'18':'18'," + 27176 "'24':'24'," + 27177 "'selected': '" + opts.currentPaymentRate + "'}", 27178 type: 'select', 27179 submit : 'OK' 27180 }); 27181 27182}; 27183 27184;function VehicleInfoCheckVM(opts) { 27185 var self = this; 27186 27187 self.vehicleInfoSearchMeta = { 27188 id : ko.observable(), 27189 requestParam: ko.observable(), 27190 daysOld: ko.observable(), 27191 datetime : ko.observable(), 27192 dataSource: ko.observable(), 27193 dataSourceLongText: ko.observable(), 27194 dataSourceShortText: ko.observable() 27195 }; 27196 27197 self.id = ko.computed(function(){ 27198 return ko.toJS(self.vehicleInfoSearchMeta.id); 27199 }); 27200 27201 //self.searchAgeVisual = ko.computed(window.trafiExtras.visualizeSearchAge, self); 27202 self.searchAge = ko.computed(window.trafiExtras.searchAge, self); 27203 27204 self.vehicleInfo = { 27205 reg_no: ko.observable(''), 27206 vehicle_class: ko.observable(''), 27207 vehicle_brand: ko.observable(''), 27208 vehicle_model: ko.observable(''), 27209 vehicle_brand_and_model: ko.observable(''), 27210 vehicle_commercial_model: ko.observable(''), 27211 vehicle_status: ko.observable(''), 27212 vehicle_model_year: ko.observable(''), 27213 vehicle_color: ko.observable(''), 27214 serial_no: ko.observable(''), 27215 initialization_date: ko.observable(''), 27216 first_registration_date: ko.observable(''), 27217 last_inspection_date: ko.observable(''), 27218 last_inspection_result: ko.observable(''), 27219 last_inspection_result_description: ko.observable(''), 27220 next_inspection_date: ko.observable(''), 27221 restriction_info: ko.observable(''), 27222 remarks: ko.observable(''), 27223 fuel: ko.observable(''), 27224 transmission: ko.observable(''), 27225 drive: ko.observable(''), 27226 displacement: ko.observable(''), 27227 max_net_effect: ko.observable(''), 27228 max_net_weight: ko.observable(''), 27229 max_tech_net_weight: ko.observable(''), 27230 length: ko.observable(''), 27231 width: ko.observable(''), 27232 height: ko.observable(''), 27233 weight: ko.observable(''), 27234 holder_name: ko.observable(''), 27235 holder_address: ko.observable(''), 27236 owner_name: ko.observable(''), 27237 owner_address: ko.observable(''), 27238 }; 27239 27240 self.insuranceInfo = { 27241 insurance_company: ko.observable(''), 27242 insurance_start_date: ko.observable(''), 27243 insurance_end_date: ko.observable(''), 27244 insured_party: ko.observable('') 27245 }; 27246 27247 self.restrictionInfos = ko.observableArray(); 27248 self.ownersHolders = ko.observableArray(); 27249 self.transferPermit = ko.observable(null); 27250 27251 self.ownersHoldersConsumers = ko.computed(function (){ 27252 27253 var consumers = [], customerList = [], ownersHolders = ko.toJS(self.ownersHolders); 27254 27255 console.log('VehicleInfoCheckVM::ownersHolders:', ownersHolders); 27256 27257 if( ! ownersHolders) 27258 return []; 27259 27260 ownersHolders 27261 .filter(function (ownerHolder){ 27262 return ownerHolder.customer_type === 'person' && ownerHolder.restriction < 1; 27263 }) 27264 .forEach(function(ownerHolder) { 27265 27266 var trafiRes = $.extend(true, {}, ownerHolder); 27267 var trafiName = trafiRes.name || ''; 27268 var nameParts = (trafiRes.name || '').split(' ');
27269 var trafiNameLen = nameParts.length; 27270 var hasDeath = nameParts[trafiNameLen -1] === '(Kuolinpesä)'; 27271 var lName = hasDeath ? nameParts[0] + ' (Kuolinpesä)' : nameParts[0]; 27272 var fName = hasDeath ? nameParts.slice(1, trafiNameLen -1).join(' ') : nameParts.slice(1, trafiNameLen).join(' '); 27273 console.table({hasDeath: hasDeath, lName: lName, fName: fName, nameParts: nameParts, trafiNameLen: trafiNameLen, part: nameParts[-1]}); 27274 var moddedTrafiResult = Object.assign(trafiRes, { 27275 displayName: 'Trafi / ' + trafiRes.ownership_type_description + ' / ' + trafiRes.name, 27276 company_name: trafiRes.name, 27277 // business_id: trafiRes.identifier, 27278 customer_type: 0, 27279 lastname: lName, 27280 firstname: fName, 27281 // lastname: trafiName.split(' ')[0] + ' ' 27282 // firstname: trafiName 27283 // .split(' ') 27284 // .slice(1, trafiNameLen) 27285 // .join(' '), 27286 source: null, 27287 }); 27288 // self.customerList.unshift(moddedTrafiResult); 27289 // customerList.unshift(moddedTrafiResult); 27290 27291 // Remove stuff not related to the consumer 27292 moddedTrafiResult.company_name = null; 27293 moddedTrafiResult.business_id = null; 27294 27295 consumers.push(moddedTrafiResult); 27296 }); 27297 27298 return consumers; 27299 }); 27300 27301 self.ownersHoldersCompanies = ko.computed(function (){ 27302 27303 var companies = [], customerList = [], ownersHolders = ko.toJS(self.ownersHolders); 27304 27305 if( ! ownersHolders) 27306 return []; 27307 27308 ownersHolders 27309 .filter(function (ownerHolder){ 27310 return ownerHolder.customer_type === 'company' && ownerHolder.restriction < 1; 27311 }) 27312 .forEach(function(ownerHolder) { 27313 27314 var trafiRes = $.extend(true, {}, ownerHolder); 27315 var trafiName = trafiRes.name || ''; 27316 var trafiNameLen = (trafiRes.name || '').split(' ').length; 27317 var moddedTrafiResult = Object.assign(trafiRes, { 27318 displayName: 'Trafi / ' + trafiRes.ownership_type_description + ' / ' + trafiRes.name, 27319 company_name: trafiRes.name, 27320 business_id: trafiRes.identifier, 27321 customer_type: 1, 27322 lastname: trafiName.split(' ')[0], 27323 firstname: trafiName 27324 .split(' ') 27325 .slice(1, trafiNameLen) 27326 .join(' '), 27327 source: null, 27328 }); 27329 // self.customerList.unshift(moddedTrafiResult); 27330 27331 // Remove stuff not related to the company 27332 moddedTrafiResult.firstname = null; 27333 moddedTrafiResult.lastname = null; 27334 27335 ownerHolder.business_id = ownerHolder.identifier; 27336 27337 // @HACK override addresses for a few special cases 27338 // Santander consumer finance 27339 if (ownerHolder.business_id === '2076455-0') { 27340 ownerHolder.address = 'PL 626'; 27341 ownerHolder.zipcode = '00026'; 27342 ownerHolder.city = 'BASWARE'; 27343 ownerHolder.e_invoice_address = '00372076455001'; 27344 ownerHolder.e_invoice_operator = 'BAWCFI22'; 27345 ownerHolder.delivery_by = 'e_invoice'; 27346 } 27347 27348 // Veho Oy Ab 27349 if (ownerHolder.business_id === '0115761-6') { 27350 ownerHolder.address = 'PL 1004'; 27351 ownerHolder.contact_person = 'Ostolaskut'; 27352 ownerHolder.zipcode = '01511'; 27353 ownerHolder.city = 'VANTAA'; 27354 ownerHolder.e_invoice_address = '003701157616'; 27355 ownerHolder.e_invoice_operator = 'BAWCFI22'; 27356 ownerHolder.delivery_by = 'e_invoice'; 27357 } 27358 27359 // LeasePlan Finland Oy 27360 if (ownerHolder.business_id === '1440371-6') { 27361 ownerHolder.address = 'PL 1400'; 27362 ownerHolder.zipcode = '02066'; 27363 ownerHolder.city = 'DOCUSCAN'; 27364 ownerHolder.e_invoice_address = 'TE003714403716'; 27365 ownerHolder.e_invoice_operator = '003701011385'; 27366 ownerHolder.delivery_by = 'e_invoice'; 27367 } 27368 27369 companies.push(moddedTrafiResult); 27370
27371 companies.forEach(function(key, idx) { 27372 companies[idx].company_name = key.name; 27373 }); 27374 }); 27375 27376 return companies; 27377 }); 27378 27379 self.parseVehicleInfo = function(data) { 27380 27381 console.log('VehicleInfoCheckVm, data:', data); 27382 27383 self.vehicleInfoSearchMeta.id(data.id); 27384 self.vehicleInfoSearchMeta.requestParam(data.searchMeta.requestParam); 27385 self.vehicleInfoSearchMeta.dataSource(data.searchMeta.dataSource); 27386 self.vehicleInfoSearchMeta.datetime(data.searchMeta.datetime); 27387 self.vehicleInfoSearchMeta.daysOld(data.searchMeta.daysOld); 27388 self.vehicleInfoSearchMeta.dataSourceLongText(data.searchMeta.dataSourceLongText ? data.searchMeta.dataSourceLongText : '') 27389 self.vehicleInfoSearchMeta.dataSourceShortText(data.searchMeta.dataSourceShortText ? data.searchMeta.dataSourceShortText : '') 27390 27391 // Vehicle info 27392 self.vehicleInfo.reg_no(data.vehicleInfo.reg_no); 27393 self.vehicleInfo.serial_no(data.vehicleInfo.serial_no); 27394 self.vehicleInfo.vehicle_class(data.vehicleInfo.vehicle_class); 27395 self.vehicleInfo.vehicle_brand(data.vehicleInfo.vehicle_brand); 27396 self.vehicleInfo.vehicle_model(data.vehicleInfo.vehicle_model); 27397 self.vehicleInfo.vehicle_commercial_model(data.vehicleInfo.vehicle_commercial_model); 27398 self.vehicleInfo.vehicle_brand_and_model(data.vehicleInfo.vehicle_brand_and_model); 27399 self.vehicleInfo.vehicle_status(data.vehicleInfo.vehicle_status); 27400 self.vehicleInfo.vehicle_model_year(data.vehicleInfo.vehicle_model_year); 27401 self.vehicleInfo.vehicle_color(data.vehicleInfo.vehicle_color); 27402 self.vehicleInfo.fuel(data.vehicleInfo.fuel); 27403 self.vehicleInfo.transmission(data.vehicleInfo.transmission); 27404 self.vehicleInfo.drive(data.vehicleInfo.drive); 27405 self.vehicleInfo.displacement(data.vehicleInfo.displacement); 27406 self.vehicleInfo.max_net_effect(data.vehicleInfo.max_net_effect); 27407 self.vehicleInfo.max_net_weight(data.vehicleInfo.max_net_weight); 27408 self.vehicleInfo.max_tech_net_weight(data.vehicleInfo.max_tech_net_weight); 27409 self.vehicleInfo.length(data.vehicleInfo.length); 27410 self.vehicleInfo.width(data.vehicleInfo.width); 27411 self.vehicleInfo.height(data.vehicleInfo.height); 27412 self.vehicleInfo.weight(data.vehicleInfo.weight); 27413 self.vehicleInfo.initialization_date(data.vehicleInfo.initialization_date); 27414 self.vehicleInfo.first_registration_date(data.vehicleInfo.first_registration_date); 27415 self.vehicleInfo.last_inspection_date(data.vehicleInfo.last_inspection_date); 27416 self.vehicleInfo.last_inspection_result(data.vehicleInfo.last_inspection_result); 27417 self.vehicleInfo.last_inspection_result_description(data.vehicleInfo.last_inspection_result_description); 27418 self.vehicleInfo.next_inspection_date(data.vehicleInfo.next_inspection_date); 27419 self.vehicleInfo.remarks(data.vehicleInfo.remarks); 27420 self.vehicleInfo.holder_name(data.vehicleInfo.holder_name); 27421 self.vehicleInfo.holder_address(data.vehicleInfo.holder_address); 27422 self.vehicleInfo.owner_name(data.vehicleInfo.owner_name); 27423 self.vehicleInfo.owner_address(data.vehicleInfo.owner_address); 27424 27425 // RestrictionInfos 27426 // reset observableArray 27427 self.restrictionInfos([]); 27428 27429 _.each(data.restrictionInfos, function(restrictionInfo) { 27430 self.restrictionInfos.push(restrictionInfo); 27431 }); 27432 27433 self.transferPermit(null); 27434 if(data.transferPermit){ 27435 var applicant = (data.transferPermit && data.transferPermit.applicant) ? data.transferPermit.applicant : {}; 27436 self.transferPermit({ 27437 purposeOfUse: data.transferPermit.purposeOfUse ? data.transferPermit.purposeOfUse : '', 27438 validityStarts: data.transferPermit.validityStarts ? data.transferPermit.validityStarts : '', 27439 validityEnds: data.transferPermit.validityEnds ? data.transferPermit.validityEnds : '', 27440 lastNameMainUnit: applicant.lastNameMainUnit ? applicant.lastNameMainUnit : '', 27441 firstNameSubUnit: applicant.firstNameSubUnit ? applicant.firstNameSubUnit : '', 27442 streetAddress: applicant.streetAddress ? applicant.streetAddress : '', 27443 postalCode: applicant.postalCode ? applicant.postalCode : '', 27444 city: applicant.city ? applicant.city : '', 27445 route: data.transferPermit.route ? data.transferPermit.route : '' 27446 }); 27447 } 27448 27449 // Holders info 27450 // reset observableArray 27451 self.ownersHolders([]); 27452 27453 _.each(data.ownersHolders, function(ownerHolder) { 27454 self.ownersHolders.push(ownerHolder); 27455 }); 27456 27457 // Insurance info 27458 self.insuranceInfo.insurance_company(data.insuranceInfo.insurance_company); 27459 self.insuranceInfo.insurance_start_date(data.insuranceInfo.insurance_start_date); 27460 self.insuranceInfo.insurance_end_date(data.insuranceInfo.insurance_end_date); 27461 self.insuranceInfo.insured_party(data.insuranceInfo.insured_party); 27462 27463 self.printVehicleInfo = function() { 27464 $('#vehicle-info-check').printArea({
27465 extraCss: '/assets/css/new/bootstrap-3.2.0.min.css, /assets/css/kuormakirja-print.css' 27466 }); 27467 }; 27468 27469 self.closeJQueryUIVehicleInfoDialog = function() { 27470 global.$dialog.dialog("close"); 27471 }; 27472 27473 }; 27474 27475 if (opts) { 27476 self.parseVehicleInfo(opts); 27477 } 27478 27479}; 27480 27481;// Common features for enhanced Trafi searches 27482window.trafiExtras = function() { 27483 var changeTimeToFinnishStyle = function(timeString) { 27484 if (timeString === '0000-00-00') { return 'Aikaa ei asetettu'; } 27485 var time = timeString.split('-'); 27486 return [time[2], time[1], time[0]].join('.'); 27487 }; 27488 27489 var renderTRecordStatus = function(code) { 27490 switch(code) { 27491 case 'deleted': return 'Poistettu'; 27492 case 'payment_undefined': return 'Laskuttamaton'; 27493 case 'aggregate': return 'Koonti'; 27494 case 'unfinished': return 'Kesken'; 27495 case 'complete': return 'Valmis'; 27496 default: return 'Tuntematon'; 27497 } 27498 }; 27499 27500 var renderTOrderStatus = function(code) { 27501 switch(code) { 27502 case 'pending_acceptance': return 'Odottaa kuittausta'; 27503 case 'open': return 'Avoin'; 27504 case 'accepted': return 'Hyväksytty'; 27505 case 'assigned': return 'Osoitettu'; 27506 case 'accepted': return 'Avoin'; 27507 case 'cancelled': return 'Peruutettu'; 27508 case 'autoliitto': return 'Autoliitto'; 27509 case 'towing_record_created': return 'Kuormakirja luotu'; 27510 default: return 'Tuntematon ('+code+')'; 27511 } 27512 }; 27513 27514 var togglePreviousHistory = function() { 27515 $('.previous-searches').toggle(); 27516 $('.previous-searches-open').toggle(); 27517 $('.previous-searches-close').toggle(); 27518 }; 27519 27520 /* 27521 var visualizeSearchAge = function() { 27522 if(this.vehicleInfoSearchMeta.dataSource() == 'undefined'){ 27523 return '#d9534f'; 27524 } 27525 var days = Number(this.vehicleInfoSearchMeta.daysOld()); 27526 if (days <= 14) { return '#5cb85c'; } 27527 if (days > 14 && days <= 30) { return '#f0ad4e'; } 27528 return '#d9534f'; 27529 }; 27530*/ 27531 27532 var searchAge = function() { 27533 return this.vehicleInfoSearchMeta.dataSourceLongText(); 27534 // var ago = Number(this.vehicleInfoSearchMeta.daysOld()); 27535 // if (isNaN(ago)) { return 'ei haettu Traficomista'; } 27536 // var time = this.vehicleInfoSearchMeta.datetime(); 27537 // if (!time) { return ''; } 27538 // var splitted = time.split(' '); 27539 // var dataSource 27540 27541 // switch(this.vehicleInfoSearchMeta.dataSource()){ 27542 // case 'trafi': 27543 // dataSource = 'haettu Traficomista'; 27544 // break; 27545 // case 'sos': 27546 // dataSource = 'saatu SOS tilauksen yhteydessä'; 27547 // break; 27548 // default: 27549 // return 'ei haettu Traficomista'; 27550 // } 27551 27552 // switch(ago) { 27553 // case 0: return dataSource + ' tänään klo. ' + splitted[1]; 27554 // case 1: return dataSource + ' eilen klo. ' + splitted[1]; 27555 // default: return dataSource + ' ' + splitted[0] + ', ' + ago + ' päivää sitten'; 27556 // } 27557 }; 27558 27559 return { 27560 changeTimeToFinnishStyle: changeTimeToFinnishStyle, 27561 renderTRecordStatus: renderTRecordStatus, 27562 togglePreviousHistory: togglePreviousHistory, 27563 searchAge: searchAge, 27564 renderTOrderStatus: renderTOrderStatus 27565 }; 27566}(); 27567 27568;/*! 27569 * Datepicker for Bootstrap v1.7.0-dev (https://github.com/eternicode/bootstrap-datepicker) 27570 * 27571 * Copyright 2012 Stefan Petre 27572 * Improvements by Andrew Rowls 27573 * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) 27574 */(function(factory){ 27575 if (typeof define === "function" && define.amd) { 27576 define(["jquery"], factory); 27577 } else if (typeof exports === 'object') { 27578 factory(require('jquery')); 27579 } else { 27580 factory(jQuery); 27581 } 27582}(function($, undefined){ 27583 27584 function UTCDate(){ 27585 return new Date(Date.UTC.apply(Date, arguments)); 27586 } 27587 function UTCToday(){ 27588 var today = new Date(); 27589 return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); 27590 } 27591 function isUTCEquals(date1, date2) { 27592 return ( 27593 date1.getUTCFullYear() === date2.getUTCFullYear() && 27594 date1.getUTCMonth() === date2.getUTCMonth() && 27595 date1.getUTCDate() === date2.getUTCDate() 27596 ); 27597 } 27598 function alias(method){ 27599 return function(){ 27600 return this[method].apply(this, arguments); 27601 }; 27602 } 27603 function isValidDate(d) { 27604 return d && !isNaN(d.getTime()); 27605 } 27606 27607 var DateArray = (function(){ 27608 var extras = { 27609 get: function(i){ 27610 return this.slice(i)[0]; 27611 }, 27612 contains: function(d){ 27613 // Array.indexOf is not cross-browser; 27614 // $.inArray doesn't work with Dates 27615 var val = d && d.valueOf(); 27616 for (var i=0, l=this.length; i < l; i++) 27617 if (this[i].valueOf() === val) 27618 return i; 27619 return -1; 27620 }, 27621 remove: function(i){ 27622 this.splice(i,1); 27623 }, 27624 replace: function(new_array){ 27625 if (!new_array) 27626 return; 27627 if (!$.isArray(new_array)) 27628 new_array = [new_array]; 27629 this.clear(); 27630 this.push.apply(this, new_array); 27631 }, 27632 clear: function(){ 27633 this.length = 0; 27634 }, 27635 copy: function(){ 27636 var a = new DateArray(); 27637 a.replace(this); 27638 return a; 27639 } 27640 }; 27641 27642 return function(){ 27643 var a = []; 27644 a.push.apply(a, arguments); 27645 $.extend(a, extras); 27646 return a; 27647 }; 27648 })(); 27649 27650 27651 // Picker object 27652 27653 var Datepicker = function(element, options){ 27654 $(element).data('datepicker', this); 27655 this._process_options(options); 27656 27657 this.dates = new DateArray(); 27658 this.viewDate = this.o.defaultViewDate; 27659 this.focusDate = null; 27660 27661 this.element = $(element); 27662 this.isInline = false;
27663 this.isInput = this.element.is('input'); 27664 this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; 27665 this.hasInput = this.component && this.element.find('input').length; 27666 if (this.component && this.component.length === 0) 27667 this.component = false; 27668 27669 this.picker = $(DPGlobal.template); 27670 27671 // Checking templates and inserting 27672 if (this._check_template(this.o.templates.leftArrow)) { 27673 this.picker.find('.prev').html(this.o.templates.leftArrow); 27674 } 27675 if (this._check_template(this.o.templates.rightArrow)) { 27676 this.picker.find('.next').html(this.o.templates.rightArrow); 27677 } 27678 27679 this._buildEvents(); 27680 this._attachEvents(); 27681 27682 if (this.isInline){ 27683 this.picker.addClass('datepicker-inline').appendTo(this.element); 27684 } 27685 else { 27686 this.picker.addClass('datepicker-dropdown dropdown-menu'); 27687 } 27688 27689 if (this.o.rtl){ 27690 this.picker.addClass('datepicker-rtl'); 27691 } 27692 27693 this.viewMode = this.o.startView; 27694 27695 if (this.o.calendarWeeks) 27696 this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear') 27697 .attr('colspan', function(i, val){ 27698 return parseInt(val) + 1; 27699 }); 27700 27701 this._allow_update = false; 27702 27703 this.setStartDate(this._o.startDate); 27704 this.setEndDate(this._o.endDate); 27705 this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); 27706 this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted); 27707 this.setDatesDisabled(this.o.datesDisabled); 27708 27709 this.fillDow(); 27710 this.fillMonths(); 27711 27712 this._allow_update = true; 27713 27714 this.update(); 27715 this.showMode(); 27716 27717 if (this.isInline){ 27718 this.show(); 27719 } 27720 }; 27721 27722 Datepicker.prototype = { 27723 constructor: Datepicker, 27724 27725 _resolveViewName: function(view, default_value){ 27726 if (view === 0 || view === 'days' || view === 'month') { 27727 return 0; 27728 } 27729 if (view === 1 || view === 'months' || view === 'year') { 27730 return 1; 27731 } 27732 if (view === 2 || view === 'years' || view === 'decade') { 27733 return 2; 27734 } 27735 if (view === 3 || view === 'decades' || view === 'century') { 27736 return 3; 27737 } 27738 if (view === 4 || view === 'centuries' || view === 'millennium') { 27739 return 4; 27740 } 27741 return default_value === undefined ? false : default_value; 27742 }, 27743 27744 _check_template: function(tmp){
27745 try { 27746 // If empty 27747 if (tmp === undefined || tmp === "") { 27748 return false; 27749 } 27750 // If no html, everything ok 27751 if ((tmp.match(/[<>]/g) || []).length <= 0) { 27752 return true; 27753 } 27754 // Checking if html is fine 27755 var jDom = $(tmp); 27756 return jDom.length > 0; 27757 } 27758 catch (ex) { 27759 return false; 27760 } 27761 }, 27762 27763 _process_options: function(opts){ 27764 // Store raw options for reference 27765 this._o = $.extend({}, this._o, opts); 27766 // Processed options 27767 var o = this.o = $.extend({}, this._o); 27768 27769 // Check if "de-DE" style date is available, if not language should 27770 // fallback to 2 letter code eg "de" 27771 var lang = o.language; 27772 if (!dates[lang]){ 27773 lang = lang.split('-')[0]; 27774 if (!dates[lang]) 27775 lang = defaults.language; 27776 } 27777 o.language = lang; 27778 27779 // Retrieve view index from any aliases 27780 o.startView = this._resolveViewName(o.startView, 0); 27781 o.minViewMode = this._resolveViewName(o.minViewMode, 0); 27782 o.maxViewMode = this._resolveViewName(o.maxViewMode, 4); 27783 27784 // Check that the start view is between min and max 27785 o.startView = Math.min(o.startView, o.maxViewMode); 27786 o.startView = Math.max(o.startView, o.minViewMode); 27787 27788 // true, false, or Number > 0 27789 if (o.multidate !== true){ 27790 o.multidate = Number(o.multidate) || false; 27791 if (o.multidate !== false) 27792 o.multidate = Math.max(0, o.multidate); 27793 } 27794 o.multidateSeparator = String(o.multidateSeparator); 27795 27796 o.weekStart %= 7; 27797 o.weekEnd = (o.weekStart + 6) % 7; 27798 27799 var format = DPGlobal.parseFormat(o.format); 27800 if (o.startDate !== -Infinity){ 27801 if (!!o.startDate){ 27802 if (o.startDate instanceof Date) 27803 o.startDate = this._local_to_utc(this._zero_time(o.startDate)); 27804 else 27805 o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear); 27806 } 27807 else { 27808 o.startDate = -Infinity; 27809 } 27810 } 27811 if (o.endDate !== Infinity){ 27812 if (!!o.endDate){ 27813 if (o.endDate instanceof Date) 27814 o.endDate = this._local_to_utc(this._zero_time(o.endDate)); 27815 else 27816 o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear); 27817 } 27818 else { 27819 o.endDate = Infinity; 27820 } 27821 } 27822 27823 o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; 27824 if (!$.isArray(o.daysOfWeekDisabled)) 27825 o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); 27826 o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ 27827 return parseInt(d, 10); 27828 }); 27829 27830 o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[]; 27831 if (!$.isArray(o.daysOfWeekHighlighted)) 27832 o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/); 27833 o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){ 27834 return parseInt(d, 10); 27835 }); 27836 27837 o.datesDisabled = o.datesDisabled||[]; 27838 if (!$.isArray(o.datesDisabled)) { 27839 var datesDisabled = []; 27840 datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language, o.assumeNearbyYear)); 27841 o.datesDisabled = datesDisabled; 27842 } 27843 o.datesDisabled = $.map(o.datesDisabled,function(d){ 27844 return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear); 27845 }); 27846 27847 var plc = String(o.orientation).toLowerCase().split(/\s+/g), 27848 _plc = o.orientation.toLowerCase(); 27849 plc = $.grep(plc, function(word){ 27850 return /^auto|left|right|top|bottom$/.test(word); 27851 }); 27852 o.orientation = {x: 'auto', y: 'auto'}; 27853 if (!_plc || _plc === 'auto') 27854 ; // no action 27855 else if (plc.length === 1){ 27856 switch (plc[0]){ 27857 case 'top': 27858 case 'bottom': 27859 o.orientation.y = plc[0]; 27860 break; 27861 case 'left': 27862 case 'right': 27863 o.orientation.x = plc[0]; 27864 break; 27865 } 27866 } 27867 else { 27868 _plc = $.grep(plc, function(word){ 27869 return /^left|right$/.test(word); 27870 }); 27871 o.orientation.x = _plc[0] || 'auto'; 27872 27873 _plc = $.grep(plc, function(word){ 27874 return /^top|bottom$/.test(word); 27875 }); 27876 o.orientation.y = _plc[0] || 'auto'; 27877 } 27878 if (o.defaultViewDate) { 27879 var year = o.defaultViewDate.year || new Date().getFullYear();
27880 var month = o.defaultViewDate.month || 0; 27881 var day = o.defaultViewDate.day || 1; 27882 o.defaultViewDate = UTCDate(year, month, day); 27883 } else { 27884 o.defaultViewDate = UTCToday(); 27885 } 27886 }, 27887 _events: [], 27888 _secondaryEvents: [], 27889 _applyEvents: function(evs){ 27890 for (var i=0, el, ch, ev; i < evs.length; i++){ 27891 el = evs[i][0]; 27892 if (evs[i].length === 2){ 27893 ch = undefined; 27894 ev = evs[i][1]; 27895 } 27896 else if (evs[i].length === 3){ 27897 ch = evs[i][1]; 27898 ev = evs[i][2]; 27899 } 27900 el.on(ev, ch); 27901 } 27902 }, 27903 _unapplyEvents: function(evs){ 27904 for (var i=0, el, ev, ch; i < evs.length; i++){ 27905 el = evs[i][0]; 27906 if (evs[i].length === 2){ 27907 ch = undefined; 27908 ev = evs[i][1]; 27909 } 27910 else if (evs[i].length === 3){ 27911 ch = evs[i][1]; 27912 ev = evs[i][2]; 27913 } 27914 el.off(ev, ch); 27915 } 27916 }, 27917 _buildEvents: function(){ 27918 var events = { 27919 keyup: $.proxy(function(e){ 27920 if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1) 27921 this.update(); 27922 }, this), 27923 keydown: $.proxy(this.keydown, this), 27924 paste: $.proxy(this.paste, this) 27925 }; 27926 27927 if (this.o.showOnFocus === true) { 27928 events.focus = $.proxy(this.show, this); 27929 } 27930 27931 if (this.isInput) { // single input 27932 this._events = [ 27933 [this.element, events] 27934 ]; 27935 } 27936 else if (this.component && this.hasInput) { // component: input + button 27937 this._events = [ 27938 // For components that are not readonly, allow keyboard nav 27939 [this.element.find('input'), events], 27940 [this.component, { 27941 click: $.proxy(this.show, this) 27942 }] 27943 ]; 27944 } 27945 else if (this.element.is('div')){ // inline datepicker 27946 this.isInline = true; 27947 } 27948 else { 27949 this._events = [ 27950 [this.element, { 27951 click: $.proxy(this.show, this), 27952 keydown: $.proxy(this.keydown, this) 27953 }] 27954 ]; 27955 } 27956 this._events.push( 27957 // Component: listen for blur on element descendants 27958 [this.element, '*', { 27959 blur: $.proxy(function(e){ 27960 this._focused_from = e.target; 27961 }, this) 27962 }], 27963 // Input: listen for blur on element 27964 [this.element, { 27965 blur: $.proxy(function(e){ 27966 this._focused_from = e.target; 27967 }, this) 27968 }] 27969 ); 27970 27971 if (this.o.immediateUpdates) { 27972 // Trigger input updates immediately on changed year/month 27973 this._events.push([this.element, { 27974 'changeYear changeMonth': $.proxy(function(e){ 27975 this.update(e.date); 27976 }, this) 27977 }]); 27978 } 27979 27980 this._secondaryEvents = [ 27981 [this.picker, { 27982 click: $.proxy(this.click, this) 27983 }], 27984 [$(window), { 27985 resize: $.proxy(this.place, this) 27986 }], 27987 [$(document), { 27988 mousedown: $.proxy(function(e){ 27989 // Clicked outside the datepicker, hide it 27990 if (!( 27991 this.element.is(e.target) || 27992 this.element.find(e.target).length || 27993 this.picker.is(e.target) || 27994 this.picker.find(e.target).length || 27995 this.picker.hasClass('datepicker-inline') 27996 )){ 27997 this.hide(); 27998 } 27999 }, this) 28000 }] 28001 ]; 28002 }, 28003 _attachEvents: function(){ 28004 this._detachEvents(); 28005 this._applyEvents(this._events); 28006 }, 28007 _detachEvents: function(){ 28008 this._unapplyEvents(this._events); 28009 }, 28010 _attachSecondaryEvents: function(){ 28011 this._detachSecondaryEvents(); 28012 this._applyEvents(this._secondaryEvents); 28013 }, 28014 _detachSecondaryEvents: function(){ 28015 this._unapplyEvents(this._secondaryEvents); 28016 }, 28017 _trigger: function(event, altdate){ 28018 var date = altdate || this.dates.get(-1), 28019 local_date = this._utc_to_local(date); 28020 28021 this.element.trigger({ 28022 type: event, 28023 date: local_date, 28024 dates: $.map(this.dates, this._utc_to_local), 28025 format: $.proxy(function(ix, format){ 28026 if (arguments.length === 0){ 28027 ix = this.dates.length - 1; 28028 format = this.o.format; 28029 } 28030 else if (typeof ix === 'string'){ 28031 format = ix; 28032 ix = this.dates.length - 1; 28033 } 28034 format = format || this.o.format; 28035 var date = this.dates.get(ix); 28036 return DPGlobal.formatDate(date, format, this.o.language); 28037 }, this) 28038 }); 28039 }, 28040 28041 show: function(){ 28042 var element = this.component ? this.element.find('input') : this.element; 28043 if (element.attr('readonly') && this.o.enableOnReadonly === false) 28044 return; 28045 if (!this.isInline) 28046 this.picker.appendTo(this.o.container); 28047 this.place(); 28048 this.picker.show(); 28049 this._attachSecondaryEvents(); 28050 this._trigger('show'); 28051 if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) { 28052 $(this.element).blur(); 28053 } 28054 return this; 28055 }, 28056 28057 hide: function(){ 28058 if (this.isInline) 28059 return this; 28060 if (!this.picker.is(':visible')) 28061 return this; 28062 this.focusDate = null; 28063 this.picker.hide().detach(); 28064 this._detachSecondaryEvents(); 28065 this.viewMode = this.o.startView; 28066 this.showMode(); 28067 28068 if ( 28069 this.o.forceParse && 28070 ( 28071 this.isInput && this.element.val() || 28072 this.hasInput && this.element.find('input').val() 28073 ) 28074 ) 28075 this.setValue(); 28076 this._trigger('hide'); 28077 return this; 28078 }, 28079 28080 destroy: function(){ 28081 this.hide(); 28082 this._detachEvents(); 28083 this._detachSecondaryEvents(); 28084 this.picker.remove(); 28085 delete this.element.data().datepicker; 28086 if (!this.isInput){ 28087 delete this.element.data().date; 28088 } 28089 return this; 28090 }, 28091 28092 paste: function(evt){ 28093 var dateString; 28094 if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types 28095 && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) { 28096 dateString = evt.originalEvent.clipboardData.getData('text/plain'); 28097 } 28098 else if (window.clipboardData) { 28099 dateString = window.clipboardData.getData('Text'); 28100 } 28101 else { 28102 return; 28103 } 28104 this.setDate(dateString); 28105 this.update(); 28106 evt.preventDefault(); 28107 }, 28108 28109 _utc_to_local: function(utc){ 28110 return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); 28111 }, 28112 _local_to_utc: function(local){ 28113 return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); 28114 }, 28115 _zero_time: function(local){ 28116 return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); 28117 }, 28118 _zero_utc_time: function(utc){ 28119 return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); 28120 }, 28121 28122 getDates: function(){ 28123 return $.map(this.dates, this._utc_to_local); 28124 }, 28125 28126 getUTCDates: function(){ 28127 return $.map(this.dates, function(d){ 28128 return new Date(d); 28129 }); 28130 }, 28131 28132 getDate: function(){ 28133 return this._utc_to_local(this.getUTCDate()); 28134 }, 28135 28136 getUTCDate: function(){ 28137 var selected_date = this.dates.get(-1); 28138 if (typeof selected_date !== 'undefined') { 28139 return new Date(selected_date); 28140 } else { 28141 return null; 28142 } 28143 }, 28144 28145 clearDates: function(){ 28146 var element; 28147 if (this.isInput) { 28148 element = this.element; 28149 } else if (this.component) { 28150 element = this.element.find('input'); 28151 } 28152 28153 if (element) { 28154 element.val(''); 28155 } 28156 28157 this.update(); 28158 this._trigger('changeDate'); 28159 28160 if (this.o.autoclose) { 28161 this.hide(); 28162 } 28163 }, 28164 setDates: function(){ 28165 var args = $.isArray(arguments[0]) ? arguments[0] : arguments; 28166 this.update.apply(this, args); 28167 this._trigger('changeDate'); 28168 this.setValue(); 28169 return this; 28170 }, 28171 28172 setUTCDates: function(){ 28173 var args = $.isArray(arguments[0]) ? arguments[0] : arguments; 28174 this.update.apply(this, $.map(args, this._utc_to_local)); 28175 this._trigger('changeDate'); 28176 this.setValue(); 28177 return this; 28178 }, 28179 28180 setDate: alias('setDates'), 28181 setUTCDate: alias('setUTCDates'), 28182 remove: alias('destroy'), 28183 28184 setValue: function(){ 28185 var formatted = this.getFormattedDate(); 28186 if (!this.isInput){ 28187 if (this.component){ 28188 this.element.find('input').val(formatted); 28189 } 28190 } 28191 else { 28192 this.element.val(formatted); 28193 } 28194 return this; 28195 }, 28196 28197 getFormattedDate: function(format){ 28198 if (format === undefined) 28199 format = this.o.format; 28200 28201 var lang = this.o.language; 28202 return $.map(this.dates, function(d){ 28203 return DPGlobal.formatDate(d, format, lang); 28204 }).join(this.o.multidateSeparator); 28205 }, 28206 28207 getStartDate: function(){ 28208 return this.o.startDate; 28209 }, 28210 28211 setStartDate: function(startDate){ 28212 this._process_options({startDate: startDate}); 28213 this.update(); 28214 this.updateNavArrows(); 28215 return this; 28216 }, 28217 28218 getEndDate: function(){ 28219 return this.o.endDate; 28220 }, 28221
28222 setEndDate: function(endDate){ 28223 this._process_options({endDate: endDate}); 28224 this.update(); 28225 this.updateNavArrows(); 28226 return this; 28227 }, 28228 28229 setDaysOfWeekDisabled: function(daysOfWeekDisabled){ 28230 this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); 28231 this.update(); 28232 this.updateNavArrows(); 28233 return this; 28234 }, 28235 28236 setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){ 28237 this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted}); 28238 this.update(); 28239 return this; 28240 }, 28241 28242 setDatesDisabled: function(datesDisabled){ 28243 this._process_options({datesDisabled: datesDisabled}); 28244 this.update(); 28245 this.updateNavArrows(); 28246 }, 28247 28248 place: function(){ 28249 if (this.isInline) 28250 return this; 28251 var calendarWidth = this.picker.outerWidth(), 28252 calendarHeight = this.picker.outerHeight(), 28253 visualPadding = 10, 28254 container = $(this.o.container), 28255 windowWidth = container.width(), 28256 scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(), 28257 appendOffset = container.offset(); 28258 28259 var parentsZindex = []; 28260 this.element.parents().each(function(){ 28261 var itemZIndex = $(this).css('z-index'); 28262 if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex)); 28263 }); 28264 var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset; 28265 var offset = this.component ? this.component.parent().offset() : this.element.offset(); 28266 var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); 28267 var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); 28268 var left = offset.left - appendOffset.left, 28269 top = offset.top - appendOffset.top; 28270 28271 if (this.o.container !== 'body') { 28272 top += scrollTop; 28273 } 28274 28275 this.picker.removeClass( 28276 'datepicker-orient-top datepicker-orient-bottom '+ 28277 'datepicker-orient-right datepicker-orient-left' 28278 ); 28279 28280 if (this.o.orientation.x !== 'auto'){ 28281 this.picker.addClass('datepicker-orient-' + this.o.orientation.x); 28282 if (this.o.orientation.x === 'right') 28283 left -= calendarWidth - width; 28284 } 28285 // auto x orientation is best-placement: if it crosses a window 28286 // edge, fudge it sideways 28287 else { 28288 if (offset.left < 0) { 28289 // component is outside the window on the left side. Move it into visible range 28290 this.picker.addClass('datepicker-orient-left'); 28291 left -= offset.left - visualPadding; 28292 } else if (left + calendarWidth > windowWidth) { 28293 // the calendar passes the widow right edge. Align it to component right side 28294 this.picker.addClass('datepicker-orient-right'); 28295 left += width - calendarWidth; 28296 } else { 28297 // Default to left 28298 this.picker.addClass('datepicker-orient-left'); 28299 } 28300 } 28301 28302 // auto y orientation is best-situation: top or bottom, no fudging, 28303 // decision based on which shows more of the calendar 28304 var yorient = this.o.orientation.y, 28305 top_overflow; 28306 if (yorient === 'auto'){ 28307 top_overflow = -scrollTop + top - calendarHeight; 28308 yorient = top_overflow < 0 ? 'bottom' : 'top'; 28309 } 28310 28311 this.picker.addClass('datepicker-orient-' + yorient); 28312 if (yorient === 'top') 28313 top -= calendarHeight + parseInt(this.picker.css('padding-top')); 28314 else 28315 top += height; 28316 28317 if (this.o.rtl) { 28318 var right = windowWidth - (left + width); 28319 this.picker.css({ 28320 top: top, 28321 right: right, 28322 zIndex: zIndex 28323 }); 28324 } else { 28325 this.picker.css({ 28326 top: top, 28327 left: left, 28328 zIndex: zIndex 28329 }); 28330 } 28331 return this; 28332 }, 28333 28334 _allow_update: true, 28335 update: function(){ 28336 if (!this._allow_update) 28337 return this; 28338 28339 var oldDates = this.dates.copy(), 28340 dates = [], 28341 fromArgs = false; 28342 if (arguments.length){ 28343 $.each(arguments, $.proxy(function(i, date){ 28344 if (date instanceof Date) 28345 date = this._local_to_utc(date); 28346 dates.push(date); 28347 }, this)); 28348 fromArgs = true; 28349 } 28350 else { 28351 dates = this.isInput 28352 ? this.element.val() 28353 : this.element.data('date') || this.element.find('input').val(); 28354 if (dates && this.o.multidate) 28355 dates = dates.split(this.o.multidateSeparator); 28356 else 28357 dates = [dates]; 28358 delete this.element.data().date; 28359 } 28360 28361 dates = $.map(dates, $.proxy(function(date){ 28362 return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear); 28363 }, this)); 28364 dates = $.grep(dates, $.proxy(function(date){ 28365 return ( 28366 !this.dateWithinRange(date) || 28367 !date 28368 ); 28369 }, this), true); 28370 this.dates.replace(dates); 28371 28372 if (this.dates.length) 28373 this.viewDate = new Date(this.dates.get(-1)); 28374 else if (this.viewDate < this.o.startDate) 28375 this.viewDate = new Date(this.o.startDate); 28376 else if (this.viewDate > this.o.endDate) 28377 this.viewDate = new Date(this.o.endDate); 28378 else 28379 this.viewDate = this.o.defaultViewDate; 28380 28381 if (fromArgs){ 28382 // setting date by clicking 28383 this.setValue(); 28384 } 28385 else if (dates.length){ 28386 // setting date by typing 28387 if (String(oldDates) !== String(this.dates)) 28388 this._trigger('changeDate'); 28389 } 28390 if (!this.dates.length && oldDates.length) 28391 this._trigger('clearDate'); 28392 28393 this.fill(); 28394 this.element.change(); 28395 return this; 28396 }, 28397 28398 fillDow: function(){ 28399 var dowCnt = this.o.weekStart, 28400 html = '<tr>'; 28401 if (this.o.calendarWeeks){ 28402 this.picker.find('.datepicker-days .datepicker-switch') 28403 .attr('colspan', function(i, val){ 28404 return parseInt(val) + 1; 28405 }); 28406 html += '<th class="cw"> </th>'; 28407 } 28408 while (dowCnt < this.o.weekStart + 7){ 28409 html += '<th class="dow'; 28410 if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1) 28411 html += ' disabled'; 28412 html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>'; 28413 } 28414 html += '</tr>'; 28415 this.picker.find('.datepicker-days thead').append(html); 28416 }, 28417 28418 fillMonths: function(){ 28419 var localDate = this._utc_to_local(this.viewDate); 28420 var html = '', 28421 i = 0; 28422 while (i < 12){ 28423 var focused = localDate && localDate.getMonth() === i ? ' focused' : ''; 28424 html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i++]+'</span>'; 28425 } 28426 this.picker.find('.datepicker-months td').html(html); 28427 }, 28428 28429 setRange: function(range){ 28430 if (!range || !range.length) 28431 delete this.range; 28432 else 28433 this.range = $.map(range, function(d){ 28434 return d.valueOf(); 28435 }); 28436 this.fill(); 28437 }, 28438 28439 getClassNames: function(date){ 28440 var cls = [], 28441 year = this.viewDate.getUTCFullYear(),
28442 month = this.viewDate.getUTCMonth(), 28443 today = new Date(); 28444 if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){ 28445 cls.push('old'); 28446 } 28447 else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){ 28448 cls.push('new'); 28449 } 28450 if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) 28451 cls.push('focused'); 28452 // Compare internal UTC date with local today, not UTC today 28453 if (this.o.todayHighlight && 28454 date.getUTCFullYear() === today.getFullYear() && 28455 date.getUTCMonth() === today.getMonth() && 28456 date.getUTCDate() === today.getDate()){ 28457 cls.push('today'); 28458 } 28459 if (this.dates.contains(date) !== -1) 28460 cls.push('active'); 28461 if (!this.dateWithinRange(date)){ 28462 cls.push('disabled'); 28463 } 28464 if (this.dateIsDisabled(date)){ 28465 cls.push('disabled', 'disabled-date'); 28466 } 28467 if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){ 28468 cls.push('highlighted'); 28469 } 28470 28471 if (this.range){ 28472 if (date > this.range[0] && date < this.range[this.range.length-1]){ 28473 cls.push('range'); 28474 } 28475 if ($.inArray(date.valueOf(), this.range) !== -1){ 28476 cls.push('selected'); 28477 } 28478 if (date.valueOf() === this.range[0]){ 28479 cls.push('range-start'); 28480 } 28481 if (date.valueOf() === this.range[this.range.length-1]){ 28482 cls.push('range-end'); 28483 } 28484 } 28485 return cls; 28486 }, 28487 28488 _fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){ 28489 var html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before; 28490 28491 html = ''; 28492 view = this.picker.find(selector); 28493 year = parseInt(currentYear / factor, 10) * factor; 28494 startStep = parseInt(startYear / step, 10) * step; 28495 endStep = parseInt(endYear / step, 10) * step; 28496 steps = $.map(this.dates, function(d){ 28497 return parseInt(d.getUTCFullYear() / step, 10) * step; 28498 }); 28499 28500 view.find('.datepicker-switch').text(year + '-' + (year + step * 9)); 28501 28502 thisYear = year - step; 28503 for (i = -1; i < 11; i += 1) { 28504 classes = [cssClass]; 28505 tooltip = null; 28506 28507 if (i === -1) { 28508 classes.push('old'); 28509 } else if (i === 10) { 28510 classes.push('new'); 28511 } 28512 if ($.inArray(thisYear, steps) !== -1) { 28513 classes.push('active'); 28514 } 28515 if (thisYear < startStep || thisYear > endStep) { 28516 classes.push('disabled'); 28517 } 28518 if (thisYear === this.viewDate.getFullYear()) { 28519 classes.push('focused'); 28520 } 28521 28522 if (callback !== $.noop) { 28523 before = callback(new Date(thisYear, 0, 1)); 28524 if (before === undefined) { 28525 before = {}; 28526 } else if (typeof(before) === 'boolean') { 28527 before = {enabled: before}; 28528 } else if (typeof(before) === 'string') { 28529 before = {classes: before}; 28530 } 28531 if (before.enabled === false) { 28532 classes.push('disabled'); 28533 } 28534 if (before.classes) { 28535 classes = classes.concat(before.classes.split(/\s+/)); 28536 } 28537 if (before.tooltip) { 28538 tooltip = before.tooltip; 28539 } 28540 } 28541 28542 html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + thisYear + '</span>'; 28543 thisYear += step; 28544 } 28545 view.find('td').html(html); 28546 }, 28547 28548 fill: function(){ 28549 var d = new Date(this.viewDate), 28550 year = d.getUTCFullYear(), 28551 month = d.getUTCMonth(), 28552 startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, 28553 startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, 28554 endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, 28555 endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, 28556 todaytxt = dates[this.o.language].today || dates['en'].today || '', 28557 cleartxt = dates[this.o.language].clear || dates['en'].clear || '', 28558 titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat, 28559 tooltip, 28560 before; 28561 if (isNaN(year) || isNaN(month)) 28562 return; 28563 this.picker.find('.datepicker-days .datepicker-switch') 28564 .text(DPGlobal.formatDate(d, titleFormat, this.o.language)); 28565 this.picker.find('tfoot .today') 28566 .text(todaytxt) 28567 .toggle(this.o.todayBtn !== false); 28568 this.picker.find('tfoot .clear') 28569 .text(cleartxt) 28570 .toggle(this.o.clearBtn !== false); 28571 this.picker.find('thead .datepicker-title') 28572 .text(this.o.title) 28573 .toggle(this.o.title !== ''); 28574 this.updateNavArrows(); 28575 this.fillMonths(); 28576 var prevMonth = UTCDate(year, month-1, 28), 28577 day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); 28578 prevMonth.setUTCDate(day); 28579 prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); 28580 var nextMonth = new Date(prevMonth); 28581 if (prevMonth.getUTCFullYear() < 100){ 28582 nextMonth.setUTCFullYear(prevMonth.getUTCFullYear()); 28583 } 28584 nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); 28585 nextMonth = nextMonth.valueOf(); 28586 var html = []; 28587 var clsName; 28588 while (prevMonth.valueOf() < nextMonth){ 28589 if (prevMonth.getUTCDay() === this.o.weekStart){ 28590 html.push('<tr>'); 28591 if (this.o.calendarWeeks){ 28592 // ISO 8601: First week contains first thursday. 28593 // ISO also states week starts on Monday, but we can be more abstract here. 28594 var 28595 // Start of current week: based on weekstart/current date 28596 ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5), 28597 // Thursday of this week 28598 th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5), 28599 // First Thursday of year, year from thursday 28600 yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5), 28601 // Calendar week: ms between thursdays, div ms per day, div 7 days 28602 calWeek = (th - yth) / 864e5 / 7 + 1; 28603 html.push('<td class="cw">'+ calWeek +'</td>'); 28604 28605 } 28606 } 28607 clsName = this.getClassNames(prevMonth); 28608 clsName.push('day'); 28609 28610 if (this.o.beforeShowDay !== $.noop){ 28611 before = this.o.beforeShowDay(this._utc_to_local(prevMonth)); 28612 if (before === undefined) 28613 before = {}; 28614 else if (typeof(before) === 'boolean') 28615 before = {enabled: before}; 28616 else if (typeof(before) === 'string') 28617 before = {classes: before}; 28618 if (before.enabled === false) 28619 clsName.push('disabled'); 28620 if (before.classes) 28621 clsName = clsName.concat(before.classes.split(/\s+/)); 28622 if (before.tooltip) 28623 tooltip = before.tooltip; 28624 } 28625 28626 clsName = $.unique(clsName); 28627 html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>'); 28628 tooltip = null; 28629 if (prevMonth.getUTCDay() === this.o.weekEnd){ 28630 html.push('</tr>'); 28631 } 28632 prevMonth.setUTCDate(prevMonth.getUTCDate()+1); 28633 } 28634 this.picker.find('.datepicker-days tbody').empty().append(html.join('')); 28635 28636 var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months'; 28637 var months = this.picker.find('.datepicker-months') 28638 .find('.datepicker-switch') 28639 .text(this.o.maxViewMode < 2 ? monthsTitle : year) 28640 .end() 28641 .find('span').removeClass('active'); 28642 28643 $.each(this.dates, function(i, d){ 28644 if (d.getUTCFullYear() === year) 28645 months.eq(d.getUTCMonth()).addClass('active'); 28646 }); 28647 28648 if (year < startYear || year > endYear){ 28649 months.addClass('disabled'); 28650 } 28651 if (year === startYear){ 28652 months.slice(0, startMonth).addClass('disabled'); 28653 } 28654 if (year === endYear){ 28655 months.slice(endMonth+1).addClass('disabled'); 28656 } 28657 28658 if (this.o.beforeShowMonth !== $.noop){ 28659 var that = this; 28660 $.each(months, function(i, month){ 28661 var moDate = new Date(year, i, 1); 28662 var before = that.o.beforeShowMonth(moDate); 28663 if (before === undefined) 28664 before = {}; 28665 else if (typeof(before) === 'boolean') 28666 before = {enabled: before}; 28667 else if (typeof(before) === 'string') 28668 before = {classes: before}; 28669 if (before.enabled === false && !$(month).hasClass('disabled')) 28670 $(month).addClass('disabled'); 28671 if (before.classes) 28672 $(month).addClass(before.classes); 28673 if (before.tooltip) 28674 $(month).prop('title', before.tooltip); 28675 }); 28676 } 28677 28678 // Generating decade/years picker 28679 this._fill_yearsView( 28680 '.datepicker-years', 28681 'year', 28682 10, 28683 1, 28684 year, 28685 startYear, 28686 endYear, 28687 this.o.beforeShowYear 28688 ); 28689 28690 // Generating century/decades picker 28691 this._fill_yearsView( 28692 '.datepicker-decades', 28693 'decade', 28694 100, 28695 10, 28696 year, 28697 startYear, 28698 endYear, 28699 this.o.beforeShowDecade 28700 ); 28701 28702 // Generating millennium/centuries picker 28703 this._fill_yearsView( 28704 '.datepicker-centuries', 28705 'century', 28706 1000, 28707 100, 28708 year, 28709 startYear, 28710 endYear, 28711 this.o.beforeShowCentury 28712 ); 28713 }, 28714 28715 updateNavArrows: function(){ 28716 if (!this._allow_update) 28717 return; 28718 28719 var d = new Date(this.viewDate), 28720 year = d.getUTCFullYear(),
28721 month = d.getUTCMonth(); 28722 switch (this.viewMode){ 28723 case 0: 28724 if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){ 28725 this.picker.find('.prev').css({visibility: 'hidden'}); 28726 } 28727 else { 28728 this.picker.find('.prev').css({visibility: 'visible'}); 28729 } 28730 if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){ 28731 this.picker.find('.next').css({visibility: 'hidden'}); 28732 } 28733 else { 28734 this.picker.find('.next').css({visibility: 'visible'}); 28735 } 28736 break; 28737 case 1: 28738 case 2: 28739 case 3: 28740 case 4: 28741 if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){ 28742 this.picker.find('.prev').css({visibility: 'hidden'}); 28743 } 28744 else { 28745 this.picker.find('.prev').css({visibility: 'visible'}); 28746 } 28747 if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){ 28748 this.picker.find('.next').css({visibility: 'hidden'}); 28749 } 28750 else { 28751 this.picker.find('.next').css({visibility: 'visible'}); 28752 } 28753 break; 28754 } 28755 }, 28756 28757 click: function(e){ 28758 e.preventDefault(); 28759 e.stopPropagation(); 28760 28761 var target, dir, day, year, month, monthChanged, yearChanged; 28762 target = $(e.target); 28763 28764 // Clicked on the switch 28765 if (target.hasClass('datepicker-switch')){ 28766 this.showMode(1); 28767 } 28768 28769 // Clicked on prev or next 28770 var navArrow = target.closest('.prev, .next'); 28771 if (navArrow.length > 0) { 28772 dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1); 28773 if (this.viewMode === 0){ 28774 this.viewDate = this.moveMonth(this.viewDate, dir); 28775 this._trigger('changeMonth', this.viewDate); 28776 } else { 28777 this.viewDate = this.moveYear(this.viewDate, dir); 28778 if (this.viewMode === 1){ 28779 this._trigger('changeYear', this.viewDate); 28780 } 28781 } 28782 this.fill(); 28783 } 28784 28785 // Clicked on today button 28786 if (target.hasClass('today')){ 28787 this.showMode(-2); 28788 this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view'); 28789 } 28790 28791 // Clicked on clear button 28792 if (target.hasClass('clear')){ 28793 this.clearDates(); 28794 } 28795 28796 if (!target.hasClass('disabled')){ 28797 // Clicked on a day 28798 if (target.hasClass('day')){ 28799 day = parseInt(target.text(), 10) || 1; 28800 year = this.viewDate.getUTCFullYear(); 28801 month = this.viewDate.getUTCMonth(); 28802 28803 // From last month 28804 if (target.hasClass('old')){ 28805 if (month === 0) { 28806 month = 11; 28807 year = year - 1; 28808 monthChanged = true; 28809 yearChanged = true; 28810 } else { 28811 month = month - 1; 28812 monthChanged = true; 28813 } 28814 } 28815 28816 // From next month 28817 if (target.hasClass('new')) { 28818 if (month === 11){ 28819 month = 0; 28820 year = year + 1; 28821 monthChanged = true; 28822 yearChanged = true; 28823 } else { 28824 month = month + 1; 28825 monthChanged = true; 28826 } 28827 } 28828 this._setDate(UTCDate(year, month, day)); 28829 if (yearChanged) { 28830 this._trigger('changeYear', this.viewDate); 28831 } 28832 if (monthChanged) { 28833 this._trigger('changeMonth', this.viewDate); 28834 } 28835 } 28836 28837 // Clicked on a month 28838 if (target.hasClass('month')) { 28839 this.viewDate.setUTCDate(1); 28840 day = 1; 28841 month = target.parent().find('span').index(target); 28842 year = this.viewDate.getUTCFullYear(); 28843 this.viewDate.setUTCMonth(month); 28844 this._trigger('changeMonth', this.viewDate); 28845 if (this.o.minViewMode === 1){ 28846 this._setDate(UTCDate(year, month, day)); 28847 this.showMode(); 28848 } else { 28849 this.showMode(-1); 28850 } 28851 this.fill(); 28852 } 28853 28854 // Clicked on a year 28855 if (target.hasClass('year') 28856 || target.hasClass('decade') 28857 || target.hasClass('century')) { 28858 this.viewDate.setUTCDate(1); 28859 28860 day = 1;
28861 month = 0; 28862 year = parseInt(target.text(), 10)||0; 28863 this.viewDate.setUTCFullYear(year); 28864 28865 if (target.hasClass('year')){ 28866 this._trigger('changeYear', this.viewDate); 28867 if (this.o.minViewMode === 2){ 28868 this._setDate(UTCDate(year, month, day)); 28869 } 28870 } 28871 if (target.hasClass('decade')){ 28872 this._trigger('changeDecade', this.viewDate); 28873 if (this.o.minViewMode === 3){ 28874 this._setDate(UTCDate(year, month, day)); 28875 } 28876 } 28877 if (target.hasClass('century')){ 28878 this._trigger('changeCentury', this.viewDate); 28879 if (this.o.minViewMode === 4){ 28880 this._setDate(UTCDate(year, month, day)); 28881 } 28882 } 28883 28884 this.showMode(-1); 28885 this.fill(); 28886 } 28887 } 28888 28889 if (this.picker.is(':visible') && this._focused_from){ 28890 $(this._focused_from).focus(); 28891 } 28892 delete this._focused_from; 28893 }, 28894 28895 _toggle_multidate: function(date){ 28896 var ix = this.dates.contains(date); 28897 if (!date){ 28898 this.dates.clear(); 28899 } 28900 28901 if (ix !== -1){ 28902 if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){ 28903 this.dates.remove(ix); 28904 } 28905 } else if (this.o.multidate === false) { 28906 this.dates.clear(); 28907 this.dates.push(date); 28908 } 28909 else { 28910 this.dates.push(date); 28911 } 28912 28913 if (typeof this.o.multidate === 'number') 28914 while (this.dates.length > this.o.multidate) 28915 this.dates.remove(0); 28916 }, 28917 28918 _setDate: function(date, which){ 28919 if (!which || which === 'date') 28920 this._toggle_multidate(date && new Date(date)); 28921 if (!which || which === 'view') 28922 this.viewDate = date && new Date(date); 28923 28924 this.fill(); 28925 this.setValue(); 28926 if (!which || which !== 'view') { 28927 this._trigger('changeDate'); 28928 } 28929 var element; 28930 if (this.isInput){ 28931 element = this.element; 28932 } 28933 else if (this.component){ 28934 element = this.element.find('input'); 28935 } 28936 if (element){ 28937 element.change(); 28938 } 28939 if (this.o.autoclose && (!which || which === 'date')){ 28940 this.hide(); 28941 } 28942 }, 28943 28944 moveDay: function(date, dir){ 28945 var newDate = new Date(date); 28946 newDate.setUTCDate(date.getUTCDate() + dir); 28947 28948 return newDate; 28949 }, 28950 28951 moveWeek: function(date, dir){ 28952 return this.moveDay(date, dir * 7); 28953 }, 28954 28955 moveMonth: function(date, dir){ 28956 if (!isValidDate(date)) 28957 return this.o.defaultViewDate; 28958 if (!dir) 28959 return date; 28960 var new_date = new Date(date.valueOf()), 28961 day = new_date.getUTCDate(), 28962 month = new_date.getUTCMonth(), 28963 mag = Math.abs(dir), 28964 new_month, test; 28965 dir = dir > 0 ? 1 : -1; 28966 if (mag === 1){ 28967 test = dir === -1 28968 // If going back one month, make sure month is not current month 28969 // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) 28970 ? function(){ 28971 return new_date.getUTCMonth() === month; 28972 } 28973 // If going forward one month, make sure month is as expected 28974 // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) 28975 : function(){ 28976 return new_date.getUTCMonth() !== new_month; 28977 }; 28978 new_month = month + dir; 28979 new_date.setUTCMonth(new_month); 28980 // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 28981 if (new_month < 0 || new_month > 11) 28982 new_month = (new_month + 12) % 12; 28983 } 28984 else { 28985 // For magnitudes >1, move one month at a time... 28986 for (var i=0; i < mag; i++) 28987 // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... 28988 new_date = this.moveMonth(new_date, dir); 28989 // ...then reset the day, keeping it in the new month 28990 new_month = new_date.getUTCMonth(); 28991 new_date.setUTCDate(day); 28992 test = function(){ 28993 return new_month !== new_date.getUTCMonth(); 28994 }; 28995 } 28996 // Common date-resetting loop -- if date is beyond end of month, make it 28997 // end of month 28998 while (test()){ 28999 new_date.setUTCDate(--day); 29000 new_date.setUTCMonth(new_month); 29001 } 29002 return new_date; 29003 }, 29004 29005 moveYear: function(date, dir){ 29006 return this.moveMonth(date, dir*12); 29007 }, 29008 29009 moveAvailableDate: function(date, dir, fn){ 29010 do { 29011 date = this[fn](date, dir); 29012 29013 if (!this.dateWithinRange(date)) 29014 return false;
29015 29016 fn = 'moveDay'; 29017 } 29018 while (this.dateIsDisabled(date)); 29019 29020 return date; 29021 }, 29022 29023 weekOfDateIsDisabled: function(date){ 29024 return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1; 29025 }, 29026 29027 dateIsDisabled: function(date){ 29028 return ( 29029 this.weekOfDateIsDisabled(date) || 29030 $.grep(this.o.datesDisabled, function(d){ 29031 return isUTCEquals(date, d); 29032 }).length > 0 29033 ); 29034 }, 29035 29036 dateWithinRange: function(date){ 29037 return date >= this.o.startDate && date <= this.o.endDate; 29038 }, 29039 29040 keydown: function(e){ 29041 if (!this.picker.is(':visible')){ 29042 if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker 29043 this.show(); 29044 e.stopPropagation(); 29045 } 29046 return; 29047 } 29048 var dateChanged = false, 29049 dir, newViewDate, 29050 focusDate = this.focusDate || this.viewDate; 29051 switch (e.keyCode){ 29052 case 27: // escape 29053 if (this.focusDate){ 29054 this.focusDate = null; 29055 this.viewDate = this.dates.get(-1) || this.viewDate; 29056 this.fill(); 29057 } 29058 else 29059 this.hide(); 29060 e.preventDefault(); 29061 e.stopPropagation(); 29062 break; 29063 case 37: // left 29064 case 38: // up 29065 case 39: // right 29066 case 40: // down 29067 if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7) 29068 break; 29069 dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1; 29070 if (this.viewMode === 0) { 29071 if (e.ctrlKey){ 29072 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear'); 29073 29074 if (newViewDate) 29075 this._trigger('changeYear', this.viewDate); 29076 } 29077 else if (e.shiftKey){ 29078 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth'); 29079 29080 if (newViewDate) 29081 this._trigger('changeMonth', this.viewDate); 29082 } 29083 else if (e.keyCode === 37 || e.keyCode === 39){ 29084 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay'); 29085 } 29086 else if (!this.weekOfDateIsDisabled(focusDate)){ 29087 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek'); 29088 } 29089 } else if (this.viewMode === 1) { 29090 if (e.keyCode === 38 || e.keyCode === 40) { 29091 dir = dir * 4; 29092 } 29093 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth'); 29094 } else if (this.viewMode === 2) { 29095 if (e.keyCode === 38 || e.keyCode === 40) { 29096 dir = dir * 4; 29097 } 29098 newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear'); 29099 } 29100 if (newViewDate){ 29101 this.focusDate = this.viewDate = newViewDate; 29102 this.setValue(); 29103 this.fill(); 29104 e.preventDefault(); 29105 } 29106 break; 29107 case 13: // enter 29108 if (!this.o.forceParse) 29109 break; 29110 focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; 29111 if (this.o.keyboardNavigation) { 29112 this._toggle_multidate(focusDate); 29113 dateChanged = true; 29114 } 29115 this.focusDate = null; 29116 this.viewDate = this.dates.get(-1) || this.viewDate; 29117 this.setValue(); 29118 this.fill(); 29119 if (this.picker.is(':visible')){ 29120 e.preventDefault(); 29121 e.stopPropagation(); 29122 if (this.o.autoclose) 29123 this.hide(); 29124 } 29125 break; 29126 case 9: // tab 29127 this.focusDate = null; 29128 this.viewDate = this.dates.get(-1) || this.viewDate; 29129 this.fill(); 29130 this.hide(); 29131 break; 29132 } 29133 if (dateChanged){ 29134 if (this.dates.length) 29135 this._trigger('changeDate'); 29136 else 29137 this._trigger('clearDate'); 29138 var element; 29139 if (this.isInput){ 29140 element = this.element; 29141 } 29142 else if (this.component){ 29143 element = this.element.find('input'); 29144 } 29145 if (element){ 29146 element.change(); 29147 } 29148 } 29149 }, 29150 29151 showMode: function(dir){ 29152 if (dir){ 29153 this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir)); 29154 } 29155 this.picker 29156 .children('div') 29157 .hide() 29158 .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName) 29159 .show(); 29160 this.updateNavArrows(); 29161 } 29162 }; 29163 29164 var DateRangePicker = function(element, options){ 29165 $(element).data('datepicker', this); 29166 this.element = $(element); 29167 this.inputs = $.map(options.inputs, function(i){ 29168 return i.jquery ? i[0] : i; 29169 }); 29170 delete options.inputs; 29171 29172 datepickerPlugin.call($(this.inputs), options) 29173 .on('changeDate', $.proxy(this.dateUpdated, this)); 29174 29175 this.pickers = $.map(this.inputs, function(i){ 29176 return $(i).data('datepicker'); 29177 }); 29178 this.updateDates(); 29179 }; 29180 DateRangePicker.prototype = { 29181 updateDates: function(){ 29182 this.dates = $.map(this.pickers, function(i){ 29183 return i.getUTCDate(); 29184 }); 29185 this.updateRanges(); 29186 }, 29187 updateRanges: function(){ 29188 var range = $.map(this.dates, function(d){ 29189 return d.valueOf(); 29190 }); 29191 $.each(this.pickers, function(i, p){ 29192 p.setRange(range); 29193 }); 29194 }, 29195 dateUpdated: function(e){ 29196 // `this.updating` is a workaround for preventing infinite recursion 29197 // between `changeDate` triggering and `setUTCDate` calling. Until 29198 // there is a better mechanism. 29199 if (this.updating) 29200 return; 29201 this.updating = true; 29202 29203 var dp = $(e.target).data('datepicker'); 29204 29205 if (typeof(dp) === "undefined") { 29206 return; 29207 } 29208 29209 var new_date = dp.getUTCDate(), 29210 i = $.inArray(e.target, this.inputs),
29211 j = i - 1, 29212 k = i + 1, 29213 l = this.inputs.length; 29214 if (i === -1) 29215 return; 29216 29217 $.each(this.pickers, function(i, p){ 29218 if (!p.getUTCDate()) 29219 p.setUTCDate(new_date); 29220 }); 29221 29222 if (new_date < this.dates[j]){ 29223 // Date being moved earlier/left 29224 while (j >= 0 && new_date < this.dates[j]){ 29225 this.pickers[j--].setUTCDate(new_date); 29226 } 29227 } 29228 else if (new_date > this.dates[k]){ 29229 // Date being moved later/right 29230 while (k < l && new_date > this.dates[k]){ 29231 this.pickers[k++].setUTCDate(new_date); 29232 } 29233 } 29234 this.updateDates(); 29235 29236 delete this.updating; 29237 }, 29238 remove: function(){ 29239 $.map(this.pickers, function(p){ p.remove(); }); 29240 delete this.element.data().datepicker; 29241 } 29242 }; 29243 29244 function opts_from_el(el, prefix){ 29245 // Derive options from element data-attrs 29246 var data = $(el).data(), 29247 out = {}, inkey, 29248 replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'); 29249 prefix = new RegExp('^' + prefix.toLowerCase()); 29250 function re_lower(_,a){ 29251 return a.toLowerCase(); 29252 } 29253 for (var key in data) 29254 if (prefix.test(key)){ 29255 inkey = key.replace(replace, re_lower); 29256 out[inkey] = data[key]; 29257 } 29258 return out; 29259 } 29260 29261 function opts_from_locale(lang){ 29262 // Derive options from locale plugins 29263 var out = {}; 29264 // Check if "de-DE" style date is available, if not language should 29265 // fallback to 2 letter code eg "de" 29266 if (!dates[lang]){ 29267 lang = lang.split('-')[0]; 29268 if (!dates[lang]) 29269 return; 29270 } 29271 var d = dates[lang]; 29272 $.each(locale_opts, function(i,k){ 29273 if (k in d) 29274 out[k] = d[k]; 29275 }); 29276 return out; 29277 } 29278 29279 var old = $.fn.datepicker; 29280 var datepickerPlugin = function(option){ 29281 var args = Array.apply(null, arguments); 29282 args.shift(); 29283 var internal_return; 29284 this.each(function(){ 29285 var $this = $(this), 29286 data = $this.data('datepicker'), 29287 options = typeof option === 'object' && option; 29288 if (!data){ 29289 var elopts = opts_from_el(this, 'date'), 29290 // Preliminary otions 29291 xopts = $.extend({}, defaults, elopts, options), 29292 locopts = opts_from_locale(xopts.language), 29293 // Options priority: js args, data-attrs, locales, defaults 29294 opts = $.extend({}, defaults, locopts, elopts, options); 29295 if ($this.hasClass('input-daterange') || opts.inputs){ 29296 $.extend(opts, { 29297 inputs: opts.inputs || $this.find('input').toArray() 29298 }); 29299 data = new DateRangePicker(this, opts); 29300 } 29301 else { 29302 data = new Datepicker(this, opts); 29303 } 29304 $this.data('datepicker', data); 29305 } 29306 if (typeof option === 'string' && typeof data[option] === 'function'){ 29307 internal_return = data[option].apply(data, args); 29308 } 29309 }); 29310 29311 if ( 29312 internal_return === undefined || 29313 internal_return instanceof Datepicker || 29314 internal_return instanceof DateRangePicker 29315 ) 29316 return this; 29317 29318 if (this.length > 1) 29319 throw new Error('Using only allowed for the collection of a single element (' + option + ' function)'); 29320 else 29321 return internal_return; 29322 }; 29323 $.fn.datepicker = datepickerPlugin; 29324 29325 var defaults = $.fn.datepicker.defaults = { 29326 assumeNearbyYear: false, 29327 autoclose: false, 29328 beforeShowDay: $.noop, 29329 beforeShowMonth: $.noop, 29330 beforeShowYear: $.noop, 29331 beforeShowDecade: $.noop, 29332 beforeShowCentury: $.noop, 29333 calendarWeeks: false, 29334 clearBtn: false, 29335 toggleActive: false, 29336 daysOfWeekDisabled: [], 29337 daysOfWeekHighlighted: [], 29338 datesDisabled: [], 29339 endDate: Infinity, 29340 forceParse: true, 29341 format: 'mm/dd/yyyy', 29342 keyboardNavigation: true, 29343 language: 'en', 29344 minViewMode: 0, 29345 maxViewMode: 4, 29346 multidate: false, 29347 multidateSeparator: ',', 29348 orientation: "auto", 29349 rtl: false, 29350 startDate: -Infinity, 29351 startView: 0, 29352 todayBtn: false, 29353 todayHighlight: false, 29354 weekStart: 0, 29355 disableTouchKeyboard: false, 29356 enableOnReadonly: true, 29357 showOnFocus: true, 29358 zIndexOffset: 10, 29359 container: 'body', 29360 immediateUpdates: false, 29361 title: '', 29362 templates: { 29363 leftArrow: '«', 29364 rightArrow: '»' 29365 } 29366 }; 29367 var locale_opts = $.fn.datepicker.locale_opts = [ 29368 'format', 29369 'rtl', 29370 'weekStart' 29371 ]; 29372 $.fn.datepicker.Constructor = Datepicker; 29373 var dates = $.fn.datepicker.dates = { 29374 en: { 29375 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 29376 daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 29377 daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], 29378 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
29378November", "December"], 29379 monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 29380 today: "Today", 29381 clear: "Clear", 29382 titleFormat: "MM yyyy" 29383 } 29384 }; 29385 29386 var DPGlobal = { 29387 modes: [ 29388 { 29389 clsName: 'days', 29390 navFnc: 'Month', 29391 navStep: 1 29392 }, 29393 { 29394 clsName: 'months', 29395 navFnc: 'FullYear', 29396 navStep: 1 29397 }, 29398 { 29399 clsName: 'years', 29400 navFnc: 'FullYear', 29401 navStep: 10 29402 }, 29403 { 29404 clsName: 'decades', 29405 navFnc: 'FullDecade', 29406 navStep: 100 29407 }, 29408 { 29409 clsName: 'centuries', 29410 navFnc: 'FullCentury', 29411 navStep: 1000 29412 }], 29413 isLeapYear: function(year){ 29414 return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 29415 }, 29416 getDaysInMonth: function(year, month){ 29417 return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; 29418 }, 29419 validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, 29420 nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g, 29421 parseFormat: function(format){ 29422 if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function') 29423 return format; 29424 // IE treats \0 as a string end in inputs (truncating the value), 29425 // so it's a bad format delimiter, anyway 29426 var separators = format.replace(this.validParts, '\0').split('\0'), 29427 parts = format.match(this.validParts); 29428 if (!separators || !separators.length || !parts || parts.length === 0){ 29429 throw new Error("Invalid date format."); 29430 } 29431 return {separators: separators, parts: parts}; 29432 }, 29433 parseDate: function(date, format, language, assumeNearby){ 29434 if (!date) 29435 return undefined; 29436 if (date instanceof Date) 29437 return date; 29438 if (typeof format === 'string') 29439 format = DPGlobal.parseFormat(format); 29440 if (format.toValue) 29441 return format.toValue(date, format, language); 29442 var part_re = /([\-+]\d+)([dmwy])/, 29443 parts = date.match(/([\-+]\d+)([dmwy])/g), 29444 fn_map = { 29445 d: 'moveDay', 29446 m: 'moveMonth', 29447 w: 'moveWeek', 29448 y: 'moveYear' 29449 }, 29450 dateAliases = { 29451 yesterday: '-1d', 29452 today: '+0d', 29453 tomorrow: '+1d' 29454 }, 29455 part, dir, i, fn; 29456 if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ 29457 date = new Date(); 29458 for (i=0; i < parts.length; i++){ 29459 part = part_re.exec(parts[i]); 29460 dir = parseInt(part[1]); 29461 fn = fn_map[part[2]]; 29462 date = Datepicker.prototype[fn](date, dir); 29463 } 29464 return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); 29465 } 29466 29467 if (typeof dateAliases[date] !== 'undefined') { 29468 date = dateAliases[date]; 29469 parts = date.match(/([\-+]\d+)([dmwy])/g); 29470 29471 if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ 29472 date = new Date(); 29473 for (i=0; i < parts.length; i++){ 29474 part = part_re.exec(parts[i]); 29475 dir = parseInt(part[1]); 29476 fn = fn_map[part[2]]; 29477 date = Datepicker.prototype[fn](date, dir); 29478 } 29479 29480 return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); 29481 } 29482 } 29483 29484 parts = date && date.match(this.nonpunctuation) || []; 29485 date = new Date(); 29486 29487 function applyNearbyYear(year, threshold){ 29488 if (threshold === true) 29489 threshold = 10; 29490 29491 // if year is 2 digits or less, than the user most likely is trying to get a recent century 29492 if (year < 100){ 29493 year += 2000; 29494 // if the new year is more than threshold years in advance, use last century 29495 if (year > ((new Date()).getFullYear()+threshold)){ 29496 year -= 100; 29497 } 29498 } 29499 29500 return year; 29501 } 29502 29503 var parsed = {}, 29504 setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], 29505 setters_map = { 29506 yyyy: function(d,v){ 29507 return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v); 29508 }, 29509 yy: function(d,v){ 29510 return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v); 29511 }, 29512 m: function(d,v){ 29513 if (isNaN(d)) 29514 return d; 29515 v -= 1; 29516 while (v < 0) v += 12; 29517 v %= 12; 29518 d.setUTCMonth(v); 29519 while (d.getUTCMonth() !== v) 29520 d.setUTCDate(d.getUTCDate()-1); 29521 return d; 29522 }, 29523 d: function(d,v){ 29524 return d.setUTCDate(v); 29525 } 29526 }, 29527 val, filtered; 29528 setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; 29529 setters_map['dd'] = setters_map['d']; 29530 date = UTCToday(); 29531 var fparts = format.parts.slice(); 29532 // Remove noop parts 29533 if (parts.length !== fparts.length){ 29534 fparts = $(fparts).filter(function(i,p){ 29535 return $.inArray(p, setters_order) !== -1; 29536 }).toArray(); 29537 } 29538 // Process remainder 29539 function match_part(){ 29540 var m = this.slice(0, parts[i].length), 29541 p = parts[i].slice(0, m.length); 29542 return m.toLowerCase() === p.toLowerCase(); 29543 } 29544 if (parts.length === fparts.length){ 29545 var cnt; 29546 for (i=0, cnt = fparts.length; i < cnt; i++){ 29547 val = parseInt(parts[i], 10); 29548 part = fparts[i]; 29549 if (isNaN(val)){ 29550 switch (part){ 29551 case 'MM': 29552 filtered = $(dates[language].months).filter(match_part); 29553 val = $.inArray(filtered[0], dates[language].months) + 1; 29554 break; 29555 case 'M': 29556 filtered = $(dates[language].monthsShort).filter(match_part); 29557 val = $.inArray(filtered[0], dates[language].monthsShort) + 1; 29558 break; 29559 } 29560 } 29561 parsed[part] = val; 29562 } 29563 var _date, s; 29564 for (i=0; i < setters_order.length; i++){ 29565 s = setters_order[i]; 29566 if (s in parsed && !isNaN(parsed[s])){ 29567 _date = new Date(date); 29568 setters_map[s](_date, parsed[s]); 29569 if (!isNaN(_date)) 29570 date = _date; 29571 } 29572 } 29573 } 29574 return date; 29575 }, 29576 formatDate: function(date, format, language){ 29577 if (!date) 29578 return ''; 29579 if (typeof format === 'string') 29580 format = DPGlobal.parseFormat(format); 29581 if (format.toDisplay) 29582 return format.toDisplay(date, format, language); 29583 var val = { 29584 d: date.getUTCDate(), 29585 D: dates[language].daysShort[date.getUTCDay()], 29586 DD: dates[language].days[date.getUTCDay()], 29587 m: date.getUTCMonth() + 1, 29588 M: dates[language].monthsShort[date.getUTCMonth()], 29589 MM: dates[language].months[date.getUTCMonth()], 29590 yy: date.getUTCFullYear().toString().substring(2), 29591 yyyy: date.getUTCFullYear() 29592 }; 29593 val.dd = (val.d < 10 ? '0' : '') + val.d; 29594 val.mm = (val.m < 10 ? '0' : '') + val.m; 29595 date = []; 29596 var seps = $.extend([], format.separators); 29597 for (var i=0, cnt = format.parts.length; i <= cnt; i++){ 29598 if (seps.length) 29599 date.push(seps.shift()); 29600 date.push(val[format.parts[i]]); 29601 } 29602 return date.join(''); 29603 }, 29604 headTemplate: '<thead>'+ 29605 '<tr>'+ 29606 '<th colspan="7" class="datepicker-title"></th>'+ 29607 '</tr>'+ 29608 '<tr>'+ 29609 '<th class="prev">«</th>'+ 29610 '<th colspan="5" class="datepicker-switch"></th>'+ 29611 '<th class="next">»</th>'+ 29612 '</tr>'+ 29613 '</thead>', 29614 contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', 29615 footTemplate: '<tfoot>'+ 29616 '<tr>'+ 29617 '<th colspan="7" class="today"></th>'+ 29618 '</tr>'+ 29619 '<tr>'+ 29620 '<th colspan="7" class="clear"></th>'+ 29621 '</tr>'+ 29622 '</tfoot>' 29623 }; 29624 DPGlobal.template = '<div class="datepicker">'+ 29625 '<div class="datepicker-days">'+ 29626 '<table class=" table-condensed">'+ 29627 DPGlobal.headTemplate+ 29628 '<tbody></tbody>'+ 29629 DPGlobal.footTemplate+ 29630 '</table>'+ 29631 '</div>'+ 29632 '<div class="datepicker-months">'+ 29633 '<table class="table-condensed">'+ 29634 DPGlobal.headTemplate+ 29635 DPGlobal.contTemplate+ 29636 DPGlobal.footTemplate+ 29637 '</table>'+ 29638 '</div>'+ 29639 '<div class="datepicker-years">'+ 29640 '<table class="table-condensed">'+ 29641 DPGlobal.headTemplate+ 29642 DPGlobal.contTemplate+ 29643 DPGlobal.footTemplate+ 29644 '</table>'+ 29645 '</div>'+ 29646 '<div class="datepicker-decades">'+ 29647 '<table class="table-condensed">'+ 29648 DPGlobal.headTemplate+ 29649 DPGlobal.contTemplate+ 29650 DPGlobal.footTemplate+ 29651 '</table>'+ 29652 '</div>'+ 29653 '<div class="datepicker-centuries">'+ 29654 '<table class="table-condensed">'+ 29655 DPGlobal.headTemplate+ 29656 DPGlobal.contTemplate+ 29657 DPGlobal.footTemplate+ 29658 '</table>'+ 29659 '</div>'+ 29660 '</div>'; 29661 29662 $.fn.datepicker.DPGlobal = DPGlobal; 29663 29664 29665 /* DATEPICKER NO CONFLICT 29666 * =================== */ 29667 29668 $.fn.datepicker.noConflict = function(){ 29669 $.fn.datepicker = old; 29670 return this; 29671 }; 29672 29673 /* DATEPICKER VERSION 29674 * =================== */ 29675 $.fn.datepicker.version = '1.7.0-dev'; 29676 29677 /* DATEPICKER DATA-API 29678 * ================== */ 29679 29680 $(document).on(
29681 'focus.datepicker.data-api click.datepicker.data-api', 29682 '[data-provide="datepicker"]', 29683 function(e){ 29684 var $this = $(this); 29685 if ($this.data('datepicker')) 29686 return; 29687 e.preventDefault(); 29688 // component click requires us to explicitly show it 29689 datepickerPlugin.call($this, 'show'); 29690 } 29691 ); 29692 $(function(){ 29693 datepickerPlugin.call($('[data-provide="datepicker-inline"]')); 29694 }); 29695 29696})); 29697 29698;$(function(){ 29699 29700 if($.fn.datepicker){ 29701 $.fn.datepicker.dates['fi'] = { 29702 days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai", "sunnuntai"], 29703 daysShort: ["sun", "maa", "tii", "kes", "tor", "per", "lau", "sun"], 29704 daysMin: ["su", "ma", "ti", "ke", "to", "pe", "la", "su"], 29705 months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], 29706 monthsShort: ["tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou"], 29707 today: "tänään", 29708 }; 29709 29710 $.fn.datepicker.defaults.format = "dd.mm.yyyy"; 29711 $.fn.datepicker.defaults.language = 'fi-FI'; 29712 $.fn.datepicker.defaults.todayHighlight = true; 29713 $.fn.datepicker.defaults.weekStart = 1; 29714 $.fn.datepicker.defaults.startDate = '-36m'; 29715 } 29716});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.