/**
  * @param $accountId,string
  * @param $createdTime, int(timestamp)
  */
 public static function generateByYearAndQuarter($accountId, $createdTime)
 {
     $accountId = new MongoId($accountId);
     $today = new MongoDate($createdTime);
     $tomorrow = new MongoDate(strtotime('+1 day', $createdTime));
     $condition = ['accountId' => $accountId, 'createdAt' => ['$gte' => $today, '$lt' => $tomorrow]];
     $campaignLogDailys = StatsMemberCampaignLogDaily::getCollection()->aggregate([['$match' => $condition], ['$group' => ['_id' => ['productId' => '$productId', 'year' => '$year', 'quarter' => '$quarter'], 'total' => ['$sum' => 1]]]]);
     $rows = [];
     if (!empty($campaignLogDailys)) {
         foreach ($campaignLogDailys as $item) {
             $where = ['productId' => $item['_id']['productId'], 'year' => $item['_id']['year'], 'quarter' => $item['_id']['quarter']];
             $productCodeLog = self::findOne($where);
             if (!empty($productCodeLog)) {
                 //summary this product
                 $total = self::getTotalWithProductId($where);
                 if ($total > 0) {
                     $productCodeLog->total = $total;
                     $productCodeLog->save(true, ['total']);
                 }
             } else {
                 $productName = '';
                 $product = Product::findByPK($item['_id']['productId']);
                 if (!empty($product)) {
                     $productName = $product->name;
                 }
                 $rows[] = ['productId' => $item['_id']['productId'], 'productName' => $productName, 'total' => $item['total'], 'year' => $item['_id']['year'], 'quarter' => $item['_id']['quarter'], 'accountId' => $accountId];
             }
         }
         unset($item, $campaignLogDailys);
     }
     return self::batchInsert($rows);
 }