Procházet zdrojové kódy

Refactoring was made and imporved working speed

Murad Shirinov před 1 rokem
rodič
revize
afb472df3a

+ 2 - 0
BankOperationsUpdate.WorkerService/Data/Models/Enum/Status.cs

@@ -6,6 +6,8 @@ public enum Status
6 6
 	NEW,
7 7
 	CONFIRMED,
8 8
 	CANCELED,
9
+	DELETED,
10
+	CHANGED,
9 11
 
10 12
 }
11 13
 

+ 1 - 0
BankOperationsUpdate.WorkerService/Data/Models/TransactionsDTO.cs

@@ -11,5 +11,6 @@ public class TransactionsDTO
11 11
 	public decimal BalanceAmount { get; set; }
12 12
 	public bool IsChanged { get; set; }
13 13
 	public long OperationOrderId { get; set; }
14
+    public decimal ChangedDifference { get; set; }
14 15
 }
15 16
 

+ 120 - 76
BankOperationsUpdate.WorkerService/OperationsUpdate/UpdateOperations.cs

@@ -1,5 +1,6 @@
1 1
 
2 2
 
3
+using System.Collections.ObjectModel;
3 4
 using System.Security;
4 5
 
5 6
 namespace BankOperationsUpdate.WorkerService.OperationsUpdate;
@@ -62,7 +63,7 @@ public  class UpdateOperations
62 63
 
63 64
 			_logger.LogDebug("Process for account {0}", bankBalances[i].Id);
64 65
 
65
-			SetTransactionsForAccount(bankBalances[i]!.BankAccountId.Value, bankBalances[i]!.BusinessId.Value);
66
+			SetTransactionsForAccount(bankBalances[i].BankAccountId!.Value, bankBalances[i].BusinessId!.Value);
66 67
 
67 68
 		}
68 69
 	}
@@ -76,7 +77,7 @@ public  class UpdateOperations
76 77
 		//get all operations with New status 
77 78
 		var newOperations = GetAllNewOperations().OrderBy(x => x.DocDate).ThenBy(x => x.OrderId).ToList();
78 79
 		//get all bankOperationIds that added to transactions
79
-		var transactiondHashSet = GetAllTransactions().Select(x => x.BankOperationId).ToHashSet();
80
+		var transactiondHashSet = GetAllTransactions().Select(x => x.BankOperationId).Distinct().ToList();
80 81
 
81 82
 		BankAccountBalance accountBalance;
82 83
 		Transaction transaction;
@@ -88,7 +89,7 @@ public  class UpdateOperations
88 89
 				try {
89 90
 					accountBalance = GetAccountBalanceByBusinessId(item.BankAccountId!.Value, item.BusinessId!.Value);
90 91
 					//change balance on certain amount
91
-					accountBalance.Amount = accountBalance.Amount!.Value + item.IncomeAmount!.Value - item.OutcomeAmount!.Value;
92
+					accountBalance.Amount = accountBalance.Amount!.Value + item.IncomeAmount - item.OutcomeAmount;
92 93
 
93 94
 					//create new transaction
94 95
 					transaction = new Transaction {
@@ -96,13 +97,15 @@ public  class UpdateOperations
96 97
 						BankOperationId = item.Id,
97 98
 						IncomeAmount = item.IncomeAmount,
98 99
 						OutcomeAmount = item.OutcomeAmount,
99
-						BalanceAmount = item.IncomeAmount!.Value - item.OutcomeAmount!.Value,
100
+						BalanceAmount = 0,
100 101
 						ModifiedDate = item.DocDate,
101 102
 						BusinessId = item.BusinessId.Value,
102 103
 						BankAccountId = item.BankAccountId.Value,
103 104
 						CreateDate = DateTime.Now,
104 105
 						OperationCreateDate = item.CreatedDate ?? item.DocDate!.Value,
105
-						IsChanged = true,
106
+						//IsChanged = true,
107
+						Status = Status.NEW.ToString(),
108
+						ChangedDifference = item.IncomeAmount - item.OutcomeAmount,
106 109
 						OperationOrderId = item.OrderId,
107 110
 					};
108 111
 
@@ -118,6 +121,7 @@ public  class UpdateOperations
118 121
 				}
119 122
 			
120 123
 			}
124
+			//if transactions have already contained opearation but it was changed
121 125
 			else if(transactiondHashSet.Contains(item.Id) && item.IsChanged == true) {
122 126
 				UpdateChangedOperations(item, true);
123 127
 			}
@@ -143,50 +147,55 @@ public  class UpdateOperations
143 147
 		//if it is bankOperation with new status that already was in transatctions
144 148
 		if (!IsChanged) {
145 149
 			 //get the income or outcome sum of rollBackcked transaction
146
-			incomeDifference = -1 * transaction.IncomeAmount.Value;
147
-			outcomeDifference = -1 * transaction.OutcomeAmount.Value;
148
-			_repositoryWrapper.Transaction.Delete(transaction);
150
+			incomeDifference = -1 * transaction.IncomeAmount;
151
+			outcomeDifference = -1 * transaction.OutcomeAmount;
152
+			transaction.BalanceAmount = 0;
153
+			transaction.Status = Status.DELETED.ToString();
154
+
149 155
 		}
150 156
 		//else if it is confirmed transaction that has already in transactions
151 157
 		else {
152 158
 			 //get the income or outcome difference that opertion was changed
153
-			incomeDifference = operation.IncomeAmount.Value - transaction.IncomeAmount.Value;
154
-			outcomeDifference = operation.OutcomeAmount.Value - transaction.OutcomeAmount.Value;
159
+			incomeDifference = operation.IncomeAmount - transaction.IncomeAmount;
160
+			outcomeDifference = operation.OutcomeAmount - transaction.OutcomeAmount;
161
+			transaction.Status = Status.CHANGED.ToString();
155 162
 
156
-			transaction.IncomeAmount += incomeDifference;
157
-			transaction.OutcomeAmount += outcomeDifference;
158
-			operation.IsChanged = false;
163
+		}
159 164
 
160
-			_logger.LogInformation("Updated transaction with id: {0}", transaction.Id);
161
-			_repositoryWrapper.Transaction.Update(transaction);
162
-			_repositoryWrapper.BankOperation.Update(operation);
165
+        transaction.IncomeAmount += incomeDifference;
166
+        transaction.OutcomeAmount += outcomeDifference;
167
+		transaction.ChangedDifference += incomeDifference - outcomeDifference;
168
+        //transaction.IsChanged = true;
169
+        operation.IsChanged = false;
163 170
 
164
-		}
165 171
 
166
-		accountBalance.Amount = accountBalance.Amount + incomeDifference - outcomeDifference;
167
-		_repositoryWrapper.BankAccountBalance.Update(accountBalance);
172
+        accountBalance.Amount = accountBalance.Amount + incomeDifference - outcomeDifference;
173
+       
174
+		_repositoryWrapper.Transaction.Update(transaction);
175
+        _repositoryWrapper.BankOperation.Update(operation);
176
+        _repositoryWrapper.BankAccountBalance.Update(accountBalance);
168 177
 		_repositoryWrapper.Save();
169 178
 		_repositoryWrapper.Transaction.Detach(transaction);
170 179
         _repositoryWrapper.BankAccountBalance.Detach(accountBalance);
171 180
 
172 181
 
173
-        //get the transactions that come after modified transaction and change their balanceAmount on cahnged certain amount
174
-        var transactionsList = GetTransactionsByAccountId(operation.BankAccountId.Value, operation.BusinessId.Value)
175
-			.Where(x => x.BusinessId == operation.BusinessId && 
176
-				x.BankAccountId == operation.BankAccountId && 
177
-				DateTime.Compare(x.ModifiedDate.Value, transaction.ModifiedDate.Value) >= 0)
178
-			.OrderBy(x => x.ModifiedDate)
179
-			.ThenBy(x => x.OperationOrderId).ToList();	 
180
-
181
-		foreach(var item  in transactionsList) {
182
-			item.BalanceAmount = item.BalanceAmount + incomeDifference - outcomeDifference;
183
-			_logger.LogInformation("Updated transaction with id: {0}", transaction.Id);
184
-			_repositoryWrapper.Transaction.Update(item);
185
-			_repositoryWrapper.Save();
186
-			_repositoryWrapper.Transaction.Detach(item);
187
-		}
182
+  //      //get the transactions that come after modified transaction and change their balanceAmount on cahnged certain amount
183
+  //      var transactionsList = GetTransactionsByAccountId(operation.BankAccountId.Value, operation.BusinessId.Value)
184
+		//	.Where(x => x.BusinessId == operation.BusinessId && 
185
+		//		x.BankAccountId == operation.BankAccountId && 
186
+		//		DateTime.Compare(x.ModifiedDate.Value, transaction.ModifiedDate.Value) >= 0)
187
+		//	.OrderBy(x => x.ModifiedDate)
188
+		//	.ThenBy(x => x.OperationOrderId).ToList();	 
188 189
 
189
-	}
190
+		//foreach(var item  in transactionsList) {
191
+		//	item.BalanceAmount = item.BalanceAmount + incomeDifference - outcomeDifference;	
192
+		//}
193
+
194
+  //      _repositoryWrapper.Transaction.UpdateBulk(transactionsList);
195
+  //      _repositoryWrapper.Save();
196
+		//_repositoryWrapper.Transaction.DetachBulk(transactionsList);
197
+
198
+    }
190 199
 
191 200
 
192 201
 	//update all new added transactions for updating balance amount of items that comes after updated  item
@@ -194,24 +203,55 @@ public  class UpdateOperations
194 203
 	{
195 204
 		var bankAccounts = GetAllBankBalances().ToList();
196 205
 		List<Transaction> transactions;
197
-		decimal newValue = 0M;
206
+		decimal changedAmount;
198 207
 
199 208
 		foreach (var account in bankAccounts) {
200
-			transactions = GetTransactionsByAccountId(account.BankAccountId!.Value, account.BusinessId!.Value).OrderBy(x => x.ModifiedDate).ThenBy(x => x.OperationOrderId).ToList();
201 209
 
202
-			for (int i = 1; i < transactions.Count; i++) {
203
-				if (transactions[i].IsChanged == true) {
204
-					transactions[i].BalanceAmount += transactions[i - 1].BalanceAmount;
205
-					newValue += transactions[i].IncomeAmount!.Value - transactions[i].OutcomeAmount!.Value;
206
-					transactions[i].IsChanged = false;
207
-				}
208
-				else {
209
-					transactions[i].BalanceAmount += newValue;
210
-				}
211
-
212
-				_repositoryWrapper.Transaction.Update(transactions[i]);
213
-				_repositoryWrapper.Save();
214
-			}
210
+			var allTransactions = GetTransactionsByAccountId(account.BankAccountId!.Value, account.BusinessId!.Value);
211
+			List<Transaction> removedTransactions = new();
212
+
213
+			//check if transactions contains isChange element
214
+			if (allTransactions.Any(x => !x.Status.Equals(Status.CONFIRMED.ToString()))) {
215
+				//order transactions by DocDate and OperationOrderId
216
+				transactions = allTransactions.OrderBy(x => x.ModifiedDate).ThenBy(x => x.OperationOrderId).ToList();
217
+				//get the index of the first occurance of element with IsChanged = true
218
+				int changedIndex = transactions.FindIndex(x => !x.Status.Equals(Status.CONFIRMED.ToString()));
219
+                changedAmount = 0M;
220
+
221
+                for (int i = changedIndex; i < transactions.Count && changedIndex != -1; i++) {
222
+
223
+                    //added changed amount
224
+                    changedAmount += transactions[i].ChangedDifference;
225
+
226
+                    if (!transactions[i].Status.Equals(Status.DELETED.ToString())) {
227
+						if (transactions[i].Status.Equals(Status.NEW.ToString())) {
228
+							transactions[i].BalanceAmount += i > 0 ? transactions[i - 1].BalanceAmount : 0;
229
+
230
+							//if record is added newly then add to balance previous balance and changed difference
231
+							transactions[i].BalanceAmount += transactions[i].ChangedDifference; 
232
+						}
233
+						else {
234
+                            transactions[i].BalanceAmount += changedAmount;
235
+                        }
236
+
237
+						//reset changed difference of transaction
238
+						transactions[i].ChangedDifference = 0;
239
+						//set status of processed transaction to confirmed
240
+                        transactions[i].Status = Status.CONFIRMED.ToString();
241
+					}
242
+					else {
243
+						removedTransactions.Add(transactions[i]);
244
+                        transactions.RemoveAt(i);
245
+						i--;
246
+                    }
247
+
248
+                }
249
+
250
+                _repositoryWrapper.Transaction.UpdateBulk(transactions);
251
+                _repositoryWrapper.Transaction.DeleteBulk(removedTransactions);
252
+                _repositoryWrapper.Save();
253
+                _repositoryWrapper.Transaction.DetachBulk(transactions);
254
+            }
215 255
 		}
216 256
 	}
217 257
 
@@ -227,41 +267,45 @@ public  class UpdateOperations
227 267
 		var operations =  GetAllConfirmedOperations(accountId, businessId).OrderBy(x => x.DocDate).ThenBy(x => x.OrderId).ToList();
228 268
 		
229 269
 		// get Unitque bankOpertionsIds from transatctions 
230
-		var transactionsHashSet = GetTransactionsByAccountId(accountId, businessId).Select(x => x.BankOperationId).ToHashSet();
231
-		Transaction transaction = new Transaction();
270
+		var transactionsDistinct = GetTransactionsByAccountId(accountId, businessId).Select(x => x.BankOperationId).Distinct().ToList();
271
+		ICollection<Transaction> transactions = new Collection<Transaction>();
232 272
 
233 273
 		//get current balance by summarizing all Incomes and outcomes from transacitons
234
-		var currentBalance = GetTransactionsByAccountId(accountId, businessId).Sum(x => (x.IncomeAmount - x.OutcomeAmount));
235
-											   
274
+		var currentBalance = 0M;
236 275
 
237
-		for (int i = 0; i < operations.Count && transactionsHashSet.Count == 0; i++) {
276
+		for (int i = 0; i < operations.Count && transactionsDistinct.Count == 0; i++) {
238 277
 
239 278
 			//if BankOperationsIds doesn't contain confirmed operations then..
240
-			if (!transactionsHashSet.Contains(operations[i].Id) ) {
279
+			if (!transactionsDistinct.Contains(operations[i].Id)) {
241 280
 
242 281
 				//change balance on certain income or outcome amount
243
-				currentBalance = currentBalance + operations[i].IncomeAmount!.Value - operations[i].OutcomeAmount!.Value;
244
-
245
-				transaction.Id = Guid.NewGuid();
246
-				transaction.IncomeAmount = operations[i].IncomeAmount;
247
-				transaction.OutcomeAmount = operations[i].OutcomeAmount;
248
-				transaction.BankOperationId = operations[i].Id;
249
-				transaction.IsChanged = false;
250
-				transaction.ModifiedDate = operations[i].DocDate;
251
-				transaction.BusinessId = businessId;
252
-				transaction.BankAccountId = accountId;
253
-				transaction.CreateDate = DateTime.Now;
254
-                transaction.OperationCreateDate = operations[i].CreatedDate ?? transaction.ModifiedDate!.Value;
255
-                transaction.BalanceAmount = currentBalance ?? 0;
256
-				transaction.OperationOrderId = operations[i].OrderId;
257
-
258
-				//create transaction
259
-				_repositoryWrapper.Transaction.Create(transaction);
260
-				_repositoryWrapper.Save();
282
+				currentBalance = currentBalance + operations[i].IncomeAmount - operations[i].OutcomeAmount;
283
+
284
+				transactions.Add(new Transaction{
285
+					Id = Guid.NewGuid(),
286
+					IncomeAmount = operations[i].IncomeAmount,
287
+					OutcomeAmount = operations[i].OutcomeAmount,
288
+					BankOperationId = operations[i].Id,
289
+					IsChanged = false,
290
+					ModifiedDate = operations[i].DocDate,
291
+					BusinessId = businessId,
292
+					BankAccountId = accountId,
293
+					CreateDate = DateTime.Now,
294
+					OperationCreateDate = operations[i].CreatedDate ?? operations[i].DocDate!.Value,
295
+					BalanceAmount = currentBalance,
296
+					OperationOrderId = operations[i].OrderId,
297
+					ChangedDifference = 0,
298
+					Status = Status.CONFIRMED.ToString(),
299
+				});
300
+
261 301
 			}
262
-		}
263 302
 
264
-		_logger.LogInformation($"{operations.Count} count records was written");
303
+        }
304
+
305
+        //create transaction
306
+        _repositoryWrapper.Transaction.CreateBulk(transactions);
307
+        _repositoryWrapper.Save();
308
+        _logger.LogInformation($"{operations.Count} count records was written");
265 309
 
266 310
 	}
267 311
 

+ 1 - 1
BankOperationsUpdate.WorkerService/appsettings.json

@@ -11,7 +11,7 @@
11 11
     }
12 12
   },
13 13
 
14
-  "RefreshInterval" : "5"
14
+  "RefreshInterval" : "1"
15 15
 
16 16
 
17 17
 }

+ 4 - 0
Contracts/IRepositoryBase.cs

@@ -10,7 +10,11 @@ public interface IRepositoryBase<T>
10 10
     IQueryable<T> FindAll();
11 11
     IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression);
12 12
     void Create(T entity);
13
+    void CreateBulk(ICollection<T> entities);
14
+    void UpdateBulk(ICollection<T> entities);
13 15
     void Update(T entity);
14 16
     void Delete(T entity);
17
+    void DeleteBulk(ICollection<T> entities);
15 18
     void Detach(T entity);
19
+    void DetachBulk(ICollection<T> entities);
16 20
 }

+ 2 - 2
Entities/Models/BankOperation.cs

@@ -25,8 +25,8 @@ namespace Entities.Models
25 25
         public Guid? BankAccountId { get; set; }
26 26
         public Guid? CashOperationTypeId { get; set; }
27 27
         public Guid? CustomerId { get; set; }
28
-        public decimal? IncomeAmount { get; set; }
29
-        public decimal? OutcomeAmount { get; set; }
28
+        public decimal IncomeAmount { get; set; }
29
+        public decimal OutcomeAmount { get; set; }
30 30
         public string? Purpose { get; set; }
31 31
         public Guid? OperationPurposeId { get; set; }
32 32
         public Guid? IncomeItemsCollectionId { get; set; }

+ 4 - 2
Entities/Models/Transaction.cs

@@ -9,8 +9,8 @@ namespace Entities.Models
9 9
         public Guid? CollectionId { get; set; }
10 10
         public int Version { get; set; }
11 11
         public Guid BankOperationId { get; set; }
12
-        public decimal? IncomeAmount { get; set; }
13
-        public decimal? OutcomeAmount { get; set; }
12
+        public decimal IncomeAmount { get; set; }
13
+        public decimal OutcomeAmount { get; set; }
14 14
         public decimal BalanceAmount { get; set; }
15 15
         public long OperationOrderId { get; set; }
16 16
         public bool IsChanged { get; set; }
@@ -19,6 +19,8 @@ namespace Entities.Models
19 19
         public Guid BusinessId { get; set; }
20 20
         public DateTime CreateDate { get; set; }
21 21
         public DateTime OperationCreateDate { get; set; }
22
+        public decimal ChangedDifference { get; set; }
23
+        public string Status { get; set; }
22 24
 
23 25
         public virtual BankOperation BankOperation { get; set; } = null!;
24 26
     }

+ 7 - 1
Entities/RepositoryContext.cs

@@ -91,7 +91,13 @@ namespace Entities
91 91
 
92 92
 				entity.Property(e => e.OutcomeAmount).HasPrecision(18, 2);
93 93
 
94
-				entity.Property(e => e.ModifiedDate).HasColumnType("timestamp without time zone");
94
+                entity.Property(e => e.ChangedDifference).HasPrecision(18, 2);
95
+
96
+                entity.Property(e => e.Status).HasMaxLength(30);
97
+
98
+                entity.Property(e => e.IsChanged);
99
+
100
+                entity.Property(e => e.ModifiedDate).HasColumnType("timestamp without time zone");
95 101
 
96 102
 				entity.Property(e => e.CreateDate).HasColumnType("timestamp without time zone");
97 103
 

+ 2 - 2
Repository/BankOperationRepository.cs

@@ -25,8 +25,8 @@ public class BankOperationRepository : RepositoryBase<BankOperation>, IBankOpera
25 25
 	public IQueryable<BankOperation> GetAllNew(Guid accountId, Guid businessId)
26 26
 	{
27 27
 		if(accountId == Guid.Empty)
28
-			return FindByCondition(x => x.Status == "NEW");
29
-		return FindByCondition(x => x.Status == "NEW" && x.BankAccountId == accountId && x.BusinessId == businessId);
28
+			return FindByCondition(x => !x.Status!.Equals("CONFIRMED"));
29
+		return FindByCondition(x => !x.Status!.Equals("CONFIRMED") && x.BankAccountId == accountId && x.BusinessId == businessId);
30 30
 
31 31
 	}
32 32
 

+ 10 - 0
Repository/RepositoryBase.cs

@@ -20,7 +20,17 @@ public abstract class RepositoryBase<T> : IRepositoryBase<T> where T : class
20 20
     public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression) =>
21 21
         RepositoryContext.Set<T>().Where(expression).AsNoTracking();
22 22
     public void Create(T entity) => RepositoryContext.Set<T>().Add(entity);
23
+    public void CreateBulk(ICollection<T> entities) => RepositoryContext.Set<T>().AddRange(entities);
24
+    public void UpdateBulk(ICollection<T> entities) => RepositoryContext.Set<T>().UpdateRange(entities);
23 25
     public void Update(T entity) => RepositoryContext.Set<T>().Update(entity);
24 26
     public void Delete(T entity) => RepositoryContext.Set<T>().Remove(entity);
27
+    public void DeleteBulk(ICollection<T> entities) => RepositoryContext.Set<T>().RemoveRange(entities);
25 28
     public void Detach(T entity) => RepositoryContext.Entry(entity).State = EntityState.Detached;
29
+
30
+    public void DetachBulk(ICollection<T> entities)
31
+    {
32
+        foreach (var item in entities) {
33
+            RepositoryContext.Entry(item).State = EntityState.Detached;
34
+        }
35
+    }
26 36
 }