Supista
Contact Us
documentation
Supista ERP
Parameters
Entity Relationships
Belongs To Many Relation

belongsToMany relation CRUD examples using OpWithRelation functions

In Supista ERP, a belongsToMany relation is used to define a many-to-many relationship between two components, where:

One record in Table A can be linked to many records in Table B

And one record in Table B can also be linked to many records in Table A

This is made possible using an automatically generated junction table (also called a relation or pivot table), which holds the IDs of both linked records.

Example Scenario: Members ↔ Projects

A Member can work on multiple Projects

A Project can have multiple Members

In this case:

Members and Projects are the two main tables

Supista ERP auto-generates a relation table (e.g., Projects - Members Relation) with:

Member ID -> __d3__id
Project ID -> __d3__parentId


createOpWithRelation

Adds a new relation row in the junction table, linking Member ↔ Project

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
 
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__newData: { ...userData?.__d3__newData }
    };
 
    const createdData = await createOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
 
    if (createdData[0]) {
      resolve({ result: createdData[0] });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "warning",
          message: "Could not read data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__newData": {
    "__d3__id": [
      2
    ]
  },
  "__d3__parentId": 2,
  "__d3__relationId": "732f6s3717"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "projects Id": 2,
        "members Id": 2,
        "__d3__createdAt": "2025-06-18T11:53:37.614Z",
        "__d3__updatedAt": "2025-06-18T11:53:37.614Z",
        "__d3__deletedAt": null
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

readOpWithRelation

Fetches all related records for a parent entity (e.g., all Members in a Project)

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
 
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__filterdata: { where: {} }
    };
 
    const rowsData = await readOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
 
    if (rowsData?.count) {
      resolve({ result: rowsData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not read data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__filterdata": {
    "where": {}
  },
  "__d3__parentId": 1,
  "__d3__relationId": "732f6s3717"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "count": 2,
        "rows": [
          {
            "id": 2,
            "project title": "AI/ML",
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-17T08:59:23.289Z",
            "__d3__updatedAt": "2025-06-17T08:59:23.289Z",
            "__d3__deletedAt": null
          },
          {
            "id": 1,
            "project title": "Web3",
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-16T20:24:46.032Z",
            "__d3__updatedAt": "2025-06-16T20:24:46.032Z",
            "__d3__deletedAt": null
          }
        ]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

updateOpWithRelation

Updates metadata or related values in the junction row (if any exist)

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
  const { updateOp } = apiOperations;
 
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__id: userData?.__d3__id,
      __d3__newData: { ...userData?.__d3__newData }
    };
 
    const updatedData = await updateOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
 
    if (updatedData?.affectedCount?.[0]) {
      resolve({ result: updatedData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not update data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__newData": {
    "id": 2,
    "project title": "AI/ML/design",
    "__d3__createdBy": 575,
    "__d3__lastUpdatedBy": null,
    "__d3__createdAt": "2025-06-17T08:59:23.289Z",
    "__d3__updatedAt": "2025-06-17T08:59:23.289Z",
    "__d3__deletedAt": null
  },
  "__d3__id": 2,
  "__d3__parentId": 1,
  "__d3__relationId": "732f6s3717"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "affectedCount": [
          1
        ]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

removeOpWithRelation

Removes the link between a Member and a Project

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "members";
 
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__id: [userData?.__d3__id]
    };
 
    const deletedData = await removeOpWithRelation(
      parentTableName,
      payload,
      userData?.__d3__parentId,
      userData?.__d3__relationId
    );
 
    if (deletedData?.deletedObjNo) {
      resolve({ result: deletedData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not delete data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__parentId": 1,
  "__d3__id": 2,
  "__d3__relationId": "732f6s3717"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "deletedObjNo": 1
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}
Transform Data into Decisions with Supista – Your Intelligent Data Partner
AI-Powered Operational Intelligence for Growing Businesses

Automate your operations. Orchestrate your workflows. Scale with confidence.

Book a free strategy session with our Automation Experts and discover how Supista’s AI-Composable ERP can transform your operations into a scalable and intelligent system.