duanlu2935 2016-10-31 16:23
浏览 8
已采纳

SF3 + Doctrine计算日期之间的价格

So in my Symfony 3 project I need to create a sort of price calculator with takes 3 params: date_from, date_to, guest_number. Table in MySql looks like:

-----------------------------------------------------------------
id    |    date_from    |    date_to     |   people   |     price
-----------------------------------------------------------------
1     |    2016-01-15   |    2016-04-20  |   1        |     100
-----------------------------------------------------------------
2     |    2016-04-20   |    2016-08-15  |   1        |     200
-----------------------------------------------------------------
3     |    2016-04-20   |    2016-08-15  |   2        |     250

For example, someone choose 2016-01-01 till 2016-01-10 for 1 guest. Calculator should return 1000. And it is no big deal to create SQL statement for this

Example 2, someone choose 2016-04-15 til 2016-04-25 for 1 person.

The question is how can I build with Doctrine QueryBuilder statement which would calculate 'n' days from one period multiply price and 'n' days from another period multiply corresponding price?

  • 写回答

1条回答 默认 最新

  • dqwcdqs358367 2016-10-31 20:19
    关注

    Let's say you have an entity Calendar:

    <?php
    
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity(repositoryClass="CalendarRepository")
     * @ORM\Table(name="calendar")
     */
    class Calendar
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * @ORM\Column(type="date")
         */
        private $dateFrom;
    
        /**
         * @ORM\Column(type="date")
         */
        private $dateTo;
    
        /**
         * @ORM\Column(type="integer")
         */
        private $people;
    
        /**
         * @ORM\Column(type="integer")
         */
        private $price;
    }
    

    Then your repository class could look like this:

    <?php
    
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\EntityRepository;
    
    class CalendarRepository extends EntityRepository
    {
        public function findPriceFor(\DateTime $dateFrom, \DateTime $dateTo, $nrOfPeople)
        {
            $qb = $this->createQueryBuilder('calendar');
            $qb->select('SUM(
                            CASE 
                                WHEN calendar.dateFrom >= :dateFromChosen AND calendar.dateTo >= :dateToChosen THEN DATE_DIFF(:dateToChosen, calendar.dateFrom)
                                WHEN calendar.dateFrom <= :dateFromChosen AND calendar.dateTo >= :dateToChosen THEN DATE_DIFF(:dateToChosen, :dateFromChosen)
                                WHEN calendar.dateFrom <= :dateFromChosen AND calendar.dateTo <= :dateToChosen THEN DATE_DIFF(calendar.dateTo, :dateFromChosen)
                                WHEN calendar.dateFrom >= :dateFromChosen AND calendar.dateTo <= :dateToChosen THEN DATE_DIFF(calendar.dateTo, calendar.dateFrom)
                                ELSE 0
                            END
                        )*calendar.price AS intervalPrice');
    
            $qb->andWhere('calendar.people = :nrOfPeople')
                ->andWhere(
                    $qb->expr()->andX(
                        $qb->expr()->lt('calendar.dateFrom', ':dateToChosen'),
                        $qb->expr()->gt('calendar.dateTo', ':dateFromChosen')
                    )
                );
    
            $qb->setParameter('nrOfPeople', $nrOfPeople)
                ->setParameter('dateFromChosen', $dateFrom->format('Y-m-d'))
                ->setParameter('dateToChosen', $dateTo->format('Y-m-d'));
    
            $qb->groupBy('calendar.id');
    
            $query = $qb->getQuery();
    
            $resultArray = $query->execute();
    
            $totalPrice = array_sum(array_column($resultArray, 'intervalPrice'));
    
            return $totalPrice;
        }
    }
    

    If we took your example MySQL table, and decide to calculate a price for 1 person, from "2016-04-15" to "2016-04-25", then result would be this:

    result array and total price

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源