• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

samsmithnz / SatisfactoryTree / 17900254622

21 Sep 2025 11:16PM UTC coverage: 68.101% (+0.3%) from 67.811%
17900254622

Pull #310

github

web-flow
Merge 70432fd7a into 0525e91df
Pull Request #310: Added new imported item type

435 of 750 branches covered (58.0%)

Branch coverage included in aggregate %.

79 of 125 new or added lines in 6 files covered. (63.2%)

11 existing lines in 3 files now uncovered.

1164 of 1598 relevant lines covered (72.84%)

1069.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.46
/src/SatisfactoryTree.Logic/Models/Plan.cs
1

2
namespace SatisfactoryTree.Logic.Models
3
{
4
    public class Plan
5
    {
6
        public List<Part> Parts { get; set; } = new();
1✔
7
        public List<Recipe> Recipes { get; set; } = new();
1✔
8
        public List<Building> Buildings { get; set; } = new();
1✔
9
        public List<Factory> Factories { get; set; } = new();
11✔
10

11
        public void UpdatePlanCalculations(FactoryCatalog factoryCatalog)
12
        {
1✔
13
            Calculator calculator = new();
1✔
14

15
            // Complete initial calculations
16
            foreach (Factory factory in Factories)
7✔
17
            {
2✔
18
                factory.ComponentParts = calculator.CalculateFactoryProduction(factoryCatalog, factory);
2✔
19
            }
2✔
20

21
            // Balance imports and exports across factories
22
            BalanceImportsAndExports();
1✔
23
        }
1✔
24

25
        private void BalanceImportsAndExports()
26
        {
1✔
27
            // Create a map of what each factory produces (exports)
28
            Dictionary<int, Dictionary<string, double>> factoryProduction = new();
1✔
29

30
            foreach (Factory factory in Factories)
7✔
31
            {
2✔
32
                factoryProduction[factory.Id] = new();
2✔
33

34
                // Add target parts as potential exports
35
                if (factory.TargetParts != null)
2✔
36
                {
2✔
37
                    foreach (Item targetPart in factory.TargetParts)
10✔
38
                    {
2✔
39
                        factoryProduction[factory.Id][targetPart.Name] = targetPart.Quantity;
2✔
40
                    }
2✔
41
                }
2✔
42

43
                // Initialize surplus list if it doesn't exist
44
                if (factory.Surplus == null)
2!
45
                {
×
46
                    factory.Surplus = new();
×
47
                }
×
48
            }
2✔
49

50
            // Check and balance imported parts
51
            foreach (Factory factory in Factories)
7✔
52
            {
2✔
53
                if (factory.ImportedParts == null)
2!
54
                {
×
55
                    continue;
×
56
                }
57

58
                Dictionary<int, ImportedItem> updatedImports = new();
2✔
59

60
                foreach (KeyValuePair<int, ImportedItem> import in factory.ImportedParts.ToList())
8✔
61
                {
1✔
62
                    int sourceFactoryId = import.Key;
1✔
63
                    ImportedItem importedItem = import.Value;
1✔
64

65
                    // Find the source factory
66
                    Factory? sourceFactory = Factories.FirstOrDefault(f => f.Id == sourceFactoryId);
2✔
67

68
                    if (sourceFactory == null)
1!
69
                    {
×
70
                        // Source factory not found - mark as unavailable
NEW
71
                        importedItem.Item.Quantity = 0;
×
NEW
72
                        AddPlanningNote(factory, $"Warning: Source factory '{sourceFactoryId}' not found for import '{importedItem.Item.Name}'");
×
UNCOV
73
                        continue;
×
74
                    }
75

76
                    // Check if source factory produces this item
77
                    if (factoryProduction.ContainsKey(sourceFactoryId) &&
1!
78
                        factoryProduction[sourceFactoryId].ContainsKey(importedItem.Item.Name))
1✔
79
                    {
1✔
80
                        double availableQuantity = factoryProduction[sourceFactoryId][importedItem.Item.Name];
1✔
81
                        double requestedQuantity = importedItem.Item.Quantity;
1✔
82

83
                        if (availableQuantity >= requestedQuantity)
1!
84
                        {
1✔
85
                            // Sufficient production available
86
                            factoryProduction[sourceFactoryId][importedItem.Item.Name] -= requestedQuantity;
1✔
87
                            updatedImports[sourceFactoryId] = importedItem;
1✔
88

89
                            // Mark as allocated in source factory
90
                            MarkAsExported(sourceFactory, importedItem.Item.Name, requestedQuantity, factory.Name);
1✔
91
                        }
1✔
92
                        else if (availableQuantity > 0)
×
93
                        {
×
94
                            // Partial allocation possible
NEW
95
                            importedItem.Item.Quantity = availableQuantity;
×
NEW
96
                            factoryProduction[sourceFactoryId][importedItem.Item.Name] = 0;
×
UNCOV
97
                            updatedImports[sourceFactoryId] = importedItem;
×
98

NEW
99
                            AddPlanningNote(factory, $"Warning: Only {availableQuantity:F2} of {requestedQuantity:F2} '{importedItem.Item.Name}' available from '{sourceFactoryId}'");
×
NEW
100
                            MarkAsExported(sourceFactory, importedItem.Item.Name, availableQuantity, factory.Name);
×
UNCOV
101
                        }
×
102
                        else
103
                        {
×
104
                            // No production available
NEW
105
                            importedItem.Item.Quantity = 0;
×
NEW
106
                            AddPlanningNote(factory, $"Error: No '{importedItem.Item.Name}' available from '{sourceFactoryId}' (already fully allocated)");
×
UNCOV
107
                        }
×
108
                    }
1✔
109
                    else
110
                    {
×
111
                        // Source factory doesn't produce this item
NEW
112
                        importedItem.Item.Quantity = 0;
×
NEW
113
                        AddPlanningNote(factory, $"Error: Factory '{sourceFactoryId}' does not produce '{importedItem.Item.Name}'");
×
UNCOV
114
                    }
×
115
                }
1✔
116

117
                // Update the factory's imported parts with validated quantities
118
                factory.ImportedParts = updatedImports;
2✔
119
            }
2✔
120

121
            // Mark remaining production as surplus
122
            foreach (Factory factory in Factories)
7✔
123
            {
2✔
124
                if (factoryProduction.ContainsKey(factory.Id))
2✔
125
                {
2✔
126
                    foreach (var remainingProduction in factoryProduction[factory.Id])
10✔
127
                    {
2✔
128
                        if (remainingProduction.Value > 0)
2✔
129
                        {
1✔
130
                            // Add to surplus
131
                            var surplusItem = new Item
1✔
132
                            {
1✔
133
                                Name = remainingProduction.Key,
1✔
134
                                Quantity = remainingProduction.Value
1✔
135
                            };
1✔
136

137
                            factory.Surplus.Add(surplusItem);
1✔
138
                        }
1✔
139
                    }
2✔
140
                }
2✔
141
            }
2✔
142
        }
1✔
143

144
        private void MarkAsExported(Factory sourceFactory, string itemName, double quantity, string destinationFactory)
145
        {
1✔
146
            // Initialize exports list if it doesn't exist
147
            if (sourceFactory.Surplus == null)
1!
148
            {
×
NEW
149
                sourceFactory.Surplus = new List<Item>();
×
150
            }
×
151

152
            // Find existing export entry or create new one
153
            var exportItem = sourceFactory.Surplus.FirstOrDefault(s => s.Name == $"Export to {destinationFactory}: {itemName}");
1✔
154

155
            if (exportItem != null)
1!
156
            {
×
157
                exportItem.Quantity += quantity;
×
158
            }
×
159
            else
160
            {
1✔
161
                sourceFactory.Surplus.Add(new Item
1✔
162
                {
1✔
163
                    Name = $"Export to {destinationFactory}: {itemName}",
1✔
164
                    Quantity = quantity
1✔
165
                });
1✔
166
            }
1✔
167
        }
1✔
168

169
        private void AddPlanningNote(Factory factory, string note)
170
        {
×
171
            // For now, we'll use the surplus list to store planning notes
172
            // In a more complete implementation, you might want a dedicated Notes property
NEW
173
            factory.Surplus ??= new List<Item>();
×
174

175
            factory.Surplus.Add(new Item
×
176
            {
×
177
                Name = $"Planning Note",
×
178
                Quantity = 0,
×
179
                // You might want to add a Notes property to Item class for this
×
180
                Building = note
×
181
            });
×
182
        }
×
183

184
        public Dictionary<string, List<string>> GetPlanValidationReport()
185
        {
×
NEW
186
            var report = new Dictionary<string, List<string>>();
×
187

188
            foreach (Factory factory in Factories)
×
189
            {
×
NEW
190
                var factoryIssues = new List<string>();
×
191

192
                if (factory.Surplus != null)
×
193
                {
×
194
                    foreach (var surplus in factory.Surplus)
×
195
                    {
×
196
                        if (surplus.Name == "Planning Note")
×
197
                        {
×
198
                            factoryIssues.Add(surplus.Building); // Using Building field to store the note text
×
199
                        }
×
200
                        else if (surplus.Name.StartsWith("Export to"))
×
201
                        {
×
202
                            factoryIssues.Add($"Exporting: {surplus.Name} - {surplus.Quantity:F2} per/min");
×
203
                        }
×
204
                        else if (surplus.Quantity > 0)
×
205
                        {
×
206
                            factoryIssues.Add($"Surplus: {surplus.Name} - {surplus.Quantity:F2} per/min");
×
207
                        }
×
208
                    }
×
209
                }
×
210

211
                report[factory.Name] = factoryIssues;
×
212
            }
×
213

214
            return report;
×
215
        }
×
216
    }
217
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc