From 4251b5522bc50d61144e746cb5bfe47afa1c0c7a Mon Sep 17 00:00:00 2001 From: Rob Ellison Date: Sat, 11 Nov 2023 14:52:51 +0000 Subject: [PATCH] feat: remove unused reservations --- components/resourcing/DemandTable.js | 4 +- components/resourcing/FileUpload.js | 2 +- components/resourcing/ResourceTable.js | 209 +++++++-- lib/redis/index.js | 33 ++ pages/api/resourcing/demand.js | 236 ++++++++++ pages/api/resourcing/resources.js | 151 +++--- pages/api/resourcing/users.json | 616 +++++-------------------- 7 files changed, 626 insertions(+), 625 deletions(-) create mode 100644 pages/api/resourcing/demand.js diff --git a/components/resourcing/DemandTable.js b/components/resourcing/DemandTable.js index 5bf19f8d..ed662bd3 100644 --- a/components/resourcing/DemandTable.js +++ b/components/resourcing/DemandTable.js @@ -135,7 +135,7 @@ export function DemandTable() { const fetchData = async () => { setIsLoading(true); try { - const response = await fetch('/api/resourcing/resources?demand=true'); + const response = await fetch('/api/resourcing/demand?demand=true'); if (!response.ok) throw new Error('Network response was not ok'); const fetchedData = await response.json(); if (fetchedData.content) { @@ -160,7 +160,7 @@ export function DemandTable() { } try { - const response = await fetch('/api/resourcing/resources'); + const response = await fetch('/api/resourcing/demand'); if (!response.ok) throw new Error('Network response was not ok'); const fetchedData = await response.json(); if (fetchedData.content) { diff --git a/components/resourcing/FileUpload.js b/components/resourcing/FileUpload.js index 386ac43a..b7714ac3 100644 --- a/components/resourcing/FileUpload.js +++ b/components/resourcing/FileUpload.js @@ -51,7 +51,7 @@ export const FileUpload = () => { formData.append('file', file); try { - const response = await fetch('/api/resourcing/resources', { + const response = await fetch('/api/resourcing/demand', { method: 'POST', body: formData, }); diff --git a/components/resourcing/ResourceTable.js b/components/resourcing/ResourceTable.js index 4f766ed5..b86cbbe4 100644 --- a/components/resourcing/ResourceTable.js +++ b/components/resourcing/ResourceTable.js @@ -22,6 +22,7 @@ import { Stack } from '@mui/material'; + import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; @@ -38,30 +39,136 @@ function determineColor(daysAllocated, daysHypo) { function UserPopup({ data, open, handleClose }) { // Example toggles' state - const [toggle1, setToggle1] = useState(false); - const [toggle2, setToggle2] = useState(false); - const [toggle3, setToggle3] = useState(false); + const [toggleSC, setToggleSC] = useState(false); + const [toggleTIR, setToggleTIR] = useState(false); + const [toggleMH, setToggleMH] = useState(false); + const [resource, setResource] = useState(null); + + const updateUser = async () => { + const recordProposal = { 'resource': data.mail, 'sc': toggleSC, 'tir': toggleTIR, 'mh': toggleMH } + console.log('updated:', recordProposal) + try { + const response = await fetch('/api/resourcing/resources', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(recordProposal), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + console.log(result); // Process the response as needed + + } catch (error) { + console.error('There was a problem with the fetch operation:', error); + } + } // Handle toggle change const handleToggleChange = (toggleSetter) => (event) => { toggleSetter(event.target.checked); }; + useEffect(() => { + if (resource) { + setToggleSC(resource.sc); + setToggleTIR(resource.tir); + setToggleMH(resource.mh); + } + }, [resource]); + + useEffect(() => { + if (resource) { + updateUser(); + } + }, [toggleSC, toggleTIR, toggleMH]); + + + useEffect(() => { + const fetchData = async () => { + + try { + const response = await fetch('/api/resourcing/resources?resource=' + data.mail); + if (!response.ok) throw new Error('Network response was not ok'); + const fetchedData = await response.json(); + // console.log('Resource:response: ', response) + + + if (fetchedData.content && fetchedData.content.length > 0) { + const jsonParsedData = JSON.parse(fetchedData.content) + setResource(jsonParsedData); // Adjust according to actual API response + } else { // record doesn't exist yet + const recordProposal = { 'resource': data.mail, 'sc': false, 'tir': false, 'mh': false } + + setResource(recordProposal); // Adjust according to actual API response + } + + + // console.log('Resource:jsonParsedData: ', jsonParsedData) + + + } catch (err) { + console.error('Resource:ERROR: ', err) + } + }; + + fetchData(); + }, []); + + + + + const LoadingSkeleton = () => { + return ( + + {Array.from(new Array(3)).map((_, index) => ( + } + label={} + /> + ))} + + ); + }; + + if (!resource) { + return ( + + + {data.displayName || data.name} {" - " + data.jobTitle || ""} + + + + + + + + + ); + } + + return ( - {data.displayName || data.name} + {data.displayName || data.name} {" - " + data.jobTitle || ""} + } label="SC Cleared" @@ -69,8 +176,8 @@ function UserPopup({ data, open, handleClose }) { } label="TIR" @@ -78,8 +185,8 @@ function UserPopup({ data, open, handleClose }) { } label="Mansion House" @@ -91,7 +198,26 @@ function UserPopup({ data, open, handleClose }) { } -function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder }) { +function ResourceInfo({ info }) { + + if (info) { + return ( + + {info.sc && } + {info.mh && } + {info.tir && } + + ) + } +} + + +function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder, refreshData }) { // console.debug('Row: ', data) // if (placeholder) { // console.debug('Placeholder: ', placeholder) @@ -115,9 +241,14 @@ function Row({ data, displayedMonths, setPopupContent, setShowPopup, placeholder justifyContent="space-between" alignItems="center"> {data.displayName || data.name} + {data.info && } + - {popupOpen && } + {popupOpen && { + handleClose(); + refreshData(); // <-- Invoke refreshData after closing the popup + }} />} @@ -225,24 +356,24 @@ export function ResourceTable({ bench = false }) { const [months, setMonths] = useState([]); // const [months, setMonths] = useState([]); - + const refreshData = async () => { + setIsLoading(true); + try { + const response = await fetch('/api/resourcing/demand'); + if (!response.ok) throw new Error('Network response was not ok'); + const fetchedData = await response.json(); + const jsonParsedData = JSON.parse(fetchedData.content) + setData(jsonParsedData); // Adjust according to actual API response + setMonths(Array.from(new Set(jsonParsedData.flatMap(item => item.jobs.map(b => b.month)))).sort()) + setIsLoading(false); + } catch (err) { + setError(err.message); + setIsLoading(false); + } + }; useEffect(() => { - const fetchData = async () => { - setIsLoading(true); - try { - const response = await fetch('/api/resourcing/resources'); - if (!response.ok) throw new Error('Network response was not ok'); - const fetchedData = await response.json(); - const jsonParsedData = JSON.parse(fetchedData.content) - setData(jsonParsedData); // Adjust according to actual API response - setMonths(Array.from(new Set(jsonParsedData.flatMap(item => item.jobs.map(b => b.month)))).sort()) - setIsLoading(false); - } catch (err) { - setError(err.message); - setIsLoading(false); - } - }; + const fetchPlaceholderData = async () => { try { @@ -260,7 +391,7 @@ export function ResourceTable({ bench = false }) { } }; - fetchData(); + refreshData(); fetchPlaceholderData(); }, []); @@ -312,11 +443,18 @@ export function ResourceTable({ bench = false }) { !user.jobs.some(job => job.month.startsWith(month)) ); - // Condition 2: Check if days_allocated plus holiday is less than days_hypo minus 3, using 20 if days_hypo is undefined + // Condition 2: Check if days_allocated plus holiday is less than days_hypo minus 3, using 18 if days_hypo is undefined + // Only for jobs within the displayed months const hasLessDaysAllocated = user.jobs.some(job => { + const isInDisplayedMonths = displayedMonths.some(displayedMonth => job.month.startsWith(displayedMonth)); + if (!isInDisplayedMonths) { + return false; // Skip this job if it's not in one of the displayed months + } + const holiday = job.holiday || 0; // If there is no holiday, default to 0 - const daysHypo = job.days_hypo || 20; // Use 20 if days_hypo is not defined - return (job.days_allocated + holiday) < (daysHypo - 3); + const daysHypo = job.days_hypo || 18; // Use 18 if days_hypo is not defined + const days_allocated = job.days_allocated || 0; + return (days_allocated + holiday) < (daysHypo - 3); }); // Return true if either condition is met @@ -455,6 +593,7 @@ export function ResourceTable({ bench = false }) { displayedMonths={displayedMonths} setPopupContent={setPopupContent} setShowPopup={setShowPopup} + refreshData={refreshData} placeholder={placeholder && placeholder[item.mail] ? placeholder[item.mail] : null} /> @@ -464,9 +603,9 @@ export function ResourceTable({ bench = false }) { setShowPopup(false)}> Job Details - setShowPopup(false)} sx={{ position: 'absolute', right: 8, top: 8 }}> - - + setShowPopup(false)} sx={{ position: 'absolute', right: 8, top: 8 }}> + + {popupContent && popupContent.map(job => ( diff --git a/lib/redis/index.js b/lib/redis/index.js index 6c324d6e..95c43ca5 100644 --- a/lib/redis/index.js +++ b/lib/redis/index.js @@ -115,6 +115,39 @@ export async function cacheRead(key) { } } +export async function cacheMRead(keys, prefix = '') { + try { + if (!redisInstance) { + redisInstance = await createRedisInstance(); + } + + // Check if keys is an array and has elements + if (!Array.isArray(keys) || keys.length === 0) return null; + + // Add prefix to each key if prefix is provided + const fullKeys = prefix ? keys.map(key => `${prefix}${key}`) : keys; + + // Use MGET to retrieve multiple keys + const values = await redisInstance.mget(...fullKeys); + + // Process the returned values + return values.map(value => { + if (value === null || value === undefined) return null; + try { + const parsedValue = JSON.parse(value); + return parsedValue.buffer ? Buffer.from(parsedValue.buffer) : parsedValue; + } catch (parseError) { + console.error("Error parsing value from Redis:", parseError); + return null; + } + }); + } catch (error) { + console.error("Error during Redis read operation:", error); + return null; + } +} + + // Function to write data to the cache export async function cacheWrite(key, value, ttl = null) { try { diff --git a/pages/api/resourcing/demand.js b/pages/api/resourcing/demand.js new file mode 100644 index 00000000..c533f716 --- /dev/null +++ b/pages/api/resourcing/demand.js @@ -0,0 +1,236 @@ +// pages/resources/resources.js + +import formidable from 'formidable-serverless'; +import { promises as fs } from 'fs'; +import { parseExcelXml, expandResourceData, calculateDemand, timesheetPortalHolidays, combineResourcesWithHolidays } from '@/lib/loaders'; // Adjust the path as necessary +import { cacheWrite, cacheRead, cacheMRead, cacheSearch, cacheDelete } from '@/lib/redis'; + +import users from './users.json'; +// import { each } from 'cheerio/lib/api/traversing'; + + +export const config = { + api: { + bodyParser: false, + }, +}; + + + + +export default async function handler(req, res) { + const cacheKey = 'geco-all-resources' + if (req.method === 'POST') { + // Parse the multipart form data + const data = await new Promise((resolve, reject) => { + const form = new formidable.IncomingForm(); + form.parse(req, (err, fields, files) => { + if (err) return reject(err); + resolve(files); + }); + }); + + try { + // Access the uploaded file + const file = data.file instanceof Array ? data.file[0] : data.file; + if (!file) { + throw new Error('No file uploaded.'); + } + + // Read the file from the uploaded path + const content = await fs.readFile(file.path, 'utf-8'); + + // Process the file content through parseExcelXml + try { + const jsonData = await parseExcelXml(content); + // console.debug('/api/upload: ', jsonData); + + const resourceData = expandResourceData(jsonData, users) + + const holidays = await timesheetPortalHolidays(process.env.TSP_CLIENT_ID, process.env.TSP_CLIENT_SECRET) + // const groupedHolidays = groupLeaveData() + const resourceDataWithHolidays = combineResourcesWithHolidays(resourceData, holidays) + // res.status(200).json({'resource': resourceData, 'holidays': holidays}); // Respond with JSON data + + const demandData = calculateDemand(resourceData) + + try { + await cacheWrite('geco-excel-conversion', JSON.stringify(jsonData)); // attempt to cache data + } catch (cacheError) { + // If cacheWrite fails, log the error but dont send a 500 response + console.error('[API/resourcing/resources/POST][Cache Write Error (geco-excel-conversion)]:', cacheError); + } + try { + await cacheWrite('geco-demand', JSON.stringify(demandData)); // attempt to cache data + } catch (cacheError) { + // If cacheWrite fails, log the error and send a 500 response + res.status(500).json({ error: 'Failed to write to cache.' }); + console.error('[API/resourcing/resources/POST][Cache Write Error (geco-demand)]:', cacheError); + } + + try { + await cacheWrite(cacheKey, JSON.stringify(resourceDataWithHolidays)); // attempt to cache data + res.status(200).json(resourceDataWithHolidays); // Respond with JSON data + } catch (cacheError) { + // If cacheWrite fails, log the error and send a 500 response + console.error('[API/resourcing/resources/POST][Cache Write Error (', cacheKey, ')]:', cacheError); + res.status(500).json({ error: 'Failed to write to cache.' }); + return; // Stop further execution + } + + + } catch (error) { + return res.status(500).json({ error: error.message }); + } + } catch (error) { + return res.status(500).json({ error: error.message }); + } + } else if (req.method === 'GET') { + + if (req.query.demand === 'true') { + try { + const obj = await cacheRead('geco-demand') + + const jobCodes = extractCodeForRedis(obj) + + console.log('API:Demand:GET: ', jobCodes); + + const redisPrefix = 'geco-placeholder-*' + const reservations = await cacheSearch(redisPrefix); + + + // Function to strip off the prefix and trailing details + const stripPrefix = (reservation) => { + const parts = reservation.split('geco-placeholder-'); + return parts[1]; + }; + // Strip off the prefix 'geco-placeholder-' and any following content after the demand key + const strippedReservations = reservations.map(stripPrefix); + + // Filter the reservations to find those not in demand + const unmatchedReservations = strippedReservations.filter(reservation => !jobCodes.includes(reservation)); + + // Re-add the prefix and prepare keys for deletion + const keysToDelete = reservations.filter(reservation => { + const strippedKey = stripPrefix(reservation); + return unmatchedReservations.includes(strippedKey); + }); + + console.log('unmatchedReservations', keysToDelete); + // Delete each key from Redis + keysToDelete && keysToDelete.forEach(async key => { + try { + await cacheDelete(key); + console.log(`Deleted key: ${key}`); + } catch (error) { + console.error(`Error deleting key ${key}:`, error); + } + }); + + res.status(200).json({ content: obj }) + } catch (error) { + // console.log(error) + res.status(500).json({ error: 'error fetching from cache: ' + error }) + } + } else { + + try { + const obj = await cacheRead(cacheKey) + const resourceData = await cacheMRead(extractEmailsForRedis(obj), 'geco-resource-') + // console.log(resourceData) + const mergedResourceData = mergeApiAndRedisResults(obj, resourceData) + // console.log('API:Cache: ', req.query.key, ' : ', obj ); + res.status(200).json({ content: JSON.stringify(mergedResourceData) }) + } catch (error) { + // console.log(error) + res.status(500).json({ error: 'error fetching from cache: ' + error }) + } + } + + + } else { + // Handle any other HTTP method + res.setHeader('Allow', ['POST, GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} + +const extractEmailsForRedis = (jsonData) => { + // Parse the JSON data + const data = JSON.parse(jsonData); + + // Extract the 'mail' field from each object + const emails = data.map(item => item.mail).filter(mail => mail); + + // Return the array of emails + return emails; +}; + + +const extractCodeForRedi2s = (jsonData) => { + // Parse the JSON data + const data = JSON.parse(jsonData); + + // Extract the 'mail' field from each object + const codes = data.map(item => item.Code).filter(Code => Code); + + // Return the array of emails + return codes; +}; + +const extractCodeForRedis = (jsonData) => { + // Parse the JSON data + const data = JSON.parse(jsonData); + + // Initialize an array to hold the code-role_id combinations + let codeRoleCombinations = []; + console.log(data) + + // Iterate over each item + data.forEach(item => { + const code = item.Code; + // Iterate over each date in Roles + Object.keys(item.Roles).forEach(date => { + // Iterate over each role on that date + item.Roles[date].forEach(role => { + // Create a combination of Code and role_id + const combination = `${code}-${role.role_id}`; + codeRoleCombinations.push(combination); + }); + }); + }); + + // Return the array of code-role_id combinations + return codeRoleCombinations; +}; + + + +function mergeApiAndRedisResults(apiResults, redisResults) { + // Parse the API results if they are in string format + const parsedApiResults = typeof apiResults === 'string' ? JSON.parse(apiResults) : apiResults; + + // Filter out null values from Redis results and parse each JSON string + const validRedisResults = redisResults + .filter(item => item !== null) + .map(item => JSON.parse(item)); + + // Convert the valid Redis results to a map for efficient lookup + const redisDataMap = new Map(validRedisResults.map(item => [item.resource, item])); + + // Merge the API results with the corresponding Redis data + const mergedResults = parsedApiResults.map(apiItem => { + const redisData = redisDataMap.get(apiItem.mail); + + // If there's matching Redis data, merge it (excluding the 'resource' field) + if (redisData) { + const { resource, ...otherRedisData } = redisData; + return { ...apiItem, 'info': { ...otherRedisData } }; + } + + // If there's no matching Redis data, return the API item as is + return apiItem; + }); + + return mergedResults; +} \ No newline at end of file diff --git a/pages/api/resourcing/resources.js b/pages/api/resourcing/resources.js index 43124b6a..0a1694ca 100644 --- a/pages/api/resourcing/resources.js +++ b/pages/api/resourcing/resources.js @@ -1,116 +1,87 @@ -// pages/resources/resources.js - -import formidable from 'formidable-serverless'; -import { promises as fs } from 'fs'; -import { parseExcelXml, expandResourceData, calculateDemand, timesheetPortalHolidays, combineResourcesWithHolidays } from '@/lib/loaders'; // Adjust the path as necessary -import { cacheWrite, cacheRead } from '@/lib/redis'; - -import users from './users.json'; - - -export const config = { - api: { - bodyParser: false, - }, -}; - - - +import { cacheWrite, cacheRead, cacheDelete, cacheSearch } from '@/lib/redis'; export default async function handler(req, res) { - const cacheKey = 'geco-all-resources' if (req.method === 'POST') { - // Parse the multipart form data - const data = await new Promise((resolve, reject) => { - const form = new formidable.IncomingForm(); - form.parse(req, (err, fields, files) => { - if (err) return reject(err); - resolve(files); - }); - }); - try { - // Access the uploaded file - const file = data.file instanceof Array ? data.file[0] : data.file; - if (!file) { - throw new Error('No file uploaded.'); - } - - // Read the file from the uploaded path - const content = await fs.readFile(file.path, 'utf-8'); - - // Process the file content through parseExcelXml - try { - const jsonData = await parseExcelXml(content); - // console.debug('/api/upload: ', jsonData); - - const resourceData = expandResourceData(jsonData, users) - - const holidays = await timesheetPortalHolidays(process.env.TSP_CLIENT_ID, process.env.TSP_CLIENT_SECRET) - // const groupedHolidays = groupLeaveData() - const resourceDataWithHolidays = combineResourcesWithHolidays(resourceData, holidays) - // res.status(200).json({'resource': resourceData, 'holidays': holidays}); // Respond with JSON data - - const demandData = calculateDemand(resourceData) - - try { - await cacheWrite('geco-excel-conversion', JSON.stringify(jsonData)); // attempt to cache data - } catch (cacheError) { - // If cacheWrite fails, log the error but dont send a 500 response - console.error('[API/resourcing/resources/POST][Cache Write Error (geco-excel-conversion)]:', cacheError); - } - try { - await cacheWrite('geco-demand', JSON.stringify(demandData)); // attempt to cache data - } catch (cacheError) { - // If cacheWrite fails, log the error and send a 500 response - res.status(500).json({ error: 'Failed to write to cache.' }); - console.error('[API/resourcing/resources/POST][Cache Write Error (geco-demand)]:', cacheError); - } - - try { - await cacheWrite(cacheKey, JSON.stringify(resourceDataWithHolidays)); // attempt to cache data - res.status(200).json(resourceDataWithHolidays); // Respond with JSON data - } catch (cacheError) { - // If cacheWrite fails, log the error and send a 500 response - console.error('[API/resourcing/resources/POST][Cache Write Error (', cacheKey, ')]:', cacheError); - res.status(500).json({ error: 'Failed to write to cache.' }); - return; // Stop further execution - } - - - } catch (error) { - return res.status(500).json({ error: error.message }); + // Extract data from the request body + const data = req.body; + const cacheKeyResource = 'geco-resource-' + req.body.resource + + try { // write the placeholder data per job + await cacheWrite(cacheKeyResource, JSON.stringify(data)); // attempt to cache data + } catch (cacheError) { + // If cacheWrite fails, log the error and send a 500 response + res.status(500).json({ error: 'Failed to write to cache.' }); + console.error('[API/resourcing/resources/POST][Cache Write Error (Job)]:', cacheError); } + // try { // write placeholder data per resource + // await cacheWrite(cacheKeyResource, JSON.stringify(data)); // attempt to cache data + // } catch (cacheError) { + // // If cacheWrite fails, log the error and send a 500 response + // res.status(500).json({ error: 'Failed to write to cache.' }); + // console.error('[API/resourcing/placeholder/POST][Cache Write Error (Resource)]:', cacheError); + // } + + res.status(200).json({ status: 'Success', message: 'Resource Updated' }); } catch (error) { - return res.status(500).json({ error: error.message }); + // Handle any errors + res.status(500).json({ status: 'Error', message: error.message }); } } else if (req.method === 'GET') { - if (req.query.demand === 'true') { + if (req.query.resource) { try { - const obj = await cacheRead('geco-demand') + const cacheKey = 'geco-resource-' + req.query.resource + + const obj = await cacheRead(cacheKey) // console.log('API:Cache: ', req.query.key, ' : ', obj ); res.status(200).json({ content: obj }) } catch (error) { // console.log(error) res.status(500).json({ error: 'error fetching from cache: ' + error }) } - } else { - + } else { // return all try { - const obj = await cacheRead(cacheKey) - // console.log('API:Cache: ', req.query.key, ' : ', obj ); - res.status(200).json({ content: obj }) + + const cacheKey = 'geco-resource*' + const keys = await cacheSearch(cacheKey); + + + // If keys is null or undefined, handle the error or send an empty array response. + if (!keys || keys.length === 0) { + res.status(200).json({ content: [] }); + return; + } + + let placeholderData = []; + const cacheAll = await Promise.all(keys.map(item => cacheRead(item))); + + // console.log('API:/api/etherpad/imported: ', padMeta) + + cacheAll.forEach((item, index) => { + item = JSON.parse(item); + placeholderData.push(item); + }) + console.log(placeholderData) + res.status(200).json({ content: placeholderData }); } catch (error) { // console.log(error) res.status(500).json({ error: 'error fetching from cache: ' + error }) } } - - + } else if (req.method === 'DELETE') { + try { + const cacheKey = 'geco-placeholder-' + req.query.code + '-' + req.query.role_id + await cacheDelete(cacheKey); // assuming cacheDelete is a function you have for deleting cache + res.status(200).json({ status: 'Success', message: `Data deleted from cache` }); + } catch (error) { + console.error('[API/resourcing/placeholder/DELETE][Cache Delete Error]:', error); + res.status(500).json({ status: 'Error', message: 'Failed to delete from cache : ' + error }); + } } else { - // Handle any other HTTP method - res.setHeader('Allow', ['POST, GET']); + // If the request is not POST, GET, or DELETE, return a 405 Method Not Allowed error + res.setHeader('Allow', ['POST', 'GET', 'DELETE']); res.status(405).end(`Method ${req.method} Not Allowed`); } } + diff --git a/pages/api/resourcing/users.json b/pages/api/resourcing/users.json index ad0d9a9c..85007643 100644 --- a/pages/api/resourcing/users.json +++ b/pages/api/resourcing/users.json @@ -24,7 +24,7 @@ "mobilePhone": "07946018562", "officeLocation": "London", "preferredLanguage": null, - "department": "Progtramme Management", + "department": "DCC Bullet", "manager_email": "maj.shafi@airwalkconsulting.com" }, { @@ -38,7 +38,7 @@ "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "tom.heyes@airwalkconsulting.com" }, { @@ -83,34 +83,6 @@ "department": null, "manager_email": null }, - { - "id": "f659fe3d-cb33-45f7-b265-efcda0142f50", - "displayName": "Adam Domanski", - "userPrincipalName": "adam.domanski@airwalkconsulting.com", - "givenName": "Adam", - "surname": "Domanski", - "jobTitle": "Engineer", - "mail": "adam.domanski@airwalkconsulting.com", - "mobilePhone": "07584418370", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Associate", - "manager_email": null - }, - { - "id": "3a31af5a-b25a-4eb8-9cfb-6eaa382e5edf", - "displayName": "Adam Wilson", - "userPrincipalName": "adam.wilson@airwalkconsulting.com", - "givenName": "Adam", - "surname": "Wilson", - "jobTitle": "Senior Consultant", - "mail": "adam.wilson@airwalkconsulting.com", - "mobilePhone": "07535809502", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Product Delivery", - "manager_email": "craig.duffus@airwalkconsulting.com" - }, { "id": "24303a3c-ba3d-4801-954a-f8efcd774de8", "displayName": "Ben Walker", @@ -290,7 +262,7 @@ "mobilePhone": "07375505509", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "tom.heyes@airwalkconsulting.com" }, { @@ -307,6 +279,34 @@ "department": null, "manager_email": null }, + { + "id": "1a699363-ce9f-4354-801a-c448e0033af6", + "displayName": "AI Chatbot for Confluence access", + "userPrincipalName": "aichatbotconfluenceaccess@airwalkconsulting.com", + "givenName": "AI Chatbot", + "surname": "Confluence access", + "jobTitle": null, + "mail": "aichatbotconfluenceaccess@airwalkconsulting.com", + "mobilePhone": null, + "officeLocation": null, + "preferredLanguage": null, + "department": null, + "manager_email": null + }, + { + "id": "a94f04b0-e825-4276-9dc5-23be326d9a97", + "displayName": "AI Chatbot for Confluence Accesss 2", + "userPrincipalName": "aichatbotconfluenceaccess2@airwalkconsulting.com", + "givenName": "AI Chatbot", + "surname": "Confluence Accesss 2", + "jobTitle": null, + "mail": "aichatbotconfluenceaccess2@airwalkconsulting.com", + "mobilePhone": null, + "officeLocation": null, + "preferredLanguage": null, + "department": null, + "manager_email": null + }, { "id": "02fffa93-80d5-4476-98fa-0a32c4305436", "displayName": "Galileo - Airwalk Sheffield", @@ -599,7 +599,7 @@ "officeLocation": "London", "preferredLanguage": null, "department": "Operations", - "manager_email": "ben.walker@airwalkconsulting.com" + "manager_email": null }, { "id": "50200c73-4668-4742-9749-d8e09d6aedc0", @@ -640,7 +640,7 @@ "mobilePhone": "07495899979", "officeLocation": "London", "preferredLanguage": "en-US", - "department": "PMO", + "department": "DCC Atlas", "manager_email": "louis.maxwell@airwalkconsulting.com" }, { @@ -668,7 +668,7 @@ "mobilePhone": "07957644748", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "taz.hussain@airwalkconsulting.com" }, { @@ -682,7 +682,7 @@ "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, - "department": "AWC Partners", + "department": "Engineering", "manager_email": null }, { @@ -724,7 +724,7 @@ "mobilePhone": "07496865138", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Product Delivery", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -738,7 +738,7 @@ "mobilePhone": "07496811693", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -1175,20 +1175,6 @@ "department": "Engineering", "manager_email": "jim.lamb@airwalkconsulting.com" }, - { - "id": "ffbab824-11db-4ca6-9b03-7951854d6eea", - "displayName": "Byron Sorgdrager", - "userPrincipalName": "byron.sorgdrager@airwalkconsulting.com", - "givenName": "Byron", - "surname": "Sorgdrager", - "jobTitle": "Engineer (Interim)", - "mail": "byron.sorgdrager@airwalkconsulting.com", - "mobilePhone": "+447828316872", - "officeLocation": null, - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "38507b0e-c4f1-483f-9ce0-4e0d888fc96f", "displayName": "Carlos Preuschoff", @@ -1203,20 +1189,6 @@ "department": null, "manager_email": null }, - { - "id": "0753d570-38ea-4b80-945d-d2feb89bca35", - "displayName": "Callum Spencer", - "userPrincipalName": "callum.spencer@airwalkconsulting.com", - "givenName": "Callum", - "surname": "Spencer", - "jobTitle": "Senior Consultant", - "mail": "callum.spencer@airwalkconsulting.com", - "mobilePhone": "0739 953 5833", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "a7431073-c5d7-4bd0-8523-cda8f6e1d503", "displayName": "Cameron Scott", @@ -1245,20 +1217,6 @@ "department": null, "manager_email": null }, - { - "id": "087de4b9-896c-4bb0-96c8-2cd6bddad57f", - "displayName": "Charlotte Young", - "userPrincipalName": "charlotte.young@airwalkconsulting.com", - "givenName": "Charlotte", - "surname": "Young", - "jobTitle": "Senior Consultant", - "mail": "charlotte.young@airwalkconsulting.com", - "mobilePhone": "07870 617720", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Service Management", - "manager_email": null - }, { "id": "2c07c9fa-f6dd-4a14-ad55-42352094a673", "displayName": "Clare Flynn", @@ -1270,7 +1228,7 @@ "mobilePhone": "07946018566", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "clare.flynn@airwalkconsulting.com" }, { @@ -1284,23 +1242,9 @@ "mobilePhone": "07741590409", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Programme Management", + "department": "DCC", "manager_email": "alex.hammond@airwalkconsulting.com" }, - { - "id": "9266a863-bea9-4476-bfef-edbee1c3babd", - "displayName": "Clare Zilinckas", - "userPrincipalName": "clare.zilinckas@airwalkconsulting.com", - "givenName": "Clare", - "surname": "Zilinckas", - "jobTitle": "Senior Consultant", - "mail": "clare.zilinckas@airwalkconsulting.com", - "mobilePhone": "07496382448", - "officeLocation": "London", - "preferredLanguage": null, - "department": "PMO", - "manager_email": null - }, { "id": "c3ffd0ef-8d12-4c75-a403-76cbb6fa3c9b", "displayName": "Cloud Service Enumerator", @@ -1354,36 +1298,8 @@ "mobilePhone": "07814522707\u202c", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Product Delivery", - "manager_email": "darren.womack@airwalkconsulting.com" - }, - { - "id": "fb3bb6dc-616a-4b92-9a61-de9bc60748d4", - "displayName": "Craig Tubb", - "userPrincipalName": "craig.tubb@airwalkconsulting.com", - "givenName": "Craig", - "surname": "Tubb", - "jobTitle": "Senior Consultant", - "mail": "craig.tubb@airwalkconsulting.com", - "mobilePhone": "07920405757", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Engineering", - "manager_email": null - }, - { - "id": "69d82bf8-4f1e-420a-a3da-8978703d53f5", - "displayName": "Dan Bovenzi", - "userPrincipalName": "Daniel.Bovenzi@airwalkconsulting.com", - "givenName": "Dan", - "surname": "Bovenzi", - "jobTitle": "Senior Consultant", - "mail": "Daniel.Bovenzi@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": "London", - "preferredLanguage": null, - "department": "Architecture", - "manager_email": "rob.ellison@airwalkconsulting.com" + "department": "DCC Bullet", + "manager_email": "alex.hammond@airwalkconsulting.com" }, { "id": "844b0343-d03a-45e4-a2e9-e43624a99355", @@ -1427,34 +1343,6 @@ "department": "Architecture", "manager_email": "matt.ward@airwalkconsulting.com" }, - { - "id": "c9c3284c-d59c-4e4c-9781-7d445d432b5d", - "displayName": "Dave Chapple", - "userPrincipalName": "dave.chapple@airwalkconsulting.com", - "givenName": "Dave", - "surname": "Chapple", - "jobTitle": "Senior Consultant", - "mail": "dave.chapple@airwalkconsulting.com", - "mobilePhone": "07495900012", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Service Management", - "manager_email": "adrian.cloke@airwalkconsulting.com" - }, - { - "id": "c6cef7c4-0231-4d00-809c-536b07458027", - "displayName": "Dave Otter", - "userPrincipalName": "david.otter@airwalkconsulting.com", - "givenName": "Dave", - "surname": "Otter", - "jobTitle": "Head of Talent", - "mail": "david.otter@airwalkconsulting.com", - "mobilePhone": "07957647460", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Operations", - "manager_email": "Justin@airwalkconsulting.com" - }, { "id": "dcb4bd5c-3fa3-47b3-86de-f1e6bf0f6737", "displayName": "Dave Wilson", @@ -1550,23 +1438,9 @@ "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "tyrone.griffiths@airwalkconsulting.com" }, - { - "id": "27f223aa-5e1b-4287-9702-0bef6164e74b", - "displayName": "Eden Finch", - "userPrincipalName": "eden.finch@airwalkconsulting.com", - "givenName": "Eden", - "surname": "Finch", - "jobTitle": "People Operations Co-ordinator", - "mail": "eden.finch@airwalkconsulting.com", - "mobilePhone": "07538718692", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Operations", - "manager_email": "hollie.alexander@airwalkconsulting.com" - }, { "id": "06a16875-077d-41e0-87b9-6742de7e2bf3", "displayName": "Edinburgh Office", @@ -1581,20 +1455,6 @@ "department": null, "manager_email": null }, - { - "id": "13672a40-be1d-4d74-99ad-3d12e9999a50", - "displayName": "Ella Jennings", - "userPrincipalName": "ella.jennings@airwalkconsulting.com", - "givenName": "Ella", - "surname": "Jennings", - "jobTitle": "Content Marketing Manager", - "mail": "ella.jennings@airwalkconsulting.com", - "mobilePhone": "07946018848", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Operations", - "manager_email": "emma.smith@airwalkconsulting.com" - }, { "id": "ecd4d917-29de-45ed-8dec-569edad33a29", "displayName": "Emeka Umeh", @@ -1623,20 +1483,6 @@ "department": "Operations", "manager_email": "alex.hammond@airwalkconsulting.com" }, - { - "id": "300a6297-c608-4569-94e0-0690c3ddada4", - "displayName": "Emmanuel Chukwu", - "userPrincipalName": "emmanuel.chukwu@airwalkconsulting.com", - "givenName": "Emmanuel", - "surname": "Chukwu", - "jobTitle": "Senior Consultant", - "mail": "emmanuel.chukwu@airwalkconsulting.com", - "mobilePhone": "07497112032", - "officeLocation": "Sheffield", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": "vishal.bhalla@airwalkconsulting.com" - }, { "id": "a08585af-363a-432e-a653-0ab40c843f6b", "displayName": "AWC Partners - Enquiries", @@ -1662,7 +1508,7 @@ "mobilePhone": "07939874458", "officeLocation": "Sheffield", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "jenny.rose@airwalkconsulting.com" }, { @@ -1676,7 +1522,7 @@ "mobilePhone": null, "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "paul.barrett@airwalkconsulting.com" }, { @@ -1690,7 +1536,7 @@ "mobilePhone": "07538317605", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Bullet", "manager_email": "anthony.condon@airwalkconsulting.com" }, { @@ -1721,20 +1567,6 @@ "department": "Operations", "manager_email": "phil.notley@airwalkconsulting.com" }, - { - "id": "c63e62e2-d04a-4107-b43e-75242a7228c7", - "displayName": "Greg White", - "userPrincipalName": "greg.white@airwalkconsulting.com", - "givenName": "Greg", - "surname": "White", - "jobTitle": "Senior Consultant", - "mail": "greg.white@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": "London", - "preferredLanguage": null, - "department": "Architecture", - "manager_email": null - }, { "id": "0a269ace-8753-4b7a-a1a9-787f0f50331b", "displayName": "Guy Fabron", @@ -1760,7 +1592,7 @@ "mobilePhone": null, "officeLocation": "London", "preferredLanguage": null, - "department": "Product Delivery", + "department": "DCC Tytans", "manager_email": "tyrone.griffiths@airwalkconsulting.com" }, { @@ -1803,7 +1635,7 @@ "officeLocation": "London", "preferredLanguage": "en-GB", "department": "Operations", - "manager_email": "david.otter@airwalkconsulting.com" + "manager_email": null }, { "id": "5df158e4-3757-4369-ae7a-fbe92ee112e8", @@ -1833,20 +1665,6 @@ "department": "Architecture", "manager_email": "rob.ellison@airwalkconsulting.com" }, - { - "id": "60c98ce7-7846-4be4-a92c-07809d198041", - "displayName": "Ian Kelly", - "userPrincipalName": "ian.kelly@airwalkconsulting.com", - "givenName": "Ian", - "surname": "Kelly", - "jobTitle": "Senior Consultant", - "mail": "ian.kelly@airwalkconsulting.com", - "mobilePhone": " 07734822599", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "e3369112-d40f-48f4-907f-59c74550bf1d", "displayName": "Idon Wong", @@ -1861,20 +1679,6 @@ "department": "Engineering", "manager_email": "jim.lamb@airwalkconsulting.com" }, - { - "id": "d7b64ac4-dc45-4274-bc31-eaca39891dbb", - "displayName": "Imran Aslam", - "userPrincipalName": "imran.aslam@airwalkconsulting.com", - "givenName": "Imran", - "surname": "Aslam", - "jobTitle": "Senior Consultant", - "mail": "imran.aslam@airwalkconsulting.com", - "mobilePhone": "07958197375", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": "paul.hasenfuss@airwalkconsulting.com" - }, { "id": "e599f56a-87fc-4c67-be8f-44fa774d5dc5", "displayName": "Information @ AirWalk", @@ -1914,7 +1718,7 @@ "mobilePhone": "07495899955", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "clare.flynn@airwalkconsulting.com" }, { @@ -1945,20 +1749,6 @@ "department": "Architecture", "manager_email": "rob.ellison@airwalkconsulting.com" }, - { - "id": "46ca4b8d-b295-4204-9094-fce37e15c94f", - "displayName": "James Humphreys", - "userPrincipalName": "james.humphreys@airwalkconsulting.com", - "givenName": "James", - "surname": "Humphreys", - "jobTitle": "Consultant", - "mail": "james.humphreys@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": null, - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "d63de3c6-2435-4680-8f66-3e049fa6e558", "displayName": "James Mak", @@ -1984,23 +1774,9 @@ "mobilePhone": "07497112025", "officeLocation": "London", "preferredLanguage": null, - "department": "PMO", + "department": "DCC Tytans", "manager_email": "clare.flynn@airwalkconsulting.com" }, - { - "id": "97f39508-7890-46bd-b5bf-189b00a0ba92", - "displayName": "James Stanley", - "userPrincipalName": "james.stanley@airwalkconsulting.com", - "givenName": "James", - "surname": "Stanley", - "jobTitle": null, - "mail": "james.stanley@airwalkconsulting.com", - "mobilePhone": "0776 500 1884", - "officeLocation": null, - "preferredLanguage": null, - "department": null, - "manager_email": null - }, { "id": "fcc5cbfb-d3bd-48a0-ae68-4470807a2f52", "displayName": "Jason Aird", @@ -2029,20 +1805,6 @@ "department": "Programme Management", "manager_email": null }, - { - "id": "d53a2704-c505-4c3c-9a43-7baa19e062be", - "displayName": "Jennifer Michael", - "userPrincipalName": "jennifer.michael@airwalkconsulting.com", - "givenName": "Jennifer", - "surname": "Michael", - "jobTitle": "Senior Consultant", - "mail": "jennifer.michael@airwalkconsulting.com", - "mobilePhone": "07494017820", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Programme Management", - "manager_email": null - }, { "id": "62fb26ef-c713-4595-872d-ef4a55d35288", "displayName": "Jenny Rose", @@ -2054,7 +1816,7 @@ "mobilePhone": null, "officeLocation": "London", "preferredLanguage": null, - "department": "Product Delivery", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -2071,20 +1833,6 @@ "department": "Reply HR", "manager_email": "hollie.alexander@airwalkconsulting.com" }, - { - "id": "6555ff43-edf2-4271-8da9-a5d74dc65cbc", - "displayName": "Jessica Tolley", - "userPrincipalName": "jessica.tolley@airwalkconsulting.com", - "givenName": "Jessica", - "surname": "Tolley", - "jobTitle": "Senior Consultant", - "mail": "jessica.tolley@airwalkconsulting.com", - "mobilePhone": "+44(0) 208 142 8686", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Architecture", - "manager_email": null - }, { "id": "f8d0a98c-dfe1-4a1a-9677-950e2828d28c", "displayName": "JGilroy", @@ -2141,25 +1889,11 @@ "department": null, "manager_email": null }, - { - "id": "8ba2aa8c-8101-4ad5-8b12-0e274a60901e", - "displayName": "John Helsby", - "userPrincipalName": "john.helsby@airwalkconsulting.com", - "givenName": "John", - "surname": "Helsby", - "jobTitle": "Work Experience", - "mail": "john.helsby@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": "Sheffield", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "989b19c4-7d31-4ba9-b93f-bb3e49b1f755", "displayName": "John Roberts", "userPrincipalName": "john.roberts@airwalkconsulting.com", - "givenName": "Johm", + "givenName": "John", "surname": "Roberts", "jobTitle": "Senior Consultant", "mail": "john.roberts@airwalkconsulting.com", @@ -2208,7 +1942,7 @@ "mobilePhone": "+447967332645", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Core", + "department": "Operations", "manager_email": "company@airwalkconsulting.com" }, { @@ -2222,7 +1956,7 @@ "mobilePhone": "07375505220", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "Product Delivery", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -2245,12 +1979,12 @@ "userPrincipalName": "karen.turnbull@airwalkconsulting.com", "givenName": "Karen", "surname": "Turnbull", - "jobTitle": "Senior Consultant (Interim)", + "jobTitle": "Senior Consultant", "mail": "karen.turnbull@airwalkconsulting.com", "mobilePhone": "+447932661988", "officeLocation": "London", "preferredLanguage": "en-GB", - "department": "HoP R&R Team", + "department": "DCC", "manager_email": null }, { @@ -2264,51 +1998,9 @@ "mobilePhone": "07950740439", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC", "manager_email": "Jason@airwalkconsulting.com" }, - { - "id": "aeff67c2-8102-4567-8cf6-638da6d6a695", - "displayName": "Kendrick Ng", - "userPrincipalName": "kendrick.ng@airwalkconsulting.com", - "givenName": "Kendrick", - "surname": "Ng", - "jobTitle": "Senior Consultant", - "mail": "kendrick.ng@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": "Hong Kong", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, - { - "id": "f52017d9-5b23-40af-93d9-25ee8eff5835", - "displayName": "Khavir Ali", - "userPrincipalName": "khavir.ali@airwalkconsulting.com", - "givenName": "Khavir", - "surname": "Ali", - "jobTitle": "Senior Consultant", - "mail": "khavir.ali@airwalkconsulting.com", - "mobilePhone": "07931503290", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Engineering", - "manager_email": "tom.allen@airwalkconsulting.com" - }, - { - "id": "3514306b-8b14-46a2-bc93-43fe1f34ecab", - "displayName": "Laura Smith", - "userPrincipalName": "laura.smith@airwalkconsulting.com", - "givenName": "Laura", - "surname": "Smith", - "jobTitle": "Business Operations Lead", - "mail": "laura.smith@airwalkconsulting.com", - "mobilePhone": "07946018846", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Operations", - "manager_email": "phil.notley@airwalkconsulting.com" - }, { "id": "a2ef9e51-35c3-4526-a7be-fc3687922b16", "displayName": "Laurent Allegre", @@ -2351,20 +2043,6 @@ "department": "Engineering", "manager_email": "jim.lamb@airwalkconsulting.com" }, - { - "id": "ee1ed39b-68f5-4a2d-9338-4f46d266e819", - "displayName": "Lewis Desforges", - "userPrincipalName": "lewis.desforges@airwalkconsulting.com", - "givenName": "Lewis", - "surname": "Desforges", - "jobTitle": "Senior Consultant", - "mail": "lewis.desforges@airwalkconsulting.com", - "mobilePhone": "07398 827604", - "officeLocation": "London", - "preferredLanguage": "en-GB", - "department": "Engineering", - "manager_email": null - }, { "id": "e30043fd-5993-49ad-8af3-f5b8673cd408", "displayName": "Louis Maxwell", @@ -2376,7 +2054,7 @@ "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, - "department": "Product Delivery", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -2390,7 +2068,7 @@ "mobilePhone": "+44(0) 208 142 8686", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -2432,7 +2110,7 @@ "mobilePhone": "07946018559", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -2446,7 +2124,7 @@ "mobilePhone": "07950740411", "officeLocation": "London", "preferredLanguage": null, - "department": "PMO", + "department": "DCC Tytans", "manager_email": "tyrone.griffiths@airwalkconsulting.com" }, { @@ -2572,7 +2250,7 @@ "mobilePhone": "07375505272", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "tyrone.griffiths@airwalkconsulting.com" }, { @@ -2600,7 +2278,7 @@ "mobilePhone": "07497112024", "officeLocation": "Sheffield", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -2628,7 +2306,7 @@ "mobilePhone": "+447398827632", "officeLocation": "Sheffield", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Bullet", "manager_email": "anthony.onyekweli@airwalkconsulting.com" }, { @@ -2687,20 +2365,6 @@ "department": null, "manager_email": "clare.mitchell@airwalkconsulting.com" }, - { - "id": "963ef23e-b829-4a82-88fc-8b02be1ea1b7", - "displayName": "Nick Wilkins", - "userPrincipalName": "nick.wilkins@airwalkconsulting.com", - "givenName": "Nick", - "surname": "Wilkins", - "jobTitle": "Senior Consultant", - "mail": "nick.wilkins@airwalkconsulting.com", - "mobilePhone": "07535806685", - "officeLocation": "London", - "preferredLanguage": "en-US", - "department": "PMO", - "manager_email": null - }, { "id": "b5fc6772-df63-4af0-89b4-feacf419469e", "displayName": "Nikil Chitturi", @@ -2715,34 +2379,6 @@ "department": null, "manager_email": null }, - { - "id": "8a16374a-b784-4c84-ab43-3bb5662eab0d", - "displayName": "Nizam Khan", - "userPrincipalName": "nizam.khan@airwalkconsulting.com", - "givenName": "Nizam", - "surname": "Khan", - "jobTitle": "Senior Consultant", - "mail": "nizam.khan@airwalkconsulting.com", - "mobilePhone": "07506524537", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Architecture", - "manager_email": null - }, - { - "id": "3d17fcd5-21dc-4ac7-a7ae-317f299a00a6", - "displayName": "Olufemi Oyekanmi", - "userPrincipalName": "olufemi.oyekanmi@airwalkconsulting.com", - "givenName": "Olufemi", - "surname": "Oyekanmi", - "jobTitle": "Engineer (Interim)", - "mail": "olufemi.oyekanmi@airwalkconsulting.com", - "mobilePhone": "07735725841", - "officeLocation": null, - "preferredLanguage": null, - "department": "Engineering", - "manager_email": null - }, { "id": "9590b2ba-e796-4abd-a8b2-147d2ce3703f", "displayName": "AWC Partners - Ops", @@ -2768,37 +2404,9 @@ "mobilePhone": "07956130358", "officeLocation": "Manchester", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Tytans", "manager_email": "tyrone.griffiths@airwalkconsulting.com" }, - { - "id": "684d3666-98e4-4269-985c-b0d7362e9ea2", - "displayName": "Paul Butler", - "userPrincipalName": "Paul.Butler@airwalkconsulting.com", - "givenName": "Paul", - "surname": "Butler", - "jobTitle": "Senior Consultant", - "mail": "Paul.Butler@airwalkconsulting.com", - "mobilePhone": "07950740418", - "officeLocation": "Sheffield", - "preferredLanguage": null, - "department": "Product Delivery", - "manager_email": "craig.duffus@airwalkconsulting.com" - }, - { - "id": "7e8fbfe7-4d90-440b-8d2e-a79fdff3fc30", - "displayName": "Paul Gill", - "userPrincipalName": "paul.gill@airwalkconsulting.com", - "givenName": "Paul", - "surname": "Gill", - "jobTitle": "Senior Talent Acquisition Specialist", - "mail": "paul.gill@airwalkconsulting.com", - "mobilePhone": "0739 953 5828", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Operations", - "manager_email": "phil.notley@airwalkconsulting.com" - }, { "id": "2e2e799c-cd39-43ad-9d6c-307027eedf21", "displayName": "Paul Hasenfuss", @@ -2810,23 +2418,9 @@ "mobilePhone": "07375505236", "officeLocation": "Sheffield", "preferredLanguage": "en-GB", - "department": "Product Delivery Discipline", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, - { - "id": "81e023a6-4537-4f98-b3e0-8afaf3a273c1", - "displayName": "Paul Lancashire", - "userPrincipalName": "paul.lancashire@airwalkconsulting.com", - "givenName": "Paul", - "surname": "Lancashire", - "jobTitle": "Senior Consultant", - "mail": "paul.lancashire@airwalkconsulting.com", - "mobilePhone": null, - "officeLocation": "London", - "preferredLanguage": null, - "department": "Architecture", - "manager_email": null - }, { "id": "ff68b936-c641-4df7-971d-ef95024cf62c", "displayName": "Pavan Mathur", @@ -2838,7 +2432,7 @@ "mobilePhone": null, "officeLocation": "London", "preferredLanguage": null, - "department": "Product Delivery", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -3048,7 +2642,7 @@ "mobilePhone": null, "officeLocation": "Edinburgh", "preferredLanguage": null, - "department": "Program Management", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -3090,7 +2684,7 @@ "mobilePhone": null, "officeLocation": "Sheffield", "preferredLanguage": null, - "department": "Service Management", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, { @@ -3149,6 +2743,34 @@ "department": "Architecture", "manager_email": "rob.ellison@airwalkconsulting.com" }, + { + "id": "52eb9b75-543c-4a8d-81eb-b1c25d29053f", + "displayName": "Shaun Laughton (Test)", + "userPrincipalName": "shaun.laughton_awrsandbox.onmicrosoft.com#EXT#@airwalkconsulting.onmicrosoft.com", + "givenName": "Shaun", + "surname": "Laughton", + "jobTitle": null, + "mail": "shaun.laughton@awrsandbox.onmicrosoft.com", + "mobilePhone": null, + "officeLocation": null, + "preferredLanguage": "en-US", + "department": null, + "manager_email": null + }, + { + "id": "d571ce68-e043-4b9b-b85f-8332b9408409", + "displayName": "Shaun Laughton 2 (Test)", + "userPrincipalName": "shaun.laughton2_awrsandbox.onmicrosoft.com#EXT#@airwalkconsulting.onmicrosoft.com", + "givenName": "Shaun", + "surname": "Laughton", + "jobTitle": null, + "mail": "shaun.laughton2@awrsandbox.onmicrosoft.com", + "mobilePhone": null, + "officeLocation": null, + "preferredLanguage": "en-US", + "department": null, + "manager_email": null + }, { "id": "6f08b277-bb38-49e9-97fc-5a1f125b5c86", "displayName": "Shaun Satterthwaite", @@ -3230,23 +2852,9 @@ "mobilePhone": "07494017822", "officeLocation": "London", "preferredLanguage": null, - "department": "PMO", + "department": "DCC Bullet", "manager_email": "craig.duffus@airwalkconsulting.com" }, - { - "id": "ecd2e1c6-5fea-4617-939f-e80cea7a1c0e", - "displayName": "Stephen Doyle", - "userPrincipalName": "stephen.doyle@airwalkconsulting.com", - "givenName": "Stephen", - "surname": "Doyle", - "jobTitle": "Senior Consultant", - "mail": "stephen.doyle@airwalkconsulting.com", - "mobilePhone": "07946018560", - "officeLocation": "London", - "preferredLanguage": null, - "department": "Product Delivery", - "manager_email": "tyrone.griffiths@airwalkconsulting.com" - }, { "id": "4cc270ce-05d2-4dd6-bb21-6ecb6dae269e", "displayName": "Steve Isbell", @@ -3258,8 +2866,8 @@ "mobilePhone": null, "officeLocation": "London", "preferredLanguage": null, - "department": "Product Delivery", - "manager_email": "darren.womack@airwalkconsulting.com" + "department": "DCC Atlas", + "manager_email": "Ahammond@airwalkconsulting.com" }, { "id": "d1b53537-fa5a-4975-9397-21ecbb2d2f77", @@ -3314,7 +2922,7 @@ "mobilePhone": "07375505238", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -3342,7 +2950,7 @@ "mobilePhone": "07494498860", "officeLocation": "London", "preferredLanguage": "en-US", - "department": "PMO", + "department": "DCC Tytans", "manager_email": "paul.barrett@airwalkconsulting.com" }, { @@ -3398,7 +3006,7 @@ "mobilePhone": "07832956907", "officeLocation": "London", "preferredLanguage": null, - "department": "Programme Management", + "department": "DCC Atlas", "manager_email": "steve.isbell@airwalkconsulting.com" }, { @@ -3454,8 +3062,8 @@ "mobilePhone": "07917192350", "officeLocation": "Manchester", "preferredLanguage": "en-GB", - "department": "Programme Managment", - "manager_email": "darren.womack@airwalkconsulting.com" + "department": "DCC Tytans", + "manager_email": "alex.hammond@airwalkconsulting.com" }, { "id": "b7a2dd25-ffe6-4df1-909a-5ccb53cff6f7", @@ -3496,7 +3104,7 @@ "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, - "department": null, + "department": "Associate", "manager_email": null }, { @@ -3540,5 +3148,19 @@ "preferredLanguage": "en-GB", "department": "Architecture", "manager_email": "rob.ellison@airwalkconsulting.com" + }, + { + "id": "e4bcc077-0837-4496-ba90-d8677bc5b0ba", + "displayName": "Yogesh Patel", + "userPrincipalName": "yogesh.patel@airwalkconsulting.com", + "givenName": "Yogesh", + "surname": "Patel", + "jobTitle": null, + "mail": "yogesh.patel@airwalkconsulting.com", + "mobilePhone": null, + "officeLocation": null, + "preferredLanguage": null, + "department": null, + "manager_email": null } ] \ No newline at end of file