You are here

public function Reports::customSales in Ubercart 8.4

Displays the custom sales report form and table.

1 string reference to 'Reports::customSales'
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 792

Class

Reports
Provides reports for Ubercart.

Namespace

Drupal\uc_report\Controller

Code

public function customSales() {

  // Use default report parameters if we don't detect values in the URL.
  if (arg(5) == '') {
    $args = [
      'start_date' => mktime(0, 0, 0, date('n'), 1, date('Y') - 1),
      'end_date' => \Drupal::time()
        ->getRequestTime(),
      'length' => 'month',
      'status' => uc_report_order_statuses(),
      'detail' => FALSE,
    ];
  }
  else {
    $args = [
      'start_date' => arg(5),
      'end_date' => arg(6),
      'length' => arg(7),
      'status' => explode(',', arg(8)),
      'detail' => arg(9),
    ];
  }

  // Build the header for the report table.
  $header = [
    $this
      ->t('Date'),
    $this
      ->t('Number of orders'),
    $this
      ->t('Products sold'),
    $this
      ->t('Total revenue'),
  ];

  // Build the header to the CSV export.
  $csv_rows = [
    [
      $this
        ->t('Date'),
      $this
        ->t('Number of orders'),
      $this
        ->t('Products sold'),
      $this
        ->t('Total revenue'),
    ],
  ];

  // Grab the subreports based on the date range and the report breakdown.
  $subreports = $this
    ->subreport_intervals($args['start_date'], $args['end_date'], $args['length']);

  // Loop through the subreports and build the report table.
  foreach ($subreports as $subreport) {
    $product_data = '';
    $product_csv = '';

    // Create the date title for the subreport.
    if ($args['length'] == 'day') {
      $date = \Drupal::service('date.formatter')
        ->format($subreport['start'], 'uc_store');
    }
    else {
      $date = \Drupal::service('date.formatter')
        ->format($subreport['start'], 'uc_store') . ' - ' . \Drupal::service('date.formatter')
        ->format($subreport['end'], 'uc_store');
    }

    // Build the order data for the subreport.
    $result = $this->database
      ->query("SELECT COUNT(*) as count, title FROM {uc_orders} LEFT JOIN {uc_order_statuses} ON order_status_id = order_status WHERE :start <= created AND created <= :end AND order_status IN (:statuses[]) GROUP BY order_status, {uc_order_statuses}.title, {uc_order_statuses}.weight ORDER BY weight ASC", [
      ':statuses[]' => $args['status'],
      ':start' => $subreport['start'],
      ':end' => $subreport['end'],
    ]);
    $statuses = [];

    // Put the order counts into an array by status.
    foreach ($result as $status) {
      $statuses[] = $this
        ->t('@count - @title', [
        '@count' => $status->count,
        '@title' => $status->title,
      ]);
    }
    $order_data = implode('<br />', $statuses);
    $order_csv = implode("\n", $statuses);

    // Build the product data for the subreport.
    if ($args['detail']) {

      // Grab the detailed product breakdown if selected.
      $result = $this->database
        ->query("SELECT SUM(op.qty) as count, n.title, n.nid FROM {uc_order_products} op LEFT JOIN {uc_orders} o ON o.order_id = op.order_id LEFT JOIN {node_field_data} n ON n.nid = op.nid WHERE :start <= o.created AND o.created <= :end AND o.order_status IN (:statuses[]) GROUP BY n.nid ORDER BY count DESC, n.title ASC", [
        ':statuses[]' => $args['status'],
        ':start' => $subreport['start'],
        ':end' => $subreport['end'],
      ]);
      foreach ($result as $product_breakdown) {
        $product_data .= $product_breakdown->count . ' x ' . Link::createFromRoute($product_breakdown->title, 'entity.node.canonical', [
          'node' => $product_breakdown->nid,
        ])
          ->toString() . "<br />\n";
        $product_csv .= $product_breakdown->count . ' x ' . $product_breakdown->title . "\n";
      }
    }
    else {

      // Otherwise just display the total number of products sold.
      $product_data = $this->database
        ->query("SELECT SUM(qty) FROM {uc_orders} o LEFT JOIN {uc_order_products} op ON o.order_id = op.order_id WHERE :start <= created AND created <= :end AND order_status IN (:statuses[])", [
        ':statuses[]' => $args['status'],
        ':start' => $subreport['start'],
        ':end' => $subreport['end'],
      ])
        ->fetchField();
      $product_csv = $product_data;
    }

    // Tally up the revenue from the orders.
    $revenue_count = $this->database
      ->query("SELECT SUM(order_total) FROM {uc_orders} WHERE :start <= created AND created <= :end AND order_status IN (:statuses[])", [
      ':statuses[]' => $args['status'],
      ':start' => $subreport['start'],
      ':end' => $subreport['end'],
    ])
      ->fetchField();

    // Add the subreport's row to the report table.
    $rows[] = [
      $date,
      empty($order_data) ? '0' : $order_data,
      empty($product_data) ? '0' : $product_data,
      uc_currency_format($revenue_count),
    ];

    // Add the data to the CSV export.
    $csv_rows[] = [
      $date,
      empty($order_csv) ? '0' : $order_csv,
      empty($product_csv) ? '0' : $product_csv,
      $revenue_count,
    ];
  }

  // Calculate the totals for the report.
  $order_total = $this->database
    ->query("SELECT COUNT(*) FROM {uc_orders} WHERE :start <= created AND created <= :end AND order_status IN (:statuses[])", [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ])
    ->fetchField();
  $product_total = $this->database
    ->query("SELECT SUM(qty) FROM {uc_orders} o LEFT JOIN {uc_order_products} op ON o.order_id = op.order_id WHERE :start <= created AND created <= :end AND order_status IN (:statuses[])", [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ])
    ->fetchField();
  $revenue_total = $this->database
    ->query("SELECT SUM(order_total) FROM {uc_orders} WHERE :start <= created AND created <= :end AND order_status IN (:statuses[])", [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ])
    ->fetchField();

  // Add the total row to the report table.
  $rows[] = [
    $this
      ->t('Total'),
    $order_total,
    $product_total,
    uc_currency_format($revenue_total),
  ];

  // Add the total data to the CSV export.
  $csv_rows[] = [
    $this
      ->t('Total'),
    $order_total,
    $product_total,
    $revenue_total,
  ];

  // Cache the CSV export.
  $csv_data = $this
    ->store_csv('uc_sales_custom', $csv_rows);

  // Build the page output holding the form, table, and CSV export link.
  $build['form'] = $this
    ->formBuilder()
    ->getForm('uc_report_sales_custom_form', $args, $args['status']);
  $build['report'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'width' => '100%',
      'class' => [
        'uc-sales-table',
      ],
    ],
  ];
  $build['links'] = [
    '#prefix' => '<div class="uc-reports-links">',
    '#suffix' => '</div>',
  ];
  $build['links']['export_csv'] = [
    '#markup' => Link::createFromRoute($this
      ->t('Export to CSV file.'), 'uc_report.getcsv', [
      'report_id' => $csv_data['report'],
      'user_id' => $csv_data['user'],
    ])
      ->toString(),
  ];
  return $build;
}