@@ -10,9 +10,31 @@ def index
10
10
@stocks_with_data = collection
11
11
end
12
12
format . csv do
13
- GenerateStocksCsvJob . perform_later ( current_tenant , current_user . email )
14
- flash [ :notice ] = "CSV is being generated and will be emailed to you shortly."
15
- redirect_to stocks_path
13
+ if params [ :detailed ]
14
+ begin
15
+ csv_data = generate_detailed_csv
16
+ send_data csv_data ,
17
+ filename : "detailed_stock_calculations_#{ Date . today } .csv" ,
18
+ type : 'text/csv; charset=utf-8' ,
19
+ disposition : 'attachment'
20
+ rescue => e
21
+ Rails . logger . error "Error generating CSV: #{ e . message } "
22
+ flash [ :error ] = "Erro ao gerar o CSV. Por favor, tente novamente."
23
+ redirect_to stocks_path
24
+ end
25
+ else
26
+ begin
27
+ csv_data = generate_regular_csv
28
+ send_data csv_data ,
29
+ filename : "stock_calculations_#{ Date . today } .csv" ,
30
+ type : 'text/csv; charset=utf-8' ,
31
+ disposition : 'attachment'
32
+ rescue => e
33
+ Rails . logger . error "Error generating CSV: #{ e . message } "
34
+ flash [ :error ] = "Erro ao gerar o CSV. Por favor, tente novamente."
35
+ redirect_to stocks_path
36
+ end
37
+ end
16
38
end
17
39
end
18
40
end
@@ -76,6 +98,48 @@ def collection
76
98
. filter_by_sku ( params [ 'sku' ] )
77
99
. joins ( :product )
78
100
101
+ # Calculate total balance for null tipo_estoque products
102
+ default_warehouse_id = '9023657532' # ID for Estoque São Paulo Base
103
+ null_tipo_stocks = Stock . where ( account_id : current_tenant )
104
+ . joins ( :product )
105
+ . includes ( :product )
106
+ . where ( products : { tipo_estoque : nil } )
107
+ . includes ( :balances )
108
+ . to_a
109
+
110
+ Rails . logger . info "Starting balance calculations..."
111
+
112
+ @total_null_balance = null_tipo_stocks . sum do |stock |
113
+ balance = stock . balances . find { |b | b . deposit_id . to_s == default_warehouse_id }
114
+ next 0 unless balance
115
+
116
+ # Get the base physical balance
117
+ physical_balance = balance . physical_balance
118
+
119
+ # Calculate the actual balance based on conditions
120
+ actual_balance = if stock . discounted_warehouse_sku_id == "#{ default_warehouse_id } _#{ stock . product . sku } "
121
+ # If discounted, subtract 1000 first
122
+ discounted = physical_balance - 1000
123
+ # If the discounted value is negative, don't count this stock
124
+ discounted <= 0 ? 0 : discounted
125
+ else
126
+ # If not discounted, apply the regular rules
127
+ if physical_balance >= 1000
128
+ physical_balance - 1000
129
+ elsif physical_balance <= 0
130
+ 0
131
+ else
132
+ physical_balance
133
+ end
134
+ end
135
+
136
+ Rails . logger . info "SKU: #{ stock . product . sku } | Physical Balance: #{ physical_balance } | Actual Balance: #{ actual_balance } | Discounted?: #{ stock . discounted_warehouse_sku_id . present? } "
137
+
138
+ actual_balance
139
+ end
140
+
141
+ Rails . logger . info "Total balance calculated: #{ @total_null_balance } "
142
+
79
143
stocks = case @default_tipo_estoque
80
144
when 'null'
81
145
stocks . where ( products : { tipo_estoque : nil } )
@@ -99,8 +163,6 @@ def collection
99
163
. group ( :sku )
100
164
. sum ( :quantity )
101
165
102
- default_warehouse_id = '9023657532' # ID for Estoque São Paulo Base
103
-
104
166
total_in_production = Stock . total_in_production_for_all
105
167
106
168
stocks_with_forecasts = stocks . map do |stock |
@@ -158,4 +220,64 @@ def set_stock
158
220
flash [ :alert ] = "Stock not found"
159
221
redirect_to stocks_path
160
222
end
223
+
224
+ def generate_detailed_csv
225
+ require 'csv'
226
+
227
+ default_warehouse_id = '9023657532'
228
+ stocks = Stock . where ( account_id : current_tenant )
229
+ . includes ( :product , :balances )
230
+ . joins ( :product )
231
+ . where ( products : { tipo_estoque : nil } )
232
+
233
+ CSV . generate ( headers : true , col_sep : ';' , encoding : 'UTF-8' ) do |csv |
234
+ csv << [
235
+ 'SKU' , 'Saldo Físico'
236
+ ]
237
+
238
+ stocks . each do |stock |
239
+ begin
240
+ balance = stock . balances . find { |b | b . deposit_id . to_s == default_warehouse_id }
241
+ next unless balance
242
+
243
+ physical_balance = if stock . discounted_warehouse_sku_id == "#{ default_warehouse_id } _#{ stock . product . sku } "
244
+ stock . discounted_balance ( balance )
245
+ else
246
+ balance . physical_balance
247
+ end
248
+
249
+ csv << [
250
+ stock . product . sku ,
251
+ physical_balance || 0
252
+ ]
253
+ rescue => e
254
+ Rails . logger . error "Error processing stock #{ stock . id } : #{ e . message } "
255
+ next
256
+ end
257
+ end
258
+ end
259
+ end
260
+
261
+ def generate_regular_csv
262
+ CSV . generate ( headers : true , col_sep : ';' , encoding : 'UTF-8' ) do |csv |
263
+ csv << [ 'id' , 'SKU' , 'Saldo Total' , 'Saldo Virtual Total' , 'Quantidade Vendida dos Últimos 30 dias' ,
264
+ 'Previsão para os Próximos 30 dias' , 'Produto' ]
265
+
266
+ stocks = Stock . where ( account_id : current_tenant )
267
+ . includes ( :product , :balances )
268
+ . joins ( :product )
269
+ . where ( products : { tipo_estoque : nil } )
270
+ . sort_by ( &:calculate_basic_forecast )
271
+ . reverse!
272
+
273
+ stocks . each do |stock |
274
+ next if stock . total_balance . zero? && stock . count_sold . zero?
275
+
276
+ row = [ stock . id , stock . sku , stock . total_balance , stock . total_virtual_balance , stock . count_sold ,
277
+ stock . calculate_basic_forecast ,
278
+ stock . product . name ]
279
+ csv << row
280
+ end
281
+ end
282
+ end
161
283
end
0 commit comments