You are here

public function Reports::sales in Ubercart 8.4

Displays the sales summary report.

1 string reference to 'Reports::sales'
uc_report.routing.yml in uc_report/uc_report.routing.yml
uc_report/uc_report.routing.yml

File

uc_report/src/Controller/Reports.php, line 540

Class

Reports
Provides reports for Ubercart.

Namespace

Drupal\uc_report\Controller

Code

public function sales() {
  $order_statuses = uc_report_order_statuses();
  $date_day_of_month = date('j');
  $date_month = date('n');
  $month_start = mktime(0, 0, 0, $date_month, 1);
  $month_end = mktime(0, 0, 0, $date_month + 1, 1) - 1;
  $today_start = mktime(0, 0, 0);
  $today_end = mktime(23, 59, 59);

  // Build the report table header.
  $header = [
    $this
      ->t('Sales data'),
    $this
      ->t('Number of orders'),
    $this
      ->t('Total revenue'),
    $this
      ->t('Average order'),
  ];

  // Calculate and add today's sales summary to the report table.
  $today = self::get_sales($today_start);
  $rows[] = [
    Link::fromTextAndUrl($this
      ->t('Today, @date', [
      '@date' => \Drupal::service('date.formatter')
        ->format($today_start, 'uc_store'),
    ]), Url::fromUri('base:admin/store/orders/search/results/0/0/0/0/0/0/' . $today_start . '/' . $today_end))
      ->toString(),
    $today['total'],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $today['income'],
      ],
    ],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $today['average'],
      ],
    ],
  ];

  // Calculate and add yesterday's sales summary to the report table.
  $yesterday = self::get_sales($today_start - 86400);
  $rows[] = [
    Link::fromTextAndUrl($this
      ->t('Yesterday, @date', [
      '@date' => \Drupal::service('date.formatter')
        ->format($today_start - 86400, 'uc_store'),
    ]), Url::fromUri('base:admin/store/orders/search/results/0/0/0/0/0/0/' . ($today_start - 86400) . '/' . ($today_end - 86400)))
      ->toString(),
    $yesterday['total'],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $yesterday['income'],
      ],
    ],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $yesterday['average'],
      ],
    ],
  ];

  // Get the sales report for the month.
  $month = self::get_sales($month_start, 'month');
  $month_title = \Drupal::service('date.formatter')
    ->format($month_start, 'custom', 'M Y');

  // Add the month-to-date details to the report table.
  $rows[] = [
    Link::fromTextAndUrl($this
      ->t('Month-to-date, @month', [
      '@month' => $month_title,
    ]), Url::fromUri('base:admin/store/orders/search/results/0/0/0/0/0/0/' . $month_start . '/' . $month_end))
      ->toString(),
    $month['total'],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $month['income'],
      ],
    ],
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $month['average'],
      ],
    ],
  ];

  // Calculate the daily averages for the month.
  $daily_orders = round($month['total'] / $date_day_of_month, 2);
  $daily_revenue = round($month['income'] / $date_day_of_month, 2);
  if ($daily_orders > 0) {
    $daily_average = round($daily_revenue / $daily_orders, 2);
  }
  else {
    $daily_average = 0;
  }

  // Add the daily averages for the month to the report table.
  $rows[] = [
    $this
      ->t('Daily average for @month', [
      '@month' => $month_title,
    ]),
    $daily_orders,
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => $daily_revenue,
      ],
    ],
    '',
  ];

  // Store the number of days remaining in the month.
  $remaining_days = date('t') - $date_day_of_month;

  // Add the projected totals for the month to the report table.
  $rows[] = [
    $this
      ->t('Projected totals for @date', [
      '@date' => $month_title,
    ]),
    round($month['total'] + $daily_orders * $remaining_days, 2),
    [
      'data' => [
        '#theme' => 'uc_price',
        '#price' => round($month['income'] + $daily_revenue * $remaining_days, 2),
      ],
    ],
    '',
  ];

  // Add the sales data report table to the output.
  $build['sales'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'class' => [
        'uc-sales-table',
      ],
    ],
  ];

  // Build the header statistics table header.
  $header = [
    [
      'data' => $this
        ->t('Statistics'),
      'width' => '50%',
    ],
    '',
  ];
  $rows = [
    [
      [
        'data' => $this
          ->t('Grand total sales'),
      ],
      [
        'data' => [
          '#theme' => 'uc_price',
          '#price' => $this->database
            ->query("SELECT SUM(order_total) FROM {uc_orders} WHERE order_status IN (:statuses[])", [
            ':statuses[]' => $order_statuses,
          ])
            ->fetchField(),
        ],
      ],
    ],
    [
      [
        'data' => $this
          ->t('Customers total'),
      ],
      [
        'data' => $this->database
          ->query("SELECT COUNT(DISTINCT uid) FROM {uc_orders} WHERE order_status IN (:statuses[])", [
          ':statuses[]' => $order_statuses,
        ])
          ->fetchField(),
      ],
    ],
    [
      [
        'data' => $this
          ->t('New customers today'),
      ],
      [
        'data' => $this->database
          ->query("SELECT COUNT(DISTINCT uid) FROM {uc_orders} WHERE order_status IN (:statuses[]) AND :start <= created AND created <= :end", [
          ':statuses[]' => $order_statuses,
          ':start' => $today_start,
          ':end' => $today_end,
        ])
          ->fetchField(),
      ],
    ],
    [
      [
        'data' => $this
          ->t('Online customers'),
      ],
      [
        'data' => $this->database
          ->query("SELECT COUNT(DISTINCT s.uid) FROM {sessions} s LEFT JOIN {uc_orders} o ON s.uid = o.uid WHERE s.uid > 0 AND o.order_status IN (:statuses[])", [
          ':statuses[]' => $order_statuses,
        ])
          ->fetchField(),
      ],
    ],
  ];

  // Add the statistics table to the output.
  $build['statistics'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'width' => '100%',
      'class' => [
        'uc-sales-table',
      ],
    ],
  ];

  // Build the total orders by status table header.
  $header = [
    [
      'data' => $this
        ->t('Total orders by status'),
      'width' => '50%',
    ],
    '',
  ];
  $rows = [];
  $unknown = 0;

  // Loop through the order statuses with their total number of orders.

  /*
      $result = $this->database->query("SELECT s.order_status_id, order_status, s.title, s.weight, COUNT(o.order_status) as order_count FROM {uc_orders} o LEFT JOIN {uc_order_statuses} s ON s.order_status_id = o.order_status GROUP BY s.order_status_id, order_status, s.title, s.weight ORDER BY s.weight DESC");
      while ($status = $result->fetchAssoc()) {
        if (!empty($status['title'])) {
          // Add the total number of orders with this status to the table.
          $rows[] = [
            Link::fromTextAndUrl($status['title'], Url::fromUri('base:admin/store/orders/view', ['query' => ['order_status' => $status['order_status_id']]]))->toString(),
            $status['order_count'],
          ];
        }
        else {
          // Keep track of the count of orders with an unknown status.
          $unknown += $status['order_count'];
        }
      }
  */

  // Add the unknown status count to the table.
  if ($unknown > 0) {
    $rows[] = [
      $this
        ->t('Unknown status'),
      $unknown,
    ];
  }

  // Add the total orders by status table to the output.
  $build['orders'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'class' => [
        'uc-sales-table',
      ],
    ],
  ];
  return $build;
}