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

samsmithnz / SatisfactoryTree / 17381497476

01 Sep 2025 03:12PM UTC coverage: 52.786% (+0.4%) from 52.406%
17381497476

push

github

web-flow
Merge pull request #274 from samsmithnz/copilot/fix-273

Replace TreeView with ListView and implement auto-population of production dependencies

517 of 657 branches covered (78.69%)

Branch coverage included in aggregate %.

54 of 71 new or added lines in 3 files covered. (76.06%)

1880 of 3884 relevant lines covered (48.4%)

2449.32 hits per line

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

70.25
/src/SatisfactoryTree/Services/ProductionPlanningService.cs
1
using SatisfactoryTree.Models;
2

3
namespace SatisfactoryTree.Services
4
{
5
    public class ProductionPlanningService
6
    {
7
        public ProductionPlanningService()
16✔
8
        {
16✔
9
            Factories = new Dictionary<string, Factory>();
16✔
10
            // Create default factory
11
            AddFactory("default", "Main Factory");
16✔
12
        }
16✔
13

14
        public Dictionary<string, Factory> Factories { get; set; }
120✔
15

16
        public Factory AddFactory(string id, string name = "")
17
        {
22✔
18
            if (Factories.ContainsKey(id))
22!
19
            {
×
20
                throw new ArgumentException($"Factory with ID '{id}' already exists.");
×
21
            }
22

23
            var factory = new Factory(id, name);
22✔
24
            Factories[id] = factory;
22✔
25
            return factory;
22✔
26
        }
22✔
27

28
        public void RemoveFactory(string id)
29
        {
1✔
30
            if (id == "default")
1!
31
            {
1✔
32
                throw new ArgumentException("Cannot remove the default factory.");
1✔
33
            }
34
            Factories.Remove(id);
×
35
        }
×
36

37
        public Factory? GetFactory(string id)
38
        {
26✔
39
            return Factories.ContainsKey(id) ? Factories[id] : null;
26!
40
        }
26✔
41

42
        public List<Factory> GetAllFactories()
43
        {
×
44
            return Factories.Values.ToList();
×
45
        }
×
46

47
        public ProductionGoal AddProductionGoal(string itemName, decimal targetQuantity, string factoryId = "default")
48
        {
9✔
49
            var factory = GetFactory(factoryId);
9✔
50
            if (factory == null)
9!
51
            {
×
52
                throw new ArgumentException($"Factory with ID '{factoryId}' not found.");
×
53
            }
54

55
            return factory.AddProductionGoal(itemName, targetQuantity);
9✔
56
        }
9✔
57

58
        public void ProcessProduction(string itemName, decimal quantity, string factoryId = "default")
59
        {
3✔
60
            var factory = GetFactory(factoryId);
3✔
61
            if (factory == null)
3!
62
            {
×
63
                throw new ArgumentException($"Factory with ID '{factoryId}' not found.");
×
64
            }
65

66
            factory.ProcessProduction(itemName, quantity);
3✔
67
        }
3✔
68

69
        public List<ProductionGoal> GetAllActiveGoals()
70
        {
4✔
71
            return Factories.Values.SelectMany(f => f.GetActiveGoals()).ToList();
8✔
72
        }
4✔
73

74
        public List<ProductionGoal> GetAllCompletedGoals()
75
        {
1✔
76
            return Factories.Values.SelectMany(f => f.GetCompletedGoals()).ToList();
2✔
77
        }
1✔
78

79
        public List<ProductionGoal> GetTopLevelGoals(string factoryId = "default")
80
        {
1✔
81
            var factory = GetFactory(factoryId);
1✔
82
            if (factory == null) return new List<ProductionGoal>();
1!
83

84
            return factory.GetActiveGoals().Where(g => string.IsNullOrEmpty(g.ParentGoalId)).ToList();
3✔
85
        }
1✔
86

87
        public List<ProductionGoal> GetAllGoalsIncludingDependencies(string factoryId = "default")
88
        {
2✔
89
            var factory = GetFactory(factoryId);
2✔
90
            if (factory == null) return new List<ProductionGoal>();
2!
91

92
            var allGoals = new List<ProductionGoal>();
2✔
93
            var topLevelGoals = factory.GetActiveGoals().Where(g => string.IsNullOrEmpty(g.ParentGoalId));
5✔
94

95
            foreach (var goal in topLevelGoals)
12✔
96
            {
3✔
97
                allGoals.Add(goal);
3✔
98
                allGoals.AddRange(goal.GetAllDependencies());
3✔
99
            }
3✔
100

101
            return allGoals;
2✔
102
        }
2✔
103

104
        public void ToggleGoalProductionMethod(string goalId, bool produceInternally)
105
        {
3✔
106
            var goal = GetAllActiveGoals().FirstOrDefault(g => g.Id == goalId);
6✔
107
            if (goal != null)
3✔
108
            {
3✔
109
                goal.ProduceInternally = produceInternally;
3✔
110
                
111
                if (!produceInternally)
3✔
112
                {
3✔
113
                    // Clear dependencies if switching to import
114
                    goal.DependentGoals.Clear();
3✔
115
                }
3✔
116
            }
3✔
117
        }
3✔
118

119
        public void RemoveProductionGoal(string goalId, string factoryId = "default")
NEW
120
        {
×
NEW
121
            var factory = GetFactory(factoryId);
×
NEW
122
            if (factory == null) return;
×
123

NEW
124
            var goal = factory.GetActiveGoals().FirstOrDefault(g => g.Id == goalId);
×
NEW
125
            if (goal != null)
×
NEW
126
            {
×
127
                // Remove from parent if this is a dependent goal
NEW
128
                if (!string.IsNullOrEmpty(goal.ParentGoalId))
×
NEW
129
                {
×
NEW
130
                    var parentGoal = factory.GetActiveGoals().FirstOrDefault(g => g.Id == goal.ParentGoalId);
×
NEW
131
                    parentGoal?.RemoveDependentGoal(goalId);
×
NEW
132
                }
×
133

134
                // Remove from factory
NEW
135
                factory.RemoveProductionGoal(goal);
×
NEW
136
            }
×
NEW
137
        }
×
138

139
        public void TransferItemsBetweenFactories(string fromFactoryId, string toFactoryId, string itemName, decimal quantity)
140
        {
1✔
141
            var fromFactory = GetFactory(fromFactoryId);
1✔
142
            var toFactory = GetFactory(toFactoryId);
1✔
143

144
            if (fromFactory == null || toFactory == null)
1!
145
            {
×
146
                throw new ArgumentException("One or both factories not found.");
×
147
            }
148

149
            if (fromFactory.Storage.RemoveItem(itemName, quantity))
1!
150
            {
1✔
151
                toFactory.Storage.AddItem(itemName, quantity);
1✔
152
            }
1✔
153
            else
154
            {
×
155
                throw new InvalidOperationException($"Insufficient {itemName} in factory {fromFactoryId} storage.");
×
156
            }
157
        }
1✔
158

159
        public Dictionary<string, decimal> GetTotalStorage()
160
        {
1✔
161
            var totalStorage = new Dictionary<string, decimal>();
1✔
162

163
            foreach (var factory in Factories.Values)
9✔
164
            {
3✔
165
                foreach (var item in factory.Storage.GetAllItems())
17✔
166
                {
4✔
167
                    if (totalStorage.ContainsKey(item.Key))
4✔
168
                    {
2✔
169
                        totalStorage[item.Key] += item.Value;
2✔
170
                    }
2✔
171
                    else
172
                    {
2✔
173
                        totalStorage[item.Key] = item.Value;
2✔
174
                    }
2✔
175
                }
4✔
176
            }
3✔
177

178
            return totalStorage;
1✔
179
        }
1✔
180
    }
181
}
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