Passed
Pull Request — master (#99)
by
unknown
02:46
created

FactoryBasedBuilder   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Importance

Changes 15
Bugs 0 Features 1
Metric Value
eloc 108
dl 0
loc 254
rs 9.6
c 15
b 0
f 1
wmc 35
1
<?php
2
declare(strict_types=1);
3
/**
4
 * PHP Billing Library
5
 *
6
 * @link      https://github.com/hiqdev/php-billing
7
 * @package   php-billing
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\php\billing\tests\behat\bootstrap;
13
14
use hiqdev\billing\hiapi\plan\PlanFactory;
15
use hiqdev\billing\hiapi\tests\support\order\SimpleCalculator;
16
use hiqdev\php\billing\price\EnumPrice;
17
use hiqdev\php\billing\price\PriceFactory;
18
use hiqdev\php\billing\price\RatePrice;
19
use hiqdev\php\billing\price\SinglePrice;
20
use hiqdev\php\billing\target\Target;
21
use hiqdev\php\billing\tests\support\order\SimpleBilling;
22
use hiqdev\php\billing\tests\support\tools\SimpleFactory;
23
use RuntimeException;
24
25
class FactoryBasedBuilder implements BuilderInterface
26
{
27
    private $reseller;
28
29
    private $customer;
30
31
    private $time;
32
33
    private $plan;
34
35
    private $sale;
36
37
    private $prices = [];
38
39
    private $actions = [];
40
41
    private $factory;
42
43
    private $calculator;
44
45
    private $billing;
46
47
    public function __construct()
48
    {
49
        $this->factory = new SimpleFactory([
50
            'price'     => new PriceFactory([
51
                'certificate,certificate_purchase' => EnumPrice::class,
52
                'certificate,certificate_renewal' => EnumPrice::class,
53
                'referral,referral' => RatePrice::class,
54
            ], SinglePrice::class),
55
            'plan' => new PlanFactory(),
56
        ]);
57
    }
58
59
    private function getBilling()
60
    {
61
        if ($this->billing === null) {
62
            $this->billing = new SimpleBilling($this->getCalculator());
63
        }
64
65
        return $this->billing;
66
    }
67
68
    private function getCalculator()
69
    {
70
        if ($this->calculator === null) {
71
            $this->calculator = new SimpleCalculator(null, $this->sale, $this->plan);
72
        }
73
74
        return $this->calculator;
75
    }
76
77
    public function buildReseller(string $login)
78
    {
79
        $this->reseller = $login;
80
        $this->factory->get('customer', $login);
81
    }
82
83
    public function buildCustomer(string $login)
84
    {
85
        $this->customer = $login;
86
        $this->factory->get('customer', [
87
            'login' => $login,
88
            'seller' => $this->reseller,
89
        ]);
90
    }
91
92
    public function buildPlan(string $name, string $type, bool $is_grouping = false)
93
    {
94
        $this->prices = [];
95
        $this->plan = $this->factory->get('plan', [
96
            'id' => $name,
97
            'name' => $name,
98
            'seller' => $this->reseller,
99
            'is_grouping' => $is_grouping,
100
        ]);
101
    }
102
103
    public function buildPrice(array $data)
104
    {
105
        if (!empty($data['price'])) {
106
            $data['price'] = "$data[price] $data[currency]";
107
        }
108
        $data['prepaid'] = ($data['prepaid'] ?? 0) . " $data[unit]";
109
        if (empty($data['target'])) {
110
            $data['target'] = Target::any();
111
        }
112
        if (empty($data['plan'])) {
113
            $data['plan'] = $this->plan;
114
        }
115
        $this->prices[] = $this->factory->get('price', $data);
116
    }
117
118
    public function recreatePlan(string $name)
119
    {
120
        $plan = $this->factory->get('plan', $name);
121
        $plan->setPrices($this->prices);
122
    }
123
124
    public function buildSale(string $target, $plan, string $time = null)
125
    {
126
        $this->time = $time;
127
        $this->sale = $this->factory->get('sale', array_filter([
128
            'customer' => $this->customer,
129
            'target' => $target,
130
            'plan' => $plan,
131
            'time' => $time,
132
        ]));
133
134
        return $this->sale;
135
    }
136
137
    public function setConsumption($type, $amount, $unit, $target, $time)
138
    {
139
        $this->actions[] = $this->buildAction([
140
            'type' => $type,
141
            'quantity' => "$amount $unit",
142
            'target' => $target,
143
            'time' => $time,
144
        ]);
145
    }
146
147
    public function setAction(string $type, int $amount, string $unit, string $target, string $time): void
148
    {
149
        $this->actions[] = $this->buildAction([
150
            'type' => $type,
151
            'quantity' => "$amount $unit",
152
            'target' => $target,
153
            'time' => $time,
154
            'sale' => $this->buildSale($target, $this->plan, $time),
155
        ]);
156
    }
157
158
    public function buildPurchase(string $target, string $plan, string $time, ?array $uses = [])
159
    {
160
        $this->performAction([
161
            'sale' => $this->buildSale($target, $plan, $time),
162
            'type' => 'monthly,cdn_traf95_max',
163
            'quantity' => '1 items',
164
            'target' => $target,
165
            'initial_uses' => $uses
166
        ]);
167
    }
168
169
    public function buildTarget(string $target)
170
    {
171
        return $this->factory->get('target', $target);
172
    }
173
174
    public function performCalculation(string $time = null): array
175
    {
176
        return $this->getBilling()->calculateCharges($this->actions);
177
    }
178
179
    public function performBilling(string $time): void
180
    {
181
        $this->getBilling()->perform($this->actions);
182
        #$bills = $this->getBilling()->getBillRepository()->findAll(new Specification);
183
        #var_dump(__FILE__ . ':' . __LINE__ . ' ' . __METHOD__, $bills);die;
184
        #$b1 = reset($bills);
185
        #var_dump(__FILE__ . ':' . __LINE__ . ' ' . __METHOD__, $b1->getCharges());die;
186
    }
187
188
    public function performAction(array $data)
189
    {
190
        $action = $this->buildAction($data);
191
        $this->getBilling()->perform($action);
192
    }
193
194
    public function buildAction(array $data)
195
    {
196
        $data['time'] = $data['time'] ?? $this->time;
197
        $data['customer'] = $data['customer'] ?? $this->customer;
198
        if (!empty($data['targets'])) {
199
            $data['target'] = $this->factory->get('targets', $data['targets']);
200
        }
201
202
        return $this->factory->get('action', $data);
203
    }
204
205
    public function findBills(array $data): array
206
    {
207
        $data['sum'] = $data['sum'] ?? '0 USD';
208
        $data['quantity'] = $data['quantity'] ?? '0 items';
209
        $bill = $this->buildBill($data);
210
        $repo = $this->getBilling()->getBillRepository();
211
212
        return $repo->findByUniqueness([$bill]);
213
    }
214
215
    public function buildBill(array $data)
216
    {
217
        $data['time'] = $data['time'] ?? $this->time;
218
        $data['customer'] = $data['customer'] ?? $this->customer;
219
        if (!empty($data['targets'])) {
220
            $data['target'] = $this->factory->get('targets', $data['targets']);
221
        }
222
223
        return $this->factory->get('bill', $data);
224
    }
225
226
    public function findCharges(array $data): array
227
    {
228
        $data['sum'] = $data['sum'] ?? '0 USD';
229
        $data['quantity'] = $data['quantity'] ?? '0 items';
230
        $bill = $this->buildCharge($data);
231
        $repo = $this->getBilling()->getChargeRepository();
232
233
        return $repo->findByUniqueness($bill);
234
    }
235
236
    public function buildCharge(array $data)
237
    {
238
        $data['time'] = $data['time'] ?? $this->time;
239
        $data['customer'] = $data['customer'] ?? $this->customer;
240
        if (!empty($data['targets'])) {
241
            $data['target'] = $this->factory->get('targets', $data['targets']);
242
        }
243
244
        return $this->factory->get('bill', $data);
245
    }
246
247
    public function targetChangePlan(string $target, string $planName, string $date, string $wallTime = null)
248
    {
249
        throw new RuntimeException('Not implemented yet');
250
    }
251
252
    public function findSales(array $params)
253
    {
254
        $keys = $this->factory->getEntityUniqueKeys('sale');
255
256
        return $this->factory->find('sale', $keys);
257
    }
258
259
    public function findHistoricalSales(array $params)
260
    {
261
        $keys = $this->factory->getEntityUniqueKeys('sale');
262
263
        return $this->factory->find('sale', $keys);
264
    }
265
266
    public function flushEntitiesCache(): void
267
    {
268
        $this->factory->clearEntitiesCache();
269
    }
270
271
    public function flushEntitiesCacheByType(string $type): void
272
    {
273
        $this->factory->clearEntitiesCacheByType($type);
274
    }
275
276
    public function findUsage(string $time, string $targetName, string $typeName): array
277
    {
278
        throw new RuntimeException('Not implemented yet');
279
    }
280
}
281