From 02563fed9f43d74cb195d3271ef46c409cc15328 Mon Sep 17 00:00:00 2001 From: zino Date: Wed, 20 Jan 2021 12:30:51 +0100 Subject: [PATCH] first migration --- seatmap-client/close.html | 54 + seatmap-client/img/30.svg | 1 + seatmap-client/img/FhHRx.gif | Bin 0 -> 2608 bytes seatmap-client/img/Tickets-medium.png | Bin 0 -> 9536 bytes seatmap-client/img/Tickets-small.png | Bin 0 -> 8343 bytes seatmap-client/img/favicon.png | Bin 0 -> 428 bytes .../img/iconfinder_basics-22_296812.png | Bin 0 -> 971 bytes seatmap-client/img/iconfinder_tick_216457.png | Bin 0 -> 1062 bytes seatmap-client/index.html | 102 + seatmap-client/offline/MapTicketSales.xml | 111 + .../offline/MapTicketSales_Parkett.xml | 252 ++ .../offline/MapTicketSales_Rang.xml | 139 + seatmap-client/seatmap.1.js | 2417 +++++++++++++++++ seatmap-client/seatmap.js | 1912 +++++++++++++ seatmap-client/seatmap090120.js | 2257 +++++++++++++++ seatmap-client/seatmap11_18_19.js | 2065 ++++++++++++++ seatmap-client/seatmap11_22_19.js | 2162 +++++++++++++++ seatmap-client/seatmap12_12.js | 2163 +++++++++++++++ seatmap-client/style.css | 486 ++++ seatmap-client/venue.css | 9 + seatmap-inject/seatmap-inject-np.js | 151 + seatmap-server/seatmap-server.pl | 619 +++++ 22 files changed, 14900 insertions(+) create mode 100644 seatmap-client/close.html create mode 100644 seatmap-client/img/30.svg create mode 100644 seatmap-client/img/FhHRx.gif create mode 100644 seatmap-client/img/Tickets-medium.png create mode 100644 seatmap-client/img/Tickets-small.png create mode 100644 seatmap-client/img/favicon.png create mode 100644 seatmap-client/img/iconfinder_basics-22_296812.png create mode 100644 seatmap-client/img/iconfinder_tick_216457.png create mode 100644 seatmap-client/index.html create mode 100644 seatmap-client/offline/MapTicketSales.xml create mode 100644 seatmap-client/offline/MapTicketSales_Parkett.xml create mode 100644 seatmap-client/offline/MapTicketSales_Rang.xml create mode 100644 seatmap-client/seatmap.1.js create mode 100644 seatmap-client/seatmap.js create mode 100644 seatmap-client/seatmap090120.js create mode 100644 seatmap-client/seatmap11_18_19.js create mode 100644 seatmap-client/seatmap11_22_19.js create mode 100644 seatmap-client/seatmap12_12.js create mode 100644 seatmap-client/style.css create mode 100644 seatmap-client/venue.css create mode 100644 seatmap-inject/seatmap-inject-np.js create mode 100755 seatmap-server/seatmap-server.pl diff --git a/seatmap-client/close.html b/seatmap-client/close.html new file mode 100644 index 0000000..1954c12 --- /dev/null +++ b/seatmap-client/close.html @@ -0,0 +1,54 @@ + + + + + + + SeatmapClose + + + + + + +
+ + Buchung abgebrochen. Sie können dieses Fenster nun schließen. +
+ + + diff --git a/seatmap-client/img/30.svg b/seatmap-client/img/30.svg new file mode 100644 index 0000000..0a6c5cb --- /dev/null +++ b/seatmap-client/img/30.svg @@ -0,0 +1 @@ + diff --git a/seatmap-client/img/FhHRx.gif b/seatmap-client/img/FhHRx.gif new file mode 100644 index 0000000000000000000000000000000000000000..574b1d4a161707c6c7f0ba9d2bc531bead4a3028 GIT binary patch literal 2608 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

dUlAJ*pq^wPu4+>? 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 literal 0 HcmV?d00001 diff --git a/seatmap-client/img/favicon.png b/seatmap-client/img/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7c0420811a35bdd67529465283158c764adcdc GIT binary patch literal 428 zcmV;d0aN~oP)mY_HQ5)$OJNhu?r-J z(LjjjLl4+MSp}L1$N7iodL#mIanVCLMWiC#VXvyYaWUM?KSn3X{1C1{wnd~OKPw_R z;2`#waw8C6-Kr(xBa}xW(6kj*)nFNR!w@*?ZkFU?`MLfE%mUuf1dPZTP*v3yfC8#| z32eO@;{!W@-^+`&OM4nJ za0`PlBg3pY5)2H?xt=bLAr*7p-r3m~<0|3)@x8*t2oIibH!2zhl?)&7Zl3v;v4Tmi zvx8kh(XGQ=q0r$-TJz1^30*C<>WYqP2gHrbzUtilUUqktmHo?SSO3oaA+P8;Nd+BU za*951w4-9f7w5EBl@HE#+|c+tK{JOjp7DC)`okP~Uu8Z#@BRNg$R%f5-Gvnm=6Qd1 zyml*?o!)4l_p?4u_wS00xeV_m59Ssfuh&+3r}cM(<{joe`7Hk{mo0zH-}4~epLzfH zvOfnM9|Rp2EUEqDxLz>k!w>VXVh4i{GOf}a`jT}js58|2N%oLSGlK29khI)-oIbYy}>^XXpa7axCfUdT?(!}o*rz~wD~~4 z-2OF-52UjySv>yuJo&ER9Jaa-KRy?U{HWm-toS22+o~y8uKr)2ugF2o2i5)Y?a2qk zmEAsc9AAI_<3yzji67@4Uw>&)P}<62Q^)MbaD7_G1H}i?{rB7cx;^+PT_XSCshpC< z%a6CWMzg3l=G)ZW7IXd3bo~ACzjx-WjQmph=h$1Io8BMkp85E{tl)BQd!Ngv&u-$0 z@9JRZ+V3xXO1Jn=DobsI$>}1dirXBww%yh_efNO1+l6J^Z*u1(GFM#ZxV7niq?mHX ziA}R@cDh~`aSNClYF=5CJWaD_0ax8j`Bq|?K~v55W*Bgun3Q>0Q(^+p1fZq>3qF-3Z_Pa;dU;dIAkcV?t=DbKia z2dG@QOtU9JsMz}70gh`4@0xvf${rSRGw6z9n+Y~4L3Jyy(bF=XV2Oi4=K`JsZ91ga zD)`3xZL^QthNfHn_9uLAEH!A7-MZ~qD$DN+ucX4k3UV(0g0fs(?16@I?iQKre&O^- zb}-BB!fS4nJ za0`PlBg3pY5)2H?Cp=voLn`LHy|a6DOsL55kMECk92C)F6G~28D$(QkzrjPKX5zV1 z?y6b2&zV`0mEC5~aAA>m)X~YwF^!cnWONiURA^Gr%Bq>9#JN+h`|*K-oyO(oEUVWR zr#<`Kcr`Zd{nqbN@1B-F=kb`N;)w-q*|hD;UdE?4nPgb}7}6WN9a#VH*0Am2dGj*2 zoU2s+1Mk^^1FV%F@E9@|7;fa>`bEQVdVJvVqf#4IH@xqZZqUDEHS^H_ zsI%Wp3W6WJu9y08>s1E(2l2x9|F|qBT2iu#Oo==>|ET_F= z-$MWXvY>j2MQ0c83(Medv$MSk4#ACm)h9S=`AY9RzEst1#C|80W0CXx`779CU*9?S zXaDELZ4at=YO6lWJ>~yhaoARd_r~EA$zMK&tcCCQRJJE9b)LWPt?IW2&n25)`2Ujl zai(Cxjl=63%+uD$%l=x!xP80L?5Q6FJ~A8Ra=0CM`JnXv+cKNe@8ycv5^Pu&cW#yE zj5~iJop1L^>4uYv245s6Y<|LjaPz@ziC-okY<4mS1pY4+`}xaX%yyw_x$Xz)pUwiI zZFagY{~f1A@{8Ebp88SiZ+zT!qc1Ntel^dSnEE34#3H`Nh5nA+W-QM?X2*3$FHx+} ze8CfTPl@N?d5K>wUH>+?0hN0iTmjnVX>tTank@m6FHZ`zCGg%5zq?{t_1rr42QD?; zw|wHA6J8iA)bcbgJbxesXzqE3RNjNZk-RH+Dj$ja7kd+1c>cA9t~PdI|hrlQYE|-mlnSyX94JFqT|& + + + + + + + Saalplan-Buchung | Tickets.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ +

Displaybreite zu gering: Bitte versuchen Sie, Ihren Bildschirm zu drehen, sofern Sie ein mobiles Endgerät benutzen.

Cannot display seat map: Screen width too small. Please try to rotate your screen if you are using a mobile device.

+

Internet Explorer ist veraltet und wird nicht unterstützt. Bitte benutzen Sie einen anderen Browser.

Internet Explorer is outdated and not supported. Please use another browser.

+ + + + + + + + diff --git a/seatmap-client/offline/MapTicketSales.xml b/seatmap-client/offline/MapTicketSales.xml new file mode 100644 index 0000000..1a47eb4 --- /dev/null +++ b/seatmap-client/offline/MapTicketSales.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + +
+ + + + +
+
+ + + + +
+
+ + + +
+
+ + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/seatmap-client/offline/MapTicketSales_Parkett.xml b/seatmap-client/offline/MapTicketSales_Parkett.xml new file mode 100644 index 0000000..a5814e4 --- /dev/null +++ b/seatmap-client/offline/MapTicketSales_Parkett.xml @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + diff --git a/seatmap-client/offline/MapTicketSales_Rang.xml b/seatmap-client/offline/MapTicketSales_Rang.xml new file mode 100644 index 0000000..01cdce9 --- /dev/null +++ b/seatmap-client/offline/MapTicketSales_Rang.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + diff --git a/seatmap-client/seatmap.1.js b/seatmap-client/seatmap.1.js new file mode 100644 index 0000000..17cab40 --- /dev/null +++ b/seatmap-client/seatmap.1.js @@ -0,0 +1,2417 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var extra_param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +const branch = 'seatmap_testing'; // seatmap_testing or seatmap_main +// var config = { +// "TAD": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "LEFT_NAMING": false, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 0.8vw; \ +// width: 0.8vw; \ +// line-height: 1.5vw; \ +// } \ +// @media (min-width: 628px) and (max-width: 766px) { \ +// div.seatCharts-cell { \ +// height: 0.794vw; \ +// width: 0.794vw; \ +// } \ +// } \ +// @media (min-width: 498px) and (max-width: 627px) { \ +// div.seatCharts-cell { \ +// height: 0.786vw; \ +// width: 0.786vw; \ +// } \ +// } \ +// @media (min-width: 477px) and (max-width: 497px) { \ +// div.seatCharts-cell { \ +// height: 0.78vw; \ +// width: 0.78vw; \ +// } \ +// } \ +// @media (min-width: 400px) and (max-width: 476px) { \ +// div.seatCharts-cell { \ +// height: 0.77vw; \ +// width: 0.77vw; \ +// } \ +// } \ +// ', +// }, +// "KLEINER": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CUSTOM_PRICESCALES_COLOR": { +// 1824661: "228B22", +// 2542349: "8B4513", +// 2542350:"4682B4", +// }, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.43vw; \ +// width: 1.43vw; \ +// line-height: 1.5vw; \ +// } \ +// @media (min-width: 400px) and (max-width: 540px) { \ +// div.seatCharts-cell { \ +// height: 1.398vw; \ +// width: 1.398vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "INT_TH_3": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CUSTOM_PRICESCALES_COLOR": { +// 5273153: "228B22", +// }, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 2.6vw; \ +// width: 2.6vw; \ +// line-height: 2.5vw; \ +// max-width: 30px; \ +// max-height: 30px; \ +// } \ +// @media (min-width: 400px) and (max-width: 700px) { \ +// div.seatCharts-cell { \ +// height: 2.52vw; \ +// width: 2.52vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "GRO_SAAL": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 0.9vw; \ +// width: 0.9vw; \ +// line-height: 1.4vw; \ +// } \ +// ', +// }, +// "STADTHAL": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "BOTTOM", +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.85vw; \ +// width: 1.85vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 400px) and (max-width: 480px) { \ +// div.seatCharts-cell { \ +// height: 1.81vw; \ +// width: 1.81vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "STUDIONU": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "BOTTOM", +// "CUSTOM_PRICESCALES_COLOR": { +// 2447833: "B9DEA0", +// }, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.85vw; \ +// width: 1.85vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 400px) and (max-width: 480px) { \ +// div.seatCharts-cell { \ +// height: 1.81vw; \ +// width: 1.81vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "GR.SAAL": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "49%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "BOTTOM", +// "CUSTOM_PRICESCALES_COLOR": { +// 152965: "FFFF00", +// 152966: "FF0000", +// 152967: "74DF00", +// 152968: "0080FF", +// }, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.19vw; \ +// width: 1.19vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 445px) and (max-width: 555px) { \ +// div.seatCharts-cell { \ +// height: 1.17vw; \ +// width: 1.17vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// @media (min-width: 400px) and (max-width: 444px) { \ +// div.seatCharts-cell { \ +// height: 1.15vw; \ +// width: 1.15vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "THEATHOF": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "50%", +// "PADDING-LEFT-STAGE": "50%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "BOTTOM", +// "CUSTOM_PRICESCALES_COLOR": { +// 2446505: "FFFF00", +// 2446506: "FF0000", +// 2446507: "74DF00", +// 2446508: "0080FF", +// }, +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.2vw; \ +// width: 1.2vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 530px) and (max-width:768px) { \ +// div.seatCharts-cell { \ +// height: 1.24vw; \ +// width: 1.24vw; \ +// } \ +// } \ +// @media (min-width: 405px) and (max-width:529px) { \ +// div.seatCharts-cell { \ +// height: 1.215vw; \ +// width: 1.215vw; \ +// } \ +// } \ +// @media (min-width: 400px) and (max-width: 768px) { \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "THEATER": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "60%", +// "PADDING-LEFT-STAGE": "47%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.54vw; \ +// width: 1.54vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 400px) and (max-width:530px) { \ +// div.seatCharts-cell { \ +// height: 1.505vw; \ +// width: 1.505vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "NEUES TH": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "50%", +// "PADDING-LEFT-STAGE": "50%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": '\ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 3.47vw !important; \ +// width: 3.47vw !important; \ +// max-width: 27px; \ +// max-height: 27px; \ +// line-height: 1.4vw; \ +// } \ +// @media all and (-ms-high-contrast: none), \ +// (-ms-high-contrast: active) { \ +// div.seatCharts-cell { \ +// height: 3.55vw !important; \ +// width: 3.55vw !important; \ +// } \ +// } \ +// ', +// }, +// "SAAL KKM": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "47%", +// "TONPULT": "

Tonpult

", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": ' \ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.3vw; \ +// width: 1.3vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 411px) and (max-width:539px) { \ +// div.seatCharts-cell { \ +// height: 1.275vw; \ +// width: 1.275vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// @media (min-width: 400px) and (max-width:410px) { \ +// div.seatCharts-cell { \ +// height: 1.25vw; \ +// width: 1.25vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// "GSP KKM": { +// "FRONT-INDICATOR-WIDTH": "90%", +// "PADDING-LEFT": "47%", +// "PADDING-LEFT-STAGE": "47%", +// "TONPULT": "

Tonpult

", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": ' \ +// .booking-details p,li { \ +// font-size: 1vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 1.39vw; \ +// width: 1.39vw; \ +// line-height: 1.4vw; \ +// } \ +// @media (min-width: 400px) and (max-width:504px) { \ +// div.seatCharts-cell { \ +// height: 1.36vw; \ +// width: 1.36vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// ', +// }, +// 'KOMÖDIE': { +// "PADDING-LEFT": "47%", +// "MAX_TICKETS_PER_USER": 9, +// "BUEHNE": "TOP", +// "CSS": ' \ +// .booking-details p,li { \ +// font-size: 1.0vw; \ +// } \ +// .seatCharts-container h4, div.seatCharts-cell { \ +// font-size: 1.0vw; \ +// } \ +// div.seatCharts-cell { \ +// height: 2.72vw; \ +// width: 2.72vw; \ +// line-height: 1.4vw; \ +// max-height: 25px; \ +// max-width: 25px; \ +// } \ +// @media (min-width: 400px) and (max-width:405px) { \ +// div.seatCharts-cell { \ +// height: 2.7vw; \ +// width: 2.7vw; \ +// } \ +// .glyphicon { \ +// display: none; \ +// } \ +// } \ +// @media (min-width: 406px) and (max-width:768px) { \ +// div.seatCharts-cell { \ +// height: 2.72vw; \ +// width: 2.72vw; \ +// } \ +// } \ +// ', +// }, +// "THEATER AM DOM": { +// "AGENCY": "TADK", +// "BUYER_TYPES": { +// "Z1": "Vollzahler", +// } +// }, +// "GROßER SAAL": { +// "AGENCY": "GMB1", +// "BUYER_TYPES": { +// "01": "Vollzahler", +// } +// }, +// "KLEINER SAAL": { +// "AGENCY": "GMB1", +// "BUYER_TYPES": { +// "01": "Vollzahler", +// } +// }, +// "INTIMES THEATER BESTUHLT": { +// "AGENCY": "GMB1", +// "BUYER_TYPES": { +// "01": "Vollzahler", +// } +// }, +// "THEATER HOF": { +// "AGENCY": "THOF", +// "BUYER_TYPES": { +// "I1": "Vollzahler", +// "I3": "Behinderte mit Ausweis", +// "I2": "Schüler", +// "IE": "Erwachsener", +// "IK": "Kind", +// } +// }, +// "STUDIO NUMMERIERT": { +// "AGENCY": "THOF", +// "BUYER_TYPES": { +// "I1": "Vollzahler", +// "I3": "Behinderte mit Ausweis", +// "I2": "Schüler", +// "IE": "Erwachsener", +// "IK": "Kind", +// } +// }, +// "KOMÖDIE BRAUNSCHWEIG": { +// "AGENCY": "KOMB", +// "BUYER_TYPES": { +// "IV": "Vollzahler", +// "IE": "Ermäßigt", +// "IG": "Gutschein", +// "ME": "Vollzahler", +// "MK": "Ermäßigt", +// "NI": "Ermäßigt", +// "NN": "Vollzahler", +// "SI": "Vollzahler", +// } +// }, +// "THEATER IM RATHAUS": { +// "AGENCY": "TIRE", +// "BUYER_TYPES": { +// "I1": "Vollzahler", +// "I2": "Ermäßigt", +// "FR": "Freitag_13", +// "11": "10% Ermäßigung", +// } +// }, +// "NEUES THEATER HANNOVER": { +// "AGENCY": "NTHH", +// "BUYER_TYPES": { +// "WW": "Vollzahler", +// } +// }, +// "STAATSOPERETTE DRESDEN": { +// "AGENCY": "SOPD", +// "BUYER_TYPES": { +// "97": "Vollzahler", +// "A0": "Ermäßigt", +// "A5": "Online-Aktion", +// "95": "Aktionspreis", +// "09": "Schüler", +// "A6": "Kind bis 18 J.", +// "86": "Buch", +// "85": "CD", +// "00": "Tagespreis", +// "03": "Tagespreis ermäßigt", +// "98": "Aktionspreis", +// "31": "Studenten/Azubis bis 27 J.", +// "23": "Andere Gäste", +// "A7": "ab 80% GdB/Begleitung", +// } +// }, +// "SEATMAP-SERVER": { +// "ROOT_URL": "https://zinomedia.de/seatmap_main/seatmap-server/seatmap-server.pl", +// }, +// "CORS-ANYWHERE": { +// "ROOT_URL": "https://cors.zinomedia.de/", +// }, +// "DEBUG": true, +// "SEATMAP_VERSION": "0.9.7", +// "CURRENCY_SYMBOL": "€", +// }; + +// if (branch === 'seatmap_testing') { +// config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; +// config["SEATMAP-SERVER"]["ROOT_URL"] = "https://seatmap-testing.zinomedia.de/seatmap-server/seatmap-server.pl"; +// } +var config = { + 'DEBUG': 1, + 'SEATMAP-SERVER': { }, +}; + if (branch === 'seatmap_testing') { + //config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; + config['SEATMAP-SERVER']['ROOT_URL'] = 'https://seatmap-testing.zinomedia.de/seatmap-server/seatmap-server.pl'; +} + +const checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + }; +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (config['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + // THROW ERROR AND DIE IF BROWSER IS IE + detect_die_IE(); + + // PARSE PARAM FROM POSTURL, CREATES param and extra_param + var decoded_uri = decodeURIComponent(getParamValue('posturl')); + getParamsFromPosturl(decoded_uri); + + // GET DATA FROM SERVER AND BUILD SEATMAP + seatmapWorkflow(decoded_uri); +} + +function load_config(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + console.log(DATA.CONFIG); + // config = JSON.parse(DATA.CONFIG); + config = DATA.CONFIG; + console.log(config); + + if (config['DEBUG']) console.log(param); + if (config['DEBUG']) console.log(extra_param); +} + +function detect_die_IE() { + if (config['DEBUG']) console.log(getFuncName()); + + var IEdetected = detectIE(); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } +} + +function getParamsFromPosturl(decoded_uri) { + if (config['DEBUG']) console.log(getFuncName()); + + var checkoutParam = [ + 'APPTE', 'age_consent_is_checked', 'agency', 'cancelAndRedirectTrxState', 'cogid', 'coids', 'discount=A=IE', 'discount=A=IV', 'discountdesc=A=IE', 'discountdesc=A=IV', 'discountfees=A=IE', 'discountfees=A=IV', 'discountprice=A=IE', 'discountprice=A=IV', 'dpa_selection', 'etpgcode', 'flashDetected', 'gid', 'hbx_discount_prices', 'hbx_discounts', 'hbx_offered_pg', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_pids', 'hbx_requested_pg', 'hbx_selected_tixx', 'hbx_upsell_flag', 'request_type', 'invalid_seats', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'isCapEnabled', 'is_availability_switch_from_map', 'is_ticket_exchange_request', 'ism_map_current_state_json_data', 'jcarousel_auto_off_val', 'listing_type', 'mainEventPID', 'map_coupon_code', 'mlbamsp', 'oid', 'ooids', 'orderkey', 'orgid', 'p_orgid', 'package_pids', 'parent_offer_id', 'pay_pal_token', 'pid', 'prevtrxstate', 'recapToken', 'redeem_voucher_data_event_mapping', 'replay_request', 'request_action', 's_mem_tkt_ren_retrieval', 'schedule', 'secure_trxn_enabled', 'selected_seat_indexes', 'selected_upsell_option', 'supplierCode', 'supplier_code', 'target_name_value', 'target_prev_trxstate', 'target_trxstate', 'target_url', 'timeout_seconds', 'trxstate', 'upsell_selected', 'user_context', 'valid_coupon_code_message', + ]; + var extraParam = ['note']; + + for (var i = 0; i < checkoutParam.length; i++) { + let value = getParamValue(checkoutParam[i], decoded_uri); + if (value !== undefined) { + param[checkoutParam[i]] = getParamValue(checkoutParam[i], decoded_uri); + } + } + for (var i = 0; i < extraParam.length; i++) { + let value = getParamValue(extraParam[i], decoded_uri); + if (value !== undefined) { + extra_param[extraParam[i]] = value; + } + } +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init() { + if (config['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: config["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (config['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (config['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (config['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + var modal_body = 'Bitte überprüfen Sie Ihre Plätze. Dies ist die letze Möglichkeit, um ggfs. die Ermäßigung zu ändern.'; + if (extra_param['note']) { + modal_body = modal_body + '
' + extra_param['note']; + } + + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + console.log('successfull, now going to: ' + checkoutURL); + window.location.replace(checkoutURL); + // window.open(checkoutURL, '_blank'); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (config['DEBUG']) console.log(getFuncName()); + + if (config['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (config['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (config['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (config['DEBUG']) console.log(v); + if (config['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // CUSTOM CONFIG SETTINGS FOR SEATMAP + var left = true; + if (typeof config[DATA.VENUE.CODE]["LEFT_NAMING"] != "undefined") { + left = config[DATA.VENUE.CODE]["LEFT_NAMING"]; + } + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: left, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (config['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (config['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = config[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = config[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(config[DATA.VENUE.CODE]["TONPULT"]); + } + + // VENUE SPECIFIC CSS + if (config['DEBUG']) console.log('Applying venue specific CSS for ' + config[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = config[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/seatmap.js b/seatmap-client/seatmap.js new file mode 100644 index 0000000..8f34b4d --- /dev/null +++ b/seatmap-client/seatmap.js @@ -0,0 +1,1912 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var extra_param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +const branch = 'seatmap_main'; // seatmap_testing or seatmap_main +var DATA = { + 'CONFIG': {}, +}; +set_predefined_config(DATA); + +function set_predefined_config(DATA) { + DATA['CONFIG']['DEBUG'] = 1; + DATA['CONFIG']['SEATMAP-SERVER'] = {}; + + if (branch === 'seatmap_testing') { + if (typeof DATA.CONFIG['SEATMAP_VERSION'] != 'undefined') { + DATA.CONFIG["SEATMAP_VERSION"] = DATA.CONFIG["SEATMAP_VERSION"] + ' (testing)'; + } + DATA.CONFIG['SEATMAP-SERVER']['ROOT_URL'] = 'https://seatmap-testing.zinomedia.de/seatmap-server/seatmap-server.pl'; + } + else if (branch === 'seatmap_main') { + DATA.CONFIG['SEATMAP-SERVER']['ROOT_URL'] = 'https://zinomedia.de/seatmap_main/seatmap-server/seatmap-server.pl'; + } +} + +const checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + }; +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + // THROW ERROR AND DIE IF BROWSER IS IE + detect_die_IE(); + + // PARSE PARAM FROM POSTURL, CREATES param and extra_param + var decoded_uri = decodeURIComponent(getParamValue('posturl')); + getParamsFromPosturl(decoded_uri); + if (DATA.CONFIG['DEBUG']) console.log(param); + if (DATA.CONFIG['DEBUG']) console.log(extra_param); + + // GET DATA FROM SERVER AND BUILD SEATMAP + seatmapWorkflow(decoded_uri); +} + +function detect_die_IE() { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + var IEdetected = detectIE(); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } +} + +function getParamsFromPosturl(decoded_uri) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + var checkoutParam = [ + 'APPTE', 'age_consent_is_checked', 'agency', 'cancelAndRedirectTrxState', 'cogid', 'coids', 'discount=A=IE', 'discount=A=IV', 'discountdesc=A=IE', 'discountdesc=A=IV', 'discountfees=A=IE', 'discountfees=A=IV', 'discountprice=A=IE', 'discountprice=A=IV', 'dpa_selection', 'etpgcode', 'flashDetected', 'gid', 'hbx_discount_prices', 'hbx_discounts', 'hbx_offered_pg', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_pids', 'hbx_requested_pg', 'hbx_selected_tixx', 'hbx_upsell_flag', 'request_type', 'invalid_seats', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'isCapEnabled', 'is_availability_switch_from_map', 'is_ticket_exchange_request', 'ism_map_current_state_json_data', 'jcarousel_auto_off_val', 'listing_type', 'mainEventPID', 'map_coupon_code', 'mlbamsp', 'oid', 'ooids', 'orderkey', 'orgid', 'p_orgid', 'package_pids', 'parent_offer_id', 'pay_pal_token', 'pid', 'prevtrxstate', 'recapToken', 'redeem_voucher_data_event_mapping', 'replay_request', 'request_action', 's_mem_tkt_ren_retrieval', 'schedule', 'secure_trxn_enabled', 'selected_seat_indexes', 'selected_upsell_option', 'supplierCode', 'supplier_code', 'target_name_value', 'target_prev_trxstate', 'target_trxstate', 'target_url', 'timeout_seconds', 'trxstate', 'upsell_selected', 'user_context', 'valid_coupon_code_message', + ]; + var extraParam = ['note']; + + for (var i = 0; i < checkoutParam.length; i++) { + let value = getParamValue(checkoutParam[i], decoded_uri); + if (value !== undefined) { + param[checkoutParam[i]] = getParamValue(checkoutParam[i], decoded_uri); + } + } + for (var i = 0; i < extraParam.length; i++) { + let value = getParamValue(extraParam[i], decoded_uri); + if (value !== undefined) { + extra_param[extraParam[i]] = value; + } + } +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init(DATA) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: DATA.CONFIG["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (DATA.CONFIG['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (DATA.CONFIG['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (DATA.CONFIG['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + var modal_body = 'Bitte überprüfen Sie Ihre Plätze. Dies ist die letze Möglichkeit, um ggfs. die Ermäßigung zu ändern.'; + if (extra_param['note']) { + modal_body = modal_body + '
' + extra_param['note']; + } + + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + console.log('successfull, now going to: ' + checkoutURL); + window.location.replace(checkoutURL); + // window.open(checkoutURL, '_blank'); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + if (DATA.CONFIG['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (DATA.CONFIG['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (DATA.CONFIG['DEBUG']) console.log(v); + if (DATA.CONFIG['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // CUSTOM CONFIG SETTINGS FOR SEATMAP + var left = true; + if (typeof DATA.CONFIG[DATA.VENUE.CODE]["LEFT_NAMING"] != "undefined") { + left = DATA.CONFIG[DATA.VENUE.CODE]["LEFT_NAMING"]; + } + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: left, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > DATA.CONFIG[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + DATA.CONFIG[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id, DATA); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (DATA.CONFIG['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (DATA.CONFIG['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID, DATA); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (DATA.CONFIG['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = DATA.CONFIG[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = DATA.CONFIG[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(DATA.CONFIG[DATA.VENUE.CODE]["TONPULT"]); + } + + // VENUE SPECIFIC CSS + if (DATA.CONFIG['DEBUG']) console.log('Applying venue specific CSS for ' + DATA.CONFIG[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = DATA.CONFIG[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/seatmap090120.js b/seatmap-client/seatmap090120.js new file mode 100644 index 0000000..0e988bd --- /dev/null +++ b/seatmap-client/seatmap090120.js @@ -0,0 +1,2257 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +var branch = 'seatmap_main'; +var config = { + "TAD": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "LEFT_NAMING": false, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 0.8vw; \ + width: 0.8vw; \ + line-height: 1.5vw; \ + } \ + @media (min-width: 628px) and (max-width: 766px) { \ + div.seatCharts-cell { \ + height: 0.794vw; \ + width: 0.794vw; \ + } \ + } \ + @media (min-width: 498px) and (max-width: 627px) { \ + div.seatCharts-cell { \ + height: 0.786vw; \ + width: 0.786vw; \ + } \ + } \ + @media (min-width: 477px) and (max-width: 497px) { \ + div.seatCharts-cell { \ + height: 0.78vw; \ + width: 0.78vw; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 476px) { \ + div.seatCharts-cell { \ + height: 0.77vw; \ + width: 0.77vw; \ + } \ + } \ + ', + }, + "KLEINER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 1824661: "228B22", + 2542349: "8B4513", + 2542350:"4682B4", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.43vw; \ + width: 1.43vw; \ + line-height: 1.5vw; \ + } \ + @media (min-width: 400px) and (max-width: 540px) { \ + div.seatCharts-cell { \ + height: 1.398vw; \ + width: 1.398vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "INT_TH_3": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 5273153: "228B22", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 2.6vw; \ + width: 2.6vw; \ + line-height: 2.5vw; \ + max-width: 30px; \ + max-height: 30px; \ + } \ + @media (min-width: 400px) and (max-width: 700px) { \ + div.seatCharts-cell { \ + height: 2.52vw; \ + width: 2.52vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GRO_SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 0.9vw; \ + width: 0.9vw; \ + line-height: 1.4vw; \ + } \ + ', + }, + "STADTHAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "STUDIONU": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2447833: "B9DEA0", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GR.SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 152965: "FFFF00", + 152966: "FF0000", + 152967: "74DF00", + 152968: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.19vw; \ + width: 1.19vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 445px) and (max-width: 555px) { \ + div.seatCharts-cell { \ + height: 1.17vw; \ + width: 1.17vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 444px) { \ + div.seatCharts-cell { \ + height: 1.15vw; \ + width: 1.15vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATHOF": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2446505: "FFFF00", + 2446506: "FF0000", + 2446507: "74DF00", + 2446508: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.2vw; \ + width: 1.2vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 530px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 1.24vw; \ + width: 1.24vw; \ + } \ + } \ + @media (min-width: 405px) and (max-width:529px) { \ + div.seatCharts-cell { \ + height: 1.215vw; \ + width: 1.215vw; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 768px) { \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "60%", + "PADDING-LEFT-STAGE": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.54vw; \ + width: 1.54vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:530px) { \ + div.seatCharts-cell { \ + height: 1.505vw; \ + width: 1.505vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "NEUES TH": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 3.47vw !important; \ + width: 3.47vw !important; \ + max-width: 27px; \ + max-height: 27px; \ + line-height: 1.4vw; \ + } \ + @media all and (-ms-high-contrast: none), \ + (-ms-high-contrast: active) { \ + div.seatCharts-cell { \ + height: 3.55vw !important; \ + width: 3.55vw !important; \ + } \ + } \ + ', + }, + "SAAL KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.3vw; \ + width: 1.3vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 411px) and (max-width:539px) { \ + div.seatCharts-cell { \ + height: 1.275vw; \ + width: 1.275vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width:410px) { \ + div.seatCharts-cell { \ + height: 1.25vw; \ + width: 1.25vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GSP KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.39vw; \ + width: 1.39vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:504px) { \ + div.seatCharts-cell { \ + height: 1.36vw; \ + width: 1.36vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + 'KOM├ÛDIE': { + "PADDING-LEFT": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1.0vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1.0vw; \ + } \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + line-height: 1.4vw; \ + max-height: 25px; \ + max-width: 25px; \ + } \ + @media (min-width: 400px) and (max-width:405px) { \ + div.seatCharts-cell { \ + height: 2.7vw; \ + width: 2.7vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 406px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + } \ + } \ + ', + }, + "THEATER AM DOM": { + "AGENCY": "TADK", + "BUYER_TYPES": { + "Z1": "Vollzahler", + } + }, + "GRO├ƑER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "KLEINER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "INTIMES THEATER BESTUHLT": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "THEATER HOF": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "STUDIO NUMMERIERT": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "KOMÖDIE BRAUNSCHWEIG": { + "AGENCY": "KOMB", + "BUYER_TYPES": { + "IV": "Vollzahler", + "IE": "Ermäßigt", + "IG": "Gutschein", + "ME": "Vollzahler", + "MK": "Ermäßigt", + "NI": "Ermäßigt", + "NN": "Vollzahler", + } + }, + "THEATER IM RATHAUS": { + "AGENCY": "TIRE", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I2": "Ermäßigt", + "FR": "Freitag_13", + } + }, + "NEUES THEATER HANNOVER": { + "AGENCY": "NTHH", + "BUYER_TYPES": { + "WW": "Vollzahler", + } + }, + "STAATSOPERETTE DRESDEN": { + "AGENCY": "SOPD", + "BUYER_TYPES": { + "97": "Vollzahler", + "A0": "Ermäßigt", + "A5": "Online-Aktion", + "95": "Aktionspreis", + "09": "Schüler", + "A6": "Kind bis 18 J.", + "86": "Buch", + "85": "CD", + "00": "Tagespreis", + "03": "Tagespreis ermäßigt", + "98": "Aktionspreis", + "31": "Studenten/Azubis bis 27 J.", + "23": "Andere Gäste", + } + }, + "SEATMAP-SERVER": { + "ROOT_URL": "https://zinomedia.de/" + branch + "/seatmap-server/seatmap-server.pl", + }, + "CORS-ANYWHERE": { + "ROOT_URL": "https://cors.zinomedia.de/", + }, + "DEBUG": true, + "SEATMAP_VERSION": "0.9.6", + "CURRENCY_SYMBOL": "€", +}; +if (branch === 'seatmap_testing') config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; + +var checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + } +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (config['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + if (config['DEBUG']) console.log("Visible"); + + var IEdetected = detectIE(); + if (config['DEBUG']) console.log("IE " + IEdetected); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } + init(); + + var decoded_uri = decodeURIComponent(getParamValue('posturl')); + getParamsFromPosturl(decoded_uri); + + if (config['DEBUG']) console.log(param); + + seatmapWorkflow(decoded_uri); +} + +function getParamsFromPosturl(decoded_uri) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(decoded_uri); + + var checkoutParam = [ + 'APPTE', 'age_consent_is_checked', 'agency', 'cancelAndRedirectTrxState', 'cogid', 'coids', 'discount=A=IE', 'discount=A=IV', 'discountdesc=A=IE', 'discountdesc=A=IV', 'discountfees=A=IE', 'discountfees=A=IV', 'discountprice=A=IE', 'discountprice=A=IV', 'dpa_selection', 'etpgcode', 'flashDetected', 'gid', 'hbx_discount_prices', 'hbx_discounts', 'hbx_offered_pg', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_pids', 'hbx_requested_pg', 'hbx_selected_tixx', 'hbx_upsell_flag', 'request_type', 'invalid_seats', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'isCapEnabled', 'is_availability_switch_from_map', 'is_ticket_exchange_request', 'ism_map_current_state_json_data', 'jcarousel_auto_off_val', 'listing_type', 'mainEventPID', 'map_coupon_code', 'mlbamsp', 'oid', 'ooids', 'orderkey', 'orgid', 'p_orgid', 'package_pids', 'parent_offer_id', 'pay_pal_token', 'pid', 'prevtrxstate', 'recapToken', 'redeem_voucher_data_event_mapping', 'replay_request', 'request_action', 's_mem_tkt_ren_retrieval', 'schedule', 'secure_trxn_enabled', 'selected_seat_indexes', 'selected_upsell_option', 'supplierCode', 'supplier_code', 'target_name_value', 'target_prev_trxstate', 'target_trxstate', 'target_url', 'timeout_seconds', 'trxstate', 'upsell_selected', 'user_context', 'valid_coupon_code_message' + ]; + for (var i = 0; i < checkoutParam.length; i++) { + var value = getParamValue(checkoutParam[i], decoded_uri); + if (value !== undefined) { + param[checkoutParam[i]] = getParamValue(checkoutParam[i], decoded_uri); + } + } +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init() { + if (config['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: config["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (config['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (config['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (config['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + console.log('successfull, now going to: ' + checkoutURL); + window.location.replace(checkoutURL); + // window.open(checkoutURL, '_blank'); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (config['DEBUG']) console.log(getFuncName()); + + if (config['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (config['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (config['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (config['DEBUG']) console.log(v); + if (config['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // CUSTOM CONFIG SETTINGS FOR SEATMAP + var left = true; + if (typeof config[DATA.VENUE.CODE]["LEFT_NAMING"] != "undefined") { + left = config[DATA.VENUE.CODE]["LEFT_NAMING"]; + } + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: left, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (config['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (config['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = config[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = config[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(config[DATA.VENUE.CODE]["Tonpult"]); + } + + // VENUE SPECIFIC CSS + if (config['DEBUG']) console.log('Applying venue specific CSS for ' + config[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = config[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/seatmap11_18_19.js b/seatmap-client/seatmap11_18_19.js new file mode 100644 index 0000000..73aee4f --- /dev/null +++ b/seatmap-client/seatmap11_18_19.js @@ -0,0 +1,2065 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +var branch = 'seatmap_main'; +var config = { + "STADTHAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "STUDIONU": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2447833: "B9DEA0", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GR.SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 152965: "FFFF00", + 152966: "FF0000", + 152967: "74DF00", + 152968: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.19vw; \ + width: 1.19vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 445px) and (max-width: 555px) { \ + div.seatCharts-cell { \ + height: 1.17vw; \ + width: 1.17vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 444px) { \ + div.seatCharts-cell { \ + height: 1.15vw; \ + width: 1.15vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATHOF": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2446505: "FFFF00", + 2446506: "FF0000", + 2446507: "74DF00", + 2446508: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.2vw; \ + width: 1.2vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 530px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 1.24vw; \ + width: 1.24vw; \ + } \ + } \ + @media (min-width: 405px) and (max-width:529px) { \ + div.seatCharts-cell { \ + height: 1.215vw; \ + width: 1.215vw; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 768px) { \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "60%", + "PADDING-LEFT-STAGE": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.54vw; \ + width: 1.54vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:530px) { \ + div.seatCharts-cell { \ + height: 1.505vw; \ + width: 1.505vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "NEUES TH": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 3.47vw !important; \ + width: 3.47vw !important; \ + max-width: 27px; \ + max-height: 27px; \ + line-height: 1.4vw; \ + } \ + @media all and (-ms-high-contrast: none), \ + (-ms-high-contrast: active) { \ + div.seatCharts-cell { \ + height: 3.55vw !important; \ + width: 3.55vw !important; \ + } \ + } \ + ', + }, + "SAAL KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.3vw; \ + width: 1.3vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 411px) and (max-width:539px) { \ + div.seatCharts-cell { \ + height: 1.275vw; \ + width: 1.275vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width:410px) { \ + div.seatCharts-cell { \ + height: 1.25vw; \ + width: 1.25vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GSP KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.39vw; \ + width: 1.39vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:504px) { \ + div.seatCharts-cell { \ + height: 1.36vw; \ + width: 1.36vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + 'KOM├ÛDIE': { + "PADDING-LEFT": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1.0vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1.0vw; \ + } \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + line-height: 1.4vw; \ + max-height: 25px; \ + max-width: 25px; \ + } \ + @media (min-width: 400px) and (max-width:405px) { \ + div.seatCharts-cell { \ + height: 2.7vw; \ + width: 2.7vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 406px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + } \ + } \ + ', + }, + "GRO├ƑER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "THEATER HOF": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "STUDIO NUMMERIERT": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "KOMÖDIE BRAUNSCHWEIG": { + "AGENCY": "KOMB", + "BUYER_TYPES": { + "IV": "Vollzahler", + "IE": "Ermäßigt", + "IG": "Gutschein", + "ME": "Vollzahler", + "MK": "Ermäßigt", + "NI": "Ermäßigt", + "NN": "Vollzahler", + } + }, + "THEATER IM RATHAUS": { + "AGENCY": "TIRE", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I2": "Ermäßigt", + } + }, + "NEUES THEATER HANNOVER": { + "AGENCY": "NTHH", + "BUYER_TYPES": { + "WW": "Vollzahler", + } + }, + "STAATSOPERETTE DRESDEN": { + "AGENCY": "SOPD", + "BUYER_TYPES": { + "97": "Vollzahler", + "A0": "Ermäßigt", + "A5": "Online-Aktion", + "95": "Aktionspreis", + "09": "Schüler", + "A6": "Kind bis 18 J.", + "86": "Buch", + "85": "CD", + "00": "Tagespreis", + "03": "Tagespreis ermäßigt", + "98": "Aktionspreis", + "31": "Studenten/Azubis bis 27 J.", + "23": "Andere Gäste", + } + }, + "SEATMAP-SERVER": { + "ROOT_URL": "https://zinomedia.de/" + branch + "/seatmap-server/seatmap-server.pl", + }, + "CORS-ANYWHERE": { + "ROOT_URL": "https://cors.zinomedia.de/", + }, + "DEBUG": true, + "SEATMAP_VERSION": "0.9.1", + "CURRENCY_SYMBOL": "€", +}; +if (branch === 'seatmap_testing') config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; + +var checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + } +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (config['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + if (config['DEBUG']) console.log("Visible"); + + var IEdetected = detectIE(); + if (config['DEBUG']) console.log("IE " + IEdetected); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } + init(); + param["posturl"] = getParamValue('posturl'); + param["decodedURI"] = decodeURIComponent(param["posturl"]); + param["user_context"] = getParamValue('user_context', param["decodedURI"]); + param["pid"] = getParamValue('pid', param["decodedURI"]); + + if (config['DEBUG']) console.log("posturl: " + param["posturl"]); + if (config['DEBUG']) console.log("decodedURI: " + param["decodedURI"]); + if (config['DEBUG']) console.log("user_context: " + param["user_context"]); + if (config['DEBUG']) console.log("pid: " + param["pid"]); + + seatmapWorkflow(param["decodedURI"]); +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init() { + if (config['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: config["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (config['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (config['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (config['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + // if (errorMsg == '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + window.location.replace(checkoutURL); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (config['DEBUG']) console.log(getFuncName()); + + if (config['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (config['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (config['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (config['DEBUG']) console.log(v); + if (config['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: true, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (config['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (config['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = config[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = config[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(config[DATA.VENUE.CODE]["Tonpult"]); + } + + // VENUE SPECIFIC CSS + if (config['DEBUG']) console.log('Applying venue specific CSS for ' + config[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = config[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/seatmap11_22_19.js b/seatmap-client/seatmap11_22_19.js new file mode 100644 index 0000000..5104b65 --- /dev/null +++ b/seatmap-client/seatmap11_22_19.js @@ -0,0 +1,2162 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +var branch = 'seatmap_main'; +var config = { + "KLEINER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 1824661: "228B22", + 2542349: "8B4513", + 2542350:"4682B4", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.43vw; \ + width: 1.43vw; \ + line-height: 1.5vw; \ + } \ + @media (min-width: 400px) and (max-width: 540px) { \ + div.seatCharts-cell { \ + height: 1.398vw; \ + width: 1.398vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "INT_TH_3": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 5273153: "228B22", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 2.6vw; \ + width: 2.6vw; \ + line-height: 2.5vw; \ + max-width: 30px; \ + max-height: 30px; \ + } \ + @media (min-width: 400px) and (max-width: 700px) { \ + div.seatCharts-cell { \ + height: 2.52vw; \ + width: 2.52vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GRO_SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 0.9vw; \ + width: 0.9vw; \ + line-height: 1.4vw; \ + } \ + ', + }, + "STADTHAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "STUDIONU": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2447833: "B9DEA0", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GR.SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 152965: "FFFF00", + 152966: "FF0000", + 152967: "74DF00", + 152968: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.19vw; \ + width: 1.19vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 445px) and (max-width: 555px) { \ + div.seatCharts-cell { \ + height: 1.17vw; \ + width: 1.17vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 444px) { \ + div.seatCharts-cell { \ + height: 1.15vw; \ + width: 1.15vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATHOF": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2446505: "FFFF00", + 2446506: "FF0000", + 2446507: "74DF00", + 2446508: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.2vw; \ + width: 1.2vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 530px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 1.24vw; \ + width: 1.24vw; \ + } \ + } \ + @media (min-width: 405px) and (max-width:529px) { \ + div.seatCharts-cell { \ + height: 1.215vw; \ + width: 1.215vw; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 768px) { \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "60%", + "PADDING-LEFT-STAGE": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.54vw; \ + width: 1.54vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:530px) { \ + div.seatCharts-cell { \ + height: 1.505vw; \ + width: 1.505vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "NEUES TH": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 3.47vw !important; \ + width: 3.47vw !important; \ + max-width: 27px; \ + max-height: 27px; \ + line-height: 1.4vw; \ + } \ + @media all and (-ms-high-contrast: none), \ + (-ms-high-contrast: active) { \ + div.seatCharts-cell { \ + height: 3.55vw !important; \ + width: 3.55vw !important; \ + } \ + } \ + ', + }, + "SAAL KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.3vw; \ + width: 1.3vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 411px) and (max-width:539px) { \ + div.seatCharts-cell { \ + height: 1.275vw; \ + width: 1.275vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width:410px) { \ + div.seatCharts-cell { \ + height: 1.25vw; \ + width: 1.25vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GSP KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.39vw; \ + width: 1.39vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:504px) { \ + div.seatCharts-cell { \ + height: 1.36vw; \ + width: 1.36vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + 'KOM├ÛDIE': { + "PADDING-LEFT": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1.0vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1.0vw; \ + } \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + line-height: 1.4vw; \ + max-height: 25px; \ + max-width: 25px; \ + } \ + @media (min-width: 400px) and (max-width:405px) { \ + div.seatCharts-cell { \ + height: 2.7vw; \ + width: 2.7vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 406px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + } \ + } \ + ', + }, + "GRO├ƑER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "KLEINER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "INTIMES THEATER BESTUHLT": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "THEATER HOF": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "STUDIO NUMMERIERT": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "KOMÖDIE BRAUNSCHWEIG": { + "AGENCY": "KOMB", + "BUYER_TYPES": { + "IV": "Vollzahler", + "IE": "Ermäßigt", + "IG": "Gutschein", + "ME": "Vollzahler", + "MK": "Ermäßigt", + "NI": "Ermäßigt", + "NN": "Vollzahler", + } + }, + "THEATER IM RATHAUS": { + "AGENCY": "TIRE", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I2": "Ermäßigt", + } + }, + "NEUES THEATER HANNOVER": { + "AGENCY": "NTHH", + "BUYER_TYPES": { + "WW": "Vollzahler", + } + }, + "STAATSOPERETTE DRESDEN": { + "AGENCY": "SOPD", + "BUYER_TYPES": { + "97": "Vollzahler", + "A0": "Ermäßigt", + "A5": "Online-Aktion", + "95": "Aktionspreis", + "09": "Schüler", + "A6": "Kind bis 18 J.", + "86": "Buch", + "85": "CD", + "00": "Tagespreis", + "03": "Tagespreis ermäßigt", + "98": "Aktionspreis", + "31": "Studenten/Azubis bis 27 J.", + "23": "Andere Gäste", + } + }, + "SEATMAP-SERVER": { + "ROOT_URL": "https://zinomedia.de/" + branch + "/seatmap-server/seatmap-server.pl", + }, + "CORS-ANYWHERE": { + "ROOT_URL": "https://cors.zinomedia.de/", + }, + "DEBUG": true, + "SEATMAP_VERSION": "0.9.2", + "CURRENCY_SYMBOL": "€", +}; +if (branch === 'seatmap_testing') config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; + +var checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + } +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (config['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + if (config['DEBUG']) console.log("Visible"); + + var IEdetected = detectIE(); + if (config['DEBUG']) console.log("IE " + IEdetected); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } + init(); + param["posturl"] = getParamValue('posturl'); + param["decodedURI"] = decodeURIComponent(param["posturl"]); + param["user_context"] = getParamValue('user_context', param["decodedURI"]); + param["pid"] = getParamValue('pid', param["decodedURI"]); + + if (config['DEBUG']) console.log("posturl: " + param["posturl"]); + if (config['DEBUG']) console.log("decodedURI: " + param["decodedURI"]); + if (config['DEBUG']) console.log("user_context: " + param["user_context"]); + if (config['DEBUG']) console.log("pid: " + param["pid"]); + + seatmapWorkflow(param["decodedURI"]); +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init() { + if (config['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: config["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (config['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (config['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (config['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + // if (errorMsg == '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + window.location.replace(checkoutURL); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (config['DEBUG']) console.log(getFuncName()); + + if (config['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (config['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (config['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (config['DEBUG']) console.log(v); + if (config['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: true, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (config['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (config['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = config[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = config[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(config[DATA.VENUE.CODE]["Tonpult"]); + } + + // VENUE SPECIFIC CSS + if (config['DEBUG']) console.log('Applying venue specific CSS for ' + config[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = config[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/seatmap12_12.js b/seatmap-client/seatmap12_12.js new file mode 100644 index 0000000..5171c1c --- /dev/null +++ b/seatmap-client/seatmap12_12.js @@ -0,0 +1,2163 @@ +// GLOBAL +var $cartBadge; +var options; +var drawTable; +var jqxhr; +var selectOptionSelected = {}; +var sc; +var inputsWithValue = []; +var showModal; +var param = new Object; +var idCartModal; +var ProductManager; +var seatmapWorkflowURL; + +var branch = 'seatmap_main'; +var config = { + "KLEINER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 1824661: "228B22", + 2542349: "8B4513", + 2542350:"4682B4", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.43vw; \ + width: 1.43vw; \ + line-height: 1.5vw; \ + } \ + @media (min-width: 400px) and (max-width: 540px) { \ + div.seatCharts-cell { \ + height: 1.398vw; \ + width: 1.398vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "INT_TH_3": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CUSTOM_PRICESCALES_COLOR": { + 5273153: "228B22", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 2.6vw; \ + width: 2.6vw; \ + line-height: 2.5vw; \ + max-width: 30px; \ + max-height: 30px; \ + } \ + @media (min-width: 400px) and (max-width: 700px) { \ + div.seatCharts-cell { \ + height: 2.52vw; \ + width: 2.52vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GRO_SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 0.9vw; \ + width: 0.9vw; \ + line-height: 1.4vw; \ + } \ + ', + }, + "STADTHAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "STUDIONU": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2447833: "B9DEA0", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.85vw; \ + width: 1.85vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width: 480px) { \ + div.seatCharts-cell { \ + height: 1.81vw; \ + width: 1.81vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GR.SAAL": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "49%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 152965: "FFFF00", + 152966: "FF0000", + 152967: "74DF00", + 152968: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.19vw; \ + width: 1.19vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 445px) and (max-width: 555px) { \ + div.seatCharts-cell { \ + height: 1.17vw; \ + width: 1.17vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 444px) { \ + div.seatCharts-cell { \ + height: 1.15vw; \ + width: 1.15vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATHOF": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "BOTTOM", + "CUSTOM_PRICESCALES_COLOR": { + 2446505: "FFFF00", + 2446506: "FF0000", + 2446507: "74DF00", + 2446508: "0080FF", + }, + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.2vw; \ + width: 1.2vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 530px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 1.24vw; \ + width: 1.24vw; \ + } \ + } \ + @media (min-width: 405px) and (max-width:529px) { \ + div.seatCharts-cell { \ + height: 1.215vw; \ + width: 1.215vw; \ + } \ + } \ + @media (min-width: 400px) and (max-width: 768px) { \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "THEATER": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "60%", + "PADDING-LEFT-STAGE": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.54vw; \ + width: 1.54vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:530px) { \ + div.seatCharts-cell { \ + height: 1.505vw; \ + width: 1.505vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "NEUES TH": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "50%", + "PADDING-LEFT-STAGE": "50%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": '\ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 3.47vw !important; \ + width: 3.47vw !important; \ + max-width: 27px; \ + max-height: 27px; \ + line-height: 1.4vw; \ + } \ + @media all and (-ms-high-contrast: none), \ + (-ms-high-contrast: active) { \ + div.seatCharts-cell { \ + height: 3.55vw !important; \ + width: 3.55vw !important; \ + } \ + } \ + ', + }, + "SAAL KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.3vw; \ + width: 1.3vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 411px) and (max-width:539px) { \ + div.seatCharts-cell { \ + height: 1.275vw; \ + width: 1.275vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 400px) and (max-width:410px) { \ + div.seatCharts-cell { \ + height: 1.25vw; \ + width: 1.25vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + "GSP KKM": { + "FRONT-INDICATOR-WIDTH": "90%", + "PADDING-LEFT": "47%", + "PADDING-LEFT-STAGE": "47%", + "Tonpult": "

Tonpult

", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1vw; \ + } \ + div.seatCharts-cell { \ + height: 1.39vw; \ + width: 1.39vw; \ + line-height: 1.4vw; \ + } \ + @media (min-width: 400px) and (max-width:504px) { \ + div.seatCharts-cell { \ + height: 1.36vw; \ + width: 1.36vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + ', + }, + 'KOM├ÛDIE': { + "PADDING-LEFT": "47%", + "MAX_TICKETS_PER_USER": 9, + "BUEHNE": "TOP", + "CSS": ' \ + .booking-details p,li { \ + font-size: 1.0vw; \ + } \ + .seatCharts-container h4, div.seatCharts-cell { \ + font-size: 1.0vw; \ + } \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + line-height: 1.4vw; \ + max-height: 25px; \ + max-width: 25px; \ + } \ + @media (min-width: 400px) and (max-width:405px) { \ + div.seatCharts-cell { \ + height: 2.7vw; \ + width: 2.7vw; \ + } \ + .glyphicon { \ + display: none; \ + } \ + } \ + @media (min-width: 406px) and (max-width:768px) { \ + div.seatCharts-cell { \ + height: 2.72vw; \ + width: 2.72vw; \ + } \ + } \ + ', + }, + "GRO├ƑER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "KLEINER SAAL": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "INTIMES THEATER BESTUHLT": { + "AGENCY": "GMB1", + "BUYER_TYPES": { + "01": "Vollzahler", + } + }, + "THEATER HOF": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "STUDIO NUMMERIERT": { + "AGENCY": "THOF", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I3": "Behinderte mit Ausweis", + "I2": "Schüler", + "IE": "Erwachsener", + "IK": "Kind", + } + }, + "KOMÖDIE BRAUNSCHWEIG": { + "AGENCY": "KOMB", + "BUYER_TYPES": { + "IV": "Vollzahler", + "IE": "Ermäßigt", + "IG": "Gutschein", + "ME": "Vollzahler", + "MK": "Ermäßigt", + "NI": "Ermäßigt", + "NN": "Vollzahler", + } + }, + "THEATER IM RATHAUS": { + "AGENCY": "TIRE", + "BUYER_TYPES": { + "I1": "Vollzahler", + "I2": "Ermäßigt", + } + }, + "NEUES THEATER HANNOVER": { + "AGENCY": "NTHH", + "BUYER_TYPES": { + "WW": "Vollzahler", + } + }, + "STAATSOPERETTE DRESDEN": { + "AGENCY": "SOPD", + "BUYER_TYPES": { + "97": "Vollzahler", + "A0": "Ermäßigt", + "A5": "Online-Aktion", + "95": "Aktionspreis", + "09": "Schüler", + "A6": "Kind bis 18 J.", + "86": "Buch", + "85": "CD", + "00": "Tagespreis", + "03": "Tagespreis ermäßigt", + "98": "Aktionspreis", + "31": "Studenten/Azubis bis 27 J.", + "23": "Andere Gäste", + } + }, + "SEATMAP-SERVER": { + "ROOT_URL": "https://zinomedia.de/" + branch + "/seatmap-server/seatmap-server.pl", + }, + "CORS-ANYWHERE": { + "ROOT_URL": "https://cors.zinomedia.de/", + }, + "DEBUG": true, + "SEATMAP_VERSION": "0.9.3", + "CURRENCY_SYMBOL": "€", +}; +if (branch === 'seatmap_testing') config["SEATMAP_VERSION"] = config["SEATMAP_VERSION"] + ' (testing)'; + +var checkoutParam = [ + 'request_type', 'trxstate', 'request_action', 'agency', 'etpgcode', 'parent_offer_id', 'flashDetected', 'recapToken', 'age_consent_is_checked', 'jcarousel_auto_off_val', 'selected_seat_indexes', 'ism_map_current_state_json_data', 'is_availability_switch_from_map', 'map_coupon_code', 'is_ticket_exchange_request', 'prevtrxstate', 'user_context', 'gid', 'target_trxstate', 'target_prev_trxstate', 'target_url', 'target_name_value', 'orgid', 'p_orgid', 'pid', 'redeem_voucher_data_event_mapping', 'supplier_code', 'valid_coupon_code_message', 'replay_request', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'upsell_selected', 'listing_type', 'invalid_seats', 'package_pids', 's_mem_tkt_ren_retrieval', 'mlbamsp', 'pay_pal_token', 'dpa_selection', 'timeout_seconds', 'APPTE', 'schedule', 'hbx_discounts', 'hbx_discount_prices', 'hbx_selected_tixx', 'hbx_requested_pg', 'hbx_offered_pg', 'hbx_pids', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_upsell_flag', 'selected_upsell_option', 'cancelAndRedirectTrxState', 'secure_trxn_enabled', 'isCapEnabled', 'mainEventPID', 'discountdesc=A=97', 'discountprice=A=97', 'discountfees=A=97', 'discount=A=97', 'discountdesc=A=A0', 'discountprice=A=A0', 'discountfees=A=A0', 'discount=A=A0', 'supplierCode', +]; + +// POLYPHILL repeat() +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) + throw new TypeError('can\'t convert ' + this + ' to object'); + + var str = '' + this; + // To convert string to integer. + count = +count; + // Check NaN + if (count != count) + count = 0; + + if (count < 0) + throw new RangeError('repeat count must be non-negative'); + + if (count == Infinity) + throw new RangeError('repeat count must be less than infinity'); + + count = Math.floor(count); + if (str.length == 0 || count == 0) + return ''; + + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) + throw new RangeError('repeat count must not overflow maximum string size'); + + var maxCount = str.length * count; + count = Math.floor(Math.log(count) / Math.log(2)); + while (count) { + str += str; + count--; + } + str += str.substring(0, maxCount - str.length); + return str; + } +} + +// EVENT DOMCONTENTLOADED +document.addEventListener("DOMContentLoaded", ready); +window.onload = function() { + if (config['DEBUG']) console.log(getFuncName()); + + checkDebug(); +}; + +// EVENT CONTAINER VISIBLE +if ($('.container-fluid').is(':visible')) { + if (config['DEBUG']) console.log("Visible"); + + var IEdetected = detectIE(); + if (config['DEBUG']) console.log("IE " + IEdetected); + if (parseInt(IEdetected) < 12) { + $('#IEdetected').show(); + throw new Error("IE " + IEDetected + " not supported."); + } + init(); + param["posturl"] = getParamValue('posturl'); + param["decodedURI"] = decodeURIComponent(param["posturl"]); + param["user_context"] = getParamValue('user_context', param["decodedURI"]); + param["pid"] = getParamValue('pid', param["decodedURI"]); + + if (config['DEBUG']) console.log("posturl: " + param["posturl"]); + if (config['DEBUG']) console.log("decodedURI: " + param["decodedURI"]); + if (config['DEBUG']) console.log("user_context: " + param["user_context"]); + if (config['DEBUG']) console.log("pid: " + param["pid"]); + + seatmapWorkflow(param["decodedURI"]); +} + +// EVENT RESIZE +$(window).resize(function() { + if ($(window).width() < 400) { + $('.container-fluid').hide(); + $('#screenTooSmall').show(); + } + else { + $('.container-fluid').show(); + $('#screenTooSmall').hide(); + } +}); + +function detectIE () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('Edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; +} + +function init() { + if (config['DEBUG']) console.log(getFuncName()); + + /* + * jQuery myCart - v1.7 - 2018-03-07 + * http://asraf-uddin-ahmed.github.io/ + * Copyright (c) 2017 Asraf Uddin Ahmed; Licensed None + */ + + (function($) { + + "use strict"; + + var OptionManager = (function() { + var objToReturn = {}; + + var _options = null; + var DEFAULT_OPTIONS = { + currencySymbol: config["CURRENCY_SYMBOL"], + classCartIcon: 'my-cart-icon', + classCartBadge: 'my-cart-badge', + classProductQuantity: 'my-product-quantity', + classProductRemove: 'my-product-remove', + classCheckoutCart: 'my-cart-checkout', + affixCartIcon: true, + showCheckoutModal: true, + numberOfDecimals: 2, + cartItems: null, + clickOnAddToCart: function($addTocart) {}, + afterAddOnCart: function(products, totalPrice, totalQuantity) {}, + clickOnCartIcon: function($cartIcon, products, totalPrice, totalQuantity) {}, + checkoutCart: function(products, totalPrice, totalQuantity) { + if (config['DEBUG']) console.log("checkoutCart"); + return false; + }, + getDiscountPrice: function(products, totalPrice, totalQuantity) { + return null; + } + }; + + var loadOptions = function(customOptions) { + _options = $.extend({}, DEFAULT_OPTIONS); + if (typeof customOptions === 'object') { + $.extend(_options, customOptions); + } + }; + var getOptions = function() { + return _options; + }; + + objToReturn.loadOptions = loadOptions; + objToReturn.getOptions = getOptions; + return objToReturn; + }()); + + var MathHelper = (function() { + var objToReturn = {}; + var getRoundedNumber = function(number) { + if (isNaN(number)) { + throw new Error('Parameter is not a Number'); + } + number = number * 1; + options = OptionManager.getOptions(); + return number.toFixed(options.numberOfDecimals); + }; + objToReturn.getRoundedNumber = getRoundedNumber; + return objToReturn; + }()); + + ProductManager = (function() { + var objToReturn = {}; + var localStorage = {}; + + /* + PRIVATE + */ + // localStorage.products = localStorage.products ? localStorage.products : ""; + if (typeof localStorage.products !== "undefined") { + if (config['DEBUG']) console.log("localStorage defined"); + localStorage.products = ""; + } + else { + if (config['DEBUG']) console.log("localStorage undefined"); + } + + var getIndexOfProduct = function(id) { + var productIndex = -1; + var products = getAllProducts(); + $.each(products, function(index, value) { + if (value.id == id) { + productIndex = index; + return; + } + }); + return productIndex; + }; + var setAllProducts = function(products) { + localStorage.products = JSON.stringify(products); + }; + var addProduct = function(id, name, summary, price, quantity, image, seatObj) { + var products = getAllProducts(); + products.push({ + id: id, + name: name, + summary: summary, + price: price, + quantity: quantity, + image: image, + seatObj: seatObj, + }); + setAllProducts(products); + }; + + /* + PUBLIC + */ + var getAllProducts = function() { + try { + var products = JSON.parse(localStorage.products); + return products; + } + catch (e) { + return []; + } + }; + var updatePoduct = function(id, quantity) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + setAllProducts(products); + return true; + }; + var updatePrice = function(id, price) { + var productIndex = getIndexOfProduct(id); + if (productIndex < 0) { + return false; + } + var products = getAllProducts(); + // products[productIndex].quantity = typeof quantity === "undefined" ? products[productIndex].quantity * 1 + 1 : quantity; + products[productIndex].price = price; + setAllProducts(products); + return true; + }; + var setProduct = function(id, name, summary, price, quantity, image, seatObj) { + if (typeof id === "undefined") { + console.error("id required"); + return false; + } + if (typeof name === "undefined") { + console.error("name required"); + return false; + } + if (typeof image === "undefined") { + console.error("image required"); + return false; + } + if (!$.isNumeric(price)) { + console.error("price is not a number"); + return false; + } + if (!$.isNumeric(quantity)) { + console.error("quantity is not a number"); + return false; + } + if (typeof seatObj === "undefined") { + console.error("seatObj required"); + return false; + } + summary = typeof summary === "undefined" ? "" : summary; + + if (!updatePoduct(id)) { + addProduct(id, name, summary, price, quantity, image, seatObj); + } + }; + var clearProduct = function() { + setAllProducts([]); + }; + var removeProduct = function(id) { + var products = getAllProducts(); + products = $.grep(products, function(value, index) { + return value.id != id; + }); + setAllProducts(products); + }; + var getTotalQuantity = function() { + var total = 0; + var products = getAllProducts(); + $.each(products, function(index, value) { + total += value.quantity * 1; + }); + return total; + }; + var getTotalPrice = function() { + var products = getAllProducts(); + var total = 0; + $.each(products, function(index, value) { + total += value.quantity * value.price; + total = MathHelper.getRoundedNumber(total) * 1; + }); + return total; + }; + + objToReturn.getAllProducts = getAllProducts; + objToReturn.updatePoduct = updatePoduct; + objToReturn.updatePrice = updatePrice; + objToReturn.setProduct = setProduct; + objToReturn.clearProduct = clearProduct; + objToReturn.removeProduct = removeProduct; + objToReturn.getTotalQuantity = getTotalQuantity; + objToReturn.getTotalPrice = getTotalPrice; + return objToReturn; + }()); + + + var loadMyCartEvent = function(targetSelector) { + + var options = OptionManager.getOptions(); + var $cartIcon = $("." + options.classCartIcon); + $cartBadge = $("." + options.classCartBadge); + var classProductQuantity = options.classProductQuantity; + var classProductRemove = options.classProductRemove; + var classCheckoutCart = options.classCheckoutCart; + + idCartModal = 'my-cart-modal'; + var idCartTable = 'my-cart-table'; + var idGrandTotal = 'my-cart-grand-total'; + var idEmptyCartMessage = 'my-cart-empty-message'; + var idDiscountPrice = 'my-cart-discount-price'; + var classProductTotal = 'my-product-total'; + var classAffixMyCartIcon = 'my-cart-icon-affix'; + + + if (options.cartItems && options.cartItems.constructor === Array) { + ProductManager.clearProduct(); + $.each(options.cartItems, function() { + ProductManager.setProduct(this.id, this.name, this.summary, this.price, this.quantity, this.image); + }); + } + + $cartBadge.text(ProductManager.getTotalQuantity()); + + if (!$("#" + idCartModal).length) { + $('body').append( + '' + ); + } + + drawTable = function() { + var DATA = jqxhr.responseJSON; + + var $cartTable = $("#" + idCartTable); + $cartTable.empty(); + + var products = ProductManager.getAllProducts(); + + $.each(products, function() { + var total = this.quantity * this.price; + + // OPTION DROPDOWN + var selectID = 'select' + this.id; + var select = "/)[1]; + console.log(errorMsg); + + if (errorMsg === '') { + // if (errorMsg == '') { + successful = true; + + ProductManager.clearProduct(); + $cartBadge.text(ProductManager.getTotalQuantity()); + $("#" + idCartModal).modal("hide"); + + // REDIRECT TO TICKET PURCHASE + window.location.replace(checkoutURL); + // window.location.replace(proxyCheckoutURL); + } + else { + successful = false; + + errorMsg = errorMsg.replace(/\/g, ' '); + + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + autoClose: 10000, + closeButton: 'box', + }); + } + } + }); + + return successful; +} + +function untickSeat(id) { + if (config['DEBUG']) console.log(getFuncName()); + console.log(id); + document.getElementById(id).click(); // Click on the checkbox +} + +function selectRefreshPrice(select) { + if (config['DEBUG']) console.log(getFuncName()); + + if (config['DEBUG']) console.log(select); + + var $sel = $(select); + var value = $sel.val(); + var text = $("option:selected", $sel).text(); + var idSelect = $sel[0].id; + var id = idSelect.replace("select", ""); + + ProductManager.updatePrice(id, value); + selectOptionSelected[idSelect] = { selected: text }; // Remember Select Option Value for redraw in drawTable() + // drawTable(); +} + +function setSelectedIndex() { + if (config['DEBUG']) console.log(getFuncName()); + + for (var idSelect in selectOptionSelected) { + if (selectOptionSelected.hasOwnProperty(idSelect)) { + var s = document.getElementById(idSelect); + var v = selectOptionSelected[idSelect].selected; + + if (s == null) { + delete selectOptionSelected[idSelect]; + continue; + } + else { + for (var i = 0; i < s.options.length; i++) { + if (s.options[i].text === v) { + if (config['DEBUG']) console.log(s.options[i].text + ' matches ' + v); + if (config['DEBUG']) console.log(v); + if (config['DEBUG']) console.log(s); + s.options[i].selected = true; + selectRefreshPrice(s); // FIX RIGHT PRICE OPTION DROPDOWN + } + } + } + + } + } +} + +function generateSeatmap(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + var returnArr = generateMapMatrix(DATA); + var map1d = returnArr[0]; + var seatsUnavailable = returnArr[1]; + var mappingPricescalesSections = returnArr[2]; + var rows = returnArr[3]; + var seats = generateSeats(DATA, mappingPricescalesSections); + var legend = generateLegend(DATA, 'legend'); + var firstSeatLabel = 1; + + // CHANGE HTML TITLE + document.title = DATA.EVENT.DESC + ' | Saalplanbuchung by Tickets.com'; + + // SEAT MAP + sc = $('#seat-map').seatCharts({ + map: map1d, + seats: seats, + + naming: { + top: false, + left: true, + // rows: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '1', '2', '3', '4', '5', '6', '7', '8', '9'], + rows: rows, + // columns: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'], + getLabel: function(character, row, column) { + return firstSeatLabel++; + }, + }, + legend: legend, + click: function() { + if (this.status() == 'available') { + if ((ProductManager.getTotalQuantity() + 1) > config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"]) { + var errorMsg = 'Maximale Ticketantahl erreicht: Sie können nicht mehr als ' + config[DATA.VENUE.CODE]["MAX_TICKETS_PER_USER"] + ' Tickets buchen.'; + new jBox('Notice', { + content: errorMsg, + color: 'red', + width: '100vw', + responsiveWidth: true, + position: { x: 'center', y: 'top' }, + closeButton: 'box', + autoClose: 10000, + }); + return; + } + + // ADD PRODUCT TO CART + fillSeatObjData(this.settings.id); + myCartAddWrapper(this.settings.id, this.settings.data.product, this.settings.data.color, this.settings.data.price, 1, '', this); + + return 'selected'; + } + else if (this.status() == 'selected') { + myCartRemoveWrapper(this.settings.id); + return 'available'; + } + else if (this.status() == 'unavailable') { + //seat has been already booked + console.log('unavailable'); + return 'unavailable'; + } + else { + return this.style(); + } + } + }); + + // INIT JBOX TOOLTIP + var jbox = new jBox('Tooltip', { + attach: '.available', + trigger: 'mouseenter', + onCreated: function() { + if (config['DEBUG']) console.log("onCreated"); + }, + onOpen: function() { + // GET SEAT ID AND OBJECT + var seatID = this.source.context.id; + var seatObj = sc.get(seatID); + // console.log(seatObj); + + if (seatID == '' || seatObj.settings.status == 'unavailable') { + if (config['DEBUG']) console.log("Not a real seat or seat unavailable -> Return."); + return; + } + + // FILL SEAT OBJECT IF NOT ALREADY + fillSeatObjData(seatID); + + // SET JBOX CONTENT + this.setContent(seatObj.settings.data.productJBox); + }, + onClose: function() {} + }); + + // DETACH JBOX FROM LEGEND AND UNAVAILABLE SEATS + for (var i = 0; i < jbox.attachedElements.length; i++) { + if (jbox.attachedElements[i].id == "") { + jbox.detach($(jbox.attachedElements[i])); + i = -1; + continue; + } + } + for (var j = 0; j < seatsUnavailable.length; j++) { + jbox.detach($('#' + seatsUnavailable[j])); + } + + // MYCART + $(function() { + var goToCartIcon = function($addTocartBtn) { + var $cartIcon = $(".my-cart-icon"); + var $image = $('').css({ "position": "fixed", "z-index": "999" }); + $addTocartBtn.prepend($image); + var position = $cartIcon.position(); + $image.animate({ + top: position.top, + left: position.left + }, 500, "linear", function() { + $image.remove(); + }); + }; + }); + + // RUN POST GENERATION HOOKS + sc.status(seatsUnavailable, 'unavailable'); // seatsUnavailable RECEIVED FROM SERVER + seperateSeatmapsCSS(DATA); // CSS CHANGES AFTER GENERATE + venueSpecificCSS(DATA); + $(window).trigger('resize'); +} + +function venueSpecificCSS(DATA) { + if (config['DEBUG']) console.log(getFuncName()); + + // VENUE SPECIFIC WIDTH TO CENTER FRONT INDICATORS + var paddingLeft = config[DATA.VENUE.CODE]["PADDING-LEFT"]; + $(".front-indicator").css({ "padding-left": paddingLeft }); + var paddingLeftStage = config[DATA.VENUE.CODE]["PADDING-LEFT-STAGE"]; + $(".stage-indicator").css({ "padding-left": paddingLeftStage }); + + // STAATSOPERETTE DRESDEN SPECIFIC + if (DATA.VENUE.CODE == "SAAL KKM" || DATA.VENUE.CODE == "GSP KKM") { + $("#seat-map").append(config[DATA.VENUE.CODE]["Tonpult"]); + } + + // VENUE SPECIFIC CSS + if (config['DEBUG']) console.log('Applying venue specific CSS for ' + config[DATA.VENUE.CODE]); + var styleSheet = document.createElement("style"); + styleSheet.type = "text/css"; + styleSheet.innerText = config[DATA.VENUE.CODE]["CSS"]; + document.head.appendChild(styleSheet); +} diff --git a/seatmap-client/style.css b/seatmap-client/style.css new file mode 100644 index 0000000..c3b075a --- /dev/null +++ b/seatmap-client/style.css @@ -0,0 +1,486 @@ +body { + background-color: #e9e9e9; + margin: 2em; +} + +a { + color: #b71a4c; +} + +.front-indicator { + text-align: left; + text-transform: uppercase; + font-size: 1.2vw; + margin-bottom: 1vw; + margin-top: 5vw; + display: inline-grid; +} + +.stage-indicator { + display: inline-grid; + background-color: none; + text-align: left; + text-transform: uppercase; +} + +.wrapper { + width: 100%; + text-align: center; +} + +.container { + margin: 0 auto; + width: 100% !important; + text-align: left; +} + +.booking-details { + float: left; +} + +.booking-details p,li { + font-size: 1vw; +} + +.booking-details h2 { + margin: 0px 0 10px 0; + font-size: 1.2vw; + text-transform: uppercase; +} + +.booking-details h3 { + margin: 0px 0 10px 0; + font-size: 1vw; +} + +div.seatCharts-cell { + color: #182C4E; + background-color: #e9e9e9; +} + +div.seatCharts-seat { + color: #FFFFFF; + cursor: pointer; +} + +div.seatCharts-row { + /*height: 35px;*/ + height: 1vw; +} + +div.seatCharts-seat.available { + background-color: #B9DEA0; +} + +div.seatCharts-seat.available.first-class { + /* background: url(vip.png); */ + background-color: #3a78c3; +} + +div.seatCharts-seat.focused { + background-color: #76B474; +} + +div.seatCharts-seat.selected { + background-image: url("img/iconfinder_tick_216457.png"); + background-repeat: no-repeat; + background-position: center center; + /*background-size: 100% 100%, auto;*/ + background-size: 100% 100%, auto; +} + +div.seatCharts-seat.unavailable { + /*background-color: red;*/ + cursor: not-allowed; + background: url("data:image/svg+xml;charset=utf8,"); + background-image: url("img/iconfinder_basics-22_296812.png"); + background-repeat: no-repeat; + background-position: center center; + background-size: 100% 100%, auto; + opacity: 0.3; +} + +/*div.seatCharts-seat.unavailable:before {*/ + +/* background: #037CA9;*/ + +/* content: "";*/ + +/* width: 10px;*/ + +/* height: 5px;*/ + +/* position: absolute;*/ + +/* top: 5px;*/ + +/* left: -5px;*/ + +/*}*/ + +div.seatCharts-container { + /*border-right: 1px dotted #adadad;*/ + width: auto; + padding: 0; +} + +div.seatCharts-legend { + /*padding-left: 0px;*/ + /*position: absolute;*/ + /*bottom: 16px;*/ + padding-top: 0px; +} + +ul.seatCharts-legendList { + padding-left: 0px; + display: grid; + margin: 0; +} + +span.seatCharts-legendDescription { + margin-left: 0.5vw; + line-height: 1.2vw; + /*font-size: 1vw;*/ +} + +.checkout-button { + display: block; + margin: 10px 0; + font-size: 14px; +} + +#selected-seats { + max-height: 90px; + overflow-y: scroll; + overflow-x: none; + width: 170px; +} + +#spacer { + /*margin: 40px 0px 0px 0px;*/ + margin: 2vw 0vw 0vw 0vw; +} + +p { + margin: 0px !important; + font-size: 1vw; +} + +.top-buffer-20 { + margin-top: 20px; +} + +.top-buffer-25 { + margin-top: 25px; +} + +.top-buffer-30 { + margin-top: 30px; +} + +div.seatCharts-cell { + margin: 0.2vw; +} + +#logo { + width: 50%; + position: absolute; + bottom: 0; + ; +} + +.container-fluid { + visibility: hidden; + margin: 0; + padding: 0; + + /*padding-right: 1vw;*/ + /*padding-left: 1vw;*/ + /*margin-right: auto;*/ + /*margin-left: auto;*/ +} + +h4 { + font-size: 1.2vw; +} + +/*.row {*/ + +/* display: -webkit-box;*/ + +/* display: -webkit-flex;*/ + +/* display: -ms-flexbox;*/ + +/* display: flex;*/ + +/* flex-wrap: wrap;*/ + +/*}*/ + +/*.row > [class*='col-'] {*/ + +/* display: flex;*/ + +/* flex-direction: column;*/ + +/*}*/ + +.centered { + position: fixed; + /* or absolute */ + top: 50%; + left: 50%; + /* bring your own prefixes */ + transform: translate(-50%, -50%); +} + +/*SHOPPING CART*/ + +/*.badge-notify{*/ + +/* background:red;*/ + +/* position:relative;*/ + +/* top: -20px;*/ + +/* right: 10px;*/ + +/*}*/ + +/*.my-cart-icon-affix {*/ + +/* position: fixed;*/ + +/* z-index: 999;*/ + +/*}*/ + +.glyphicon { + font-size: 2vw; + top: -.2vw; + white-space:nowrap; +} + +.btn-danger { + width: 20px; + text-align: center; + height: 20px; +} + +#my-cart-table td { + vertical-align: middle; + padding: 10px 0px 10px 0px; + font-size: 14px; +} + +.selectBuyerTypes { + width: 200px; + font-size: 14px; +} + +.badge { + padding: 0.3vw 0.5vw 0.5vw 0.5vw !important; + font-size: 0.7vw !important; + display: inline-block; + padding: 3px 7px; + font-size: 12px; + font-weight: 700; + color: #fff; + vertical-align: middle; + border-radius: 10px; +} + +.modal-backdrop { + display: none; +} + +.badge-notify { + background: red; + position: relative; + top: -0.8vw; + right: 0.5vw; +} + +.my-cart-icon-affix { + position: relative; + z-index: 999; +} + +li.seatCharts-legendItem { + margin-top: 0.2vw; + line-height: 1.8vw; +} + +#border { + width: 80vw; + margin: auto; + border-bottom: 1px dotted #ccc; +} + +#eventDesc { + text-decoration: underline; + font-weight: bold; + font-family: "Bodoni","Times New Roman",Times,serif; +} + +#venueList { + display: none; +} + +#venueDesc { + font-family: "Franklin Gothic Medium","Times New Roman",Times,serif; +} + +#datetime_DE { + font-family: "Franklin Gothic Medium","Times New Roman",Times,serif; +} + +.buttonOpenCart { + background-color: dimgrey; + color: floralwhite; + font-size: 1vw; + opacity: 0.8; + text-align: center; + transition: 0.3s; + cursor: pointer; + padding-top: 1vw; + width: 20vw; +} + +.buttonOpenCart:hover { + opacity: 1; +} + +#divCart { + margin-top: 1vw; +} + +#mycart { + float: right; + cursor: pointer; +} + +/* Start by setting display:none to make this hidden. + Then we position it in relation to the viewport window + with position:fixed. Width, height, top and left speak + for themselves. Background we set to 80% white with + our animation centered, and no-repeating */ + +.modal { + display: none; + position: fixed; + z-index: 1000; + top: 0; + left: 0; + height: 100%; + width: 100%; + background: rgba( 255, 255, 255, .8) url('img/30.svg') 50% 60% no-repeat; +} + +.modal:before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba( 255, 255, 255, .8) url('img/Tickets-small.png') 50% 50% no-repeat; +} + +.modal.special:before { + background: none; +} + +/* When the body has the loading class, we turn + the scrollbar off with overflow:hidden */ + +body.loading .modal { + overflow: hidden; +} + +/* Anytime the body has the loading class, our + modal element will be visible */ + +body.loading .modal { + display: block; + background-color: #ffffff; +} + +#seatmap_version { + text-align: right; + font-style: italic; + font-size: 1vw; +} + +.modal-content { + background-color: #e9e9e9; + min-width: 400px; +} + +.jBox-closeButton-box:before { + top: 0.7vw; +} + +.jBox-closeButton-box .jBox-closeButton { + top: 0.7vw; +} + +.jBox-content { + font-size: 1vw; +} + +h3 { + font-size: 2vw; +} + +h5 { + font-size: 1vw; +} + +.cartFont { + font-size: 14px; +} + +#screenTooSmall { + display: none; + font-size: 1.5vw; +} + +#IEdetected { + display: none; + font-size: 1.5vw; +} + +.rowBooking { + width: 60%; + margin: auto; +} + +/*ONLY IE < 10*/ + +/*@media all and (-ms-high-contrast: none),*/ +/*(-ms-high-contrast: active) {*/ +/* div.seatCharts-cell {*/ +/* height: 1.36vw;*/ +/* width: 1.36vw;*/ +/* }*/ +/*}*/ + +/*@media (min-width: 531px) and (max-width:770px) {*/ +/* div.seatCharts-cell {*/ +/* height: 1.33vw;*/ +/* width: 1.33vw;*/ +/* }*/ +/*}*/ + +/*@media (min-width: 400px) and (max-width:530px) {*/ +/* div.seatCharts-cell {*/ +/* height: 1.301vw;*/ +/* width: 1.301vw;*/ +/* }*/ +/* .glyphicon {*/ +/* display: none;*/ +/* }*/ +/*}*/ \ No newline at end of file diff --git a/seatmap-client/venue.css b/seatmap-client/venue.css new file mode 100644 index 0000000..a412471 --- /dev/null +++ b/seatmap-client/venue.css @@ -0,0 +1,9 @@ +.modal:before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba( 255, 255, 255, .8) url('img/Tickets-small.png') 50% 50% no-repeat; +} \ No newline at end of file diff --git a/seatmap-inject/seatmap-inject-np.js b/seatmap-inject/seatmap-inject-np.js new file mode 100644 index 0000000..6ada7a8 --- /dev/null +++ b/seatmap-inject/seatmap-inject-np.js @@ -0,0 +1,151 @@ +var config = { + 'DEBUG': true, + 'BRANCH': 'seatmap_main', +}; +if (config['BRANCH'] === 'seatmap_testing') { + config['SEATMAP_WEBAPI_URL'] = 'https://seatmap-testing.zinomedia.de/seatmap-webapi/api.php'; +} +else if (config['BRANCH'] === 'seatmap_main') { + config['SEATMAP_WEBAPI_URL'] = 'https://zinomedia.de/seatmap_main/seatmap-webapi/api.php'; +} + +jQuery(document).ready(function() { + if (config['DEBUG']) console.log(getFuncName('ready')); + + check_inject(); +}); + +function check_inject() { + if (config['DEBUG']) console.log(getFuncName()); + + var pvo_venue_name = jQuery('.venue span')[0].textContent.toUpperCase(); + var url = config['SEATMAP_WEBAPI_URL'] + '/records/halls?filter=PVO_VENUE_NAME,eq,' + pvo_venue_name + '&include=INJECT'; + + var result = jQuery.get(url, function(data) {}) + .done(function(data) { + if (data['records'][0]['INJECT']) { + if (config['DEBUG']) console.log('Starting inject...'); + inject_seatmap(); + } + else { + if (config['DEBUG']) console.log('Not injecting.'); + } + }); +} +function inject_seatmap() { + var url, param; + var content = document.getElementsByTagName('html')[0].innerHTML; + var inputsWithValue = getInputs(content); + if (config['DEBUG']) console.log(inputsWithValue); + + if (!jQuery.isEmptyObject(inputsWithValue)) { + if (inputsWithValue.hasOwnProperty("trxstate") && inputsWithValue["trxstate"].value == 20) { + if (config['DEBUG']) console.log("trxstate 20 identified"); + + manipulateDocument(); + var note = important_note(); + param = getPosturl(content); + if (jQuery('#flash_seat_map_box_id').length) { + url = generateUrl(param, inputsWithValue, note); + if (config['DEBUG']) console.log(url); + jQuery("#viewSeatFlashMapButton").unbind(); + jQuery('#viewSeatFlashMapButton').click(function() { + if (config['BRANCH'] === 'seatmap_testing') { + window.location.href = 'https://seatmap-testing.zinomedia.de/seatmap-client/index.html?' + "posturl=" + url; + } + else if (config['BRANCH'] === 'seatmap_main') { + window.location.href = 'https://purchase.tickets.zinomedia.de/?' + "posturl=" + url; + } + else { + throw new Error('Die: Branch not defined.'); + } + }); + } + } + else if (inputsWithValue.hasOwnProperty("prevtrxstate") && inputsWithValue["prevtrxstate"].value == 30) { + if (config['DEBUG']) console.log("prevtrxstate 30 identified"); + + // jQuery(".jq_replace")[0].text = 'Abbrechen'; + // jQuery('.jq_add').css('display', 'none'); + } + } +} +function generateUrl(param, inputsWithValue, note) { + if (config['DEBUG']) console.log(getFuncName()); + + var url = param[0]; + var event = param[1]; + var holdcode = param[2]; + + var parameter = ''; + for (var property in inputsWithValue) { + if (inputsWithValue.hasOwnProperty(property)) { + parameter = parameter + property + '=' + inputsWithValue[property].value + '&'; + } + } + parameter = parameter.substring(0, parameter.length - 1); + + url = url + "&holdcode=" + holdcode + "&event=" + event + '&nocache=0&inclpkg=Y&incloffer=Y&inclcartdetails=Y&inclCart=Y&inclvenue=Y' + parameter; + if (typeof note !== 'undefined') { + url = url + '¬e=' + note; + } + url = encodeURIComponent(url); + + return url; +} +function getPosturl(content) { + if (config['DEBUG']) console.log(getFuncName()); + + var posturl = content.match(/posturl:"(.+?)"/)[1]; + var event = content.match(/event:"(.+?)"/)[1]; + var holdcode = content.match(/holdcode:"(.+?)"/)[1]; + + return [posturl, event, holdcode, content]; +} +function getInputs(content) { + if (config['DEBUG']) console.log(getFuncName()); + + var inputsWithValue = new Object(); + var data = jQuery.parseHTML(content); + var checkoutParam = [ + 'APPTE', 'age_consent_is_checked', 'agency', 'cancelAndRedirectTrxState', 'cogid', 'coids', 'discount=A=IE', 'discount=A=IV', 'discountdesc=A=IE', 'discountdesc=A=IV', 'discountfees=A=IE', 'discountfees=A=IV', 'discountprice=A=IE', 'discountprice=A=IV', 'dpa_selection', 'etpgcode', 'flashDetected', 'gid', 'hbx_discount_prices', 'hbx_discounts', 'hbx_offered_pg', 'hbx_perf_codes', 'hbx_perf_sub_codes', 'hbx_pids', 'hbx_requested_pg', 'hbx_selected_tixx', 'hbx_upsell_flag', 'request_type', 'invalid_seats', 'inventory_filtering_action', 'inventory_month', 'inventory_year', 'isCapEnabled', 'is_availability_switch_from_map', 'is_ticket_exchange_request', 'ism_map_current_state_json_data', 'jcarousel_auto_off_val', 'listing_type', 'mainEventPID', 'map_coupon_code', 'mlbamsp', 'oid', 'ooids', 'orderkey', 'orgid', 'p_orgid', 'package_pids', 'parent_offer_id', 'pay_pal_token', 'pid', 'prevtrxstate', 'recapToken', 'redeem_voucher_data_event_mapping', 'replay_request', 'request_action', 's_mem_tkt_ren_retrieval', 'schedule', 'secure_trxn_enabled', 'selected_seat_indexes', 'selected_upsell_option', 'supplierCode', 'supplier_code', 'target_name_value', 'target_prev_trxstate', 'target_trxstate', 'target_url', 'timeout_seconds', 'trxstate', 'upsell_selected', 'user_context', 'valid_coupon_code_message' + ]; + jQuery(data).find('input').each(function() { + if (this.value !== '') { + if (checkoutParam.indexOf(this.name)) { + inputsWithValue[this.name] = this; + } + } + }); + + return inputsWithValue; +} + +function manipulateDocument() { + if (config['DEBUG']) console.log(getFuncName()); + + jQuery('#flash_seat_map_box_id').css('display', 'block'); + jQuery('#get_flash').css('display', 'none'); +} +function important_note() { + if (config['DEBUG']) console.log(getFuncName()); + + var element = document.getElementsByClassName('important_note'); + if (element.length > 0) { + var important_note = element[0].textContent; + if (config['DEBUG']) console.log(important_note); + + return important_note; + } +} +function getFuncName(arg) { + var caller; + if (getFuncName.caller.name !== '') { + caller = getFuncName.caller.name; + } + else { + caller = arg; + } + + return '\n' + '-'.repeat(80) + '\n' + 'PARENT ' + caller + '\n' + '-'.repeat(80); +} \ No newline at end of file diff --git a/seatmap-server/seatmap-server.pl b/seatmap-server/seatmap-server.pl new file mode 100755 index 0000000..42e8af5 --- /dev/null +++ b/seatmap-server/seatmap-server.pl @@ -0,0 +1,619 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use CGI ":standard"; +use CGI::Carp qw(warningsToBrowser fatalsToBrowser); +use Data::Dumper; +use LWP::UserAgent (); +use XML::LibXML; +use Encode; +use URI; +use Benchmark; +use JSON; +use utf8; +use feature qw/say/; +use Encode::Deep; +use DBD::mysql; +use URI::Encode qw(uri_encode uri_decode); + +# LWP +my $ua = LWP::UserAgent->new(keep_alive => 1); +$ua->agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'); +$ua->timeout(10); +$ua->env_proxy; + +# CGI +my $cgi = CGI->new; + +# GLOBAL +my %CONFIG = + ( + 'DEBUG' => 0, + 'DEBUG_PRINT_DATA' => 0, + 'ONLINE' => 1, + 'OFFLINE_XML' => '../seatmap-client/offline/MapTicketSales.xml', + 'OFFLINE_XML_PARKETT' => '../seatmap-client/offline/MapTicketSales_Parkett.xml', + 'OFFLINE_XML_RANG' => '../seatmap-client/offline/MapTicketSales_Rang.xml', + 'MYSQL' => { + 'database' => 'seatmap', + 'hostname' => 'localhost', + 'user' => 'seatmap_p', + 'pw' => 'r4Iybg75&3Q@9N!*', + 'port' => 3306, + }, + ); +my %DATA; +my $connection; + +# WORKFLOW +my $t0 = Benchmark->new if $CONFIG{'DEBUG'}; +&getParameter(); +print Dumper $DATA{'PARAMETER'} if $CONFIG{'DEBUG'}; +&checkHost(); +&generateVenueUrl(); + +my $xml; +if ($CONFIG{'ONLINE'}) { + print "SET AS ONLINE\n" if $CONFIG{'DEBUG'}; + + $xml = get($DATA{'PARAMETER'}{'urlVenue'}); + &loadXML($xml, \$DATA{'DOM'}); + &parseXML(); + &getSeatmaps(); +} +elsif (!$CONFIG{'ONLINE'}) { + print "SET AS OFFLINE: USING LOCAL XML\n" if $CONFIG{'DEBUG'}; + $xml = $CONFIG{'OFFLINE_XML'}; + + &loadXML($xml, \$DATA{'DOM'}); + &parseXML(); + &loadXML($CONFIG{'OFFLINE_XML_PARKETT'}, \$DATA{'DOM'}); + parxeXML_section(); + &loadXML($CONFIG{'OFFLINE_XML_RANG'}, \$DATA{'DOM'}); + parxeXML_section(); +} + +my $config_ref = &getVenueConfig(); +&benchmarkEnd(); +&printOutput($config_ref); + + +# SUBS + +sub db_getVenueConfig { + &Delimiter((caller(0))[3]); + + my $query = "Select \ + venues.AGENCY As VENUE_AGENCY, + venues.NAME As VENUE_NAME, + halls.NAME As HALL_NAME, + halls.CODE As HALL_CODE, + halls.`FRONT-INDICATOR_WIDTH` As HALL_FRONT_INDICATOR, + halls.`PADDING-LEFT` As HALL_PADDING_LEFT, + halls.`PADDING-LEFT-STAGE` As HALL_PADDING_LEFT_STAGE, + halls.MAX_TICKETS_PER_USER As HALL_MAX_TICKETS_PER_USER, + halls.BUEHNE As HALL_BUEHNE, + halls.LEFT_NAMING As HALL_LEFT_NAMING, + halls.TONPULT As HALL_TONPULT, + halls.CSS As HALL_CSS, + halls.DESCRIPTION As HALL_DESC, + buyer_types.CODE As BUYER_TYPE_CODE, + buyer_types.DESCRIPTION As BUYER_TYPE_DESC, + halls.ID As HALL_ID + From + venues Inner Join + halls On halls.VENUE_ID = venues.ID Inner Join + buyer_types On buyer_types.VENUE_ID = halls.VENUE_ID + Where + venues.AGENCY = '$DATA{'PARAMETER'}{'supplier_code'}'"; + + print Dumper $query if $CONFIG{'DEBUG'}; + my $response = &db_query($query, $connection, 'selectall_arrayref'); + + my $query_config = "SELECT * FROM config"; + print Dumper $query_config if $CONFIG{'DEBUG'}; + my $response_config = &db_query($query_config, $connection, 'selectall_hashref', 'NAME'); + + return ($response, $response_config); +} + +sub accumulate_halls_data { + &Delimiter((caller(0))[3]); + my ($response) = @_; + + my %halls; + + for my $i (0 .. $#{$response}) { + # print Dumper $$response[$i]; + + my $hall_code = $$response[$i][3]; + $halls{$hall_code}{'VENUE_AGENCY'} = $$response[$i][0]; + $halls{$hall_code}{'VENUE_NAME'} = $$response[$i][1]; + $halls{$hall_code}{'HALL_NAME'} = $$response[$i][2]; + $halls{$hall_code}{'HALL_CODE'} = $$response[$i][3]; + $halls{$hall_code}{'HALL_FRONT_INDICATOR'} = $$response[$i][4]; + $halls{$hall_code}{'HALL_PADDING_LEFT'} = $$response[$i][5]; + $halls{$hall_code}{'HALL_PADDING_LEFT_STAGE'} = $$response[$i][6]; + $halls{$hall_code}{'HALL_MAX_TICKETS_PER_USER'} = $$response[$i][7]; + $halls{$hall_code}{'HALL_BUEHNE'} = $$response[$i][8]; + $halls{$hall_code}{'HALL_LEFT_NAMING'} = $$response[$i][9]; + $halls{$hall_code}{'HALL_TONPULT'} = $$response[$i][10]; + $halls{$hall_code}{'HALL_CSS'} = $$response[$i][11]; + $halls{$hall_code}{'HALL_DESC'} = $$response[$i][12]; + $halls{$hall_code}{'BUYER_TYPES'}{$$response[$i][13]} = $$response[$i][14]; + $halls{$hall_code}{'HALL_ID'} = $$response[$i][15]; + + my $hall_id = $$response[0][15]; + my $query_color = "SELECT * FROM custom_pricescales_color WHERE HALL_ID = $halls{$hall_code}{'HALL_ID'}"; + print Dumper $query_color if $CONFIG{'DEBUG'}; + my $response_color = &db_query($query_color, $connection, 'selectall_hashref', 'ID'); + if (%$response_color) { + $halls{$hall_code}{'CUSTOM_PRICESCALES_COLOR'} = $response_color; + } + + }; + + return \%halls; +} + +sub convert_to_config_format { + &Delimiter((caller(0))[3]); + my ($halls_ref, $response_config) = @_; + + + my %seatmap_config; + for my $hall_code (keys %{$halls_ref}) { + my $hall_name = $$halls_ref{$hall_code}{'HALL_NAME'}; + + $seatmap_config{$hall_code} = # HALL CONFIG + { + "FRONT-INDICATOR-WIDTH" => $$halls_ref{$hall_code}{'HALL_FRONT_INDICATOR'}, + "PADDING-LEFT" => $$halls_ref{$hall_code}{'HALL_PADDING_LEFT'}, + "PADDING-LEFT-STAGE" => $$halls_ref{$hall_code}{'HALL_PADDING_LEFT_STAGE'}, + "MAX_TICKETS_PER_USER" => $$halls_ref{$hall_code}{'HALL_MAX_TICKETS_PER_USER'}, + "BUEHNE" => $$halls_ref{$hall_code}{'HALL_BUEHNE'}, + "LEFT_NAMING" => $$halls_ref{$hall_code}{'HALL_LEFT_NAMING'}, + "CSS" => $$halls_ref{$hall_code}{'HALL_CSS'}, + }; + $seatmap_config{$hall_name} = # HALL BUYER TYPES + { + "AGENCY" => $$halls_ref{$hall_code}{'VENUE_AGENCY'}, + "BUYER_TYPES" => $$halls_ref{$hall_code}{'BUYER_TYPES'}, + }; + + if ($$halls_ref{$hall_code}{'CUSTOM_PRICESCALES_COLOR'}) { + for my $id (keys %{$$halls_ref{$hall_code}{'CUSTOM_PRICESCALES_COLOR'}}) { + my $code = $$halls_ref{$hall_code}{'CUSTOM_PRICESCALES_COLOR'}{$id}{'CODE'}; + my $color = $$halls_ref{$hall_code}{'CUSTOM_PRICESCALES_COLOR'}{$id}{'COLOR'}; + $seatmap_config{$hall_code}{'CUSTOM_PRICESCALES_COLOR'}{$code} = $color; + }; + } + + } + + for my $key (keys %$response_config) { + if ($key eq 'CORS_ANYWHERE') { + $seatmap_config{'CORS-ANYWHERE'}{'ROOT_URL'} = $$response_config{$key}{'VALUE'}; + } + else { + $seatmap_config{$key} = $$response_config{$key}{'VALUE'}; + } + }; + + + return \%seatmap_config; +} + +sub getVenueConfig { + &Delimiter((caller(0))[3]); + + # CONNECT TO DB + $connection = connectToMySql(); + + # GET DB DATA FOR VENUE / HALLS / BUYER TYPES + my ($response, $response_config) = db_getVenueConfig(); + + # CREATE ONE DATASET AND ACCUMULATE ALL BUYER TYPES FOR HALL + my $halls_ref = &accumulate_halls_data($response); + # print Dumper $halls_ref; + + # CONVERT DATA TO STEAMAP CONFIG FORMAT + my $seatmap_config_ref = convert_to_config_format($halls_ref, $response_config); + + # DISCONNECT FROM DB + $connection->disconnect(); + + return $seatmap_config_ref; +} + +sub db_query { + &Delimiter((caller(0))[3]); + my ($query, $connection, $switch, @rest) = @_; + my $response; + + my $statement; + if ($switch eq 'fetchrow') { + $statement = $connection->prepare($query); + $statement->execute(); + $response = $statement->fetchrow(); + } + elsif ($switch eq 'fetchall_hashref') { + $statement = $connection->prepare($query); + $statement->execute(); + $response = $statement->fetchall_hashref($rest[0]); + } + elsif ($switch eq 'fetchall_arrayref') { + $statement = $connection->prepare($query); + $statement->execute(); + $response = $statement->fetchall_arrayref(); + } + elsif ($switch eq 'do') { + $response = $connection->do($query) or die $connection->errstr; + } + elsif ($switch eq 'selectall_hashref') { + $response = $connection->selectall_hashref($query, $rest[0]) or die $connection->errstr; + } + elsif ($switch eq 'selectall_array') { + my @response = $connection->selectall_array($query) or die $connection->errstr; + return \@response; + } + elsif ($switch eq 'selectall_arrayref') { + $response = $connection->selectall_arrayref($query) or die $connection->errstr; + } + elsif ($switch eq 'selectrow_hashref') { + $response = $connection->selectrow_hashref($query) or die $connection->errstr; + } + $statement->finish if $statement; + + return $response; +} + +sub connectToMySql { + &Delimiter((caller(0))[3]); + + my $connectionInfo = "dbi:mysql:$CONFIG{'MYSQL'}{'database'};$CONFIG{'MYSQL'}{'hostname'}"; + + # make connection to database + my $connection = DBI->connect($connectionInfo, $CONFIG{'MYSQL'}{'user'}, $CONFIG{'MYSQL'}{'pw'}, { + RaiseError => 0, # SUGGESTED BY AnyEvent::DBI::MySQL + AutoCommit => 1, + mysql_auto_reconnect => 1, + }); + return $connection; +} + +sub wipeDataOverhead { + &Delimiter((caller(0))[3]); + + delete $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{'AVAILABILITY'}; + for my $pricescaleID (keys(%{$DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}})) { + delete $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'SEATS'}; + } +} + +sub printOutput { + my $config_ref = shift; + + if (!$CONFIG{'DEBUG'}) { + &wipeDataOverhead(); + # print header('application/json; charset=utf-8;'), encode_json $DATA{'COMPILED'}; + + print header( + -type => 'application/json', + -access_control_allow_origin => '*', + -charset => 'utf-8', + ); + + # FIX ENCODING + $DATA{'COMPILED'} = Encode::Deep::decode('utf-8', Encode::Deep::encode('cp850', $DATA{'COMPILED'})); + # my $encoded = Encode::Deep::encode('cp850', $DATA{'COMPILED'}); + # my $decoded = Encode::Deep::decode('utf-8', $encoded); + + # ADD SEATMAP CONFIG + $DATA{'COMPILED'}{'CONFIG'} = $config_ref; + + # OUTPUT JSON + print encode_json $DATA{'COMPILED'}; + } + elsif ($CONFIG{'DEBUG'} && $CONFIG{'DEBUG_PRINT_DATA'}) { + &Delimiter((caller(0))[3]); + + print "\n\n" . encode_json $DATA{'COMPILED'}; + # print "\n\n" . Dumper(\%DATA); + + } +} + +sub checkHost() { + &Delimiter((caller(0))[3]); + return if !$CONFIG{'ONLINE'}; + + my $URI = URI->new($DATA{'PARAMETER'}{'url'}, 'http'); + if (($URI->host() eq 'purchase.tickets.com') && $URI->scheme && $DATA{'PARAMETER'}{'url'}) { + print "VALID HOST\n" if $CONFIG{'DEBUG'}; + } + else { + die "INVALID OR MISSING HOST.\n"; + } +} + +sub benchmarkEnd() { + &Delimiter((caller(0))[3]); + + if ($CONFIG{'DEBUG'}) { + my $t1 = Benchmark->new; + my $td = timediff($t1, $t0); + print "BENCHMARK: ",timestr($td),"\n" if $CONFIG{'DEBUG'}; + } +} + +sub generateVenueUrl() { + &Delimiter((caller(0))[3]); + return if !$CONFIG{'ONLINE'}; + + $DATA{'PARAMETER'}{'urlVenue'} = $DATA{'PARAMETER'}{'url'} . "&supplier_code=$DATA{'PARAMETER'}{'supplier_code'}&bots_event_code=$DATA{'PARAMETER'}{'bots_event_code'}&event_sub_code=$DATA{'PARAMETER'}{'event_sub_code'}" . "&holdcode=0&event=$DATA{'PARAMETER'}{'event'}&nocache=0&inclpkg=Y&incloffer=Y&inclcartdetails=Y&inclCart=Y&inclvenue=Y"; +} + +sub getSeatmaps() { + &Delimiter((caller(0))[3]); + + for my $seatmapID (keys(%{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}})) { + my $url = $DATA{'PARAMETER'}{'url'} . "&supplier_code=$DATA{'PARAMETER'}{'supplier_code'}&bots_event_code=$DATA{'PARAMETER'}{'bots_event_code'}&event_sub_code=$DATA{'PARAMETER'}{'event_sub_code'}" . "&event=$DATA{'PARAMETER'}{'event'}&nocache=1&inclsection=Y&incloffer=Y&offer=0&inclseatmap=Y&inclCart=Y&holdcode=0&seatmap=$seatmapID"; + + print "GET SEATMAP $seatmapID...\n" if $CONFIG{'DEBUG'}; + &loadXML(get($url), \$DATA{'DOM'}); + parxeXML_section(); + } +} + +sub parxeXML_section { + &Delimiter((caller(0))[3]); + + my $id = $DATA{'DOM'}->findvalue('//seatmap/@id'); + #print "ID: $id\n"; + + # CREATE PRICE ARRAYS + foreach my $node ($DATA{'DOM'}->findnodes('//pricescale_config/pricescale')) { + my $pricescaleID = $node->findvalue('@id'); + @{$DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'SEATS'}} = split /,/, $node->findvalue('@mask'); + } + + # CREATE AVAILABILITY ARRAYS + @{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{'AVAILABILITY'}{'AVAILABLE'}} = split /,/, $DATA{'DOM'}->findvalue('//availability/@available_selectable_mask'); + @{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{'AVAILABILITY'}{'UNAVAILABLE'}} = split /,/, $DATA{'DOM'}->findvalue('//availability/@unavailable_unselectable_mask'); + + # CREATE SEATMAP_CONFIG ROWS + my $rowCalculated = 0; + foreach my $node ($DATA{'DOM'}->findnodes('//rows/row')) { + $rowCalculated++; + my @seats = split /\|/, $node->findvalue('@seats'); + my $yCoord = $node->findvalue('@y_cell_coord'); + #print Dumper(@seats); + + my $seatNR = 0; + foreach my $i (0 .. $#seats) { + $seatNR++; + my ($id1, $id2, $number, $sectionID, $row, $seatNR_parsed) = split /,/, $seats[$i]; + #print "ID1: $id1 ID2: $id2 NUMBER: $number SECTIONID: $sectionID ROW: $rowCalculated SEATNR: $seatNR\n"; + + $row =~ s/\s+$//; + ($DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ID1'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'X_COORD'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'SECTIONID'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ROW'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'SEATNR'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'Y_COORD'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ROW_PARSED'}, $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'SEATNR_PARSED'}) = ($id1, $number, $sectionID, $rowCalculated, $seatNR, $yCoord, $row, $seatNR_parsed); + + # SECTION DESC + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'SECTIONID_DESC'} = $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$sectionID}{'DESC'}; + + # CHECK PRICE AND ADD COLOR + for my $pricescaleID (keys(%{$DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}})) { + if ( grep( /^$id1$/, @{$DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'SEATS'}} ) ) { + #print "found it for price $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'PRICES'}{'REF_PRICE'}\n"; + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'PRICESCALES_ID'} = $pricescaleID; + + #%{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'PRICES'}} = %{$DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'PRICES'}}; + #$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'COLOR'} = $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$pricescaleID}{'COLOR'}; + } + } + + # CHECK AVAILABILITY + if ( grep( /^$id1$/, @{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{'AVAILABILITY'}{'AVAILABLE'}} ) ) { + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'AVAILABLE'} = 1; + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ENABLED'} = 1; + } + elsif ( grep( /^$id1$/, @{$DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{'AVAILABILITY'}{'UNAVAILABLE'}} ) ) { + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'AVAILABLE'} = 0; + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ENABLED'} = 1; + } + else { + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'AVAILABLE'} = 0; + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ROWS'}{$rowCalculated}{$seatNR}{'ENABLED'} = 0; + } + + } + } +} + +sub substituteUmlauts { + &Delimiter((caller(0))[3]); + my $string_ref = shift; + + $$string_ref =~ s/\x{251c}\x{255d}/ue/ if $$string_ref =~ /\x{251c}\x{255d}/; + $$string_ref =~ s/\x{251c}\x{2562}/oe/ if $$string_ref =~ /\x{251c}\x{2562}/; + $$string_ref =~ s/\x{251c}\x{f1}/ae/ if $$string_ref =~ /\x{251c}\x{f1}/; + $$string_ref =~ s/\x{251c}\x{cd}/a/ if $$string_ref =~ /\x{251c}\x{cd}/; + + $$string_ref = uc($$string_ref); +} + +sub fix_encoding() { + my $string = shift; + return decode('utf-8', encode('cp850', $string)); +} + +sub parseXML { + &Delimiter((caller(0))[3]); + + # EVENT + $DATA{'COMPILED'}{'EVENT'}{'ID'} = $DATA{'DOM'}->findvalue('//event/@id'); + $DATA{'COMPILED'}{'EVENT'}{'CODE'} = $DATA{'DOM'}->findvalue('//event/@code'); + $DATA{'COMPILED'}{'EVENT'}{'DESC'} = $DATA{'DOM'}->findvalue('//event/@desc'); + # $DATA{'COMPILED'}{'EVENT'}{'DESC'} = &fix_encoding($DATA{'COMPILED'}{'EVENT'}{'DESC'}); + + # &substituteUmlauts(\$DATA{'COMPILED'}{'EVENT'}{'DESC'}); + $DATA{'COMPILED'}{'EVENT'}{'PUBLIC_DESC'} = $DATA{'DOM'}->findvalue('//event/@public_desc'); + # &substituteUmlauts(\$DATA{'COMPILED'}{'EVENT'}{'PUBLIC_DESC'}); + $DATA{'COMPILED'}{'EVENT'}{'YEAR'} = $DATA{'DOM'}->findvalue('//event/@year'); + $DATA{'COMPILED'}{'EVENT'}{'MONTH'} = $DATA{'DOM'}->findvalue('//event/@month'); + $DATA{'COMPILED'}{'EVENT'}{'DAY'} = $DATA{'DOM'}->findvalue('//event/@day'); + $DATA{'COMPILED'}{'EVENT'}{'HOUR'} = $DATA{'DOM'}->findvalue('//event/@hour'); + $DATA{'COMPILED'}{'EVENT'}{'MINUTE'} = $DATA{'DOM'}->findvalue('//event/@minute'); + $DATA{'COMPILED'}{'EVENT'}{'DATETIME_DE'} = "$DATA{'COMPILED'}{'EVENT'}{'DAY'}.$DATA{'COMPILED'}{'EVENT'}{'MONTH'}.$DATA{'COMPILED'}{'EVENT'}{'YEAR'} $DATA{'COMPILED'}{'EVENT'}{'HOUR'}:$DATA{'COMPILED'}{'EVENT'}{'MINUTE'}"; + + # VENUE + $DATA{'COMPILED'}{'VENUE'}{'CODE'} = $DATA{'DOM'}->findvalue('//venue/@code'); + $DATA{'COMPILED'}{'VENUE'}{'DESC'} = $DATA{'DOM'}->findvalue('//venue/@desc'); + $DATA{'COMPILED'}{'VENUE'}{'NAME'} = $DATA{'DOM'}->findvalue('//venue/@name'); + $DATA{'COMPILED'}{'VENUE'}{'ID'} = $DATA{'DOM'}->findvalue('//venue/@id'); + + # VENUE PRICESCALES + foreach my $node ($DATA{'DOM'}->findnodes('//pricescales/pricescale')) { + my $id = $node->findvalue('@id'); + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'ID'} = $id; + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'CODE'} = $node->findvalue('@code'); + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'COLOR'} = $node->findvalue('@color'); + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'DESC'} = $node->findvalue('@desc'); + } + + # VENUE BUYER TYPES + foreach my $node ($DATA{'DOM'}->findnodes('//buyer_types/buyer_type')) { + my $id = $node->findvalue('@id'); + $DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'ID'} = $id; + $DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'CODE'} = $node->findvalue('@code'); + $DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'DESC'} = uc($node->findvalue('@desc')); + # &substituteUmlauts(\$DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'DESC'}); + $DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'DISPLAY_INDICATOR'} = uc($node->findvalue('@desc')); + # &substituteUmlauts(\$DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id}{'DISPLAY_INDICATOR'}); + } + + # MASTER CONFIG TO VENUE + $DATA{'COMPILED'}{'VENUE'}{'CAPACITY'} = $DATA{'DOM'}->findvalue('//master_config/@capacity'); + + # MASTER SECTION CONFIG + foreach my $node ($DATA{'DOM'}->findnodes('//master_config/section_config/section')) { + my $id = $node->findvalue('@id'); + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'ID'} = $id; + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'CODE'} = $node->findvalue('@code'); + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'DESC'} = $node->findvalue('@desc'); + } + + # PRICE_STRUCTURE PRICESCALE + foreach my $node ($DATA{'DOM'}->findnodes('//price_structure/pricescale')) { + my $id = $node->findvalue('@id'); + + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'CURRENCY'} = $node->findvalue('@currency'); + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'PRICES'}{'REF_PRICE'} = $node->findvalue('@ref_price'); + + # BUYER TYPES + foreach my $node_buyer ($node->findnodes('./buyer_type')) { + my $id2 = $node_buyer->findvalue('@id'); + my $desc = $DATA{'COMPILED'}{'VENUE'}{'BUYER_TYPES'}{$id2}{'DESC'}; + my $price = $node_buyer->findvalue('@price'); + $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id}{'PRICES'}{$desc} = $price; + } + } + + # SEATMAP_CONFIG + foreach my $node ($DATA{'DOM'}->findnodes('//seatmap_config/seatmap')) { + my $id = $node->findvalue('@id'); + + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'ID'} = $id; + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'CODE'} = $node->findvalue('@code'); + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'DESC'} = $node->findvalue('@desc'); + $DATA{'COMPILED'}{'VENUE'}{'SEATMAP_CONFIG'}{$id}{'HOTSPOT_COORDS'} = $node->findvalue('@hotspot_coords'); + } + + # MASTER SECTION INVENTORY + foreach my $node ($DATA{'DOM'}->findnodes('//master_config/section_inventory/section')) { + my $id = $node->findvalue('@id'); + + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'CAPACITY'} = $node->findvalue('@capacity'); + + # PRICESCALE + my $still_available = 0; + foreach my $node_pricescale ($node->findnodes('./pricescale')) { + my $id2 = $node_pricescale->findvalue('@id'); + my $available = $node_pricescale->findvalue('@available'); + $still_available += $available; + + my $price = $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id2}{'PRICES'}{'REF_PRICE'}; + my $code = $DATA{'COMPILED'}{'VENUE'}{'PRICESCALES'}{$id2}{'CODE'}; + + + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'AVAILABLILITY'}{$code}{'PRICE'} = $price; + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'AVAILABLILITY'}{$code}{'AVAILABLE'} = $available; + } + $DATA{'COMPILED'}{'VENUE'}{'SECTION_CONFIG'}{$id}{'STILL_AVAILABLE'} = $still_available; + } +} + +sub loadXML { + &Delimiter((caller(0))[3]); + my ($xml, $DATA_ref) = @_; + + # DELETE IF DOM ALREADY PRESENT + if (ref($$DATA_ref) eq 'XML::LibXML::Document') { + print 'DELETING EXISTING ' . ref($$DATA_ref) . "\n" if $CONFIG{'DEBUG'}; + $$DATA_ref = (); + } + + if (!$CONFIG{'ONLINE'}) { + print "LOADING $xml...\n" if $CONFIG{'DEBUG'}; + $$DATA_ref = eval { XML::LibXML->load_xml(location => $xml) } or die "DIE: XML LOADING ERROR\n" . $@; + } + elsif ($CONFIG{'ONLINE'}) { + print "LOADING XML...\n" if $CONFIG{'DEBUG'}; + $$DATA_ref = eval { XML::LibXML->load_xml(string => $xml) } or die "DIE: XML LOADING ERROR\n" . $@; + # $$DATA_ref = eval { decode('utf-8', encode('cp850', XML::LibXML->load_xml(string => $xml) ) ) } or die "DIE: XML LOADING ERROR\n" . $@; + } +} + +sub getParameter { + &Delimiter((caller(0))[3]); + return if !$CONFIG{'ONLINE'}; + + my $url = $ENV{QUERY_STRING}; + my $decoded = uri_decode($url); + my $uri = URI->new($decoded); + %{$DATA{'PARAMETER'}} = $uri->query_form; + $DATA{'PARAMETER'}{'url'} = url_param('url'); +} + +sub get { + &Delimiter((caller(0))[3]); + my $url = shift; + + if ($CONFIG{'ONLINE'}) { + print "GET:\n$url\n" if $CONFIG{'DEBUG'}; + + my $response = $ua->get($url); + print 'STATUS_LINE: ' . $response->status_line . "\n" if $CONFIG{'DEBUG'}; + if ($response->is_success) { + return $response->decoded_content; + } + else { + $response->code(); + $response->message(); + $response->status_line(); + } + } + elsif (!$CONFIG{'ONLINE'}) { + print "SET AS OFFLINE: USING LOCAL XML\n" if $CONFIG{'DEBUG'}; + } + +} + +sub Delimiter { + my $SubName = shift; + print "\n" . "\n> SUB " . $SubName . "\n" . '-' x 80 . "\n" if $CONFIG{'DEBUG'}; + #print "\n" . "-" x 80 . "\nSUB " . $SubName . "\n" . '-' x 80 . "\n"; +} + +exit; \ No newline at end of file