```ruby=
module PartnerProducts
class ProcessBatchUploadOfficer
attr_reader :params, :current_row, :success_row, :error_params,:errors
def initialize(params)
@params = params
@current_row = 0
@success_row = 0
@result = { total_row: 0, partner_product_ids: [] }
@errors = []
@error_params = {}
@validated_file_url = nil
end
def perform
send("parse_#{params[:action_type]}_data!")
save_batch_upload_result!
broadcast_progress!(@current_row, @success_row)
true
rescue StandardError => e
ExceptionNotifier.notify_exception(e, data: { params: params, current_row: current_row })
Rails.logger.error "#{self.class} params: #{@params} current_row: #{current_row} errors: #{e}"
@errors << Phoenix::ResponseMessage::MESSAGES[:RUNTIME_ERROR][I18n.locale.upcase]
false
end
private
def parse_create_data!
sheet_1 = user_file_excel.sheet(0).to_a.drop(3) # skip 3 first row
sheet_2 = user_file_excel.sheet(1).to_a.drop(3) # skip 3 first row
sheet_3 = user_file_excel.sheet(2).to_a.drop(3) # skip 3 first row
new_sheet_1 = []
new_sheet_2 = []
new_sheet_3 = []
@result[:total_row] = sheet_1.size
@result[:partner_product_ids] = []
broadcast_progress!
# 1/ 10 row
#
sheet_1.each_with_index do |item, idx|
@current_row += 1
item_sku_price = sheet_2.find { |row| row[1] == item[2] }
distributions = sheet_3.select { |row| row[1] == item[2] }
if item_sku_price.present? && distributions.present?
insert_params = {
user: user,
partner: partner,
batch_upload: batch_upload,
index: idx,
item: item,
item_sku_price: item_sku_price,
distributions: distributions
}
officer = PartnerProducts::CreateOfficer.new(insert_params)
if officer.valid?
officer.perform
@result[:partner_product_ids] << officer.partner_product.id
@success_row += 1
else
new_sheet_1 << officer.item
new_sheet_2 << officer.item_sku_price
new_sheet_3 += officer.distributions
end
broadcast_progress!(@current_row, @success_row) unless @current_row == @total_row
end
end
error_params[:data] = { sheet_1: new_sheet_1, sheet_2: new_sheet_2, sheet_3: new_sheet_3 }
error_params[:partner_id] = params[:partner_id]
error_params[:user_id] = params[:user_id]
generate_error_excel!(error_params) if new_sheet_1.present? || new_sheet_2.present? || new_sheet_3.present?
end
def parse_update_basic_info_data!
end
def parse_update_price_warehouse_data!
sheet_1 = user_file_excel.sheet(0).to_a.drop(3) # skip 3 first row
sheet_2 = user_file_excel.sheet(1).to_a.drop(3) # skip 3 first row
new_sheet_1 = []
new_sheet_2 = []
@result[:total_row] = sheet_1.size
@result[:partner_product_ids] = []
broadcast_progress!
sheet_1.each_with_index do |item_sku_price, idx|
@current_row = idx + 1
distributions = sheet_2.select { |row| row[1] == item_sku_price[1] }
insert_params = {
user: user,
partner: partner,
batch_upload: batch_upload,
index: idx,
item_sku_price: item_sku_price,
distributions: distributions
}
officer = PartnerProducts::UpdatePriceWarehouseOfficer.new(insert_params)
if officer.valid?
officer.perform
@result['partner_product_ids'] << officer.partner_product.id
@success_row += 1
else
new_sheet_1 << officer.item_sku_price
new_sheet_2 << officer.distributions
end
broadcast_progress!(@current_row, @success_row)
end
end
def save_batch_upload_result!
batch_upload.result = @result
batch_upload.validated_file_url = @validated_file_url
batch_upload.save!
end
def generate_error_excel!(params)
officer = Excel::PartnerProductTemplate::CreateOfficer.new(params)
officer.perform
@validated_file_url = officer.excel_file_url
# 1. generate data error validation => done
# 2. generate file excel with error validation => done
# 3. upload to s3 => done
# 4. update to validated_file_url on table batch_upload_partner_products
# 5. broadcast
end
def partner
@partner ||= Phoenix::Partner.find(params[:partner_id])
end
def user
@user ||= batch_upload.user
end
def user_file_excel
@user_file_excel ||= Roo::Excelx.new(user_excel_file_path)
end
def batch_upload
@batch_upload ||= partner.batch_upload_partner_products.find_by(request_id: params[:request_id])
end
def broadcast_progress!(current_row = 0, success_row = 0)
Phoenix::PartnerProducts::RecalculateStatsOfficer.new(partner).perform
friday_params = {
user_id: batch_upload.user_id,
request_id: batch_upload.request_id,
current_row: current_row,
success_row: success_row,
total_row: @result[:total_row],
validated_file_url: batch_upload.validated_file_url
}
BroadcastFriday::ProgressUploadPartnerProductsOfficer.new(friday_params).perform
end
def user_excel_file_path
@user_excel_file_path ||= begin
file_path = temp_path.join("#{batch_upload.request_id}.xlsx")
FileUtils.mkdir_p(temp_path)
File.open(file_path, 'wb') do |file|
file.write URI.parse(batch_upload.user_file_url).read
end
file_path
end
end
def temp_path
@temp_path ||= Rails.root.join("tmp/batch_upload_partner_products/#{batch_upload.id}")
end
end
end
```