diff --git a/src/Reports/ProductReport.php b/src/Reports/ProductReport.php index 6cc61ffdb..a429b3149 100644 --- a/src/Reports/ProductReport.php +++ b/src/Reports/ProductReport.php @@ -3,7 +3,10 @@ namespace SilverShop\Reports; use SilverShop\Page\Product; +use SilverShop\SQLQueryList\SQLQueryList; use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\ORM\DataObject; +use SilverStripe\ORM\Queries\SQLSelect; class ProductReport extends ShopPeriodReport { @@ -13,7 +16,7 @@ class ProductReport extends ShopPeriodReport protected $dataClass = Product::class; - protected $periodfield = '"SiteTree"."Created"'; + protected $periodfield = '"SilverShop_Order"."Created"'; public function columns() { @@ -23,35 +26,124 @@ public function columns() 'formatting' => '$Title', ), 'BasePrice' => 'Price', - 'Created' => 'Created', 'Quantity' => 'Quantity', 'Sales' => 'Sales', ); } + + public function sourceRecords($params) + { + $list = SQLQueryList::create($this->query($params)); + $self = $this; + $list->setOutputClosure( + function ($row) use ($self) { + $row['BasePrice'] = $self->formatMoney($row['BasePrice']); + $row['Sales'] = $self->formatMoney($row['Sales']); + return new $self->dataClass($row); + } + ); + return $list; + } + + private function formatMoney($money) + { + return number_format($money, 2); + } + public function query($params) { - $query = parent::query($params); - $query->selectField($this->periodfield, 'FilterPeriod') - ->addSelect( - [ - '"SilverShop_Product"."ID"', - '"SiteTree"."ClassName"', + //convert dates to correct format + $fields = $this->parameterFields(); + $fields->setValues($params); + $start = $fields->fieldByName('StartPeriod')->dataValue(); + $end = $fields->fieldByName('EndPeriod')->dataValue(); + + + $table = DataObject::getSchema()->tableName($this->dataClass); + $query = new SQLSelect(); + $query->setFrom('"' . $table . '"'); + + $whereClue = '1'; + $filterperiod = $this->periodfield; + if ($start && $end) { + $whereClue = sprintf( + 'DATE("o"."Placed") BETWEEN DATE(\'%s\') AND DATE(\'%s\')', + $start, + $end + ); + } elseif ($start) { + $whereClue = sprintf( + 'DATE("o"."Placed") > DATE(\'%s\')', + $start + ); + } elseif ($end) { + $whereClue = sprintf( + 'DATE("o"."Placed") <= DATE(\'%s\')', + $end + ); + } + + $completedStatus = '\'' . implode('\', \'', [ + 'Unpaid', 'Paid', 'Processing', 'Sent', 'Complete' + ]) . '\''; + + + $query->setSelect( + [ + '"SiteTree"."ID"', '"SiteTree"."Title"', '"SilverShop_Product"."BasePrice"', - '"SiteTree"."Created"', - ] - ) - ->selectField('COUNT("SilverShop_OrderItem"."Quantity")', 'Quantity') - ->selectField('SUM("SilverShop_OrderAttribute"."CalculatedTotal")', 'Sales'); - $query->addInnerJoin('SiteTree', '"SilverShop_Product"."ID" = "SiteTree"."ID"'); - $query->addLeftJoin('SilverShop_Product_OrderItem', 'SilverShop_Product.ID = "SilverShop_Product_OrderItem"."ProductID"'); - $query->addLeftJoin('SilverShop_OrderItem', '"SilverShop_Product_OrderItem"."ID" = "SilverShop_OrderItem"."ID"'); - $query->addLeftJoin('SilverShop_OrderAttribute', '"SilverShop_Product_OrderItem"."ID" = "SilverShop_OrderAttribute"."ID"'); - $query->addLeftJoin('SilverShop_Order', '"SilverShop_OrderAttribute"."OrderID" = "SilverShop_Order"."ID"'); - $query->addGroupby('"SilverShop_Product"."ID"'); - $query->addWhere('"SilverShop_Order"."Paid" IS NOT NULL OR "SilverShop_Product_OrderItem"."ID" IS NULL'); + ] + ) + ->selectField( + sprintf( + '( + SELECT + SUM(soi."Quantity") + FROM + "SilverShop_Product_OrderItem" spo, + "SilverShop_OrderItem" soi, + "SilverShop_OrderAttribute" soa, + "SilverShop_Order" o + WHERE + spo.ProductID = "SilverShop_Product"."ID" + AND spo.ID = soi.ID + AND soi.ID = spo.ID + AND spo.ID = soa.ID + AND soa.OrderID = o.ID + AND o.Status IN (%s) + AND %s + )', + $completedStatus, + $whereClue + ), 'Quantity') + ->selectField( + sprintf( + '( + SELECT + SUM(soa."CalculatedTotal") + FROM + "SilverShop_Product_OrderItem" spo, + "SilverShop_OrderItem" soi, + "SilverShop_OrderAttribute" soa, + "SilverShop_Order" o + WHERE + spo.ProductID = "SilverShop_Product"."ID" + AND spo.ID = soi.ID + AND soi.ID = spo.ID + AND spo.ID = soa.ID + AND soa.OrderID = o.ID + AND o.Status IN (%s) + AND %s + )', + $completedStatus, + $whereClue + ), 'Sales') + ; + $query->addInnerJoin('SiteTree', '"SilverShop_Product"."ID" = "SiteTree"."ID"'); + $query->setOrderBy('Quantity DESC'); return $query; } }