ph_crop_varieties 0.3.0 copy "ph_crop_varieties: ^0.3.0" to clipboard
ph_crop_varieties: ^0.3.0 copied to clipboard

Offline Flutter lookups by line code, exact region, generic variety name, with retained stage-first APIs.

ph_crop_varieties #

Offline Flutter lookups for Philippine crop varieties using the PCIC/PABS reference data bundled with the package.

For generic rice and corn options, the package filters by crop line code and exact region before resolving the selected generic name to its source variety ID and growth stage. The existing stage-first methods remain available for actual named varieties and HV-capable consumers. The returned CropVariety.varietyId is the value a consuming application can place in its on-premises PABS payload.

Features #

  • Works offline with a bundled JSON asset
  • Lists generic rice and corn choices by line code and exact region
  • Resolves a generic variety name without requiring growth stage as an input
  • Omits unresolved generic choices when source IDs or growth stages conflict
  • Filters by exact region and normalized line code and growth stage
  • Discovers the available growth stages for a line code and region
  • Resolves the selected variety name to its source variety ID
  • Allows the same variety ID across regions, stages, or distinct choices
  • Removes only completely identical choices from lookup results
  • Caches parsed data after the first successful load
  • Reports malformed data and ambiguous exact selections explicitly

Installation #

dependencies:
  ph_crop_varieties: ^0.3.0

Then import its public library:

import 'package:ph_crop_varieties/ph_crop_varieties.dart';

Basic usage #

final repository = CropVarietyRepository();

final choices = await repository.getGenericVarieties(
  lineCode: 'CR',
  region: 1,
);

final selected = await repository.findGenericVariety(
  lineCode: 'CR',
  region: 1,
  varietyName: 'CORN 150 DAYS',
);

final varietyIdForPabs = selected?.varietyId; // 421
final sourceGrowthStage = selected?.growthStage; // days130

The generic APIs have these signatures:

Future<List<CropVariety>> getGenericVarieties({
  required String lineCode,
  required int region,
});

Future<CropVariety?> findGenericVariety({
  required String lineCode,
  required int region,
  required String varietyName,
});

getGenericVarieties recognizes line-specific generic patterns: RICE <N> DAYS for RC and CORN <N> DAYS for CR. Matching ignores whitespace and letter case, so compact source names such as RICE135DAYS remain selectable. Results use only the requested exact region; choices are never borrowed from another region. Each returned choice has one resolvable source ID and valid daysN growth stage. A generic name is omitted when its source records disagree on ID or stage, and findGenericVariety returns null when the requested choice is unavailable.

For example, CORN 150 DAYS in Region 1 resolves to variety ID 421 and source growth stage days130.

Stage-first lookup for actual varieties #

The existing stage-first methods are unchanged. Use them for actual named varieties and for line codes such as HV, which intentionally have no generic-name flow:

final growthStages = await repository.getGrowthStages(
  lineCode: 'HV',
  region: 1,
);

final varieties = await repository.getVarieties(
  lineCode: 'HV',
  region: 1,
  growthStage: growthStages.first,
);

final selected = await repository.findVariety(
  lineCode: 'HV',
  region: 1,
  growthStage: growthStages.first,
  varietyName: varieties.first.varietyName,
);

getGrowthStages returns an immutable list in numeric day order. getVarieties returns an immutable, alphabetically sorted list. Both return an empty list when there are no matching records. findVariety returns null when the selected name is absent.

Use getVarieties with the first three parameters to populate the farmer's variety choices. Use findVariety with all four parameters, including the farmer-selected varietyName, to resolve the specific source varietyId.

Manual stage-first verification for actual varieties #

Developers maintaining actual-variety or HV stage-first consumers can run the manual four-parameter lookup test with values supplied from the command line. This exercises the bundled production data and prints the exact record that will supply the PABS variety ID.

From the package root in PowerShell, run:

flutter test `
  --reporter expanded `
  --dart-define=LINE_CODE=CR `
  --dart-define=REGION=1 `
  --dart-define=GROWTH_STAGE=days120 `
  --dart-define="VARIETY_NAME=PSB Cn-01 (USMARC 104)" `
  tool\manual_variety_lookup_test.dart

The result includes:

Resolved crop variety:
  lineCode: CR
  region: 1
  growthStage: days120
  varietyName: PSB Cn-01 (USMARC 104)
  varietyId: 406

Change the four --dart-define values to test another farmer selection. The test fails with a clear message when a parameter is missing or invalid, when the complete selection does not exist, or when the complete selection is ambiguous.

Stage-first lookup contract for actual and HV varieties #

For actual-variety and HV consumers, use these three values to populate a variety dropdown:

  • lineCode: RC for rice or CR for corn
  • region: the exact integer region belonging to the selected farm
  • growthStage: the exact source category, such as days100, days110, days120, or days130

Use the returned typed object as the selection. The complete selection key is:

lineCode + region + growthStage + varietyName

The ID is not globally unique and is not used by itself to filter the dropdown. Duplicate IDs are valid when the records apply to different regions, growth stages, or names.

If the same complete selection key maps to different IDs, findVariety throws CropVarietyDataException instead of choosing an arbitrary ID. An unrelated ambiguous key elsewhere in the source data does not prevent valid lookups.

Region handling #

Region values are never inferred or remapped. Every Region value is used exactly as supplied in lib/data/varieties_clean.json.

The current data has no Region 10 records, so Region 10 lookups return an empty list. Adding valid Region 10 records to the JSON makes them available automatically without a code mapping change.

Future Farmers App integration #

The future RCCR generic-variety integration should:

  1. Map rice to RC and corn to CR.
  2. Resolve the region from the farmer's registered address.
  3. Call getGenericVarieties(lineCode: lineCode, region: region) to populate the generic choices for that exact region.
  4. After the farmer chooses a name, call findGenericVariety(lineCode: lineCode, region: region, varietyName: varietyName).
  5. Keep the returned CropVariety object; its growthStage is the source stage, so RCCR does not ask for growth stage first.
  6. Store selected.varietyName as the displayed form value.
  7. Store selected.varietyId as lot.pabsVarietyId.
  8. Send that existing varietyId field through the mobile and backend payload to PABS.

The package does not make network calls or send data to PABS. It supplies the authoritative source ID to the consuming application.

Custom JSON loader #

Tests or trusted consumers can inject JSON while retaining the same validation and lookup behavior:

final repository = CropVarietyRepository.fromJsonLoader(
  () async => trustedJsonString,
);

Data updates #

Keep lib/data/varieties_clean.json as valid standard JSON. Do not add JavaScript-style comments, remap regions, renumber IDs, or remove legitimate duplicate IDs. Run the full test suite after every data update:

flutter test

Validation #

dart format --set-exit-if-changed .
flutter analyze
flutter test
dart pub publish --dry-run

The last command validates the package archive; it does not publish the package.

0
likes
160
points
136
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Offline Flutter lookups by line code, exact region, generic variety name, with retained stage-first APIs.

Homepage
Repository (GitHub)
View/report issues

Topics

#philippines #agriculture #crops #offline

License

MIT (license)

Dependencies

flutter

More

Packages that depend on ph_crop_varieties