Documentation

Business Hours Management

The ShopBite plugin offers a powerful business hours management system, specifically designed for gastronomy and retail businesses. This chapter explains the detailed configuration and management of business hours.

Overview

The business hours system enables:

  • Flexible opening hours for each day of the week
  • Sales Channel-specific configuration
  • Special opening hours for special occasions
  • API integration for the storefront
  • Real-time query via the Shopware Store API

Database Structure

CREATE TABLE `shopbite_business_hour` (
    `id` BINARY(16) NOT NULL,
    `day_of_week` INT(11) NOT NULL,  -- 0=Sunday, 1=Monday, ..., 6=Saturday
    `opening_time` VARCHAR(5) NOT NULL,  -- Format: HH:MM
    `closing_time` VARCHAR(5) NOT NULL, -- Format: HH:MM
    `sales_channel_id` BINARY(16) NOT NULL,
    `created_at` DATETIME(3) NOT NULL,
    `updated_at` DATETIME(3) NULL,
    PRIMARY KEY (`id`),
    CONSTRAINT `fk.shopbite_business_hour.sales_channel_id` 
        FOREIGN KEY (`sales_channel_id`) 
        REFERENCES `sales_channel` (`id`) 
        ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Administration Interface

Business Hours List

  1. Navigate to ShopBite > Business Hours
  2. Overview of all configured business hours
  3. Filtering by Sales Channel
  4. Bulk actions (Export, Import)

Add New Business Hour

  1. Click Add new business hour
  2. Fill out the form:

Form Fields

FieldTypeDescriptionExample
Sales ChannelDropdownSelect sales channel"My Restaurant"
Day of WeekDropdownDay of the week (0-6)1 (Monday)
Opening TimeTime pickerOpening time11:00
Closing TimeTime pickerClosing time22:00
ClosedCheckboxMark day as closed

Edit Business Hours

  1. Click Edit button
  2. Adjust fields
  3. Click Save

Delete Business Hours

  1. Click Delete button
  2. Confirmation dialog
  3. Click Confirm

API Integration

API Endpoint

GET /store-api/shopbite/business-hour

Request Parameters

ParameterTypeDescriptionExample
sales-channel-idUUIDFilter by Sales Channel019a36f224b0704fb6835914050392f4
include-closedBooleanInclude closed daystrue

Example Request

curl -X GET "https://your-shopware-domain.com/store-api/shopbite/business-hour" \
  -H "Authorization: Bearer YourAPIToken" \
  -H "sw-access-key: YourAccessKey" \
  -H "Accept: application/json"

Example Response

{
  "apiAlias": "shopbite_business_hour",
  "data": [
    {
      "id": "019a36f224b0704fb6835914050392f4",
      "dayOfWeek": 1,
      "openingTime": "11:00",
      "closingTime": "22:00",
      "salesChannelId": "019a36f224b0704fb6835914050392f4",
      "createdAt": "2024-01-11T14:30:00+01:00",
      "updatedAt": "2024-01-11T14:30:00+01:00",
      "salesChannel": {
        "id": "019a36f224b0704fb6835914050392f4",
        "name": "My Restaurant",
        "typeId": "019a36f224b0704fb6835914050392f4"
      }
    },
    {
      "id": "019a36f224b0704fb6835914050392f5",
      "dayOfWeek": 2,
      "openingTime": "11:00",
      "closingTime": "22:00",
      "salesChannelId": "019a36f224b0704fb6835914050392f4",
      "createdAt": "2024-01-11T14:30:00+01:00",
      "updatedAt": "2024-01-11T14:30:00+01:00",
      "salesChannel": {
        "id": "019a36f224b0704fb6835914050392f4",
        "name": "My Restaurant",
        "typeId": "019a36f224b0704fb6835914050392f4"
      }
    }
  ],
  "total": 7
}

Error Handling

Status CodeMeaningSolution
200SuccessData successfully retrieved
401UnauthorizedCheck API credentials
403ForbiddenCheck permissions
404Not FoundEndpoint or Sales Channel not found
500Internal Server ErrorCheck server logs

Special Opening Hours

Database Structure

Special opening hours are stored in the same table, but with a special flag:

-- Special opening hours are stored as separate entries
-- with a special date instead of day of the week
ALTER TABLE `shopbite_business_hour` 
ADD COLUMN `special_date` DATE NULL AFTER `day_of_week`;

Management

  1. Navigate to ShopBite > Business Hours > Special Opening Hours
  2. Click Add new special opening hour
  3. Fill out the form:

Form Fields

FieldTypeDescriptionExample
Sales ChannelDropdownSelect sales channel"My Restaurant"
DateDate pickerDate of special opening2024-12-24
Opening TimeTime pickerSpecial opening time10:00
Closing TimeTime pickerSpecial closing time14:00
DescriptionTextOptional description"Christmas Eve - shortened opening hours"

API Query for Special Opening Hours

curl -X GET "https://your-shopware-domain.com/store-api/shopbite/business-hour?special=true" \
  -H "Authorization: Bearer YourAPIToken" \
  -H "sw-access-key: YourAccessKey"

Best Practices

1. Consistent Time Settings

  • Always use the 24-hour format (HH:MM)
  • Ensure that opening time < closing time
  • For overnight opening: opening time = 18:00, closing time = 02:00 (next day)

2. Sales Channel-specific Configuration

  • Each sales channel can have its own business hours
  • Ideal for multiple locations or services
  • Example: Restaurant vs. Catering Service

3. Performance Optimization

-- Indexes for better performance
CREATE INDEX `idx_sales_channel` ON `shopbite_business_hour` (`sales_channel_id`);
CREATE INDEX `idx_day_of_week` ON `shopbite_business_hour` (`day_of_week`);

-- For special opening hours
CREATE INDEX `idx_special_date` ON `shopbite_business_hour` (`special_date`);

4. Caching Strategy

# In config/packages/cache.yaml
framework:
    cache:
        pools:
            shopbite.business_hours:
                adapter: cache.adapter.redis
                default_lifetime: 3600  # 1 hour cache

Storefront Integration

JavaScript Example

// Fetch business hours
async function fetchBusinessHours(salesChannelId) {
  const response = await fetch(
    `/store-api/shopbite/business-hour?sales-channel-id=${salesChannelId}`,
    {
      headers: {
        'Authorization': `Bearer ${apiToken}`,
        'sw-access-key': accessKey
      }
    }
  );
  
  if (!response.ok) {
    throw new Error('Failed to fetch business hours');
  }
  
  return await response.json();
}

// Display business hours
function displayBusinessHours(hours) {
  const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  
  hours.data.forEach(hour => {
    const dayName = days[hour.dayOfWeek];
    console.log(`${dayName}: ${hour.openingTime} - ${hour.closingTime}`);
  });
}

// Example call
fetchBusinessHours('019a36f224b0704fb6835914050392f4')
  .then(displayBusinessHours)
  .catch(console.error);

Vue.js Component

<template>
  <div class="business-hours">
    <h3>Opening Hours</h3>
    <div v-for="hour in businessHours" :key="hour.id" class="hour-item">
      <span class="day">{{ getDayName(hour.dayOfWeek) }}</span>
      <span class="time">{{ hour.openingTime }} - {{ hour.closingTime }}</span>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      businessHours: [],
      days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
    };
  },
  
  async mounted() {
    await this.fetchBusinessHours();
  },
  
  methods: {
    getDayName(dayOfWeek) {
      return this.days[dayOfWeek];
    },
    
    async fetchBusinessHours() {
      try {
        const response = await this.$axios.get('/store-api/shopbite/business-hour');
        this.businessHours = response.data.data;
      } catch (error) {
        console.error('Failed to fetch business hours:', error);
      }
    }
  }
};
</script>

<style scoped>
.business-hours {
  margin: 20px 0;
  padding: 15px;
  background: #f5f5f5;
  border-radius: 8px;
}

.hour-item {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid #ddd;
}

.day {
  font-weight: bold;
}

.time {
  color: #666;
}
</style>

Troubleshooting and Debugging

Common Issues

Problem: Business hours are not displayed

Causes:

  • Cache issues
  • Incorrect Sales Channel ID
  • Database connection error

Solutions:

# Clear cache
bin/console cache:clear

# Check database
mysql -u shopware -p shopware -e "SELECT * FROM shopbite_business_hour;"

# Check Sales Channel ID
bin/console sales-channel:list

Problem: API delivers empty results

Causes:

  • No data in the database
  • Incorrect permissions
  • Incorrect filter parameters

Solutions:

# Check database
mysql -u shopware -p shopware -e "SELECT COUNT(*) FROM shopbite_business_hour;"

# Check API permissions
bin/console integration:list

# API test
curl -X GET "https://your-domain.com/store-api/shopbite/business-hour" -H "Authorization: Bearer YourToken"

Problem: Incorrect time format

Causes:

  • Incorrect time format in the database
  • Time zone issues

Solutions:

# Check time format
mysql -u shopware -p shopware -e "SELECT opening_time, closing_time FROM shopbite_business_hour LIMIT 5;"

# Check time zone
bin/console config:get Shopware.Core.SystemConfig.timezone

Next Steps