@agridea/suibi-module 0.1.0-preview.8 → 0.1.0-preview.82d9ee0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/elements/browser/main.js +75 -64
- package/dist/elements/browser/styles.css +1 -1
- package/dist/elements/browser/suibi-module-latest.css +1 -1
- package/dist/elements/browser/suibi-module-latest.js +75 -64
- package/dist/elements/browser/{suibi-module.v0.1.0-preview.8.css → suibi-module.v0.1.0-preview.82d9ee0.css} +1 -1
- package/dist/elements/browser/suibi-module.v0.1.0-preview.82d9ee0.js +78 -0
- package/dist/elements/browser/suibi-theme-dark.css +1 -1
- package/dist/elements/browser/version.txt +1 -1
- package/dist/elements/browser/wc-global-utilities.css +1 -0
- package/dist/types/app/app.d.ts +14 -6
- package/dist/types/app/components/add-dashed-button/add-dashed-button.component.d.ts +9 -0
- package/dist/types/app/components/data-preview/data-preview.component.d.ts +233 -0
- package/dist/types/app/components/empty-state/empty-state.component.d.ts +12 -0
- package/dist/types/app/components/gauge-arc/gauge-arc.component.d.ts +49 -0
- package/dist/types/app/components/header-bar/header-bar.component.d.ts +14 -0
- package/dist/types/app/components/inline-table/inline-table.component.d.ts +159 -0
- package/dist/types/app/components/inline-table/inline-table.types.d.ts +212 -0
- package/dist/types/app/components/module-placeholder-page/module-placeholder-page.component.d.ts +6 -0
- package/dist/types/app/components/planning-result/planning-result.component.d.ts +46 -0
- package/dist/types/app/components/planning-result-row/planning-result-row.component.d.ts +34 -0
- package/dist/types/app/components/planning-trigger/planning-trigger.component.d.ts +13 -0
- package/dist/types/app/components/results-page/results-page.component.d.ts +13 -0
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-dashboard.component.d.ts +32 -0
- package/dist/types/app/components/suissebilanz-dashboard/suissebilanz-metrics.service.d.ts +21 -0
- package/dist/types/app/components/suissebilanz-minibar/suissebilanz-minibar.component.d.ts +19 -0
- package/dist/types/app/components/validation-page/validation-page.component.d.ts +18 -0
- package/dist/types/app/components/welcome-page/metadata.types.d.ts +1 -0
- package/dist/types/app/components/welcome-page/welcome-page.component.d.ts +30 -0
- package/dist/types/app/components/workflow-stepper/workflow-stepper.component.d.ts +49 -0
- package/dist/types/app/core/data/naebi-data.service.d.ts +52 -31
- package/dist/types/app/core/error/global-error-handler.d.ts +5 -0
- package/dist/types/app/core/events/suibi-data-emitter.service.d.ts +13 -0
- package/dist/types/app/core/events/suibi-data-event.d.ts +26 -0
- package/dist/types/app/core/i18n/i18n.service.d.ts +5 -3
- package/dist/types/app/core/i18n/locales/fr.d.ts +2 -0
- package/dist/types/app/core/i18n/locales/it.d.ts +2 -0
- package/dist/types/app/core/master-data/master-data.service.d.ts +15 -1
- package/dist/types/app/core/metadata/suibi-metadata.service.d.ts +6 -0
- package/dist/types/app/core/metadata/suibi-metadata.types.d.ts +18 -0
- package/dist/types/app/core/navigation/navigation.service.d.ts +59 -5
- package/dist/types/app/core/planning/planning-balance.service.d.ts +46 -0
- package/dist/types/app/core/planning/planning-balance.types.d.ts +206 -0
- package/dist/types/app/core/planning/planning-balance.utils.d.ts +10 -0
- package/dist/types/app/core/schemas/schema-localization.util.d.ts +18 -0
- package/dist/types/app/core/telemetry/telemetry.service.d.ts +12 -0
- package/dist/types/app/core/utils/custom-unit.util.d.ts +39 -0
- package/dist/types/app/core/utils/object.util.d.ts +46 -0
- package/dist/types/app/core/validation/ajv-custom.d.ts +1 -0
- package/dist/types/app/core/validation/capabilities.d.ts +11 -5
- package/dist/types/app/core/validation/global-validation.service.d.ts +33 -4
- package/dist/types/app/jsonforms/filters/code-list-filter-resolvers.d.ts +3 -0
- package/dist/types/app/jsonforms/registry/renderers.registry.d.ts +12 -0
- package/dist/types/app/jsonforms/renderers/controls/selects/animal-category/animal-category-select.renderer.d.ts +1 -1
- package/dist/types/app/jsonforms/renderers/controls/selects/code-list/code-list-select.renderer.d.ts +16 -2
- package/dist/types/app/jsonforms/renderers/layout/array/array-layout.renderer.d.ts +43 -0
- package/dist/types/app/jsonforms/renderers/layout/categorization/selected-category-categorization.renderer.d.ts +34 -0
- package/dist/types/app/jsonforms/renderers/layout/constraint/constraint-layout.renderer.d.ts +1 -0
- package/dist/types/app/jsonforms/renderers/layout/group/base-group.renderer.d.ts +2 -0
- package/dist/types/app/jsonforms/renderers/layout/group/module-toggle-group.renderer.d.ts +38 -0
- package/dist/types/app/nutrient-cycle/animal-stock/animal-stock-detail/animal-stock-detail.component.d.ts +21 -0
- package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock/animal-stock-list}/animal-stock-list.component.d.ts +6 -9
- package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock/animal-stock-master-detail}/animal-stock-master-detail.component.d.ts +5 -2
- package/dist/types/app/{animal-stock → nutrient-cycle/animal-stock}/animal-stock.types.d.ts +6 -6
- package/dist/types/app/nutrient-cycle/animal-stock/index.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-master-detail/farm-manure-trading-master-detail.component.d.ts +19 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.component.d.ts +37 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading-table/farm-manure-trading-table.config.d.ts +24 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/farm-manure-trading.types.d.ts +31 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/index.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/farm-manure-trading/transaction-unit.util.d.ts +3 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.component.d.ts +23 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/arable-land-table/arable-land-table.config.d.ts +16 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.component.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/crop-harvest-table/crop-harvest-table.config.d.ts +13 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-detail/field-cultivation-detail.component.d.ts +22 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-general/field-cultivation-general.component.d.ts +20 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-list/field-cultivation-list.component.d.ts +17 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation-master-detail/field-cultivation-master-detail.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.types.d.ts +45 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/field-cultivation.util.d.ts +10 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/fodder-cropland-table/fodder-cropland-table.config.d.ts +21 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/index.d.ts +9 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/field-cultivation/special-crops-table/special-crops-table.config.d.ts +54 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.component.d.ts +52 -0
- package/dist/types/app/nutrient-cycle/field-spreading/fertiliser-table/fertiliser-table.config.d.ts +20 -0
- package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.component.d.ts +36 -0
- package/dist/types/app/nutrient-cycle/field-spreading/field-spreading.types.d.ts +44 -0
- package/dist/types/app/nutrient-cycle/field-spreading/index.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/field-spreading/ingredient.util.d.ts +8 -0
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.component.d.ts +32 -0
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-table.config.d.ts +17 -0
- package/dist/types/app/nutrient-cycle/field-spreading/recycling-table/recycling-transaction-unit.util.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-master-detail/fodder-master-detail.component.d.ts +25 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.component.d.ts +28 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder-table/fodder-table.config.d.ts +9 -0
- package/dist/types/app/nutrient-cycle/fodder/fodder.types.d.ts +34 -0
- package/dist/types/app/nutrient-cycle/fodder/index.d.ts +3 -0
- package/dist/types/app/nutrient-cycle/fodder/ingredient.util.d.ts +8 -0
- package/dist/types/app/nutrient-cycle/fodder/transaction-unit.util.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/lifetime-performance/index.d.ts +2 -0
- package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance-form.component.d.ts +27 -0
- package/dist/types/app/nutrient-cycle/lifetime-performance/lifetime-performance.types.d.ts +5 -0
- package/dist/types/app/nutrient-cycle/storage/index.d.ts +4 -0
- package/dist/types/app/nutrient-cycle/storage/storage-detail/storage-detail.component.d.ts +30 -0
- package/dist/types/app/nutrient-cycle/storage/storage-general/storage-general.component.d.ts +29 -0
- package/dist/types/app/nutrient-cycle/storage/storage-list/storage-list.component.d.ts +23 -0
- package/dist/types/app/nutrient-cycle/storage/storage-master-detail/storage-master-detail.component.d.ts +32 -0
- package/dist/types/app/nutrient-cycle/storage/storage.types.d.ts +40 -0
- package/dist/types/environments/environment.d.ts +11 -0
- package/dist/types/public-api.d.ts +2 -0
- package/dist/types/shared/material-icons.d.ts +3 -3
- package/package.json +69 -17
- package/dist/elements/browser/suibi-module.v0.1.0-preview.8.js +0 -67
- package/dist/types/app/animal-stock/animal-stock-detail.component.d.ts +0 -22
- package/dist/types/app/data-preview.d.ts +0 -7
- package/dist/types/app/header-bar.d.ts +0 -19
- package/dist/types/app/welcome-page.d.ts +0 -4
- /package/dist/types/app/{core/validation/validation-errors-panel.d.ts → components/validation-errors-panel/validation-errors-panel.component.d.ts} +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import exampleDetail from '../../../../assets/example-data/example-naebi-data.json';
|
|
2
|
+
type SampleEvent = typeof exampleDetail;
|
|
3
|
+
type SampleData = SampleEvent['payload']['data'];
|
|
4
|
+
export type NaebiData = SampleData;
|
|
3
5
|
/**
|
|
4
6
|
* Calculation mode determines which validation rules and features are active.
|
|
5
7
|
*/
|
|
@@ -27,10 +29,8 @@ export declare class NaebiDataService {
|
|
|
27
29
|
hoursPerDay: number;
|
|
28
30
|
};
|
|
29
31
|
stall: {
|
|
30
|
-
stableSystem:
|
|
31
|
-
stableCapacity: number;
|
|
32
|
+
stableSystem: string;
|
|
32
33
|
stableVentilationType: number;
|
|
33
|
-
stableAirPurification: number;
|
|
34
34
|
hasStableDeepLitter: boolean;
|
|
35
35
|
hasStableManureBeltDrying: boolean;
|
|
36
36
|
stableManureRemovalFrequency: number;
|
|
@@ -39,10 +39,6 @@ export declare class NaebiDataService {
|
|
|
39
39
|
hasStableFeedingStationElevated: boolean;
|
|
40
40
|
hasStableFloorSlopedUrineDrainage: boolean;
|
|
41
41
|
hasYard: boolean;
|
|
42
|
-
yardFeeding: number;
|
|
43
|
-
yardFloorType: number;
|
|
44
|
-
yardDays: number;
|
|
45
|
-
yardHoursPerDay: number;
|
|
46
42
|
};
|
|
47
43
|
};
|
|
48
44
|
hasImpexDerivedExcretion: boolean;
|
|
@@ -50,6 +46,7 @@ export declare class NaebiDataService {
|
|
|
50
46
|
feeding: {
|
|
51
47
|
fodderConsumption: number;
|
|
52
48
|
concentratedFeedstuffConsumption: number;
|
|
49
|
+
concentratedFeedStuffConsumption: number;
|
|
53
50
|
winterFeeding: {
|
|
54
51
|
feedingRoutine: {
|
|
55
52
|
typeOfFeedstuffProduct: string;
|
|
@@ -74,19 +71,14 @@ export declare class NaebiDataService {
|
|
|
74
71
|
}[];
|
|
75
72
|
storage: {
|
|
76
73
|
stableStrawLitter: number;
|
|
77
|
-
manureSupplyProportionStored: number;
|
|
78
74
|
slurrySupplyProportionStored: number;
|
|
79
75
|
createFacilitySpecificManureProduct: boolean;
|
|
80
76
|
createFacilitySpecificSlurryProduct: boolean;
|
|
77
|
+
slurryTankQuantity: number;
|
|
81
78
|
dilutionRatio: number;
|
|
82
|
-
manurePit:
|
|
83
|
-
cover: number;
|
|
84
|
-
manureFromAnimalStockStored: {
|
|
85
|
-
manureDerivation: string;
|
|
86
|
-
proportionStored: number;
|
|
87
|
-
}[];
|
|
88
|
-
}[];
|
|
79
|
+
manurePit: never[];
|
|
89
80
|
slurryTank: {
|
|
81
|
+
descriptor: string;
|
|
90
82
|
volumeInM3: number;
|
|
91
83
|
depthInM: number;
|
|
92
84
|
cover: number;
|
|
@@ -95,16 +87,7 @@ export declare class NaebiDataService {
|
|
|
95
87
|
}[];
|
|
96
88
|
};
|
|
97
89
|
farmManureTrading: {
|
|
98
|
-
supply:
|
|
99
|
-
quantity: number;
|
|
100
|
-
typeOfManureRecyclingProduct: string;
|
|
101
|
-
transactionUnit: string;
|
|
102
|
-
ingredient: {
|
|
103
|
-
quantity: number;
|
|
104
|
-
molecularFormula: string;
|
|
105
|
-
unit: string;
|
|
106
|
-
}[];
|
|
107
|
-
}[];
|
|
90
|
+
supply: never[];
|
|
108
91
|
dispense: {
|
|
109
92
|
quantity: number;
|
|
110
93
|
typeOfManureRecyclingProduct: string;
|
|
@@ -113,6 +96,11 @@ export declare class NaebiDataService {
|
|
|
113
96
|
zoologicalAnimal: string;
|
|
114
97
|
percentageAllocation: number;
|
|
115
98
|
}[];
|
|
99
|
+
ingredient: {
|
|
100
|
+
quantity: number;
|
|
101
|
+
molecularFormula: string;
|
|
102
|
+
unit: string;
|
|
103
|
+
}[];
|
|
116
104
|
}[];
|
|
117
105
|
};
|
|
118
106
|
fieldSpreading: {
|
|
@@ -125,14 +113,18 @@ export declare class NaebiDataService {
|
|
|
125
113
|
proportionOfArea: number;
|
|
126
114
|
}[];
|
|
127
115
|
applicationDuringWarmDays: number;
|
|
116
|
+
proportionAppliedSummerMonths: number;
|
|
117
|
+
proportionAppliedOtherMonths: number;
|
|
128
118
|
proportionAppliedAfter6PM: number;
|
|
129
119
|
dragHoseAreaSize: number;
|
|
130
120
|
};
|
|
131
121
|
manure: {
|
|
132
122
|
applicationIncorporationTime: number;
|
|
133
123
|
proportionAppliedSummerMonths: number;
|
|
124
|
+
proportionAppliedOtherMonths: number;
|
|
134
125
|
};
|
|
135
126
|
fertiliser: {
|
|
127
|
+
descriptor: string;
|
|
136
128
|
fertiliserProductCategory: string;
|
|
137
129
|
quantity: number;
|
|
138
130
|
transactionUnit: string;
|
|
@@ -154,8 +146,6 @@ export declare class NaebiDataService {
|
|
|
154
146
|
}[];
|
|
155
147
|
};
|
|
156
148
|
lifetimePerformance: {
|
|
157
|
-
dailyGain: number;
|
|
158
|
-
liveWeight: number;
|
|
159
149
|
milkProductionReport: number;
|
|
160
150
|
};
|
|
161
151
|
fodder: {
|
|
@@ -170,6 +160,12 @@ export declare class NaebiDataService {
|
|
|
170
160
|
unit: string;
|
|
171
161
|
}[];
|
|
172
162
|
}[];
|
|
163
|
+
dispense: {
|
|
164
|
+
typeOfFeedstuffProduct: string;
|
|
165
|
+
quantity: number;
|
|
166
|
+
transactionUnit: string;
|
|
167
|
+
ingredient: never[];
|
|
168
|
+
}[];
|
|
173
169
|
};
|
|
174
170
|
cropFromNonFodderCropland: {
|
|
175
171
|
typeOfFeedstuffProduct: string;
|
|
@@ -185,6 +181,17 @@ export declare class NaebiDataService {
|
|
|
185
181
|
totalBalanceErrorMargin: number;
|
|
186
182
|
};
|
|
187
183
|
fieldCultivation: {
|
|
184
|
+
buildingZoneAreaSize: number;
|
|
185
|
+
outdoorVegetableMainCropAreaSize: number;
|
|
186
|
+
indoorVegetableMainCropAreaSize: number;
|
|
187
|
+
feedingOfCropHarvest: {
|
|
188
|
+
agronomicCropCategory: string;
|
|
189
|
+
effectiveYield: number;
|
|
190
|
+
}[];
|
|
191
|
+
dispenseOfCropHarvest: {
|
|
192
|
+
agronomicCropCategory: string;
|
|
193
|
+
effectiveYield: number;
|
|
194
|
+
}[];
|
|
188
195
|
fodderCropland: ({
|
|
189
196
|
agronomicCropCategory: string;
|
|
190
197
|
isMainCrop: boolean;
|
|
@@ -203,25 +210,38 @@ export declare class NaebiDataService {
|
|
|
203
210
|
isMainCrop: boolean;
|
|
204
211
|
areaSize: number;
|
|
205
212
|
yieldPerSquareMeasure: number;
|
|
213
|
+
hasLongTermYieldDivergence: boolean;
|
|
206
214
|
}[];
|
|
207
215
|
special: {
|
|
208
216
|
agronomicCropCategory: string;
|
|
209
217
|
userSpecificPlantName: string;
|
|
210
218
|
isMainCrop: boolean;
|
|
211
219
|
areaSize: number;
|
|
212
|
-
|
|
220
|
+
requirementCorrection: {
|
|
221
|
+
quantity: number;
|
|
222
|
+
molecularFormula: string;
|
|
223
|
+
unit: string;
|
|
224
|
+
}[];
|
|
213
225
|
}[];
|
|
214
226
|
};
|
|
215
227
|
generateReport: boolean;
|
|
216
228
|
};
|
|
229
|
+
calculationVersion: {
|
|
230
|
+
version: string;
|
|
231
|
+
};
|
|
217
232
|
}>;
|
|
233
|
+
private readonly _lastEmitted;
|
|
234
|
+
private readonly _dirty;
|
|
235
|
+
readonly dirty: import("@angular/core").Signal<boolean>;
|
|
218
236
|
private readonly _calculationMode;
|
|
219
237
|
readonly calculationMode: import("@angular/core").Signal<CalculationMode>;
|
|
220
238
|
/**
|
|
221
239
|
* Set new data value; accepts plain object (already parsed) matching NaebiData shape.
|
|
222
|
-
* Silent no-op if value is structurally equal
|
|
240
|
+
* Silent no-op if value is structurally equal after normalization to avoid unnecessary updates.
|
|
223
241
|
*/
|
|
224
242
|
setData(value: NaebiData): void;
|
|
243
|
+
/** Mark current data as saved (clears dirty state and updates snapshot). */
|
|
244
|
+
markSaved(): void;
|
|
225
245
|
/**
|
|
226
246
|
* Set calculation mode (SuiBi or ExBi).
|
|
227
247
|
* Can affect which validation rules are active or which features are enabled.
|
|
@@ -230,3 +250,4 @@ export declare class NaebiDataService {
|
|
|
230
250
|
/** Reset to bundled example */
|
|
231
251
|
reset(): void;
|
|
232
252
|
}
|
|
253
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SuibiDataEventDetail, SuibiDataEventMetadata } from './suibi-data-event';
|
|
2
|
+
/**
|
|
3
|
+
* Centralizes construction + dispatch of the `suibi-data-emitted` payload so multiple UI entry points can reuse it.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SuibiDataEmitterService {
|
|
6
|
+
private readonly i18n;
|
|
7
|
+
private readonly validation;
|
|
8
|
+
private readonly metadataSvc;
|
|
9
|
+
private readonly naebi;
|
|
10
|
+
buildMetadata(): SuibiDataEventMetadata;
|
|
11
|
+
buildDetail(): SuibiDataEventDetail;
|
|
12
|
+
emitFrom(target: HTMLElement): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Locale } from '../i18n/i18n.service';
|
|
2
|
+
import { NaebiData } from '../data/naebi-data.service';
|
|
3
|
+
import { SuibiMetadata } from '../metadata/suibi-metadata.types';
|
|
4
|
+
/**
|
|
5
|
+
* Increment when the payload contract changes in a backwards-incompatible way.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUIBI_DATA_EVENT_VERSION = "suibi-data.v1";
|
|
8
|
+
/** Detail object emitted with the `suibi-data` CustomEvent. */
|
|
9
|
+
export interface SuibiDataEventDetail {
|
|
10
|
+
version: typeof SUIBI_DATA_EVENT_VERSION;
|
|
11
|
+
payload: SuibiDataEventPayload;
|
|
12
|
+
}
|
|
13
|
+
/** Top-level payload structure delivered to host applications. */
|
|
14
|
+
export interface SuibiDataEventPayload {
|
|
15
|
+
metadata: SuibiDataEventMetadata;
|
|
16
|
+
data: NaebiData;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Metadata describing the dataset at the moment of emission so hosts can audit and reason about it.
|
|
20
|
+
*/
|
|
21
|
+
export type SuibiDataEventMetadata = SuibiMetadata & {
|
|
22
|
+
emittedAt: string;
|
|
23
|
+
locale: Locale;
|
|
24
|
+
isValid: boolean;
|
|
25
|
+
errorCount: number;
|
|
26
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PipeTransform, Signal } from '@angular/core';
|
|
2
|
-
export type Locale = 'en' | 'de';
|
|
2
|
+
export type Locale = 'en' | 'de' | 'fr' | 'it';
|
|
3
3
|
export type JsonFormsTranslator = (key: string, defaultMessage: string | undefined, context: unknown) => string;
|
|
4
4
|
export declare class I18nService {
|
|
5
5
|
private readonly _locale;
|
|
@@ -8,13 +8,15 @@ export declare class I18nService {
|
|
|
8
8
|
readonly jsonFormsI18n: Signal<{
|
|
9
9
|
locale: Locale;
|
|
10
10
|
translate: JsonFormsTranslator;
|
|
11
|
+
translateError: (error: unknown, translate: JsonFormsTranslator) => string;
|
|
11
12
|
}>;
|
|
12
13
|
setLocale(locale: Locale): void;
|
|
14
|
+
/** Returns true if the given string is a supported locale key. */
|
|
15
|
+
isValidLocale(value: string): value is Locale;
|
|
13
16
|
t(key: string, defaultMessage?: string): string;
|
|
14
17
|
}
|
|
15
18
|
export declare class TranslatePipe implements PipeTransform {
|
|
16
|
-
private readonly i18n;
|
|
17
19
|
private readonly cache;
|
|
18
|
-
|
|
20
|
+
private readonly i18n;
|
|
19
21
|
transform(key: string, defaultMessage?: string): Signal<string>;
|
|
20
22
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { Locale } from '../i18n/i18n.service';
|
|
2
|
-
|
|
2
|
+
/** The property name of the primary key in a master-data catalog entry. */
|
|
3
|
+
type MasterDataKeyField = string;
|
|
4
|
+
interface MasterDataCatalog {
|
|
5
|
+
entries: any[];
|
|
6
|
+
/** Property name to use as the lookup key; 'id' entries are coerced to Number. */
|
|
7
|
+
key: MasterDataKeyField;
|
|
8
|
+
}
|
|
9
|
+
declare const MASTER_DATA: Record<string, MasterDataCatalog>;
|
|
3
10
|
export type MasterDataKind = keyof typeof MASTER_DATA;
|
|
4
11
|
export declare class MasterDataService {
|
|
5
12
|
private readonly i18n;
|
|
@@ -14,5 +21,12 @@ export declare class MasterDataService {
|
|
|
14
21
|
designation(kind: MasterDataKind, id: number | string | null | undefined, locale?: Locale): string;
|
|
15
22
|
resolveAnimalCategory(id: number | string | null | undefined, locale?: Locale): string;
|
|
16
23
|
resolveUtilisation(id: number | string | null | undefined, locale?: Locale): string;
|
|
24
|
+
resolveManureProduct(code: string | null | undefined, locale?: Locale): string;
|
|
25
|
+
resolveZoologicalAnimal(code: string | null | undefined, locale?: Locale): string;
|
|
26
|
+
resolveCultivationCategory(code: string | null | undefined, locale?: Locale): string;
|
|
27
|
+
resolveAgronomicCropCategory(code: string | null | undefined, locale?: Locale): string;
|
|
28
|
+
resolveFeedstuffProduct(code: string | null | undefined, locale?: Locale): string;
|
|
29
|
+
resolveCover(id: number | string | null | undefined, locale?: Locale): string;
|
|
30
|
+
resolveMixingFrequency(id: number | string | null | undefined, locale?: Locale): string;
|
|
17
31
|
}
|
|
18
32
|
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type SuibiVersion = 'v2.0';
|
|
2
|
+
export type SubmissionStatus = 'draft' | 'submitted' | 'final';
|
|
3
|
+
/** Which computation modules are active for this dossier. */
|
|
4
|
+
export interface ComputationModules {
|
|
5
|
+
suisseBilanz: boolean;
|
|
6
|
+
gmf: boolean;
|
|
7
|
+
nh3: boolean;
|
|
8
|
+
impex: boolean;
|
|
9
|
+
linear: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_COMPUTATION_MODULES: ComputationModules;
|
|
12
|
+
export interface SuibiMetadata {
|
|
13
|
+
title: string;
|
|
14
|
+
suibiVersion: SuibiVersion;
|
|
15
|
+
status: SubmissionStatus;
|
|
16
|
+
modules: ComputationModules;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_SUIBI_METADATA: SuibiMetadata;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
export type PageId = 'welcome' | 'animal_stock' | 'data_preview' | 'storage' | 'field_spreading' | 'farm_manure_trading';
|
|
1
|
+
export type PageId = 'welcome' | 'animal_stock' | 'data_preview' | 'storage' | 'field_spreading' | 'farm_manure_trading' | 'fodder' | 'field_cultivation' | 'validation' | 'results';
|
|
2
2
|
export type AnimalStockCategory = 'base' | 'formOfDetention' | 'feeding';
|
|
3
|
+
export type FarmManureTradingMode = 'supply' | 'dispense';
|
|
4
|
+
export type FarmManureTradingCategory = 'general' | 'derivation' | 'ingredients';
|
|
5
|
+
export type FodderMode = 'supply' | 'dispense' | 'non_fodder_cropland';
|
|
6
|
+
export type FodderCategory = 'general' | 'ingredients';
|
|
7
|
+
export type FieldSpreadingCategory = 'general' | 'fertiliser' | 'recycling';
|
|
8
|
+
export type FieldCultivationTab = 'general' | 'fodderCropland' | 'arableLand' | 'special';
|
|
9
|
+
export type StorageTab = 'manure' | 'slurry';
|
|
10
|
+
export type StorageEntryType = 'manure_pit' | 'slurry_tank';
|
|
3
11
|
/**
|
|
4
12
|
* NavigationService
|
|
5
13
|
* Global reactive store for application routing and deep-link state.
|
|
@@ -21,8 +29,40 @@ export declare class NavigationService {
|
|
|
21
29
|
readonly currentPage: import("@angular/core").WritableSignal<PageId>;
|
|
22
30
|
/** Selected animal stock entry index (null = list view) */
|
|
23
31
|
readonly selectedAnimalStockIndex: import("@angular/core").WritableSignal<number | null>;
|
|
24
|
-
/**
|
|
25
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Generic category (tab) selection: stores current page + selected category key.
|
|
34
|
+
* Used by categorization renderer for programmatic tab control.
|
|
35
|
+
* Format: { page: PageId, category: string }
|
|
36
|
+
*/
|
|
37
|
+
readonly selectedCategory: import("@angular/core").WritableSignal<{
|
|
38
|
+
page: PageId;
|
|
39
|
+
category: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Selected farm manure trading detail context (mode + index) */
|
|
42
|
+
readonly selectedFarmManureTrading: import("@angular/core").WritableSignal<{
|
|
43
|
+
mode: FarmManureTradingMode;
|
|
44
|
+
index: number;
|
|
45
|
+
} | null>;
|
|
46
|
+
/** Selected fodder detail context (mode + index) */
|
|
47
|
+
readonly selectedFodderDetail: import("@angular/core").WritableSignal<{
|
|
48
|
+
mode: FodderMode;
|
|
49
|
+
index: number;
|
|
50
|
+
} | null>;
|
|
51
|
+
/** Selected field cultivation detail context (tab + index) */
|
|
52
|
+
readonly selectedFieldCultivationDetail: import("@angular/core").WritableSignal<{
|
|
53
|
+
tab: Exclude<FieldCultivationTab, "general">;
|
|
54
|
+
index: number;
|
|
55
|
+
} | null>;
|
|
56
|
+
/** Selected storage detail context (type + index) */
|
|
57
|
+
readonly selectedStorageDetail: import("@angular/core").WritableSignal<{
|
|
58
|
+
type: StorageEntryType;
|
|
59
|
+
index: number;
|
|
60
|
+
} | null>;
|
|
61
|
+
/** Selected field spreading row context (category/tab + row index) — used by validation deep-links */
|
|
62
|
+
readonly selectedFieldSpreadingDetail: import("@angular/core").WritableSignal<{
|
|
63
|
+
category: FieldSpreadingCategory;
|
|
64
|
+
index: number;
|
|
65
|
+
} | null>;
|
|
26
66
|
/** True if currently viewing animal stock detail (not list) */
|
|
27
67
|
readonly isAnimalStockDetailView: import("@angular/core").Signal<boolean>;
|
|
28
68
|
/** True if currently on animal stock page (list or detail) */
|
|
@@ -41,10 +81,24 @@ export declare class NavigationService {
|
|
|
41
81
|
* Used by validation error navigation and internal routing.
|
|
42
82
|
*/
|
|
43
83
|
navigateToAnimalStockDetail(index: number, category?: AnimalStockCategory): void;
|
|
84
|
+
navigateToFarmManureTradingDetail(mode: FarmManureTradingMode, index: number, category?: FarmManureTradingCategory): void;
|
|
85
|
+
navigateToFarmManureTradingList(): void;
|
|
86
|
+
navigateToFodderDetail(mode: FodderMode, index: number, category?: FodderCategory): void;
|
|
87
|
+
navigateToFodderList(): void;
|
|
88
|
+
navigateToFieldSpreading(category?: FieldSpreadingCategory): void;
|
|
89
|
+
/** Deep-link to a specific row of a field spreading tab (e.g. from a validation error). */
|
|
90
|
+
navigateToFieldSpreadingDetail(category: FieldSpreadingCategory, index: number): void;
|
|
91
|
+
navigateToFieldCultivationDetail(tab: Exclude<FieldCultivationTab, 'general'>, index: number): void;
|
|
92
|
+
navigateToFieldCultivationList(tab?: FieldCultivationTab): void;
|
|
93
|
+
navigateToStorageDetail(type: StorageEntryType, index: number): void;
|
|
94
|
+
navigateToStorageList(tab?: StorageTab): void;
|
|
44
95
|
/**
|
|
45
|
-
* Set active category/tab
|
|
96
|
+
* Set active category/tab for current page (without changing page/entry).
|
|
97
|
+
* Generic method supporting any page's categorization navigation.
|
|
98
|
+
* No-op when page and category are already the same values to prevent
|
|
99
|
+
* unnecessary signal emissions that re-trigger the tab index computed.
|
|
46
100
|
*/
|
|
47
|
-
|
|
101
|
+
setCategory(page: PageId, category: string): void;
|
|
48
102
|
/**
|
|
49
103
|
* Reset page-specific context when navigating away.
|
|
50
104
|
* Prevents stale state (e.g., old selected index) from affecting new page.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NaebiData } from '../data/naebi-data.service';
|
|
2
|
+
import type { PlanningBalanceResponse } from './planning-balance.types';
|
|
3
|
+
export type { PlanningBalanceResponse } from './planning-balance.types';
|
|
4
|
+
/** Which backend to target for planning requests. */
|
|
5
|
+
export type PlanningEndpoint = 'ebilanz' | 'blw';
|
|
6
|
+
/**
|
|
7
|
+
* Sends NAEBI data to a planning endpoint and exposes the result as a
|
|
8
|
+
* signal-based resource. Call `runPlanning(data, endpoint)` to trigger a request.
|
|
9
|
+
*
|
|
10
|
+
* The ID counter ensures each call re-fetches even if the payload hasn't changed.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PlanningBalanceService {
|
|
13
|
+
private readonly http;
|
|
14
|
+
private readonly metadataSvc;
|
|
15
|
+
private readonly _value;
|
|
16
|
+
private readonly _error;
|
|
17
|
+
private readonly _isLoading;
|
|
18
|
+
private readonly _selectedEndpoint;
|
|
19
|
+
private readonly _lastStartedRequestId;
|
|
20
|
+
private readonly _lastCompletedRequestId;
|
|
21
|
+
private readonly _lastSuccessfulRequestId;
|
|
22
|
+
private _nextId;
|
|
23
|
+
private activeRequestId;
|
|
24
|
+
private activeRequestSub;
|
|
25
|
+
readonly planningResource: {
|
|
26
|
+
value: import("@angular/core").Signal<PlanningBalanceResponse | undefined>;
|
|
27
|
+
error: import("@angular/core").Signal<unknown>;
|
|
28
|
+
isLoading: import("@angular/core").Signal<boolean>;
|
|
29
|
+
hasValue: import("@angular/core").Signal<boolean>;
|
|
30
|
+
lastStartedRequestId: import("@angular/core").Signal<number>;
|
|
31
|
+
lastCompletedRequestId: import("@angular/core").Signal<number>;
|
|
32
|
+
lastSuccessfulRequestId: import("@angular/core").Signal<number>;
|
|
33
|
+
};
|
|
34
|
+
readonly selectedEndpoint: import("@angular/core").Signal<PlanningEndpoint>;
|
|
35
|
+
setSelectedEndpoint(endpoint: PlanningEndpoint): void;
|
|
36
|
+
/**
|
|
37
|
+
* Builds the exact payload posted to the planning API: calculationVersion stamped from
|
|
38
|
+
* the current metadata, `nutrientCycle.generateReport` forced to true (the PDF report
|
|
39
|
+
* must always be requested on submission), empty ingredient/routine slots stripped,
|
|
40
|
+
* null optional fields and host-only fields removed, custom display units converted
|
|
41
|
+
* to base units.
|
|
42
|
+
*/
|
|
43
|
+
buildApiPayload(data: NaebiData): NaebiData;
|
|
44
|
+
/** Fire a new planning-balance request with the current NAEBI data payload. */
|
|
45
|
+
runPlanning(data: NaebiData, endpoint?: PlanningEndpoint): void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for the planning-balance API response.
|
|
3
|
+
* These match the eBilanz / BLW response shape observed in the example data.
|
|
4
|
+
*/
|
|
5
|
+
/** A single nutrient quantity entry (kg or % unit). */
|
|
6
|
+
export interface NutrientEntry {
|
|
7
|
+
molecularFormula: string;
|
|
8
|
+
quantity: number;
|
|
9
|
+
quantityCorrected?: number;
|
|
10
|
+
unit: string;
|
|
11
|
+
productFamilyType?: string;
|
|
12
|
+
typeOfManureRecyclingProduct?: string;
|
|
13
|
+
fertiliserProductCategory?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CalculationVersion {
|
|
16
|
+
version: string;
|
|
17
|
+
validFrom: string;
|
|
18
|
+
validTo: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AreaAndYieldPerAgronomicCropCategory {
|
|
21
|
+
agronomicCropCategory: string;
|
|
22
|
+
areaSize: number;
|
|
23
|
+
effectiveYield: number;
|
|
24
|
+
isMainCrop: boolean;
|
|
25
|
+
isNutrientPoorFodder: boolean;
|
|
26
|
+
yieldPerSquareMeasure?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface AreaPerCultivationType {
|
|
29
|
+
areaSize: number;
|
|
30
|
+
isMainCrop: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface AreaAndYieldPerCultivationCategory {
|
|
33
|
+
cultivationCategory: string;
|
|
34
|
+
areaAndYieldPerAgronomicCropCategory: AreaAndYieldPerAgronomicCropCategory[];
|
|
35
|
+
areaPerCultivationType: AreaPerCultivationType[];
|
|
36
|
+
}
|
|
37
|
+
export interface AreaPerSubCategory {
|
|
38
|
+
cultivationSubCategory: string;
|
|
39
|
+
areaSize: number;
|
|
40
|
+
isMainCrop: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface FieldCultivation {
|
|
43
|
+
areaAndYieldPerCultivationCategory: AreaAndYieldPerCultivationCategory[];
|
|
44
|
+
areaPerSubCategory: AreaPerSubCategory[];
|
|
45
|
+
fertilizableAreaSize: number;
|
|
46
|
+
slurrySpreadingAreaSize: number;
|
|
47
|
+
totalAgriculturalLandAreaSize: number;
|
|
48
|
+
}
|
|
49
|
+
export interface FodderQuantity {
|
|
50
|
+
quantity: number;
|
|
51
|
+
unit: string;
|
|
52
|
+
proportionNutrientPoorFodder?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface FodderProduct {
|
|
55
|
+
typeOfFeedstuffProduct: string;
|
|
56
|
+
quantity: number;
|
|
57
|
+
unit: string;
|
|
58
|
+
isNutrientPoorFodder: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface ConsumptionAnimalStock {
|
|
61
|
+
animalCategoryPRIF: number;
|
|
62
|
+
averageQuantity: number;
|
|
63
|
+
order: string;
|
|
64
|
+
quantity: number;
|
|
65
|
+
unit: string;
|
|
66
|
+
}
|
|
67
|
+
export interface RequiredEffectiveYieldFromFodderCropland {
|
|
68
|
+
consumptionAnimalStock: ConsumptionAnimalStock[];
|
|
69
|
+
cropFromNonFodderCroplandPerProduct: FodderProduct[];
|
|
70
|
+
dispensePerProduct: FodderProduct[];
|
|
71
|
+
supplyPerProduct: FodderProduct[];
|
|
72
|
+
totalBalance: FodderQuantity;
|
|
73
|
+
totalConsumptionAnimalStock: FodderQuantity;
|
|
74
|
+
totalCropFromNonFodderCropland: FodderQuantity;
|
|
75
|
+
totalDispense: FodderQuantity;
|
|
76
|
+
totalSupply: FodderQuantity;
|
|
77
|
+
}
|
|
78
|
+
export interface FodderBalance {
|
|
79
|
+
requiredEffectiveYieldFromFodderCropland: RequiredEffectiveYieldFromFodderCropland;
|
|
80
|
+
totalBalance: FodderQuantity;
|
|
81
|
+
totalEffectiveYieldFromFodderCropland: FodderQuantity;
|
|
82
|
+
totalNutrientPoorFodder: FodderQuantity;
|
|
83
|
+
}
|
|
84
|
+
export interface EmissionAndAccumulationEntry {
|
|
85
|
+
animalCategoryPRIF: number;
|
|
86
|
+
order: string;
|
|
87
|
+
accumulation: NutrientEntry[];
|
|
88
|
+
emission: NutrientEntry[];
|
|
89
|
+
manureExcretion?: unknown[];
|
|
90
|
+
}
|
|
91
|
+
export interface AccumulationEntireExcretion {
|
|
92
|
+
animalCategoryPRIF: number;
|
|
93
|
+
order: string;
|
|
94
|
+
durationSumTotalCorrectedNutrientBalance: number;
|
|
95
|
+
accumulation: NutrientEntry[];
|
|
96
|
+
}
|
|
97
|
+
export interface TotalNutrientSet {
|
|
98
|
+
accumulation: NutrientEntry[];
|
|
99
|
+
emission?: NutrientEntry[];
|
|
100
|
+
}
|
|
101
|
+
export interface AnimalStock {
|
|
102
|
+
accumulationEntireExcretion: AccumulationEntireExcretion[];
|
|
103
|
+
emissionAndAccumulationPasture: EmissionAndAccumulationEntry[];
|
|
104
|
+
emissionAndAccumulationStall: EmissionAndAccumulationEntry[];
|
|
105
|
+
emissionAndAccumulationYard: EmissionAndAccumulationEntry[];
|
|
106
|
+
totalAccumulationEntireExcretion: TotalNutrientSet;
|
|
107
|
+
totalEmissionAndAccumulationAnimalStock: TotalNutrientSet;
|
|
108
|
+
totalEmissionAndAccumulationPasture: TotalNutrientSet;
|
|
109
|
+
totalEmissionAndAccumulationStall: TotalNutrientSet;
|
|
110
|
+
totalEmissionAndAccumulationYard: TotalNutrientSet;
|
|
111
|
+
}
|
|
112
|
+
export interface ManureTradingProduct {
|
|
113
|
+
typeOfManureRecyclingProduct: string;
|
|
114
|
+
quantity: number;
|
|
115
|
+
unit: string;
|
|
116
|
+
ingredient: NutrientEntry[];
|
|
117
|
+
}
|
|
118
|
+
export interface FarmManureTrading {
|
|
119
|
+
balancePerProduct: ManureTradingProduct[];
|
|
120
|
+
dispensePerProduct: ManureTradingProduct[];
|
|
121
|
+
supplyPerProduct: ManureTradingProduct[];
|
|
122
|
+
totalBalance: {
|
|
123
|
+
ingredient: NutrientEntry[];
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export interface NutrientRequirementEntry {
|
|
127
|
+
agronomicCropCategory?: string;
|
|
128
|
+
cultivationCategory?: string;
|
|
129
|
+
isMainCrop?: boolean;
|
|
130
|
+
requirement: NutrientEntry[];
|
|
131
|
+
}
|
|
132
|
+
export interface FieldCultivationNutrients {
|
|
133
|
+
nutrientTransferUnfertilizedCultivation: NutrientEntry[];
|
|
134
|
+
requirementPerAgronomicCropCategory: NutrientRequirementEntry[];
|
|
135
|
+
requirementPerCultivationCategory: NutrientRequirementEntry[];
|
|
136
|
+
totalRequirement: NutrientEntry[];
|
|
137
|
+
}
|
|
138
|
+
export interface FieldSpreading {
|
|
139
|
+
emissionAndAccumulationFieldSpreading: TotalNutrientSet;
|
|
140
|
+
totalEmissionAndAccumulationFieldSpreading: TotalNutrientSet;
|
|
141
|
+
}
|
|
142
|
+
export interface StorageBalance {
|
|
143
|
+
emissionAndAccumulationManureStorage: TotalNutrientSet;
|
|
144
|
+
totalEmissionAndAccumulationManureStorage: TotalNutrientSet;
|
|
145
|
+
}
|
|
146
|
+
export interface NutrientBalance {
|
|
147
|
+
animalStock: AnimalStock;
|
|
148
|
+
farmManureTrading: FarmManureTrading;
|
|
149
|
+
fieldCultivation: FieldCultivationNutrients;
|
|
150
|
+
fieldSpreading: FieldSpreading;
|
|
151
|
+
storage: StorageBalance;
|
|
152
|
+
/** Final per-nutrient balance figures: kg lines + % lines interleaved. */
|
|
153
|
+
totalBalance: NutrientEntry[];
|
|
154
|
+
/** Farm-wide gas emissions (NH3, NO, N2O, N2). */
|
|
155
|
+
totalEmissionFarm: NutrientEntry[];
|
|
156
|
+
nutrientBalanceTMP?: unknown[];
|
|
157
|
+
}
|
|
158
|
+
export interface NutrientCycle {
|
|
159
|
+
creationDateTime: string;
|
|
160
|
+
facilitySpecificProducts: {
|
|
161
|
+
manureRecyclingProduct: unknown[];
|
|
162
|
+
};
|
|
163
|
+
fieldCultivation: FieldCultivation;
|
|
164
|
+
fodderBalance: FodderBalance;
|
|
165
|
+
nutrientBalance: NutrientBalance;
|
|
166
|
+
version: string;
|
|
167
|
+
/** Base64-encoded PDF report, if returned by the endpoint. */
|
|
168
|
+
report?: string;
|
|
169
|
+
}
|
|
170
|
+
export interface ValidationMessageDetail {
|
|
171
|
+
designation_deu: string;
|
|
172
|
+
designation_eng: string;
|
|
173
|
+
designation_fra: string;
|
|
174
|
+
designation_ita: string;
|
|
175
|
+
}
|
|
176
|
+
export interface ValidationMessage {
|
|
177
|
+
field: string;
|
|
178
|
+
type: string;
|
|
179
|
+
detail: ValidationMessageDetail;
|
|
180
|
+
}
|
|
181
|
+
/** Full response from the planning-balance endpoint. */
|
|
182
|
+
export interface PlanningBalanceResponse {
|
|
183
|
+
calculationVersion: CalculationVersion;
|
|
184
|
+
nutrientCycle: NutrientCycle;
|
|
185
|
+
validationMessage: ValidationMessage[];
|
|
186
|
+
}
|
|
187
|
+
/** Merged kg + % row for the final balance table (Section D). */
|
|
188
|
+
export interface BalanceRow {
|
|
189
|
+
molecularFormula: string;
|
|
190
|
+
quantity: number;
|
|
191
|
+
quantityCorrected: number;
|
|
192
|
+
quantityPct: number | null;
|
|
193
|
+
quantityCorrectedPct: number | null;
|
|
194
|
+
unit: 'kg';
|
|
195
|
+
}
|
|
196
|
+
/** Crop requirement row enriched with area and yield for display (Section C). */
|
|
197
|
+
export interface CropRequirementRow {
|
|
198
|
+
cropCode: string;
|
|
199
|
+
cultivationCategory: string;
|
|
200
|
+
isMainCrop: boolean;
|
|
201
|
+
areaHa: number;
|
|
202
|
+
effectiveYield: number;
|
|
203
|
+
/** kg/ha yield per square measure field (m² basis), converted to dt/ha for display. */
|
|
204
|
+
yieldDtHa: number | null;
|
|
205
|
+
requirement: NutrientEntry[];
|
|
206
|
+
}
|