Completed
Push — master ( 43cc45...fcec9a )
by Andrii
04:42
created

SaleRepository::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 7
cp 0
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
crap 2
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, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\billing\hiapi\sale;
12
13
use DateTimeImmutable;
14
use hiqdev\yii\DataMapper\models\relations\Bucket;
15
use hiqdev\yii\DataMapper\expressions\CallExpression;
16
use hiqdev\yii\DataMapper\expressions\HstoreExpression;
17
use hiqdev\yii\DataMapper\components\EntityManagerInterface;
18
use hiqdev\yii\DataMapper\query\Specification;
19
use hiqdev\yii\DataMapper\repositories\BaseRepository;
20
use hiqdev\php\billing\action\ActionInterface;
21
use hiqdev\php\billing\customer\Customer;
22
use hiqdev\php\billing\order\OrderInterface;
23
use hiqdev\php\billing\plan\Plan;
24
use hiqdev\php\billing\plan\PlanInterface;
25
use hiqdev\php\billing\price\PriceInterface;
26
use hiqdev\php\billing\sale\SaleInterface;
27
use hiqdev\php\billing\sale\SaleFactoryInterface;
28
use hiqdev\php\billing\sale\SaleRepositoryInterface;
29
use hiqdev\php\billing\sale\Sale;
30
use hiqdev\php\billing\target\Target;
31
use Yii;
32
33
class SaleRepository extends BaseRepository implements SaleRepositoryInterface
34
{
35
    /** {@inheritdoc} */
36
    public $queryClass = SaleQuery::class;
37
38
    /**
39
     * @var SaleFactory
40
     */
41
    protected $factory;
42
43
    public function __construct(
44
        EntityManagerInterface $em,
45
        SaleFactoryInterface $factory,
46
        array $config = []
47
    ) {
48
        parent::__construct($config);
49
50
        $this->em = $em;
51
        $this->factory = $factory;
0 ignored issues
show
Documentation Bug introduced by
It seems like $factory of type object<hiqdev\php\billin...e\SaleFactoryInterface> is incompatible with the declared type object<hiqdev\billing\hiapi\sale\SaleFactory> of property $factory.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
52
    }
53
54
    public function create(array $row)
55
    {
56
        $row['target']      = $this->createEntity(Target::class, $row['target']);
57
        $row['customer']    = $this->createEntity(Customer::class, $row['customer']);
58
        $row['plan']        = $this->createEntity(Plan::class, $row['plan']);
59
        $row['time']        = new DateTimeImmutable($row['time']);
60
61
        return parent::create($row);
62
    }
63
64
    public function findId(SaleInterface $sale)
65
    {
66
        $hstore = new HstoreExpression(array_filter([
67
            'buyer'     => $sale->getCustomer()->getLogin(),
68
            'buyer_id'  => $sale->getCustomer()->getId(),
69
            'object_id' => $sale->getTarget()->getId(),
70
            'tariff_id' => $sale->getPlan()->getId(),
71
        ]));
72
        $call = new CallExpression('sale_id', [$hstore]);
73
        $command = $this->em->getConnection()->createSelect($call);
74
75
        return $command->scalar();
76
    }
77
78
    /**
79
     * @param OrderInterface $order
80
     * @return Sale[]|SaleInterface[]
81
     */
82
    public function findByOrder(OrderInterface $order)
83
    {
84
        return array_map([$this, 'findByAction'], $order->getActions());
85
    }
86
87
    /**
88
     * @param ActionInterface $action
89
     * @return SaleInterface
90
     */
91
    public function findByAction(ActionInterface $action)
92
    {
93
        $client_id = $action->getCustomer()->getId();
94
        //$seller_id = $action->getCustomer()->getSeller()->getId();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
95
        $type = $action->getTarget()->getType();
96
97
        if ($type === 'certificate') {
98
            //// XXX tmp crutch
99
            $class_id = $this->em->db->createCommand("SELECT class_id('certificate')")->queryScalar();
0 ignored issues
show
Bug introduced by
Accessing db on the interface hiqdev\yii\DataMapper\co...\EntityManagerInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
100
            $cond = [
101
                'target-id' => $class_id,
102
                'customer-id' => $client_id,
103
            ];
104
        } else if ($type === 'server') {
105
            $cond = [
106
                'target-id' => $action->getTarget()->getId(),
107
                'customer-id' => $client_id,
108
            ];
109
        } else {
110
            throw new \Exception('not implemented for: ' . $type);
111
        }
112
113
        $spec = Yii::createObject(Specification::class)
114
            /// XXX how to pass if we want with prices into joinPlans?
115
            ->with('plans')
116
            ->where($cond);
117
118
        return $this->findOne($spec);
119
    }
120
121
    protected function joinPlans(&$rows)
122
    {
123
        $bucket = Bucket::fromRows($rows, 'plan-id');
124
        $spec = (new Specification())
125
            ->with('prices')
126
            ->where(['id' => $bucket->getKeys()]);
127
        $raw_plans = $this->getRepository(PlanInterface::class)->queryAll($spec);
128
        /// TODO for SilverFire: try to do with bucket
129
        $plans = [];
130
        foreach ($raw_plans as $plan) {
131
            $plans[$plan['id']] = $plan;
132
        }
133
        foreach ($rows as &$sale) {
134
            $sale['plan'] = $plans[$sale['plan-id']];
135
        }
136
    }
137
}
138