私たちの結論は、このファイルが質問に答えるということでした。
<?php
class Mage_Reports_Model_Resource_Order_Collection extends Mage_Sales_Model_Resource_Order_Collection
{
/**
* Is live
*
* @var boolean
*/
protected $_isLive = false;
/**
* Check range for live mode
*
* @param unknown_type $range
* @return Mage_Reports_Model_Resource_Order_Collection
*/
public function checkIsLive($range)
{
$this->_isLive = (bool)!Mage::getStoreConfig('sales/dashboard/use_aggregated_data');
return $this;
}
/**
* Retrieve is live flag for rep
*
* @return boolean
*/
public function isLive()
{
return $this->_isLive;
}
public function prepareSummary($range, $customStart, $customEnd, $isFilter = 0)
{
$this->checkIsLive($range);
if ($this->_isLive) {
$this->_prepareSummaryLive($range, $customStart, $customEnd, $isFilter);
} else {
$this->_prepareSummaryAggregated($range, $customStart, $customEnd, $isFilter);
}
return $this;
}
protected function _prepareSummaryLive($range, $customStart, $customEnd, $isFilter = 0)
{
$this->setMainTable('sales/order');
$adapter = $this->getConnection();
/**
* Reset all columns, because result will group only by 'created_at' field
*/
$this->getSelect()->reset(Zend_Db_Select::COLUMNS);
$expression = sprintf('%s - %s - %s - (%s - %s - %s)',
$adapter->getIfNullSql('main_table.base_total_invoiced', 'main_table.base_grand_total'),
$adapter->getIfNullSql('main_table.base_tax_invoiced', 'main_table.base_tax_amount'),
$adapter->getIfNullSql('main_table.base_shipping_invoiced', 'main_table.base_shipping_amount'),
$adapter->getIfNullSql('main_table.base_total_refunded', 0),
$adapter->getIfNullSql('main_table.base_tax_refunded', 0),
$adapter->getIfNullSql('main_table.base_shipping_refunded', 0)
);
if ($isFilter == 0) {
$this->getSelect()->columns(array(
'revenue' => new Zend_Db_Expr(
sprintf('SUM((%s) * %s)', $expression,
$adapter->getIfNullSql('main_table.base_to_global_rate', 0)
)
)
));
} else {
$this->getSelect()->columns(array(
'revenue' => new Zend_Db_Expr(sprintf('SUM(%s)', $expression))
));
}
$dateRange = $this->getDateRange($range, $customStart, $customEnd);
$tzRangeOffsetExpression = $this->_getTZRangeOffsetExpression(
$range, 'created_at', $dateRange['from'], $dateRange['to']
);
$this->getSelect()
->columns(array(
'quantity' => 'COUNT(main_table.entity_id)',
'range' => $tzRangeOffsetExpression,
))
->where('main_table.state NOT IN (?)', array(
Mage_Sales_Model_Order::STATE_HOLDED,
Mage_Sales_Model_Order::STATE_CANCELED)
)
->order('range', Zend_Db_Select::SQL_ASC)
->group($tzRangeOffsetExpression);
$this->addFieldToFilter('created_at', $dateRange);
return $this;
}
protected function _prepareSummaryAggregated($range, $customStart, $customEnd)
{
$this->setMainTable('sales/order_aggregated_created');
/**
* Reset all columns, because result will group only by 'created_at' field
*/
$this->getSelect()->reset(Zend_Db_Select::COLUMNS);
$rangePeriod = $this->_getRangeExpressionForAttribute($range, 'main_table.period');
$tableName = $this->getConnection()->quoteIdentifier('main_table.period');
$rangePeriod2 = str_replace($tableName, "MIN($tableName)", $rangePeriod);
$this->getSelect()->columns(array(
'revenue' => 'SUM(main_table.total_revenue_amount)',
'quantity' => 'SUM(main_table.orders_count)',
'range' => $rangePeriod2,
))
->order('range')
->group($rangePeriod);
$this->getSelect()->where(
$this->_getConditionSql('main_table.period', $this->getDateRange($range, $customStart, $customEnd))
);
$statuses = Mage::getSingleton('sales/config')
->getOrderStatusesForState(Mage_Sales_Model_Order::STATE_CANCELED);
if (empty($statuses)) {
$statuses = array(0);
}
$this->addFieldToFilter('main_table.order_status', array('nin' => $statuses));
return $this;
}
protected function _getRangeExpression($range)
{
switch ($range)
{
case '24h':
$expression = $this->getConnection()->getConcatSql(array(
$this->getConnection()->getDateFormatSql('{{attribute}}', '%Y-%m-%d %H:'),
$this->getConnection()->quote('00')
));
break;
case '7d':
case '1m':
$expression = $this->getConnection()->getDateFormatSql('{{attribute}}', '%Y-%m-%d');
break;
case '1y':
case '2y':
case 'custom':
default:
$expression = $this->getConnection()->getDateFormatSql('{{attribute}}', '%Y-%m');
break;
}
return $expression;
}
protected function _getRangeExpressionForAttribute($range, $attribute)
{
$expression = $this->_getRangeExpression($range);
return str_replace('{{attribute}}', $this->getConnection()->quoteIdentifier($attribute), $expression);
}
protected function _getTZRangeOffsetExpression($range, $attribute, $from = null, $to = null)
{
return str_replace(
'{{attribute}}',
Mage::getResourceModel('sales/report_order')
->getStoreTZOffsetQuery($this->getMainTable(), $attribute, $from, $to),
$this->_getRangeExpression($range)
);
}
protected function _getTZRangeExpressionForAttribute($range, $attribute, $tzFrom = '+00:00', $tzTo = null)
{
if (null == $tzTo) {
$tzTo = Mage::app()->getLocale()->storeDate()->toString(Zend_Date::GMT_DIFF_SEP);
}
$adapter = $this->getConnection();
$expression = $this->_getRangeExpression($range);
$attribute = $adapter->quoteIdentifier($attribute);
$periodExpr = $adapter->getDateAddSql($attribute, $tzTo, Varien_Db_Adapter_Interface::INTERVAL_HOUR);
return str_replace('{{attribute}}', $periodExpr, $expression);
}
public function getDateRange($range, $customStart, $customEnd, $returnObjects = false)
{
$dateEnd = Mage::app()->getLocale()->date();
$dateStart = clone $dateEnd;
// go to the end of a day
$dateEnd->setHour(23);
$dateEnd->setMinute(59);
$dateEnd->setSecond(59);
$dateStart->setHour(0);
$dateStart->setMinute(0);
$dateStart->setSecond(0);
switch ($range)
{
case '24h':
$dateEnd = Mage::app()->getLocale()->date();
$dateEnd->addHour(1);
$dateStart = clone $dateEnd;
$dateStart->subDay(1);
break;
case '7d':
// substract 6 days we need to include
// only today and not hte last one from range
$dateStart->subDay(6);
break;
case '1m':
$dateStart->setDay(Mage::getStoreConfig('reports/dashboard/mtd_start'));
break;
case 'custom':
$dateStart = $customStart ? $customStart : $dateEnd;
$dateEnd = $customEnd ? $customEnd : $dateEnd;
break;
case '1y':
case '2y':
$startMonthDay = explode(',', Mage::getStoreConfig('reports/dashboard/ytd_start'));
$startMonth = isset($startMonthDay[0]) ? (int)$startMonthDay[0] : 1;
$startDay = isset($startMonthDay[1]) ? (int)$startMonthDay[1] : 1;
$dateStart->setMonth($startMonth);
$dateStart->setDay($startDay);
if ($range == '2y') {
$dateStart->subYear(1);
}
break;
}
$dateStart->setTimezone('Etc/UTC');
$dateEnd->setTimezone('Etc/UTC');
if ($returnObjects) {
return array($dateStart, $dateEnd);
} else {
return array('from' => $dateStart, 'to' => $dateEnd, 'datetime' => true);
}
}
public function addItemCountExpr()
{
$this->getSelect()->columns(array('items_count' => 'total_item_count'), 'main_table');
return $this;
}
public function calculateTotals($isFilter = 0)
{
if ($this->isLive()) {
$this->_calculateTotalsLive($isFilter);
} else {
$this->_calculateTotalsAggregated($isFilter);
}
return $this;
}
protected function _calculateTotalsLive($isFilter = 0)
{
$this->setMainTable('sales/order');
$this->removeAllFieldsFromSelect();
$adapter = $this->getConnection();
$baseTotalInvoiced = $adapter->getIfNullSql('main_table.base_total_invoiced', 'main_table.base_grand_total'); // This will check if there is no invoice it will calculate based on the grand totals ( so when you generate and invoice u will have no issues with the numbers also )
$baseTotalRefunded = $adapter->getIfNullSql('main_table.base_total_refunded', 0);
$baseTaxInvoiced = $adapter->getIfNullSql('main_table.base_tax_invoiced', 'main_table.base_tax_amount'); // Same here for taxes
$baseTaxRefunded = $adapter->getIfNullSql('main_table.base_tax_refunded', 0);
$baseShippingInvoiced = $adapter->getIfNullSql('main_table.base_shipping_invoiced', 'main_table.base_shipping_amount'); // Same here for shipping
$baseShippingRefunded = $adapter->getIfNullSql('main_table.base_shipping_refunded', 0);
$revenueExp = sprintf('%s - %s - %s - (%s - %s - %s)',
$baseTotalInvoiced,
$baseTaxInvoiced,
$baseShippingInvoiced,
$baseTotalRefunded,
$baseTaxRefunded,
$baseShippingRefunded
);
$taxExp = sprintf('%s - %s', $baseTaxInvoiced, $baseTaxRefunded);
$shippingExp = sprintf('%s - %s', $baseShippingInvoiced, $baseShippingRefunded);
if ($isFilter == 0) {
$rateExp = $adapter->getIfNullSql('main_table.base_to_global_rate', 0);
$this->getSelect()->columns(
array(
'revenue' => new Zend_Db_Expr(sprintf('SUM((%s) * %s)', $revenueExp, $rateExp)),
'tax' => new Zend_Db_Expr(sprintf('SUM((%s) * %s)', $taxExp, $rateExp)),
'shipping' => new Zend_Db_Expr(sprintf('SUM((%s) * %s)', $shippingExp, $rateExp))
)
);
} else {
$this->getSelect()->columns(
array(
'revenue' => new Zend_Db_Expr(sprintf('SUM(%s)', $revenueExp)),
'tax' => new Zend_Db_Expr(sprintf('SUM(%s)', $taxExp)),
'shipping' => new Zend_Db_Expr(sprintf('SUM(%s)', $shippingExp))
)
);
}
$this->getSelect()->columns(array(
'quantity' => 'COUNT(main_table.entity_id)'
))
->where('main_table.state NOT IN (?)', array(
Mage_Sales_Model_Order::STATE_HOLDED,
Mage_Sales_Model_Order::STATE_CANCELED)
);
return $this;
}
protected function _calculateTotalsAggregated($isFilter = 0)
{
$this->setMainTable('sales/order_aggregated_created');
$this->removeAllFieldsFromSelect();
$this->getSelect()->columns(array(
'revenue' => 'SUM(main_table.total_revenue_amount)',
'tax' => 'SUM(main_table.total_tax_amount_actual)',
'shipping' => 'SUM(main_table.total_shipping_amount_actual)',
'quantity' => 'SUM(orders_count)',
));
$statuses = Mage::getSingleton('sales/config')
->getOrderStatusesForState(Mage_Sales_Model_Order::STATE_CANCELED);
if (empty($statuses)) {
$statuses = array(0);
}
$this->getSelect()->where('main_table.order_status NOT IN(?)', $statuses);
return $this;
}
public function calculateSales($isFilter = 0)
{
$statuses = Mage::getSingleton('sales/config')
->getOrderStatusesForState(Mage_Sales_Model_Order::STATE_CANCELED);
if (empty($statuses)) {
$statuses = array(0);
}
$adapter = $this->getConnection();
if (Mage::getStoreConfig('sales/dashboard/use_aggregated_data')) {
$this->setMainTable('sales/order_aggregated_created');
$this->removeAllFieldsFromSelect();
$averageExpr = $adapter->getCheckSql(
'SUM(main_table.orders_count) > 0',
'SUM(main_table.total_revenue_amount)/SUM(main_table.orders_count)',
0);
$this->getSelect()->columns(array(
'lifetime' => 'SUM(main_table.total_revenue_amount)',
'average' => $averageExpr
));
if (!$isFilter) {
$this->addFieldToFilter('store_id',
array('eq' => Mage::app()->getStore(Mage_Core_Model_Store::ADMIN_CODE)->getId())
);
}
$this->getSelect()->where('main_table.order_status NOT IN(?)', $statuses);
} else {
$this->setMainTable('sales/order');
$this->removeAllFieldsFromSelect();
$expr = sprintf('%s - %s - %s - (%s - %s - %s)',
$adapter->getIfNullSql('main_table.base_total_invoiced', 'main_table.base_grand_total'),
$adapter->getIfNullSql('main_table.base_tax_invoiced', 'main_table.base_tax_amount'),
$adapter->getIfNullSql('main_table.base_shipping_invoiced', 'main_table.base_shipping_amount'),
$adapter->getIfNullSql('main_table.base_total_refunded', 0),
$adapter->getIfNullSql('main_table.base_tax_refunded', 0),
$adapter->getIfNullSql('main_table.base_shipping_refunded', 0)
);
if ($isFilter == 0) {
$expr = '(' . $expr . ') * main_table.base_to_global_rate';
}
$this->getSelect()
->columns(array(
'lifetime' => "SUM({$expr})",
'average' => "AVG({$expr})"
))
->where('main_table.status NOT IN(?)', $statuses)
->where('main_table.state NOT IN(?)', array(
Mage_Sales_Model_Order::STATE_HOLDED,
Mage_Sales_Model_Order::STATE_CANCELED)
);
}
return $this;
}
public function setDateRange($from, $to)
{
$this->_reset()
->addFieldToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter('state', array('neq' => Mage_Sales_Model_Order::STATE_CANCELED))
->getSelect()
->columns(array('orders' => 'COUNT(DISTINCT(main_table.entity_id))'))
->group('entity_id');
$this->getSelect()->columns(array(
'items' => 'SUM(main_table.total_qty_ordered)')
);
return $this;
}
public function setStoreIds($storeIds)
{
$adapter = $this->getConnection();
$baseSubtotalInvoiced = $adapter->getIfNullSql('main_table.base_subtotal_invoiced', 0);
$baseDiscountRefunded = $adapter->getIfNullSql('main_table.base_discount_refunded', 0);
$baseSubtotalRefunded = $adapter->getIfNullSql('main_table.base_subtotal_refunded', 0);
$baseDiscountInvoiced = $adapter->getIfNullSql('main_table.base_discount_invoiced', 0);
$baseTotalInvocedCost = $adapter->getIfNullSql('main_table.base_total_invoiced_cost', 0);
if ($storeIds) {
$this->getSelect()->columns(array(
'subtotal' => 'SUM(main_table.base_subtotal)',
'tax' => 'SUM(main_table.base_tax_amount)',
'shipping' => 'SUM(main_table.base_shipping_amount)',
'discount' => 'SUM(main_table.base_discount_amount)',
'total' => 'SUM(main_table.base_grand_total)',
'invoiced' => 'SUM(main_table.base_total_paid)',
'refunded' => 'SUM(main_table.base_total_refunded)',
'profit' => "SUM($baseSubtotalInvoiced) "
. "+ SUM({$baseDiscountRefunded}) - SUM({$baseSubtotalRefunded}) "
. "- SUM({$baseDiscountInvoiced}) - SUM({$baseTotalInvocedCost})"
));
} else {
$this->getSelect()->columns(array(
'subtotal' => 'SUM(main_table.base_subtotal * main_table.base_to_global_rate)',
'tax' => 'SUM(main_table.base_tax_amount * main_table.base_to_global_rate)',
'shipping' => 'SUM(main_table.base_shipping_amount * main_table.base_to_global_rate)',
'discount' => 'SUM(main_table.base_discount_amount * main_table.base_to_global_rate)',
'total' => 'SUM(main_table.base_grand_total * main_table.base_to_global_rate)',
'invoiced' => 'SUM(main_table.base_total_paid * main_table.base_to_global_rate)',
'refunded' => 'SUM(main_table.base_total_refunded * main_table.base_to_global_rate)',
'profit' => "SUM({$baseSubtotalInvoiced} * main_table.base_to_global_rate) "
. "+ SUM({$baseDiscountRefunded} * main_table.base_to_global_rate) "
. "- SUM({$baseSubtotalRefunded} * main_table.base_to_global_rate) "
. "- SUM({$baseDiscountInvoiced} * main_table.base_to_global_rate) "
. "- SUM({$baseTotalInvocedCost} * main_table.base_to_global_rate)"
));
}
return $this;
}
/**
* Add group By customer attribute
*
* @return Mage_Reports_Model_Resource_Order_Collection
*/
public function groupByCustomer()
{
$this->getSelect()
->where('main_table.customer_id IS NOT NULL')
->group('main_table.customer_id');
/*
* Allow Analytic functions usage
*/
$this->_useAnalyticFunction = true;
return $this;
}
/**
* Join Customer Name (concat)
*
* @param string $alias
* @return Mage_Reports_Model_Resource_Order_Collection
*/
public function joinCustomerName($alias = 'name')
{
$fields = array('main_table.customer_firstname', 'main_table.customer_lastname');
$fieldConcat = $this->getConnection()->getConcatSql($fields, ' ');
$this->getSelect()->columns(array($alias => $fieldConcat));
return $this;
}
/**
* Add Order count field to select
*
* @return Mage_Reports_Model_Resource_Order_Collection
*/
public function addOrdersCount()
{
$this->addFieldToFilter('state', array('neq' => Mage_Sales_Model_Order::STATE_CANCELED));
$this->getSelect()
->columns(array('orders_count' => 'COUNT(main_table.entity_id)'));
return $this;
}
public function addRevenueToSelect($convertCurrency = false)
{
if ($convertCurrency) {
$this->getSelect()->columns(array(
'revenue' => '(main_table.base_grand_total * main_table.base_to_global_rate)'
));
} else {
$this->getSelect()->columns(array(
'revenue' => 'base_grand_total'
));
}
return $this;
}
public function addSumAvgTotals($storeId = 0)
{
$adapter = $this->getConnection();
$baseSubtotalRefunded = $adapter->getIfNullSql('main_table.base_subtotal_refunded', 0);
$baseSubtotalCanceled = $adapter->getIfNullSql('main_table.base_subtotal_canceled', 0);
$baseDiscountCanceled = $adapter->getIfNullSql('main_table.base_discount_canceled', 0);
/**
* calculate average and total amount
*/
$expr = ($storeId == 0)
? "(main_table.base_subtotal -
{$baseSubtotalRefunded} - {$baseSubtotalCanceled} - ABS(main_table.base_discount_amount) -
{$baseDiscountCanceled}) * main_table.base_to_global_rate"
: "main_table.base_subtotal - {$baseSubtotalCanceled} - {$baseSubtotalRefunded} -
ABS(main_table.base_discount_amount) - {$baseDiscountCanceled}";
$this->getSelect()
->columns(array('orders_avg_amount' => "AVG({$expr})"))
->columns(array('orders_sum_amount' => "SUM({$expr})"));
return $this;
}
public function orderByTotalAmount($dir = self::SORT_ORDER_DESC)
{
$this->getSelect()->order('orders_sum_amount ' . $dir);
return $this;
}
public function orderByOrdersCount($dir = self::SORT_ORDER_DESC)
{
$this->getSelect()->order('orders_count ' . $dir);
return $this;
}
public function orderByCustomerRegistration($dir = self::SORT_ORDER_DESC)
{
$this->setOrder('customer_id', $dir);
return $this;
}
public function orderByCreatedAt($dir = self::SORT_ORDER_DESC)
{
$this->setOrder('created_at', $dir);
return $this;
}
public function getSelectCountSql()
{
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->reset(Zend_Db_Select::HAVING);
$countSelect->columns("COUNT(DISTINCT main_table.entity_id)");
return $countSelect;
}
protected function _initInitialFieldsToSelect()
{
// No fields should be initialized
return $this;
}
public function addCreateAtPeriodFilter($period)
{
list($from, $to) = $this->getDateRange($period, 0, 0, true);
$this->checkIsLive($period);
if ($this->isLive()) {
$fieldToFilter = 'created_at';
} else {
$fieldToFilter = 'period';
}
$this->addFieldToFilter($fieldToFilter, array(
'from' => $from->toString(Varien_Date::DATETIME_INTERNAL_FORMAT),
'to' => $to->toString(Varien_Date::DATETIME_INTERNAL_FORMAT)
));
return $this;
}
}
同様の問題の答えを見つけるのに役立つかもしれない他のこと。
1)[構成]>[販売]>[販売]タブで[集合データ(ベータ)を使用]が[いいえ]に設定されているかどうかを確認します。このソリューションは、「ライブ」データに対してのみ機能します(つまり、sales /order_aggregated_createdではなくsales/orderテーブルを使用します)。そうでない場合は、「いいえ」に設定します。
2)app / design / adminhtml / default / default / template /dashboard/graph.phtmlを編集し、getChartUrl(false)をgetChartUrl(true)に変更します
3)ローカルバージョンではなく、クラスが実際に使用されていることを確認してください
check_class_path.php
<?php
require_once ('app/Mage.php');
Mage::app("default");
$reflector = new ReflectionClass('Mage_Reports_Model_Resource_Order_Collection');
$t = $reflector->getFileName();
echo $t;
4)magentohttps://github.com/netz98/n98-magerunで潜在的なクラスの競合を見つけ
ます
5)apcキャッシュ/magentoキャッシュなどのキャッシュをクリアします
6)Magentoのインストールがアップグレードされた場合は、dbスキーマを新しいMagentoのインストールと比較します