APIs & services / portfolio-service

Download crop plans (portfolios with line items) for a chunk of farmers.

Endpointtoday's app
Call
GET /gateway/portfolio-service/api/v1/portfolios/ownerEntities?ownerEntityIdList=&ownerEntityType=ENTITY_TYPE.IE
Service
portfolio-service
Features
Data download (Cadre), Data download (Unit / FMT), Farmer hub (option tiles), Crop Plan, Crop Actual (portfolio)
When
Data download; per-farmer refresh
Auth
X-SESSIONID header (AuthInterceptor adds it; re-auth on 401/400)
In the App Service

Use case

Online bulk read of crop plans/actuals (portfolio with line items) for farmers. Used by data download (DataSetupViewModel chunks of 30, UnitDataSetupViewModel and SetupForUnitInChargeLogin chunks of 50, SetupForUser), by the farmer hub refresh (OptionViewModel) and by swipe-to-refresh on the portfolio screen (IePortfolioRepositoryImpl.fetchCropActualOnline with one id). Results are merged with local rows (keeping local appIds, sync errors, photos and geofence paths, and skipping PLIs with pending sync) and saved to portfolio / portfolio_portfoliolineitem tables; PLI ids are then used to fetch attachments. Failures throw in data download or show 'something went wrong' on refresh.

Headers

HeaderValueNotes
X-SESSIONID<session token>Added by AuthInterceptor (data/net/AuthInterceptor.kt) when the call does not set it; on HTTP 401 or 400 the interceptor invalidates the token, fetches a new one and retries the request once.

Parameters

ParamInRequiredExampleNotes
ownerEntityIdListqueryYes40001,40002Retrofit List<String> -> repeated/CSV IE ids; chunk 30-100 depending on caller.
ownerEntityTypequeryYesENTITY_TYPE.IEDefault.

Request

No body. IE ids (chunk 30/100), ownerEntityType

Response

Example response body (synthetic data)
[
  {
    "owningEntityId": "40001",
    "id": 5001,
    "uuid": "3a9d0000-0000-4000-8000-000000000101",
    "ownerEntityType": {
      "code": "ENTITY_TYPE.IE",
      "refClass": {
        "code": "CLASS.ENTITY_TYPE"
      }
    },
    "portfolioLineItemList": [
      {
        "portfolioId": "3a9d0000-0000-4000-8000-000000000101",
        "id": 6001,
        "asset": "ASSET-CODE-0001",
        "uuid": "5f6c1d2e-0000-4000-8000-00000000a001",
        "practiceMasterCodes": [
          "PRACTICE.MULCHING",
          "PRACTICE.SEED_TREATMENT"
        ],
        "portfolioLineItemType": "PORTFOLIO_LINE_ITEM_TYPE.ACTUAL",
        "imageUrl": null,
        "isActive": true,
        "currentSeason": "KHARIF_2026",
        "methodMaster": {
          "id": 3,
          "uuid": "m-0003",
          "methodCode": "METHOD.PMDS"
        },
        "practiceMaster": {
          "practiceCode": "PRACTICE.MULCHING",
          "id": 4,
          "uuid": "p-0004"
        },
        "appCreatedAt": "1780000000000",
        "appLastModifiedAt": "1780000000000",
        "createdAt": null,
        "lastModifiedAt": null,
        "titleId": "TILE-0001",
        "assetId": 9001,
        "assetCheckSum": "<asset checksum>",
        "syncErrorId": null,
        "compactBlockId": null,
        "isLinkedToCompactBlock": false,
        "createdByApp": 109,
        "lastModifiedByApp": 109,
        "createdFromDevice": "<device id>",
        "lastUpdatedFromDevice": "<device id>",
        "geoFencingFileName": null,
        "geoFencingCreatedOn": null,
        "geoFencingFilePath": null,
        "geoFenceAttachments": [
          88002
        ],
        "isEditable": true,
        "imageAttachmentId": null,
        "imageCreatedAt": null,
        "changeLog": null,
        "cropSeason": "KHARIF",
        "isAttachmentFetched": false,
        "portfolioProductLineItemList": [
          {
            "portfolioLineItemId": "5f6c1d2e-0000-4000-8000-00000000a001",
            "id": 7001,
            "uuid": "7b1e0000-0000-4000-8000-000000000201",
            "genericProduct": "PRODUCT.PADDY",
            "plannedStartDate": "2026-06-01",
            "plannedEndDate": "2026-10-31",
            "actualStartDate": "2026-06-05",
            "actualEndDate": null,
            "cropChangeReason": null,
            "assetProportion": {
              "id": 0,
              "uoM": {
                "code": "UOM.ACRE",
                "description": "Acre",
                "measurementType": {
                  "code": "MEASUREMENT_TYPE.AREA",
                  "description": "Area",
                  "globalRefClass": {
                    "code": "GREF.MEASUREMENT_TYPE",
                    "description": "",
                    "name": "Measurement type"
                  },
                  "name": "Area"
                },
                "name": "Acre",
                "symbol": "ac"
              },
              "value": 0.5
            },
            "isMajorCrop": true,
            "cropType": "CROP_TYPE.MAIN",
            "harvestStatus": "HARVEST_STATUS.PENDING",
            "harvestStartDateTime": null,
            "harvestCompleteDateTime": null,
            "appCreatedAt": "1780000000000",
            "appLastModifiedAt": "1780000000000",
            "createdAt": null,
            "lastModifiedAt": null,
            "ppliCropType": "PPLI_CROP_TYPE.PMDS",
            "expectedHarvestDate": "2026-10-15",
            "seedSource": "SEED_SOURCE.OWN",
            "seedVariety": "Variety A",
            "interestedInCropMarketing": false,
            "sowingDate": "2026-06-05",
            "appId": "7b1e0000-0000-4000-8000-000000000201",
            "syncStatus": "SYNC_PENDING"
          }
        ],
        "portfolioLineItemQuestionResponses": [
          {
            "portfolioLineItemAppId": "5f6c1d2e-0000-4000-8000-00000000a001",
            "id": 0,
            "uuid": "8c2f0000-0000-4000-8000-000000000301",
            "questionId": 12,
            "category": "PMDS",
            "subCategory": "SEED_TREATMENT",
            "questionType": "SINGLE_SELECT",
            "questionCode": "Q_SEED_TREATMENT",
            "questionLabel": "Seed treated?",
            "answerLanguageCode": "en",
            "answerValue": "YES",
            "answerLabel": "Yes",
            "answerText": null,
            "appCreatedAt": "1780000000000",
            "appLastModifiedAt": "1780000000000"
          }
        ]
      }
    ]
  }
]
FieldTypeRequiredNotes
[].id / uuid / owningEntityId / ownerEntityTypemixedportfolio table; owningEntityId maps back to the farmer alias via ie_flat_entity.
[].portfolioLineItemList[]arrayportfolio_portfoliolineitem rows: id, uuid, asset, assetId, assetCheckSum, titleId, portfolioLineItemType, currentSeason, cropSeason, practiceMasterCodes, methodMaster, practiceMaster, compactBlockId, isLinkedToCompactBlock, isEditable, changeLog, createdAt, lastModifiedAt.
[].portfolioLineItemList[].portfolioProductLineItemList[]arrayCrop rows (portfolio_portfoliolineitem_portfolioproductlineitem).
[].portfolioLineItemList[].portfolioLineItemQuestionResponses[]arrayPMDS answers.
[].portfolioLineItemList[].geoFenceAttachmentslong[]KML attachment ids; Unit In-charge setup fetches them via portfolios/attachment/bulk.

Errors

StatusWhenWhat the app does
401 / 400Session token expiredAuthInterceptor invalidates the token, gets a fresh session id and retries the request once.
any non-2xxOther failuresData download: 'Failed to fetch portfolio' -> step error (or Crashlytics log in background setups). Refresh: error toast.

Source

  • data/src/main/java/org/mindtree/app/agricultor/data/setup/SetupService.kt
  • app/src/main/java/org/platformcommons/urvi/view/datasetup/DataSetupViewModel.kt
  • app/src/main/java/org/platformcommons/urvi/view/datasetup/UnitDataSetupViewModel.kt
  • app/src/main/java/org/platformcommons/urvi/view/option/OptionViewModel.kt
  • app/src/main/java/org/platformcommons/urvi/datasource/repository/impl/IePortfolioRepositoryImpl.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/setup/SetupForUser.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/setup_new/SetupForUnitInChargeLogin.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/entity/Portfolio.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/entity/PortfolioLineItem.kt