From 234d809ebfef28a0afc22f115f48fcabbc097895 Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Tue, 8 Aug 2023 15:53:10 +0200 Subject: [PATCH] completely re-engineered backend for tickets --- src/server/backend/api/getHandler.js | 10 +- src/server/backend/api/postHandler.js | 154 +++++++++++------- src/server/config/settings.config.json | 2 +- src/webapp/main/src/components/noseatplan.vue | 133 +++++++++------ .../seatplan/userApp/userWindow.vue | 9 - .../views/purchasing/TicketsOrderingView.vue | 2 +- 6 files changed, 178 insertions(+), 132 deletions(-) diff --git a/src/server/backend/api/getHandler.js b/src/server/backend/api/getHandler.js index 55bf42b..69e9a76 100644 --- a/src/server/backend/api/getHandler.js +++ b/src/server/backend/api/getHandler.js @@ -28,12 +28,10 @@ class GETHandler { } ); } else if ( call === 'getReservedSeats' ) { if ( query.event ) { - db.getJSONDataSimple( 'booked', query.event ).then( data => { - db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => { - resolve( { 'booked': data ?? {}, 'user': dat[ 0 ] ? JSON.parse( dat[ 0 ].data )[ query.event ] ?? {} : {} } ); - } ); - } ).catch( error => { - reject( { 'code': 500, 'message': error } ); + db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => { + resolve( { 'user': dat[ 0 ] ? JSON.parse( dat[ 0 ].data )[ query.event ] ?? {} : {} } ); + } ).catch( () => { + reject( { 'code': 500, 'message': 'ERR_DB' } ); } ); } else { reject( { 'code': 400, 'message': 'Bad request, missing event query' } ); diff --git a/src/server/backend/api/postHandler.js b/src/server/backend/api/postHandler.js index c62ee99..028bb8a 100644 --- a/src/server/backend/api/postHandler.js +++ b/src/server/backend/api/postHandler.js @@ -7,81 +7,111 @@ * */ +const path = require( 'path' ); const db = require( '../db/db.js' ); +const fs = require( 'fs' ); class POSTHandler { constructor () { - this.allSelectedSeats = { 'test2': { 'secAr1s1': { 'id': 'secAr1s1', 'component': 1 } } }; + db.getJSONData( 'booked' ).then( dat => { + this.allSelectedSeats = dat; + } ); + // this.allSelectedSeats = { 'test2': { 'secAr1s1': { 'id': 'secAr1s1', 'component': 1 } } }; this.ticketTotals = { 'test2': { 'ticket1': 5, 'ticket2': 5 } }; - this.settings = { 'maxTickets': 10 }; + this.settings = JSON.parse( fs.readFileSync( path.join( __dirname + '/../../config/settings.config.json' ) ) ); } // Add lang in the future handleCall ( call, data, session ) { return new Promise( ( resolve, reject ) => { if ( call === 'reserveTicket' ) { - // TODO: Completely rework to optimize for speed. - db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => { - let transmit = {}; - if ( dat.length > 0 ) { - transmit = JSON.parse( dat[ 0 ].data ); - } + if ( data.count || data.count === 0 ) { + db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => { + if ( dat[ 0 ] ) { + let totalTicketsPerID = {}; + // sum up total of tickets per category (based on a sliced ID of the ticket selected, + // as ticketID is based on category and ageGroup) + let tickets = JSON.parse( dat[ 0 ].data )[ data.eventID ]; + for ( let ticket in tickets ) { + if ( !totalTicketsPerID[ ticket.slice( 0, ticket.indexOf( '_' ) ) ] ) { + totalTicketsPerID[ ticket.slice( 0, ticket.indexOf( '_' ) ) ] = 0; + } + totalTicketsPerID[ ticket.slice( 0, ticket.indexOf( '_' ) ) ] += tickets[ ticket ].count; + } + const id = data.id.slice( 0, data.id.indexOf( '_' ) ); + + if ( !totalTicketsPerID[ id ] ) { + totalTicketsPerID[ id ] = 0; + } + totalTicketsPerID[ id ] += 1; + + let totalTickets = 0; + for ( let category in totalTicketsPerID ) { + totalTickets += totalTicketsPerID[ category ]; + } + + if ( totalTickets <= this.settings.maxTickets ) { + if ( totalTicketsPerID[ id ] <= this.ticketTotals[ data.eventID ][ id ] ) { + let info = {}; + info[ data.eventID ] = tickets; + if ( data.count < 1 ) { + if ( Object.keys( info[ data.eventID ] ).length < 1 ) { + delete info[ data.eventID ]; + } else { + delete info[ data.eventID ][ data.id ]; + } + } else { + info[ data.eventID ][ data.id ] = data; + } + let ticketCount = data.count; + const maxTickets = this.ticketTotals[ data.eventID ][ data.id.slice( 0, data.id.indexOf( '_' ) ) ]; + if ( ticketCount > maxTickets ) { + ticketCount = maxTickets; + } + if ( maxTickets > 0 ) { + db.writeDataSimple( 'temp', 'user_id', session.id, { 'user_id': session.id, 'timestamp': new Date().toDateString(), 'data': JSON.stringify( info ) } ); + resolve( { 'status': 'ok', 'ticketCount': ticketCount } ); + } else { + reject( { 'code': 409, 'message': 'ERR_ALL_OCCUPIED' } ); + } + } + } else { + reject( { 'code': 418, 'message': 'ERR_TOO_MANY_TICKETS' } ); + } + } else { + let info = {}; + info[ data.eventID ] = {}; + info[ data.eventID ][ data.id ] = data; + let ticketCount = data.count; + const maxTickets = this.ticketTotals[ data.eventID ][ data.id.slice( 0, data.id.indexOf( '_' ) ) ]; + if ( ticketCount > maxTickets ) { + ticketCount = maxTickets; + } + if ( maxTickets > 0 ) { + db.writeDataSimple( 'temp', 'user_id', session.id, { 'user_id': session.id, 'timestamp': new Date().toDateString(), 'data': JSON.stringify( info ) } ); + resolve( { 'status': 'ok', 'ticketCount': ticketCount } ); + } else { + reject( { 'code': 409, 'message': 'ERR_ALL_OCCUPIED' } ); + } + } + } ); + } else { if ( !this.allSelectedSeats[ data.eventID ] ) { this.allSelectedSeats[ data.eventID ] = {}; } - - if ( !transmit[ data.eventID ] ) { - transmit[ data.eventID ] = {}; + if ( this.allSelectedSeats[ data.eventID ][ data.id ] ) { + reject( { 'code': 409, 'message': 'ERR_ALREADY_SELECTED' } ); + } else { + let info = {}; + info[ data.eventID ] = {}; + info[ data.eventID ][ data.id ] = data; + db.writeDataSimple( 'temp', 'user_id', session.id, { 'user_id': session.id, 'timestamp': new Date().toDateString(), 'data': JSON.stringify( info ) } ).catch( err => { + console.error( err ); + } ); + resolve( 'ok' ); } - - if ( this.allSelectedSeats[ data.eventID ][ data.id ] && !data.count ) { - reject( { 'code': 409, 'message': 'ERR_SEAT_SELECTED' } ); - return; - } - db.getJSONDataSimple( 'booked', data.eventID ).then( booked => { - transmit[ data.eventID ][ data.id ] = data; - // TODO: Prevent seat selection if already taken (also if in booked!) - // TODO: Respect max ticket count per user - // TODO: maybe move to per event setting - let totalUserTickets = 0; - for ( let event in transmit ) { - for ( let ticket in transmit[ event ] ) { - totalUserTickets += transmit[ event ][ ticket ][ 'count' ] ?? 1; - } - } - if ( totalUserTickets <= this.settings.maxTickets ) { - if ( data.count ) { - if ( this.ticketTotals[ data.eventID ] ) { - if ( data.count <= ( this.ticketTotals[ data.eventID ][ data.id.slice( 0, data.id.indexOf( '_' ) ) ] ?? 1 ) ) { - transmit[ data.eventID ][ data.id ][ 'count' ] = data.count; - this.allSelectedSeats[ data.eventID ].push( { 'id': data.id, 'component': data.component, 'count': data.count } ); - } else { - reject( { 'code': 409, 'message': this.ticketTotals[ data.eventID ] ?? 1 } ); - return; - } - } else { - reject( { 'code': 400, 'message': 'ERR_UNKNOWN_EVENT' } ); - return; - } - } else { - this.allSelectedSeats[ data.eventID ].push( { 'id': data.id, 'component': data.component } ); - } - db.writeDataSimple( 'temp', 'user_id', session.id, { 'user_id': session.id, 'data': JSON.stringify( transmit ), 'timestamp': new Date().toString() } ).then( () => { - resolve( 'ok' ); - } ).catch( error => { - console.error( error ); - reject( { 'code': 500, 'message': 'ERR_DB' } ); - } ); - } else { - reject( { 'code': 418, 'message': 'ERR_TOO_MANY_TICKETS' } ); - return; - } - } ); - } ).catch( error => { - console.error( error ); - reject( { 'code': 500, 'message': 'ERR_DB' } ); - } ); + } } else if ( call === 'deselectTicket' ) { db.getDataSimple( 'temp', 'user_id', session.id ).then( dat => { let transmit = {}; @@ -111,9 +141,7 @@ class POSTHandler { } else { reject( { 'code': 404, 'message': 'ERR_DATA_NOT_FOUND' } ); return; - } - - + } db.writeDataSimple( 'temp', 'user_id', session.id, { 'user_id': session.id, 'data': JSON.stringify( transmit ) } ).then( () => { resolve( 'ok' ); @@ -130,7 +158,7 @@ class POSTHandler { } getReservedSeats ( event ) { - return Object.values( this.allSelectedSeats[ event ] ); + return this.allSelectedSeats[ event ] ? Object.values( this.allSelectedSeats[ event ] ) : {}; } } diff --git a/src/server/config/settings.config.json b/src/server/config/settings.config.json index f42600a..6a3e9d1 100644 --- a/src/server/config/settings.config.json +++ b/src/server/config/settings.config.json @@ -7,5 +7,5 @@ "name": "libreevent", "yourDomain": "http://localhost:8080", "mailSender": "libreevent ", - "maxTickets": 3 + "maxTickets": 10 } \ No newline at end of file diff --git a/src/webapp/main/src/components/noseatplan.vue b/src/webapp/main/src/components/noseatplan.vue index bfe16d7..99d6948 100644 --- a/src/webapp/main/src/components/noseatplan.vue +++ b/src/webapp/main/src/components/noseatplan.vue @@ -1,23 +1,24 @@