You are here

public function Reports::customProducts in Ubercart 8.4

Displays the custom product report.

1 string reference to 'Reports::customProducts'
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 361

Class

Reports
Provides reports for Ubercart.

Namespace

Drupal\uc_report\Controller

Code

public function customProducts() {
  $views_column = $this
    ->moduleHandler()
    ->moduleExists('statistics') && $this
    ->config('statistics.settings')
    ->get('count_content_views');
  $page = isset($_GET['page']) ? intval($_GET['page']) : 0;
  $page_size = isset($_GET['nopage']) ? UC_REPORT_MAX_RECORDS : $this
    ->config('uc_report.settings')
    ->get('table_size');
  $rows = [];
  $csv_rows = [];

  // Hard code the ignore of the product kit for this report.
  $ignored_types = [
    'product_kit',
  ];

  // Build an array of valid product types to include on the report.
  $product_types = [];
  foreach (uc_product_types() as $type) {

    // Pass over any ignored types.
    if (!in_array($type, $ignored_types)) {
      $product_types[] = $type;
    }
  }

  // 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(),
      'status' => uc_report_order_statuses(),
    ];
  }
  else {
    $args = [
      'start_date' => arg(5),
      'end_date' => arg(6),
      'status' => explode(',', arg(7)),
    ];
  }
  $query = $this->database
    ->select('node', 'n', [
    'fetch' => \PDO::FETCH_ASSOC,
  ])
    ->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender')
    ->extend('Drupal\\Core\\Database\\Query\\TableSortExtender')
    ->limit($page_size)
    ->fields('n', [
    'nid',
    'title',
  ])
    ->condition('type', $product_types, 'IN')
    ->groupBy('n.nid');
  $query
    ->addExpression("(SELECT SUM(qty) FROM {uc_order_products} p LEFT JOIN {uc_orders} o ON p.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p.nid = n.nid AND o.created >= :start AND o.created <= :end)", 'sold', [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ]);
  $query
    ->addExpression("(SELECT (SUM(p2.price * p2.qty)) FROM {uc_order_products} p2 LEFT JOIN {uc_orders} o ON p2.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p2.nid = n.nid AND o.created >= :start AND o.created <= :end)", 'revenue', [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ]);
  $query
    ->addExpression("(SELECT (SUM(p3.price * p3.qty) - SUM(p3.cost * p3.qty)) FROM {uc_order_products} p3 LEFT JOIN {uc_orders} o ON p3.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p3.nid = n.nid AND o.created >= :start AND o.created <= :end)", 'gross', [
    ':statuses[]' => $args['status'],
    ':start' => $args['start_date'],
    ':end' => $args['end_date'],
  ]);
  $header = [
    [
      'data' => $this
        ->t('#'),
    ],
    [
      'data' => $this
        ->t('Product'),
      'field' => 'n.title',
    ],
    [
      'data' => $this
        ->t('Sold'),
      'field' => 'sold',
    ],
    [
      'data' => $this
        ->t('Revenue'),
      'field' => 'revenue',
      'sort' => 'desc',
    ],
    [
      'data' => $this
        ->t('Gross'),
      'field' => 'gross',
    ],
  ];
  $csv_rows[] = [
    $this
      ->t('#'),
    $this
      ->t('Product'),
    $this
      ->t('Sold'),
    $this
      ->t('Revenue'),
    $this
      ->t('Gross'),
  ];
  if ($views_column) {
    $header[] = [
      'data' => $this
        ->t('Views'),
      'field' => 'nc.totalcount',
    ];
    $csv_rows[0][] = $this
      ->t('Views');
  }
  $query
    ->orderByHeader($header);
  if ($views_column) {
    $query
      ->leftJoin('node_counter', 'c', 'n.nid = c.nid');
    $query
      ->addField('c', 'totalcount');
  }
  $products = $query
    ->execute();
  foreach ($products as $product) {
    $row_cell = $page * $this
      ->config('uc_report.settings')
      ->get('table_size') + count($rows) + 1;
    $product_cell = Link::createFromRoute($product['title'], 'entity.node.canonical', [
      'node' => $product['nid'],
    ])
      ->toString();
    $product_csv = $product['title'];
    $sold_cell = empty($product['sold']) ? 0 : $product['sold'];
    $sold_csv = $sold_cell;
    $revenue_csv = empty($product['revenue']) ? 0 : $product['revenue'];
    $revenue_cell = uc_currency_format($revenue_csv);
    $gross_csv = empty($product['gross']) ? 0 : $product['gross'];
    $gross_cell = uc_currency_format($gross_csv);
    if ($this
      ->moduleHandler()
      ->moduleExists('uc_attribute')) {
      $breakdown_product = $breakdown_sold = $breakdown_revenue = $breakdown_gross = '';

      // Get the SKUs from this product.
      $models = $this
        ->product_get_skus($product['nid']);

      // Add the product breakdown rows
      foreach ($models as $model) {
        $sold = $this->database
          ->query("SELECT SUM(qty) FROM {uc_order_products} p LEFT JOIN {uc_orders} o ON p.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p.model = :model AND p.nid = :nid AND o.created >= :start AND o.created <= :end", [
          ':statuses[]' => $args['status'],
          ':start' => $args['start_date'],
          ':end' => $args['end_date'],
          ':model' => $model,
          ':nid' => $product['nid'],
        ])
          ->fetchField();
        $sold = empty($sold) ? 0 : $sold;
        $revenue = $this->database
          ->query("SELECT SUM(p.price * p.qty) FROM {uc_order_products} p LEFT JOIN {uc_orders} o ON p.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p.model = :model AND p.nid = :nid AND o.created >= :start AND o.created <= :end", [
          ':statuses[]' => $args['status'],
          ':start' => $args['start_date'],
          ':end' => $args['end_date'],
          ':model' => $model,
          ':nid' => $product['nid'],
        ])
          ->fetchField();
        $revenue = empty($revenue) ? 0 : $revenue;
        $gross = $this->database
          ->query("SELECT (SUM(p.price * p.qty) - SUM(p.cost * p.qty)) FROM {uc_order_products} p LEFT JOIN {uc_orders} o ON p.order_id = o.order_id WHERE o.order_status IN (:statuses[]) AND p.model = :model AND p.nid = :nid AND o.created >= :start AND o.created <= :end", [
          ':statuses[]' => $args['status'],
          ':start' => $args['start_date'],
          ':end' => $args['end_date'],
          ':model' => $model,
          ':nid' => $product['nid'],
        ])
          ->fetchField();
        $gross = empty($gross) ? 0 : $gross;
        $breakdown_product .= "<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{$model}";
        $product_csv .= "\n     {$model}";
        $breakdown_sold .= "<br />" . $sold;
        $sold_csv .= "\n     " . $sold;
        $breakdown_revenue .= "<br />" . uc_currency_format($revenue);
        $revenue_csv .= "\n     " . $revenue;
        $breakdown_gross .= "<br />" . uc_currency_format($gross);
        $gross_csv .= "\n     " . $gross;
      }
      $product_cell = $product_cell . $breakdown_product;
      $sold_cell = '<strong>' . $sold_cell . '</strong>' . $breakdown_sold;
      $revenue_cell = '<strong>' . $revenue_cell . '</strong>' . $breakdown_revenue;
      $gross_cell = '<strong>' . $gross_cell . '</strong>' . $breakdown_gross;
    }
    if ($views_column) {
      $views = empty($product['totalcount']) ? 0 : $product['totalcount'];
      $rows[] = [
        [
          'data' => $row_cell,
        ],
        [
          'data' => $product_cell,
        ],
        [
          'data' => $sold_cell,
        ],
        [
          'data' => $revenue_cell,
        ],
        [
          'data' => $gross_cell,
        ],
        [
          'data' => $views,
        ],
      ];
      $csv_rows[] = [
        $row_cell,
        $product_csv,
        $sold_csv,
        $revenue_csv,
        $gross_csv,
        $views,
      ];
    }
    else {
      $rows[] = [
        [
          'data' => $row_cell,
        ],
        [
          'data' => $product_cell,
        ],
        [
          'data' => $sold_cell,
        ],
        [
          'data' => $revenue_cell,
        ],
        [
          'data' => $gross_cell,
        ],
      ];
      $csv_rows[] = [
        $row_cell,
        $product_csv,
        $sold_csv,
        $revenue_csv,
        $gross_csv,
      ];
    }
  }
  $csv_data = $this
    ->store_csv('uc_products', $csv_rows);

  // Build the page output holding the form, table, and CSV export link.
  $build['form'] = $this
    ->formBuilder()
    ->getForm('uc_report_products_custom_form', $args);
  $build['report'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'width' => '100%',
      'class' => [
        'uc-sales-table',
      ],
    ],
    '#empty' => $this
      ->t('No products found'),
  ];
  $build['pager'] = [
    '#type' => 'pager',
  ];
  $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(),
    '#suffix' => '&nbsp;&nbsp;&nbsp;',
  ];
  if (isset($_GET['nopage'])) {
    $build['links']['toggle_pager'] = [
      '#markup' => Link::createFromRoute($this
        ->t('Show paged records'), 'uc_reports.custom_report')
        ->toString(),
    ];
  }
  else {
    $build['links']['toggle_pager'] = [
      '#markup' => Link::createFromRoute($this
        ->t('Show all records'), 'uc_reports.custom_report', [
        'query' => [
          'nopage' => '1',
        ],
      ])
        ->toString(),
    ];
  }
  $build['instructions'] = [
    '#markup' => '<small>*' . $this
      ->t('Make sure %setting_name is set to %state in the <a href=":url">access log settings page</a> to enable views column.', [
      '%setting_name' => 'count content views',
      '%state' => 'enabled',
      ':url' => Url::fromUri('base:admin/config/system/statistics', [
        'query' => [
          'destination' => 'admin/store/reports/products/custom',
        ],
      ])
        ->toString(),
    ]) . '</small>',
  ];
  return $build;
}