Supista
Contact Us
documentation
Supista ERP
Parameters
Entity Relationships
Has Many Relation

hasMany relation CRUD examples using OpWithRelation functions

In Supista ERP, a hasMany relation defines a one-to-many relationship between two components (tables), where a single record in the parent table is associated with multiple records in the child table.

This is the inverse of a belongsTo relation — and in fact, they often exist together as complementary links between two modules.

Example Scenario: A Team has many Members

Parent Table: Teams
Child Table: Members

Supista creates a column in Members: Teams - Members ID

Multiple members can be assigned to a single team


createOpWithRelation

Creates a new Member and auto-assigns it to Team ID = 1.

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { createOp } = apiOperations;
 
  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?.id) {
      resolve({ result: createdData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "warning",
          message: "Could not create data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__newData": {
    "name": "john",
    "email": "[john@gmail.com](mailto:john@gmail.com)",
    "teams - members ID": 1
  },
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "id": 1,
        "name": "john",
        "email": "[john@gmail.com](mailto:john@gmail.com)",
        "teams - members ID": 1,
        "__d3__createdBy": 575,
        "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
        "__d3__createdAt": "2025-06-11T10:07:59.065Z",
        "__d3__lastUpdatedBy": null,
        "__d3__deletedAt": null
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

readOpWithRelation

Fetches all members under Team ID = 1.

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { readOpWithRelation } = apiOperations;
 
  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": "5r1i4x3071"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "count": 2,
        "rows": [
          {
            "id": 1,
            "name": "john",
            "email": "[john@gmail.com](mailto:john@gmail.com)",
            "teams - members ID": 1,
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-11T10:07:59.065Z",
            "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
            "__d3__deletedAt": null
          },
          {
            "id": 2,
            "name": "james",
            "email": "[james@gmail.com](mailto:james@gmail.com)",
            "teams - members ID": 1,
            "__d3__createdBy": 575,
            "__d3__lastUpdatedBy": null,
            "__d3__createdAt": "2025-06-10T13:23:48.594Z",
            "__d3__updatedAt": "2025-06-10T13:23:48.594Z",
            "__d3__deletedAt": null
          }
        ]
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}

updateOpWithRelation

Updates Member ID = 1 under Team ID = 1.

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { updateOpWithRelation } = 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": {
    "name": "john Doe",
    "email": "[john@gmail.com](mailto:john@gmail.com)",
    "teams - members ID": 1,
    "__d3__createdBy": 575,
    "__d3__lastUpdatedBy": null,
    "__d3__createdAt": "2025-06-11T10:07:59.065Z",
    "__d3__updatedAt": "2025-06-11T10:07:59.065Z",
    "__d3__deletedAt": null
  },
  "__d3__id": 1,
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output:

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

removeOpWithRelation

Deletes Member ID = 1 only if it belongs to Team ID = 1.

Example Code:

async function customizeERP(userData, apiOperations) {
  const parentTableName = "teams";
  const { removeOpWithRelation } = apiOperations;
 
  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": "5r1i4x3071"
}

Example Output:

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

bulkCreateOpWithRelation

Creates a multiple new Member and auto-assigns it to Team ID = 1.

Example Code:

async function customizeERP(userData, apiOperations) {
  const tableName = "teams";
  const { bulkCreateOpWithRelation } = apiOperations;
 
  return new Promise(async (resolve, reject) => {
    const payload = {
      __d3__bulkData: userData?.__d3__bulkData
    };
 
    const bulkData = await bulkCreateOpWithRelation(
      tableName,
      payload,
      userData.__d3__parentId,
      userData.__d3__relationId
    );
 
    if (bulkData) {
      resolve({ result: bulkData });
    } else {
      resolve({
        result: {},
        popupMsg: {
          type: "error",
          message: "Could Not create data! Please try again later"
        }
      });
    }
  });
}

Example input:

{
  "__d3__bulkData": [
    {
      "name": "john",
      "email": "[john@gmail.com](mailto:john@gmail.com)",
      "teams - members ID": 1
    },
    {
      "name": "james",
      "email": "[james@gmail.com](mailto:james@gmail.com)",
      "teams - members ID": 1
    }
  ],
  "__d3__parentId": 1,
  "__d3__relationId": "5r1i4x3071"
}

Example Output:

{
  "response": {
    "__d3__result": {
      "result": {
        "bulkCreated": 2
      }
    },
    "__d3__error": false,
    "printConsole": []
  }
}
Last updated on
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.