Completed
Push — master ( 104946...6683dc )
by Dmitry
02:26
created

src/bill/BillRepository.php (1 issue)

1
<?php
2
/**
3
 * API for Billing
4
 *
5
 * @link      https://github.com/hiqdev/billing-hiapi
6
 * @package   billing-hiapi
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\billing\hiapi\bill;
12
13
use hiqdev\php\billing\bill\BillInterface;
14
use hiqdev\php\billing\bill\BillRepositoryInterface;
15
use hiqdev\php\billing\charge\ChargeInterface;
16
use hiqdev\yii\DataMapper\expressions\CallExpression;
17
use hiqdev\yii\DataMapper\expressions\HstoreExpression;
18
use hiqdev\yii\DataMapper\models\relations\Bucket;
19
use hiqdev\yii\DataMapper\query\Specification;
20
use Yii;
21
use yii\db\ArrayExpression;
22
use yii\db\Query;
23
24
class BillRepository extends \hiqdev\yii\DataMapper\repositories\BaseRepository implements BillRepositoryInterface
25
{
26
    /** {@inheritdoc} */
27
    public $queryClass = BillQuery::class;
28
29
    /**
30
     * @param BillInterface $bill
31
     */
32
    public function save(BillInterface $bill)
33
    {
34
        $hstore = $this->prepareHstore($bill);
35
        $this->db->transaction(function() use ($bill, $hstore) {
36
            $chargeIds = [];
37
            $call = new CallExpression('set_bill', [$hstore]);
38
            $command = (new Query())->select($call);
39
            $bill->setId($command->scalar($this->db));
40
            foreach ($bill->getCharges() as $charge) {
41
                $charge->setBill($bill);
42
                $this->em->save($charge);
43
                $chargeIds[] = $charge->getId();
44
            }
45
            if ($chargeIds) {
46
                $call = new CallExpression('set_bill_charges', [$bill->getId(), new ArrayExpression($chargeIds, 'integer')]);
47
                (new Query())->select($call)->scalar($this->db);
48
            }
49
        });
50
    }
51
52
    public function findId(BillInterface $bill)
53
    {
54
        if ($bill->getId()) {
55
            return $bill->getId();
56
        }
57
58
        $hstore = $this->prepareHstore($bill);
59
        $call = new CallExpression('bill_id', [$hstore]);
60
61
        return (new Query())->select($call)->scalar($this->db);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new yii\db\Query(...all)->scalar($this->db) also could return the type false which is incompatible with the return type mandated by hiqdev\php\billing\bill\...toryInterface::findId() of integer|null|string.
Loading history...
62
    }
63
64
    /**
65
     * undocumented function
66
     *
67
     * @return HstoreExpression
68
     */
69
    protected function prepareHstore(BillInterface $bill): HstoreExpression
70
    {
71
        return new HstoreExpression([
72
            'id'            => $bill->getId(),
73
            'object_id'     => $bill->getTarget()->getId(),
74
            'tariff_id'     => $bill->getPlan() ? $bill->getPlan()->getId() : null,
75
            'type_id'       => $bill->getType()->getId(),
76
            'type'          => $bill->getType()->getName(),
77
            'buyer_id'      => $bill->getCustomer()->getId(),
78
            'buyer'         => $bill->getCustomer()->getLogin(),
79
            'currency'      => $bill->getSum()->getCurrency()->getCode(),
80
            'sum'           => $bill->getSum()->getAmount(),
81
            'quantity'      => $bill->getQuantity()->getQuantity(),
82
            'unit'          => $bill->getQuantity()->getUnit()->getName(),
83
            'time'          => $bill->getTime()->format('c'),
84
            'label'         => $bill->getComment() ?: null,
85
            'is_finished'   => $bill->isFinished(),
86
            'increment'     => true,
87
        ]);
88
    }
89
90
    public function findByIds(array $ids): array
91
    {
92
        $spec = Yii::createObject(Specification::class)
93
            ->with('charges')
94
            ->where(['id' => $ids]);
95
96
        return $this->findAll($spec);
97
    }
98
99
    protected function joinCharges(&$rows)
100
    {
101
        $bucket = Bucket::fromRows($rows, 'id');
102
        $spec = (new Specification())->with('parent')->where(['bill-id' => $bucket->getKeys()]);
103
        $charges = $this->getRepository(ChargeInterface::class)->queryAll($spec);
104
        $bucket->fill($charges, 'bill.id', 'id');
105
        $bucket->pour($rows, 'charges');
106
    }
107
}
108