Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mahesh-krishnakumar/cbb000cb316d0fbfbe6686a8a1789b4a to your computer and use it in GitHub Desktop.
Save mahesh-krishnakumar/cbb000cb316d0fbfbe6686a8a1789b4a to your computer and use it in GitHub Desktop.
module OmsOperations
class SendOrdersToCostcoService
include CostcoHelper
COSTCO_RETAILER_ID = 'Costco.com'.freeze
# TODO: Find a way to get the last uploaded order ID.
# Should we store the CSV files in S3 first, for debug logs.
def process
begin
return if Rails.env.staging?
return if ring_purchase_codes.blank?
current_last_uploaded_order_id = last_uploaded_order_id
csv_string = generate_csv_string
attach_and_upload_to_s3(csv_string)
upload_log.update! status: :uploaded_to_s3
temp_file = download_and_write_to_temp_file
upload_to_files_server(temp_file)
# last_uploaded_order_id = ring_purchase_codes.sort_by(&:ring_order_id).last.ring_order_id
upload_log.update! status: :completed, last_uploaded_order_id: current_last_uploaded_order_id, completed_at: Time.current
temp_file.close
temp_file.unlink
rescue StandardError => e
Rails.logger.info "Error in SendOrdersToCostcoService: #{e.message}"
schedule_slack_alert("Error in sending orders to Costco: #{e.message}")
upload_log.update! status: :failed, completed_at: Time.current
end
end
private
def schedule_slack_alert(message)
url = Rails.application.credentials.slack_channel[:costco_order_import_failure]
::SlackAlertsWorker.perform_async(url, message) if url.present?
end
def filename
epoch = Time.current.to_i
"#{epoch}_costco_orders"
end
def last_uploaded_order_id
@last_uploaded_order_id ||= CostcoUploadLog.where(status: :completed).last&.last_uploaded_order_id
end
def ring_purchase_codes
@ring_purchase_codes ||= RingPurchaseCode ### get the required purchase codes
end
def upload_log
@upload_log ||= CostcoUploadLog.create(
filename: "#{filename}.csv",
status: :processing,
started_at: Time.current
)
end
def generate_csv_string
CSV.generate do |csv|
csv << CSV_HEADERS
ring_purchase_codes.each do |ring_purchase_code|
csv << order_attributes(ring_purchase_code)
end
end
end
def attach_and_upload_to_s3(csv_string)
csv_io = StringIO.new(csv_string)
csv_io.binmode
upload_log.file.attach(io: csv_io, filename: filename, content_type: 'text/csv')
end
def download_and_write_to_temp_file
file = upload_log.file.download
# Force the downloaded content to UTF-8 before writing
file = file.force_encoding('UTF-8')
# Create temp file in binary mode to avoid encoding issues
temp_file = Tempfile.new([filename, '.csv'], encoding: 'UTF-8')
temp_file.binmode # Open in binary mode
temp_file.write(file)
temp_file.rewind
temp_file
end
def upload_to_files_server(temp_file)
upload_to_path = "/Ultrahuman/costco_com_final_ring_orders/#{filename}.csv"
Files.api_key = Rails.application.credentials.dig(:files, :api_key)
Files::File.upload_file(temp_file.path, upload_to_path)
end
def order_attributes(ring_purchase_code)
ring_order = ring_purchase_code.ring_order
[
ring_order.created_at.strftime("%m/%d/%Y"),
ring_order.order_id,
qr_code_id(ring_purchase_code.purchase_code),
COSTCO_RETAILER_ID,
ring_order.shipping_address['name'],
ring_order.shipping_address['address1'],
ring_order.shipping_address['address2'],
ring_order.shipping_address['city'],
ring_order.shipping_address['province'],
ring_order.shipping_address['zip'],
ring_order.shipping_address['phone'],
ring_order.user.email,
ring_sku(ring_order),
1
]
end
def qr_code_id(ring_purchase_code)
return "QQPPH" if Rails.env.staging?
purchase_code_to_qr_code_mapping['codes'].find {|code| code['purchase_code'] == ring_purchase_code }['qr_code']
end
def ring_sku(ring_order)
return "UHRA-AA-10" if Rails.env.staging?
RING_AIR_SKU_PREFIX + "-" + RingOrder.sku_from_color(ring_order.color) + '-' + ring_order.size.to_s.rjust(2, '0')
end
def purchase_code_to_qr_code_mapping
@code_mapping ||= JSON.parse(File.read('app/assets/jsons/costco_purchase_code_mapping.json'))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment