Automating The Processes At A Sports Club In USA Saved $1.4 Million

About Our Client

Our client is one of the top private country clubs in Florida, USA.  It is the most fabulous resort with Golf, Tennis courts, Spa, Fitness center, Pool, and multiple restaurants.  

Employing more than 100 people to support the execution of daily operations, itā€™s major focus is to create unforgettable experiences for its customers.
 

Requirements and Challenges

When our clientā€™s customers need to book the golf or tennis court or a table in the restaurant, they need to call the reception, check the availability and then book it. From the customer satisfaction survey, our client found out that their customers were not able to get the information about their bookings quickly through calls and the reception lines were always busy. Moreover managing the back office with spreadsheets and manual intervention was tedious and time-consuming.

Our client decided to opt for a solution that can automate the whole process and enhances the customer experience. Moreover, the solution requested should minimize overall operations costs along with time and labor.  Approached us to provide an appropriate solution as per his requirement.

Our Solution

As per the requirements of the client, we have analyzed the current process of the client and built a web application along with the mobile app (iOS and Android). 

Through the app, our clientā€™s customers can log-in and check the availability of the golf, tennis courts and other service offerings and book them in online mode. Through the admin access to the application, our client was able to manage the backend process.

Here are a few screenshots of the application we have developed.

To watch the demo of the application, schedule a meeting with us now! 
 

Results

Engagement & retention of the members increased by 100%

Member loyalty improved.

Convenience for the employees improved by 225%

Here iā€™m using uploads variable as an object, creating a property based on fileId in uploads object and deleting it once the process is completed.

const fs = require(‘fs’);
import socket from “./socket”
let uploads = {};
async function uploadFiles(req, res) {
 let fileId = req.query[‘fileId’];
 let startByte = 0;
 let name = req.query[‘name’];
 let mimetype = req.query[‘mimetype’];
 let fileSize = parseInt(req.query[‘size’], 10);
 let perc;
 console.log(‘file Size’, fileSize, fileId, startByte);
 let file = {
   preview: req.query[“preview”],
   size: req.query[“size”],
   name: req.query[“name”],
   type: req.query[“mimetype”]
 }
 if (!fileId) {
      res.writeHead(400, “No file id”);
        res.end(400);
 }
 if (!uploads[fileId])
   uploads[fileId] = {}; 
let upload = uploads[fileId];

Here config.path in the sense path where we are uploading the file, from the query I’m getting uploadPath, it is a directory where I should place a file. ā€œfs.existsSync()ā€ checking whether directory exist or not, if not creating a directory using ā€œfs.mkdirSync()ā€

req.uploadPath = req.query.uploadPath;
 if (req.query.uploadPath && req.query.directory) {
   if (!fs.existsSync(config.path + req.uploadPath)) {
     fs.mkdirSync(config.path + req.uploadPath)
   }
   req.uploadPath = req.uploadPath + “/” + req.query.directory;
 }
 if (!fs.existsSync(config.path + req.uploadPath)) {
   fs.mkdirSync(config.path + req.uploadPath)
}

We have imported fs in the beginning of the code.

     let fileStream;
           if (!startByte) {
                 upload.bytesReceived = 0;
                // This create a writable stream to the path
               fileStream = fs.createWriteStream(config.path + req.uploadPath + “/” + name, {
                flags: ‘w’
           });
        } else {
           fileStream = fs.createWriteStream(config.path + req.uploadPath + “/” + name, {
           flags: ‘a’
      });
 }

From content-length we will get the total size of a file and we saving that data in total variable, from ā€œreq.on(ā€˜data;ā€™)ā€ we will get information by listening to the data stream, ā€data.lengthā€ will give us how much data has been processed from there we are calculating the completed percentage of the file using  perc = parseInt((upload.bytesReceived / total) * 100);

Emit call for event ā€œprogressā€, here we emit an object response, how much data has been processed in percentages.   After completion of the data stream we call pipe stream , This pipes the post data to the file

    var total = req.headers[‘content-length’];
       req.on(‘data’, function (data) {
        upload.bytesReceived += data.length;
        perc = parseInt((upload.bytesReceived / total) * 100);
       let response = {
           text: ‘percent complete: ‘ + perc + ‘%n’,
           percentage: perc,
           name: name,
           mimetype: mimetype,
           path: config.path + req.uploadPath + “/” + name,
           filePath: req.uploadPath + “/” + name,
          file: file
       }
   socket.emit(‘progress’, response);
 });
 req.pipe(fileStream);
 

When the request is finished we call a close stream to check whether data processed completely or not .
If bytes received while processing file equals to total bytes of the file which we get from API header from starting. If both are equal we send a response text with some data which we required for further operations. If both bytes are not the same, it means while processing data is corrupted, we send an event with the same event name ā€œprogressā€ like file unfinished.  If there is an error in close, like input and output errors, an error stream will be called and ends the process by sending an error response.

Leave A Comment

Your email address will not be published. Required fields are marked *