Image Shifting Documentation

This document describes the image shifting functionality that allows you to move images up to fill empty slots in the image type order.

Overview

The image shifting system consists of:

  • Image::ImageShiftingService - Core service class with all business logic
  • Rake tasks - Command-line interface for bulk operations
  • Model methods - Convenience methods on Item model
  • Controller integration - Can be called from Rails controllers

Service Class

The main service class is Image::ImageShiftingService located at app/services/image/image_shifting_service.rb.

Key Methods

shift_images_for_item(item_id, locale: 'en', prefix: nil)

Shifts images for a specific item to fill empty slots in the image type order.

Parameters:

  • item_id (Integer) - The ID of the item to shift images for
  • locale (String) - The locale for the images (default: 'en')
  • prefix (String, nil) - Optional prefix to limit shifting to a specific group (e.g., 'AMZ', 'WAL')

Returns: Hash with result information

{
  success: true,
  errors: [],
  changes_made: false,
  before_profiles: ['AMZ_MAIN', 'AMZ_PT01', 'AMZ_PT02'],
  after_profiles: ['AMZ_MAIN', 'AMZ_FRNT', 'AMZ_SIDE'],
  item: #<Item>
}

Example:

result = Image::ImageShiftingService.shift_images_for_item(123, locale: 'en', prefix: 'AMZ')
if result[:success] && result[:changes_made]
  puts "Images shifted successfully!"
end

shift_images_for_all_items(locale: 'en', prefix: nil, batch_size: 100, dry_run: false)

Shifts images for all items that have image profiles.

Parameters:

  • locale (String) - The locale for the images (default: 'en')
  • prefix (String, nil) - Optional prefix to limit shifting to a specific group
  • batch_size (Integer) - Number of items to process in each batch (default: 100)
  • dry_run (Boolean) - If true, only shows what would be done without making changes (default: false)

Returns: Hash with summary information

{
  processed_items: 150,
  items_with_changes: 45,
  total_changes: 45,
  errors: [],
  dry_run: false,
  total_items: 150
}

Example:

result = Image::ImageShiftingService.shift_images_for_all_items(
  locale: 'en', 
  prefix: 'AMZ', 
  batch_size: 50, 
  dry_run: true
)
puts "Would process #{result[:total_items]} items"

analyze_missing_sequences(locale: 'en', prefix: nil)

Analyzes missing sequences in image profiles.

Parameters:

  • locale (String) - The locale for the images (default: 'en')
  • prefix (String, nil) - Optional prefix to limit analysis to a specific group

Returns: Hash with analysis results

{
  total_items: 150,
  items_with_gaps: 45,
  total_gaps: 67,
  items_with_complete_sequences: 105,
  gap_details: [...],
  prefix_groups: {
    'AMZ' => { items_with_gaps: 30, total_gaps: 45, gap_details: [...] },
    'WAL' => { items_with_gaps: 15, total_gaps: 22, gap_details: [...] }
  }
}

Example:

result = Image::ImageShiftingService.analyze_missing_sequences(locale: 'en', prefix: 'AMZ')
puts "Found #{result[:items_with_gaps]} items with gaps"

find_missing_image_type(image_type, locale: 'en', prefix: nil, limit: 50)

Finds items missing a specific image type.

Parameters:

  • image_type (String) - The image type to search for
  • locale (String) - The locale for the images (default: 'en')
  • prefix (String, nil) - Optional prefix to limit search to a specific group
  • limit (Integer) - Maximum number of items to return (default: 50)

Returns: Hash with missing items information

{
  image_type: 'AMZ_FRNT',
  total_missing: 25,
  missing_items: [
    { item: #<Item>, current_images: ['AMZ_MAIN', 'AMZ_PT01'] },
    ...
  ],
  limit: 50
}

Example:

result = Image::ImageShiftingService.find_missing_image_type('AMZ_FRNT', locale: 'en', prefix: 'AMZ')
puts "Found #{result[:total_missing]} items missing AMZ_FRNT"

Rake Tasks

The rake tasks provide a command-line interface for the service methods.

rake images:shift_for_item[ITEM_ID,PREFIX,LOCALE]

Shifts images for a specific item.

Examples:

# Shift all image groups for item 123
rake images:shift_for_item[123]

# Shift only Amazon images for item 123
rake images:shift_for_item[123,AMZ]

# Shift only Walmart images for item 123 in French locale
rake images:shift_for_item[123,WAL,fr]

rake images:shift_all_items[PREFIX,BATCH_SIZE,DRY_RUN,LOCALE]

Shifts images for all items with image profiles.

Examples:

# Shift all items (will prompt for confirmation)
rake images:shift_all_items

# Dry run for Amazon images
rake images:shift_all_items[AMZ,100,true]

# Shift Walmart images with batch size 50
rake images:shift_all_items[WAL,50,false]

rake images:analyze_missing[PREFIX,LOCALE,SHOW_DETAILS]

Analyzes missing sequences in image profiles.

Examples:

# Analyze all image groups
rake images:analyze_missing

# Analyze only Amazon images
rake images:analyze_missing[AMZ]

# Show detailed breakdown for Amazon images
rake images:analyze_missing[AMZ,en,true]

rake images:find_missing_type[IMAGE_TYPE,PREFIX,LOCALE]

Finds items missing a specific image type.

Examples:

# Find items missing AMZ_FRNT
rake images:find_missing_type[AMZ_FRNT,AMZ]

# Find items missing WAL_MAIN
rake images:find_missing_type[WAL_MAIN,WAL]

rake images:show_for_item[ITEM_ID,PREFIX,LOCALE]

Shows current image profiles for a specific item.

Examples:

# Show all image groups for item 123
rake images:show_for_item[123]

# Show only Amazon images for item 123
rake images:show_for_item[123,AMZ]

rake images:show_types

Shows all image types and their order for reference.

Model Integration

Item Model

The Item model has a convenience method:

# Shift images for this item
item.shift_images(locale: 'en', prefix: 'AMZ')

# Returns the same result hash as the service method
result = item.shift_images(locale: 'en', prefix: 'AMZ')
if result[:changes_made]
  puts "Images were shifted"
end

Controller Integration

The service can be called from Rails controllers. The CRM interface provides a web-based way to manage image profiles:

CRM Interface

The image profile management is accessible through the CRM marketing menu via the "Image Profile Manager" link. The main index page provides access to all functionality:

  • Main Pivot Table - Shows all image profiles grouped by item with thumbnails
  • Individual Item Actions - Shift AMZ/WAL images for specific items
  • Bulk Operations - Modal for bulk shifting across all items
  • Analyze Missing Sequences - Dedicated page for gap analysis
  • Search & Filter - Advanced filtering and sorting capabilities

Controller Example

class Crm::ImageProfilesController < CrmController
  def shift_item
    item_id = params[:item_id]
    prefix = params[:prefix]
    locale = params[:locale] || 'en'
    
    result = Image::ImageShiftingService.shift_images_for_item(
      item_id, 
      locale: locale, 
      prefix: prefix
    )
    
    if result[:success]
      if result[:changes_made]
        redirect_to admin_item_path(item_id), notice: 'Images shifted successfully!'
      else
        redirect_to admin_item_path(item_id), notice: 'No changes needed'
      end
    else
      redirect_to admin_item_path(item_id), alert: "Error: #{result[:errors].join(', ')}"
    end
  end
  
  def analyze_missing
    prefix = params[:prefix]
    locale = params[:locale] || 'en'
    
    @analysis = Image::ImageShiftingService.analyze_missing_sequences(
      locale: locale, 
      prefix: prefix
    )
  end
  
  def bulk_shift
    prefix = params[:prefix]
    locale = params[:locale] || 'en'
    dry_run = params[:dry_run] == 'true'
    
    result = Image::ImageShiftingService.shift_images_for_all_items(
      locale: locale,
      prefix: prefix,
      batch_size: 100,
      dry_run: dry_run
    )
    
    if result[:errors].any?
      redirect_to admin_image_profiles_path, alert: "Errors occurred: #{result[:errors].join(', ')}"
    else
      message = dry_run ? "Dry run completed" : "Bulk shift completed"
      redirect_to admin_image_profiles_path, notice: "#{message}. Processed #{result[:processed_items]} items."
    end
  end
end

Image Type Order

The system uses the following image type order (defined in ImageProfile::IMAGE_TYPES):

Amazon Images (AMZ)

  1. AMZ_MAIN - Amazon Main image
  2. AMZ_FRNT - Amazon Front angle shot
  3. AMZ_SIDE - Amazon Side angle shot
  4. AMZ_BACK - Amazon Back angle shot
  5. AMZ_PT01 through AMZ_PT11 - Amazon Part shots
  6. AMZ_SWCH - Amazon Swatch shots (never shifted)

Walmart Images (WAL)

  1. WAL_MAIN - Walmart Main image
  2. WAL_AD01 through WAL_AD10 - Walmart Additional images
  3. WAL_SWCH - Walmart Swatch shots (never shifted)

Gap Detection Logic

A "gap" is defined as a missing image type that comes between existing image types in the ordered sequence. For example:

  • Current: AMZ_MAIN, AMZ_PT01, AMZ_PT02, AMZ_PT03, AMZ_PT04
  • Missing: AMZ_FRNT, AMZ_SIDE, AMZ_BACK, AMZ_PT05, AMZ_PT06, AMZ_PT07, AMZ_PT08, AMZ_PT09, AMZ_PT10, AMZ_PT11, AMZ_SWCH
  • Gaps: AMZ_FRNT, AMZ_SIDE, AMZ_BACK (3 gaps)

Only the first three missing types are considered gaps because they come between existing images. Missing types after the last existing image are not considered gaps.

Swatch Shot Protection

Swatch shots (AMZ_SWCH, WAL_SWCH) are never shifted or moved. They remain in their original positions regardless of gaps in the sequence.

Error Handling

All service methods return structured results with error information:

result = Image::ImageShiftingService.shift_images_for_item(123)
if result[:success]
  # Operation succeeded
  puts "Changes made: #{result[:changes_made]}"
else
  # Operation failed
  puts "Errors: #{result[:errors].join(', ')}"
end

Performance Considerations

  • Batch processing: Use batch_size parameter for large operations
  • Dry runs: Use dry_run: true to test operations without making changes
  • Prefix filtering: Use prefix parameter to limit operations to specific image groups
  • Database transactions: All operations are wrapped in transactions for data consistency