|
@@ -14,6 +14,25 @@ interface ResourceSummary {
|
|
|
uom: string;
|
|
uom: string;
|
|
|
}[];
|
|
}[];
|
|
|
}
|
|
}
|
|
|
|
|
+interface OutputSummary {
|
|
|
|
|
+ type: string; // e.g., "FFB harvested"
|
|
|
|
|
+ outputs: {
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ totalQuantity: number;
|
|
|
|
|
+ uom: string;
|
|
|
|
|
+ totalWeight?: number; // optional, sum of weight in kg
|
|
|
|
|
+ }[];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface TargetSummary {
|
|
|
|
|
+ type: string; // e.g., "location"
|
|
|
|
|
+ targets: {
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ totalQuantity: number;
|
|
|
|
|
+ uom: string;
|
|
|
|
|
+ }[];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@Component({
|
|
@Component({
|
|
|
selector: 'app-calculate-dialog',
|
|
selector: 'app-calculate-dialog',
|
|
@@ -29,7 +48,8 @@ interface ResourceSummary {
|
|
|
})
|
|
})
|
|
|
export class CalculateDialogComponent implements OnInit {
|
|
export class CalculateDialogComponent implements OnInit {
|
|
|
filteredActivities: Activity[] = [];
|
|
filteredActivities: Activity[] = [];
|
|
|
-
|
|
|
|
|
|
|
+ outputSummary: OutputSummary[] = [];
|
|
|
|
|
+ targetSummary: TargetSummary[] = [];
|
|
|
resourceSummary: ResourceSummary[] = [];
|
|
resourceSummary: ResourceSummary[] = [];
|
|
|
totalOutputs: Record<string, number> = {};
|
|
totalOutputs: Record<string, number> = {};
|
|
|
totalOutputUoms: Record<string, string> = {};
|
|
totalOutputUoms: Record<string, string> = {};
|
|
@@ -57,6 +77,8 @@ export class CalculateDialogComponent implements OnInit {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
calculateTotals(): void {
|
|
calculateTotals(): void {
|
|
|
|
|
+ const outputTypeMap: Record<string, Record<string, { totalQuantity: number; uom: string; totalWeight: number }>> = {};
|
|
|
|
|
+ const targetTypeMap: Record<string, Record<string, { totalQuantity: number; uom: string }>> = {};
|
|
|
const resourceTypeMap: Record<string, Record<string, { totalQuantity: number; uom: string }>> = {};
|
|
const resourceTypeMap: Record<string, Record<string, { totalQuantity: number; uom: string }>> = {};
|
|
|
const outputTotals: Record<string, number> = {};
|
|
const outputTotals: Record<string, number> = {};
|
|
|
const outputUoms: Record<string, string> = {};
|
|
const outputUoms: Record<string, string> = {};
|
|
@@ -76,6 +98,29 @@ export class CalculateDialogComponent implements OnInit {
|
|
|
allStartDates.push(start);
|
|
allStartDates.push(start);
|
|
|
allEndDates.push(end);
|
|
allEndDates.push(end);
|
|
|
|
|
|
|
|
|
|
+ // --- Outputs ---
|
|
|
|
|
+ for (const output of activity.outputs) {
|
|
|
|
|
+ if (!outputTypeMap[output.type]) outputTypeMap[output.type] = {};
|
|
|
|
|
+ if (!outputTypeMap[output.type][output.name]) {
|
|
|
|
|
+ outputTypeMap[output.type][output.name] = {
|
|
|
|
|
+ totalQuantity: 0,
|
|
|
|
|
+ uom: output.value.uom,
|
|
|
|
|
+ totalWeight: 0
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ outputTypeMap[output.type][output.name].totalQuantity += output.value.quantity;
|
|
|
|
|
+ outputTypeMap[output.type][output.name].totalWeight += output.weightValue?.weight || 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // --- Targets ---
|
|
|
|
|
+ for (const target of activity.targets) {
|
|
|
|
|
+ if (!targetTypeMap[target.type]) targetTypeMap[target.type] = {};
|
|
|
|
|
+ if (!targetTypeMap[target.type][target.name]) {
|
|
|
|
|
+ targetTypeMap[target.type][target.name] = { totalQuantity: 0, uom: target.value.uom };
|
|
|
|
|
+ }
|
|
|
|
|
+ targetTypeMap[target.type][target.name].totalQuantity += target.value.quantity;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Group resources by type and sum quantity
|
|
// Group resources by type and sum quantity
|
|
|
for (const res of activity.resources) {
|
|
for (const res of activity.resources) {
|
|
|
if (!resourceTypeMap[res.type]) resourceTypeMap[res.type] = {};
|
|
if (!resourceTypeMap[res.type]) resourceTypeMap[res.type] = {};
|
|
@@ -133,6 +178,25 @@ export class CalculateDialogComponent implements OnInit {
|
|
|
uom: resourceTypeMap[type][name].uom
|
|
uom: resourceTypeMap[type][name].uom
|
|
|
}))
|
|
}))
|
|
|
}));
|
|
}));
|
|
|
|
|
+ // Transform into arrays for template
|
|
|
|
|
+ this.outputSummary = Object.keys(outputTypeMap).map(type => ({
|
|
|
|
|
+ type,
|
|
|
|
|
+ outputs: Object.keys(outputTypeMap[type]).map(name => ({
|
|
|
|
|
+ name,
|
|
|
|
|
+ totalQuantity: outputTypeMap[type][name].totalQuantity,
|
|
|
|
|
+ uom: outputTypeMap[type][name].uom,
|
|
|
|
|
+ totalWeight: outputTypeMap[type][name].totalWeight
|
|
|
|
|
+ }))
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ this.targetSummary = Object.keys(targetTypeMap).map(type => ({
|
|
|
|
|
+ type,
|
|
|
|
|
+ targets: Object.keys(targetTypeMap[type]).map(name => ({
|
|
|
|
|
+ name,
|
|
|
|
|
+ totalQuantity: targetTypeMap[type][name].totalQuantity,
|
|
|
|
|
+ uom: targetTypeMap[type][name].uom
|
|
|
|
|
+ }))
|
|
|
|
|
+ }));
|
|
|
|
|
|
|
|
this.totalOutputs = outputTotals;
|
|
this.totalOutputs = outputTotals;
|
|
|
this.totalOutputUoms = outputUoms;
|
|
this.totalOutputUoms = outputUoms;
|