SharePont Keep Modified And Edited

0

In SharepointOnLine



console.clear();
let mContext = {
    // URL du site courant (contexte de la page SharePoint classique).
    // ⚠️ Limite : si _spPageContextInfo n'existe pas (hors page SP), prévoir une URL de repli (… || "https://…").
    siteUrl: _spPageContextInfo ? _spPageContextInfo.webAbsoluteUrl : "Shared%20Documents",
    query: "Id le 500",// and FSObjType eq 0
    //query: "Id le 500",// and FSObjType eq 0
    doclib: "Shared%20Documents",
    select: "",//"&$select=TotalSize,TotalFileCount,LastModified",
    //select: "?$select=FileDirRef,HasUniqueRoleAssignments,Id,Title,FileLeafRef,Modified,vCreated,FSObjType,ContentTypeId,FileSizeDisplay",
    list: null,
    listFields: null,
    listFieldsNotHidden: null,
    webServerRelativUrl: "/sites/FDI_SandBox",
    fetchGetOptions: {
        method: 'GET',
        headers: {
            'Accept': 'application/json;odata=verbose'
        }
    }
}

// get FormDigestValue
mContext.getRequestDigest = async function () {
    const response = await fetch(`${mContext.siteUrl}/_api/contextinfo`, {
        method: "POST",
        headers: { Accept: "application/json;odata=verbose" },
        credentials: "include",
    });
    const data = await response.json();
    return data.d.GetContextWebInformation.FormDigestValue;
}

mContext.ExecuteQuery = async function ExecuteQuery(req, fetchOptions, maxRetry = 3, wait = 1, trynum = 1) {

    console.log("ExecuteQuery", req, fetchOptions, maxRetry, wait, trynum);
    if (trynum >= maxRetry) {
        console.log("ExecuteQuery Error", req);
        console.log("ExecuteQuery Error", fetchOptions);
        throw new Error(`ExecuteQuery error! maxRetry >= trynum`);
    }
    try {
        let startDate = new Date();
        let diffMinutes = 0;
        respList1 = await fetch(req, fetchOptions);
        endDate = new Date();
        const diffMs = endDate - startDate;
        diffMinutes = Math.floor(diffMs / (1000));
        console.log(`seconds ${diffMinutes} queryNumber  ${trynum}`)

        //avoid 429 too much queries
        if (!respList1.ok && respList1.status == 429) {
            const errorDetails = await respList1.text(); // Get error details from the response
            let err = JSON.parse(errorDetails);
            console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
            await sleep(wait * 10);// * trynum
            return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
        }

        //avoid 503 server unavailable / connections error
        if (!respList1.ok && respList1.status == 503) {
            const errorDetails = await respList1.text(); // Get error details from the response
            let err = JSON.parse(errorDetails);
            console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
            await sleep(wait * 10);// * trynum
            //return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
        }

        //avoid 403 reload page in another tab
        if (!respList1.ok && respList1.status == 403) {
            //debugger;
            window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
            const errorDetails = await respList1.text(); // Get error details from the response
            let err = JSON.parse(errorDetails);
            console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
            await sleep(wait * 10);// * trynum
            window.open(_spPageContextInfo.webAbsoluteUrl, '_blank')
            //return await ExecuteQuery(req, fetchOptions, maxRetry, (wait * 5), ++trynum);
        }

        

        if (!respList1.ok) {
            console.log("ExecuteQuery Error", respList1);
            const errorDetails = await respList1.text(); // Get error details from the response
            const errorDetails2 = await respList1.json(); // Get error details from the response
            console.log("ExecuteQuery Error", respList1);
            console.error(`HTTP error! Status: ${respList1.status}, Details: ${errorDetails}`);
            let err = JSON.parse(errorDetails);
            console.error(`HTTP error! Status: ${respList1.status}, Details: ${err.error.message.value}`);
            console.log(err.error.message.value);
            // Find a validation error returned by SharePoint.
            const validationError = errorDetails2.find(
                function findValidationError(result) {
                    return result.HasException === true;
                }
            );

            // Throw the SharePoint field validation error.
            if (validationError !== undefined) {
                throw new Error(
                    "SharePoint rejected the field update. " +
                    `Field: '${validationError.FieldName}'. ` +
                    `Details: '${validationError.ErrorMessage}'.`
                );
            }
            throw new Error(`HTTP error! Status: ${respList1.status}`);
        }

        return respList1

    } catch (error) {
        console.log("req", req);
        console.log("fetchOptions", fetchOptions);
        console.log(error);
        throw new Error(`HTTP error! Status: ${error}`);
    }
}
function formatDateForValidateUpdateListItem(isoDate) {
    const date = new Date(isoDate);

    if (Number.isNaN(date.getTime())) {
        throw new Error(
            `La date SharePoint reçue est invalide : '${isoDate}'.`
        );
    }

    const pad = value => String(value).padStart(2, "0");

    let hours = date.getHours();
    const minutes = date.getMinutes();

    const ampm = hours >= 12 ? "PM" : "AM";

    // Conversion 24h -> 12h
    hours = hours % 12;
    hours = hours === 0 ? 12 : hours;

    return (
        `${pad(date.getMonth() + 1)}/` +
        `${pad(date.getDate())}/` +
        `${date.getFullYear()} ` +
        `${hours}:` +
        `${pad(minutes)} ${ampm}`
    );
}

// Get a readable error message.
/**
* Change the "Modified By" system field of a SharePoint list item.
*
* Internal SharePoint field name: Editor
*
* Important:
* - listUrl must be the root URL of the list or library.
* - The list must be in the Web identified by mContext.siteUrl.
*
* Examples:
* /sites/FDI_SandBox/Lists/MyList
* /sites/FDI_SandBox/Shared Documents
*
* @param {string} listUrl
* @param {number|string} itemId
* @param {string} userEmail
* @returns {Promise}
*/
mContext.setModifiedBy = async function (
    listUrl,
    itemId,
    userEmail,
    keepDate = true
) {
    // Check the list URL.
    if (
        listUrl === null ||
        listUrl === undefined ||
        String(listUrl).trim() === ""
    ) {
        throw new Error(
            "Variable 'listUrl' is null, undefined or empty."
        );
        // #TODO check fdi
    }

    // Check the item ID.
    if (
        itemId === null ||
        itemId === undefined ||
        String(itemId).trim() === ""
    ) {
        throw new Error(
            "Variable 'itemId' is null, undefined or empty."
        );
        // #TODO check fdi
    }

    // Check the user email.
    if (
        userEmail === null ||
        userEmail === undefined ||
        String(userEmail).trim() === ""
    ) {
        throw new Error(
            "Variable 'userEmail' is null, undefined or empty."
        );
        // #TODO check fdi
    }

    // Check the current SharePoint Web URL.
    if (
        mContext.siteUrl === null ||
        mContext.siteUrl === undefined ||
        String(mContext.siteUrl).trim() === ""
    ) {
        throw new Error(
            "Variable 'mContext.siteUrl' is null, undefined or empty."
        );
        // #TODO check fdi
    }

    // Convert the item ID to a number.
    const normalizedItemId = Number(itemId);

    // Check that the item ID is a positive integer.
    if (
        !Number.isInteger(normalizedItemId) ||
        normalizedItemId <= 0
    ) {
        throw new Error(
            "Variable 'itemId' must be a positive integer. " +
            `Received value: '${itemId}'.`
        );
        // #TODO check fdi
    }

    // Normalize the user email.
    const normalizedUserEmail = String(userEmail)
        .trim()
        .toLowerCase();

    // Perform a basic email format validation.
    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    // Reject an invalid email format.
    if (!emailPattern.test(normalizedUserEmail)) {
        throw new Error(
            "Variable 'userEmail' does not contain a valid email address. " +
            `Received value: '${userEmail}'.`
        );
        // #TODO check fdi
    }

    try {
        // Normalize the current SharePoint Web URL.
        const siteUrl = String(mContext.siteUrl)
            .trim()
            .replace(/\/+$/, "");

        // Convert the provided list URL to an absolute URL object.
        const absoluteListUrl = new URL(
            String(listUrl).trim(),
            window.location.origin
        );

        // Decode the pathname to restore spaces and special characters.
        const decodedListPath = decodeURIComponent(
            absoluteListUrl.pathname
        );

        // Remove the trailing slash from the list URL.
        const listServerRelativeUrl = decodedListPath
            .replace(/\/+$/, "");

        // Check the resulting server-relative URL.
        if (
            listServerRelativeUrl === null ||
            listServerRelativeUrl === undefined ||
            listServerRelativeUrl.trim() === ""
        ) {
            throw new Error(
                "Variable 'listServerRelativeUrl' is null, undefined or empty. " +
                `Received list URL: '${listUrl}'.`
            );
        }

        // Escape apostrophes for the OData string value.
        const escapedListUrl = listServerRelativeUrl.replace(
            /'/g,
            "''"
        );

        // Build the OData alias value.
        const encodedListUrl = encodeURIComponent(
            `'${escapedListUrl}'`
        );
        let oldDate = null;
        //keep the original Modified date if keepDate is true
        if (keepDate) {
            // Get the current Modified date of the list item.
            const ensureUserFetchOptions = {
                method: "GET",
                headers: {
                    "Accept": "application/json;odata=verbose",
                    "Content-Type": "application/json;odata=verbose"
                }
            };

            const getRequestUrl =
                `${siteUrl}/_api/web/GetList(${encodedListUrl})` +
                `/items(${normalizedItemId})?$select=Modified`;
            const date = await mContext.ExecuteQuery(
                getRequestUrl,
                ensureUserFetchOptions);
            const ensureUserData = await date.json();

            console.log("oldDate", ensureUserData.d.Modified);
            oldDate = formatDateForValidateUpdateListItem(ensureUserData.d.Modified);
            console.log("oldDate", oldDate);
        }

        // Get a request digest before performing write operations.
        const requestDigest = await mContext.getRequestDigest();

        // Check the request digest.
        if (
            requestDigest === null ||
            requestDigest === undefined ||
            String(requestDigest).trim() === ""
        ) {
            throw new Error(
                "Variable 'requestDigest' is null, undefined or empty."
            );
            // #TODO check fdi
        }

        // Build the REST endpoint used to register or retrieve the user.
        const ensureUserRequestUrl =
            `${siteUrl}/_api/web/ensureuser`;

        // Build the ensureuser request body.
        const ensureUserRequestBody = {
            logonName: normalizedUserEmail
        };

        // Build the ensureuser request options.
        const ensureUserFetchOptions = {
            method: "POST",
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": requestDigest
            },
            credentials: "include",
            body: JSON.stringify(ensureUserRequestBody)
        };

        // Ensure that the user exists in the SharePoint site user information list.
        const ensureUserResponse = await mContext.ExecuteQuery(
            ensureUserRequestUrl,
            ensureUserFetchOptions
        );

        // Convert the ensureuser response to JSON.
        const ensureUserData = await ensureUserResponse.json();

        // Extract the SharePoint user object.
        const sharePointUser = ensureUserData?.d;

        // Check the SharePoint user object.
        if (
            sharePointUser === null ||
            sharePointUser === undefined
        ) {
            throw new Error(
                "Variable 'sharePointUser' is null or undefined."
            );
            // #TODO check fdi
        }

        // Check the SharePoint user ID.
        if (
            sharePointUser.Id === null ||
            sharePointUser.Id === undefined
        ) {
            throw new Error(
                "Variable 'sharePointUser.Id' is null or undefined. " +
                `User email: '${normalizedUserEmail}'.`
            );
            // #TODO check fdi
        }

        // Check the SharePoint user login name.
        if (
            sharePointUser.LoginName === null ||
            sharePointUser.LoginName === undefined ||
            String(sharePointUser.LoginName).trim() === ""
        ) {
            throw new Error(
                "Variable 'sharePointUser.LoginName' is null, undefined or empty. " +
                `User email: '${normalizedUserEmail}'.`
            );
            // #TODO check fdi
        }

        // Build the ValidateUpdateListItem endpoint.
        const updateRequestUrl =
            `${siteUrl}/_api/web/GetList(@listUrl)` +
            `/items(${normalizedItemId})` +
            "/ValidateUpdateListItem" +
            `?@listUrl=${encodedListUrl}`;

        // Build the SharePoint person field value.
        const editorFieldValue = JSON.stringify([
            {
                Key: sharePointUser.LoginName
            }
        ]);
        let updateRequestBody = null;
        if (oldDate !== null && keepDate) {
            // Build the update request body.
            updateRequestBody = {
                formValues: [
                    {
                        FieldName: "Editor",
                        FieldValue: editorFieldValue
                    },
                    {
                        FieldName: "Modified",
                        FieldValue: oldDate
                    }
                ],
                bNewDocumentUpdate: true
            };
            console.log("updateRequestBody", updateRequestBody);
        } else {
            updateRequestBody = {
                formValues: [
                    {
                        FieldName: "Editor",
                        FieldValue: editorFieldValue
                    }
                ],
                bNewDocumentUpdate: true
            };
        }

        // Build the update request options.
        const updateFetchOptions = {
            method: "POST",
            headers: {
                "Accept": "application/json;odata=verbose",
                "Content-Type": "application/json;odata=verbose",
                "X-RequestDigest": requestDigest
            },
            credentials: "include",
            body: JSON.stringify(updateRequestBody)
        };

        // Execute the Editor field update.
        const updateResponse = await mContext.ExecuteQuery(
            updateRequestUrl,
            updateFetchOptions
        );

        // Convert the update response to JSON.
        const updateData = await updateResponse.json();

        // Extract the field validation results.
        const validationResults =
            updateData?.d?.ValidateUpdateListItem?.results || [];

        // Find a validation error returned by SharePoint.
        const validationError = validationResults.find(
            function findValidationError(result) {
                return result.HasException === true;
            }
        );

        // Throw the SharePoint field validation error.
        if (validationError !== undefined) {
            throw new Error(
                "SharePoint rejected the field update. " +
                `Field: '${validationError.FieldName}'. ` +
                `Details: '${validationError.ErrorMessage}'.`
            );
            // #TODO check fdi
        }

        // Build the function result.
        const result = {
            success: true,
            listUrl: listServerRelativeUrl,
            itemId: normalizedItemId,
            editor: {
                id: sharePointUser.Id,
                email: sharePointUser.Email,
                loginName: sharePointUser.LoginName,
                title: sharePointUser.Title
            },
            validationResults: validationResults
        };

        // Log the successful operation.
        console.log(
            "The Editor field was updated successfully.",
            result
        );

        // Return the operation result.
        return result;
    } catch (error) {
        // Get a readable error message.
        console.error("Erreur lors de la mise à jour de Modified By :", error);

    }
}


await mContext.setModifiedBy(
    "/sites/FDI_SandBox/Lists/FichierDePaiementDetails",
    2,
    "fdietrich@test.com",
    true
)

Sharepoint REST javascript

No ratings yet - be the first to rate this.

Add a comment

Anti-spam