Kintone Basic JavaScript Question

Question / Problem

Kintone Application 1: Quantity and Item Fields are included.

Kintone Application 2: Quantity and Item Fields are also included inside.

If Application 1 has a quantity value of 99, I want it to be deducted by the quantity I declare in the field Quantity of Application 2.

How can I do it?

Code / Attempts

(function() {
    "use strict";

    // Define the IDs and URLs for both applications
    const app1Id = 760; // Application 1 ID
    const app2Id = 761; // Application 2 ID
    const kintoneSubdomain = ''; // Your Kintone subdomain
    const app1Url = `https://kintoneSubdomain.kintone.com/k/v1/records.json`;
    const app1UpdateUrl = `https://kintoneSubdomain.kintone.com/k/v1/record.json`;

    // Define the field codes
    const quantity1Field = 'quantity1';
    const item1Field = 'item1';
    const quantity2Field = 'quantity2';
    const item2Field = 'item2';

    // Define the API tokens
    const app1ApiToken = ''; // API token for app1
    const app2ApiToken = ''; // API token for app2

    // Add an event listener for record creation and editing in Application 2
    kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {
        const record = event.record;
        const quantity2 = Number(record[quantity2Field].value);
        const item2 = record[item2Field].value;

        // Set headers for the API request
        const headers = {
            'X-Cybozu-Authorization': app1ApiToken,
            'Content-Type': 'application/json'
        };

        // Define the query to fetch the matching record from Application 1
        const query = `${item1Field}="${item2}"`;

        // Fetch the record from Application 1
        return kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', {
            app: app1Id,
            query: query
        }, { headers: headers })
        .then(response => {
            if (response.records.length > 0) {
                const app1Record = response.records[0];
                const app1Quantity = Number(app1Record[quantity1Field].value);

                // Calculate the new quantity
                const newQuantity = app1Quantity - quantity2;

                // Prepare the payload for updating Application 1
                const updatePayload = {
                    app: app1Id,
                    id: app1Record.$id.value,
                    record: {
                        [quantity1Field]: {
                            value: newQuantity
                        }
                    }
                };

                // Update the record in Application 1
                return kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', updatePayload, { headers: headers });
            } else {
                throw new Error('Item not found in Application 1');
            }
        })
        .then(response => {
            console.log('Quantity updated in Application 1:', response);
        })
        .catch(error => {
            event.error = `Error updating Application 1: ${error.message}`;
        });
    });
})();

Hello @chaseeYT
Welcome to the community.

Here are the issues that need to be addressed:

  1. Incorrect Usage of Headers: The original script attempted to set headers for the API request in a way that is not supported by the kintone.api method. The kintone.api method automatically handles headers, so manually setting headers is unnecessary and incorrect.
  2. Improper Handling of API Tokens: The original script included the API token directly in the headers. Plus, this is not required for requests made from within Kintone itself, as Kintone's JavaScript API already handles authentication based on the user's current session (but I kept in the script just in case).
  3. Incorrect Error Handling and Logging: The error handling and logging in the original script were not correctly structured, which could result in unclear error messages or lack of proper error reporting.

Additionally, it's important to note that posting your API token publicly is not advisable.

Here's the corrected script:

(function() {
    "use strict";

    // Define the IDs and URLs for both applications
    const app1Id = 'App1Id'; // Application 1 ID
    const app2Id = 'App2Id'; // Application 2 ID

    // Define the field codes
    const quantity1Field = 'quantity1';
    const item1Field = 'item1';
    const quantity2Field = 'quantity2';
    const item2Field = 'item2';

    // Define the API token for App 1
    const app1ApiToken = 'ApiToken'; // API token for app1

    // Add an event listener for record creation and editing in Application 2
    kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {
        const record = event.record;
        const quantity2 = Number(record[quantity2Field].value);
        const item2 = record[item2Field].value;

        console.log('Event triggered');
        console.log('Quantity2:', quantity2);
        console.log('Item2:', item2);

        // Define the query to fetch the matching record from Application 1
        const query = `${item1Field}="${item2}"`;
        console.log('Query:', query);

        // Fetch the record from Application 1
        return kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', {
            app: app1Id,
            query: query,
            fields: ['$id', quantity1Field],
            headers: {
                'X-Cybozu-API-Token': app1ApiToken
            }
        }).then(response => {
            console.log('Response from App1:', response);
            if (response.records.length > 0) {
                const app1Record = response.records[0];
                const app1Quantity = Number(app1Record[quantity1Field].value);

                // Check if the quantity in Application 1 is exactly 99
                if (app1Quantity === 99) {
                    // Calculate the new quantity
                    const newQuantity = app1Quantity - quantity2;

                    console.log('New Quantity:', newQuantity);

                    // Prepare the payload for updating Application 1
                    const updatePayload = {
                        app: app1Id,
                        id: app1Record.$id.value,
                        record: {
                            [quantity1Field]: {
                                value: newQuantity
                            }
                        },
                        headers: {
                            'X-Cybozu-API-Token': app1ApiToken
                        }
                    };

                    // Update the record in Application 1 using the API token
                    return kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', updatePayload);
                } else {
                    console.log('Quantity in Application 1 is not 99. No update performed.');
                    return Promise.resolve();
                }
            } else {
                throw new Error('Item not found in Application 1');
            }
        }).then(response => {
            if (response) {
                console.log('Quantity updated in Application 1:', response);
            }
        }).catch(error => {
            console.error('Error updating Application 1:', error);
            event.error = `Error updating Application 1: ${error.message}`;
        });
    });
})();