/** * Add Member to Tab * Tab owner adds a user. Validates target user not already on a tab. * * POST: { TabID: int, OwnerUserID: int, TargetUserID: int } */ try { requestData = deserializeJSON(toString(getHttpRequestData().content)); tabID = val(requestData.TabID ?: 0); ownerUserID = val(requestData.OwnerUserID ?: 0); targetUserID = val(requestData.TargetUserID ?: 0); if (tabID == 0) apiAbort({ "OK": false, "ERROR": "missing_TabID" }); if (ownerUserID == 0) apiAbort({ "OK": false, "ERROR": "missing_OwnerUserID" }); if (targetUserID == 0) apiAbort({ "OK": false, "ERROR": "missing_TargetUserID" }); // Verify tab exists, is open, and requester is owner qTab = queryTimed(" SELECT t.ID, t.OwnerUserID, t.StatusID, t.BusinessID, b.TabMaxMembers FROM Tabs t JOIN Businesses b ON b.ID = t.BusinessID WHERE t.ID = :tabID LIMIT 1 ", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" } }); if (qTab.recordCount == 0) apiAbort({ "OK": false, "ERROR": "tab_not_found" }); if (qTab.StatusID != 1) apiAbort({ "OK": false, "ERROR": "tab_not_open" }); if (qTab.OwnerUserID != ownerUserID) apiAbort({ "OK": false, "ERROR": "not_owner" }); // Check member limit qCount = queryTimed("SELECT COUNT(*) AS Cnt FROM TabMembers WHERE TabID = :tabID AND StatusID = 1", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" } }); if (qCount.Cnt >= val(qTab.TabMaxMembers)) { apiAbort({ "OK": false, "ERROR": "max_members", "MESSAGE": "Tab has reached the maximum number of members." }); } // Check target user not already on any tab qExisting = queryTimed(" SELECT t.ID, b.Name AS BusinessName FROM TabMembers tm JOIN Tabs t ON t.ID = tm.TabID JOIN Businesses b ON b.ID = t.BusinessID WHERE tm.UserID = :uid AND tm.StatusID = 1 AND t.StatusID = 1 LIMIT 1 ", { uid: { value: targetUserID, cfsqltype: "cf_sql_integer" } }); if (qExisting.recordCount > 0) { apiAbort({ "OK": false, "ERROR": "user_already_on_tab", "MESSAGE": "This user is already on a tab." }); } // Check target user exists qTarget = queryTimed("SELECT FirstName, LastName FROM Users WHERE ID = :uid LIMIT 1", { uid: { value: targetUserID, cfsqltype: "cf_sql_integer" } }); if (qTarget.recordCount == 0) apiAbort({ "OK": false, "ERROR": "user_not_found" }); // Add member queryTimed(" INSERT INTO TabMembers (TabID, UserID, RoleID, StatusID, JoinedOn) VALUES (:tabID, :userID, 2, 1, NOW()) ON DUPLICATE KEY UPDATE StatusID = 1, LeftOn = NULL, JoinedOn = NOW() ", { tabID: { value: tabID, cfsqltype: "cf_sql_integer" }, userID: { value: targetUserID, cfsqltype: "cf_sql_integer" } }); apiAbort({ "OK": true, "MEMBER": { "UserID": targetUserID, "FirstName": qTarget.FirstName, "LastName": qTarget.LastName, "RoleID": 2 } }); } catch (any e) { apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message }); }