From 2630a1707d0f5c72eda1da774cdf675444f52dd8 Mon Sep 17 00:00:00 2001 From: janis Date: Mon, 11 Sep 2023 16:47:18 +0200 Subject: [PATCH] seat counting working --- src/server/admin/api/postHandler.js | 16 +++++++-- src/server/backend/api/postHandler.js | 36 +++++++++---------- src/server/backend/db/data/eventDrafts.json | 2 +- src/server/backend/db/data/events.json | 2 +- src/server/backend/db/data/locations.json | 2 +- src/server/backend/db/data/seatplan.json | 2 +- src/server/backend/userAPIRoutes.js | 9 ++++- src/server/config/settings.config.json | 2 +- .../src/components/seatplan/editor/window.vue | 13 ++++--- .../seatplanComponents/seats/rectangular.vue | 4 ++- .../views/admin/events/EventsDetailsView.vue | 3 ++ .../main/src/views/purchasing/OrderView.vue | 2 +- 12 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/server/admin/api/postHandler.js b/src/server/admin/api/postHandler.js index e41a368..3b2c203 100644 --- a/src/server/admin/api/postHandler.js +++ b/src/server/admin/api/postHandler.js @@ -29,14 +29,26 @@ class POSTHandler { let dat = res; dat[ 'draft' ] = data.data; db.writeJSONDataSimple( 'seatplan', data.location, dat ).then( resp => { - resolve( resp ); + db.getJSONDataSimple( 'locations', data.location ).then( dat => { + let s = dat; + s[ 'totalSeats' ] = data.data.seatInfo.count + db.writeJSONDataSimple( 'locations', data.location, s ).then( () => { + resolve( resp ); + } ); + } ); } ).catch( error => { reject( { 'code': 500, 'error': error } ); } ); } ); } else if ( call === 'saveSeatplan' ) { db.writeJSONDataSimple( 'seatplan', data.location, { 'draft': {}, 'save': data.data } ).then( resp => { - resolve( resp ); + db.getJSONDataSimple( 'locations', data.location ).then( dat => { + let s = dat; + s[ 'totalSeats' ] = data.data.seatInfo.count + db.writeJSONDataSimple( 'locations', data.location, s ).then( () => { + resolve( resp ); + } ); + } ); } ).catch( error => { reject( { 'code': 500, 'error': error } ); } ); diff --git a/src/server/backend/api/postHandler.js b/src/server/backend/api/postHandler.js index 09cdd25..c606b04 100644 --- a/src/server/backend/api/postHandler.js +++ b/src/server/backend/api/postHandler.js @@ -17,32 +17,24 @@ class POSTHandler { db.getJSONData( 'booked' ).then( dat => { this.allSelectedSeats = dat; db.getJSONData( 'events' ).then( dat => { - db.getJSONData( 'seatplan' ).then( locations => { - this.events = dat; - // TODO: Load from event db subtract all occupied seats from the ordered db from it. - this.ticketTotals = {}; - for ( let event in this.events ) { - if ( locations[ this.events[ event ][ 'location' ] ] ) { - this.ticketTotals[ event ] = locations[ this.events[ event ][ 'location' ] ][ 'save' ][ 'seatInfo' ][ 'count' ]; - this.events[ event ][ 'maxTickets' ] = this.ticketTotals[ event ]; + this.events = dat; + this.ticketTotals = {}; + for ( let event in this.events ) { + this.ticketTotals[ event ] = this.events[ event ][ 'totalSeats' ]; + } + + for ( let event in this.allSelectedSeats ) { + for ( let t in this.allSelectedSeats[ event ] ) { + if ( this.allSelectedSeats[ event ][ t ][ 'count' ] ) { + this.ticketTotals[ event ] -= this.allSelectedSeats[ event ][ t ][ 'count' ]; } else { - this.ticketTotals[ event ] = this.events[ event ][ 'maxTickets' ]; + this.ticketTotals[ event ] -= 1 } } - - // console.log( this.events ); - // console.log( this.ticketTotals ); - - // for ( let order in this.allSelectedSeats ) { - - // } - // console.log( this.allSelectedSeats ); - } ); + } } ); } ); - this.ticketTotals = { 'test2': { 'ticket1': 5, 'ticket2': 5 } }; - this.settings = JSON.parse( fs.readFileSync( path.join( __dirname + '/../../config/settings.config.json' ) ) ); } @@ -197,6 +189,10 @@ class POSTHandler { getReservedSeats ( event ) { return this.allSelectedSeats[ event ] ? Object.values( this.allSelectedSeats[ event ] ) : {}; } + + getFreeSeatsCount() { + return this.ticketTotals; + } } module.exports = POSTHandler; \ No newline at end of file diff --git a/src/server/backend/db/data/eventDrafts.json b/src/server/backend/db/data/eventDrafts.json index f2d2b4d..e933647 100644 --- a/src/server/backend/db/data/eventDrafts.json +++ b/src/server/backend/db/data/eventDrafts.json @@ -1 +1 @@ -{"test4":{"name":"Test4Event","description":"Let's see what happens if I update the description, how fast it is reflected in the UI","location":"test2","date":"2023-10-30T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#ff0000","fg":"#ff0000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"CHF","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true}} \ No newline at end of file +{"test4":{"name":"Test4Event","description":"Let's see what happens if I update the description, how fast it is reflected in the UI","location":"test2","date":"2023-10-30T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#ff0000","fg":"#ff0000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"CHF","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true,"totalSeats":353}} \ No newline at end of file diff --git a/src/server/backend/db/data/events.json b/src/server/backend/db/data/events.json index f2d2b4d..e933647 100644 --- a/src/server/backend/db/data/events.json +++ b/src/server/backend/db/data/events.json @@ -1 +1 @@ -{"test4":{"name":"Test4Event","description":"Let's see what happens if I update the description, how fast it is reflected in the UI","location":"test2","date":"2023-10-30T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#ff0000","fg":"#ff0000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"CHF","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true}} \ No newline at end of file +{"test4":{"name":"Test4Event","description":"Let's see what happens if I update the description, how fast it is reflected in the UI","location":"test2","date":"2023-10-30T10:00:00.000Z","categories":{"1":{"price":{"1":20,"2":30},"bg":"#ff0000","fg":"#ff0000","name":"Category 1","id":"1","ticketCount":1}},"ageGroups":{"1":{"id":1,"name":"Child","age":"0 - 15.99"},"2":{"id":2,"name":"Adult"}},"maxTickets":0,"eventID":"test4","time":"10:00:00.000","startingPrice":20,"currency":"CHF","isDraft":true,"locationName":"TestLocation2","hasSeatplan":true,"totalSeats":353}} \ No newline at end of file diff --git a/src/server/backend/db/data/locations.json b/src/server/backend/db/data/locations.json index 055c4f0..2d6f48b 100644 --- a/src/server/backend/db/data/locations.json +++ b/src/server/backend/db/data/locations.json @@ -1 +1 @@ -{"test2":{"locationID":"test2","name":"TestLocation2","seatplan-enabled":true},"test":{"locationID":"test","name":"TestLocation","seatplan-enabled":true}} \ No newline at end of file +{"test2":{"locationID":"test2","name":"TestLocation2","seatplan-enabled":true,"totalSeats":352},"test":{"locationID":"test","name":"TestLocation","seatplan-enabled":true}} \ No newline at end of file diff --git a/src/server/backend/db/data/seatplan.json b/src/server/backend/db/data/seatplan.json index 26b5b35..20b75a1 100644 --- a/src/server/backend/db/data/seatplan.json +++ b/src/server/backend/db/data/seatplan.json @@ -1 +1 @@ -{"test2":{"draft":{"seatInfo":{"data":{"1":{"0":22}},"count":0},"data":{"1":{"x":298.694,"y":17.138,"h":564.336,"w":730.822,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":359.068,"y":661.764,"h":121.192,"w":603.509,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":519.608,"y":671.569,"h":83.243,"w":306.039,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}},"save":{"seatInfo":{"data":{"1":{"0":22},"2":{"0":9},"3":{"0":9}},"count":100},"data":{"1":{"x":299.02,"y":17.157,"h":564.951,"w":731.618,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":359.069,"y":661.765,"h":121.324,"w":604.167,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":519.608,"y":671.569,"h":83.333,"w":306.373,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}}},"test":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22}},"count":0},"data":{"1":{"x":427.696,"y":160.539,"h":371.324,"w":734.069,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"stand","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1","ticketCount":50}}}}} \ No newline at end of file +{"test2":{"draft":{"seatInfo":{"data":{"1":{"0":22,"1":22,"2":22,"3":22,"4":22,"5":22,"6":22,"7":22,"8":22,"9":22,"10":22,"11":22,"12":22,"13":22,"14":22,"15":22}},"count":352},"data":{"1":{"x":296.892,"y":13.495,"h":560.66,"w":728.735,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":357.007,"y":660.033,"h":117.775,"w":601.145,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":517.721,"y":669.847,"h":80.971,"w":304.253,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}},"save":{"seatInfo":{"data":{"1":{"0":22,"1":22,"2":22,"3":22,"4":22,"5":22,"6":22,"7":22,"8":22,"9":22,"10":22,"11":22,"12":22,"13":22,"14":22,"15":22}},"count":0},"data":{"1":{"x":296.892,"y":13.495,"h":560.66,"w":728.735,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"seat","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1"},"2":{"x":357.375,"y":660.049,"h":117.775,"w":601.145,"active":false,"draggable":true,"resizable":true,"id":2,"origin":3,"shape":"rectangular","type":"stage","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"ticketCount":1,"numberingDirection":"left","category":"1"},"3":{"x":517.828,"y":670.99,"h":80.971,"w":304.253,"active":false,"draggable":true,"resizable":true,"id":3,"origin":1,"shape":"rectangular","type":"text","startingRow":1,"seatNumberingPosition":2,"sector":"A","text":{"text":"Stage","textSize":25,"colour":"#2160ff"},"ticketCount":1,"numberingDirection":"left","category":"1"}}}},"test":{"draft":{},"save":{"seatInfo":{"data":{"1":{"0":22}},"count":0},"data":{"1":{"x":427.696,"y":160.539,"h":371.324,"w":734.069,"active":false,"draggable":true,"resizable":true,"id":1,"origin":1,"shape":"rectangular","type":"stand","startingRow":1,"seatNumberingPosition":1,"sector":"A","text":{"text":"TestText","textSize":20,"colour":"#20FFFF"},"numberingDirection":"left","category":"1","ticketCount":50}}}}} \ No newline at end of file diff --git a/src/server/backend/userAPIRoutes.js b/src/server/backend/userAPIRoutes.js index 0bf9384..7b9ceec 100644 --- a/src/server/backend/userAPIRoutes.js +++ b/src/server/backend/userAPIRoutes.js @@ -22,7 +22,14 @@ module.exports = ( app, settings ) => { let dat = data; dat[ 'reserved' ] = postHandler.getReservedSeats( req.query.event ); res.send( dat ); - } else { + } else if ( req.params.call === 'getAllEvents' ) { + let dat = data; + const freeSeats = postHandler.getFreeSeatsCount(); + for ( let event in freeSeats ) { + dat[ event ][ 'free' ] = freeSeats[ event ]; + } + res.send( dat ); + }else { res.send( data ); } } ).catch( error => { diff --git a/src/server/config/settings.config.json b/src/server/config/settings.config.json index 3d6a25a..06161c2 100644 --- a/src/server/config/settings.config.json +++ b/src/server/config/settings.config.json @@ -3,7 +3,7 @@ "setupDone":true, "twoFA":"enforce", "twoFAMode":"enhanced", - "db":"mysql", + "db":"json", "payments":"stripe", "name":"libreevent", "yourDomain":"http://localhost:8080", diff --git a/src/webapp/main/src/components/seatplan/editor/window.vue b/src/webapp/main/src/components/seatplan/editor/window.vue index b33affb..1361ff4 100644 --- a/src/webapp/main/src/components/seatplan/editor/window.vue +++ b/src/webapp/main/src/components/seatplan/editor/window.vue @@ -15,12 +15,16 @@ - - - + + + - + @@ -410,6 +414,7 @@ }, handleSeatCountInfo ( info ) { this.seatCountInfo[ 'data' ][ info.id ] = info.data; + this.seatCountInfo[ 'data' ][ info.id ][ 'startingRow' ] = this.draggables[ info.id ].startingRow; }, getSeatCount () { this.seatCountInfo[ 'count' ] = document.getElementsByClassName( 'seats' ).length; diff --git a/src/webapp/main/src/components/seatplan/seatplanComponents/seats/rectangular.vue b/src/webapp/main/src/components/seatplan/seatplanComponents/seats/rectangular.vue index f062b72..68e92fa 100644 --- a/src/webapp/main/src/components/seatplan/seatplanComponents/seats/rectangular.vue +++ b/src/webapp/main/src/components/seatplan/seatplanComponents/seats/rectangular.vue @@ -59,9 +59,10 @@ export default { let h = Math.floor( this.h / this.scaleFactor ); const size = 33; this.seats = {}; - let details = { 'data': { '0': Math.floor( w / size ) }, 'id': this.id }; + let details = { 'data': {}, 'id': this.id }; for ( let row = 0; row < Math.floor( h / size ); row++ ) { this.seats[ row ] = {}; + details.data[ row ] = Math.floor( w / size ); for ( let n = 0; n < Math.floor( w / size ); n++ ) { if ( this.origin === 1 ) { this.seats[ row ][ n ] = { 'style': `font-size: ${this.scaleFactor * 200}%; bottom: ${ row * size * this.scaleFactor }px; left: ${ n * size * this.scaleFactor }px; rotate: ${ this.origin / 4 - 0.25 }turn;` }; @@ -74,6 +75,7 @@ export default { } } } + this.$emit( 'seatingInfo', details ); }, setScaleFactor () { diff --git a/src/webapp/main/src/views/admin/events/EventsDetailsView.vue b/src/webapp/main/src/views/admin/events/EventsDetailsView.vue index e20e2c2..4f8544d 100644 --- a/src/webapp/main/src/views/admin/events/EventsDetailsView.vue +++ b/src/webapp/main/src/views/admin/events/EventsDetailsView.vue @@ -342,6 +342,7 @@ } let lowestPrice = 1000000; + let totalSeats = parseInt( this.locations[ this.event.location ].totalSeats ); for ( let category in this.event.categories ) { for ( let price in this.event.categories[ category ].price ) { if ( this.event.categories[ category ].price[ price ] < 0.5 || ( !this.event.categories[ category ].ticketCount && this.hasSeatPlan ) ) { @@ -352,12 +353,14 @@ lowestPrice = this.event.categories[ category ].price[ price ]; }; } + totalSeats += parseInt( this.event.categories[ category ].ticketCount ?? 0 ); } this.event[ 'startingPrice' ] = lowestPrice; this.event[ 'currency' ] = this.currency; this.event[ 'locationName' ] = this.locations[ this.event.location ].name; this.event[ 'hasSeatplan' ] = this.hasSeatPlan; + this.event[ 'totalSeats' ] = totalSeats; const fullDate = new Date( this.event.date + 'T' + this.event.time +'Z' ); this.event.date = fullDate.toISOString(); if ( !this.event.maxTickets ) { diff --git a/src/webapp/main/src/views/purchasing/OrderView.vue b/src/webapp/main/src/views/purchasing/OrderView.vue index a89d577..e789005 100644 --- a/src/webapp/main/src/views/purchasing/OrderView.vue +++ b/src/webapp/main/src/views/purchasing/OrderView.vue @@ -19,7 +19,7 @@

{{ event.description }}

-

Free seats: {{ event.free }} / {{ event.maxTickets }}

+

Free seats: {{ event.free }} / {{ event.totalSeats }}

{{ event.locationName }}, {{ event.dateString }}

Starting at {{ event.currency }} {{ event.startingPrice }}