Completed
Push — master ( ab5f90...88258b )
by
unknown
41:27
created

UpdateWorkflowItemStepData::doExecute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
3
namespace OroCRM\Bundle\SalesBundle\Migrations\Schema\v1_23;
4
5
use Psr\Log\LoggerInterface;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\DBAL\Connection;
9
10
use Oro\Bundle\MigrationBundle\Migration\ArrayLogger;
11
use Oro\Bundle\MigrationBundle\Migration\ParametrizedMigrationQuery;
12
13
class UpdateWorkflowItemStepData extends ParametrizedMigrationQuery
14
{
15
    /** @var array */
16
    protected $steps;
17
18
    /**
19
     * {@inheritdoc}
20
     */
21
    public function getDescription()
22
    {
23
        $logger = new ArrayLogger();
24
        $this->doExecute($logger, true);
25
        return $logger->getMessages();
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function execute(LoggerInterface $logger)
32
    {
33
        $this->doExecute($logger);
34
    }
35
36
    /**
37
     * @param LoggerInterface $logger
38
     * @param bool            $dryRun
39
     */
40
    protected function doExecute(LoggerInterface $logger, $dryRun = false)
41
    {
42
        $this->updateWorkflowName($logger, $dryRun);
43
        $this->updateWorkflowSteps($logger, $dryRun);
44
        $this->updateWorkflowTransitionLogs($logger, $dryRun);
45
        $this->updateOpportunitySteps($logger, $dryRun);
46
    }
47
48
    /**
49
     * @param LoggerInterface $logger
50
     * @param bool            $dryRun
51
     */
52
    protected function updateWorkflowName(LoggerInterface $logger, $dryRun)
53
    {
54
        $params = [
55
            'old_workflow_name' => 'b2b_flow_sales',
56
            'new_workflow_name' => 'opportunity_flow'
57
        ];
58
59
        $types = [
60
            'old_workflow_name' => Type::STRING,
61
            'new_workflow_name' => Type::STRING,
62
        ];
63
64
        $queries = [
65
            // Copy workflow definition for new opportunity flow
66
            'INSERT INTO oro_workflow_definition ' .
67
            ' SELECT ' .
68
                ':new_workflow_name as name,' .
69
                'start_step_id,' .
70
                'label,' .
71
                'related_entity,' .
72
                'entity_attribute_name,' .
73
                'steps_display_ordered,' .
74
                'system, configuration,' .
75
                'created_at, updated_at' .
76
            ' FROM oro_workflow_definition WHERE name = :old_workflow_name',
77
78
            'UPDATE oro_workflow_step SET workflow_name = :new_workflow_name WHERE workflow_name = :old_workflow_name',
79
            'UPDATE oro_workflow_item SET workflow_name = :new_workflow_name WHERE workflow_name = :old_workflow_name',
80
        ];
81
82 View Code Duplication
        foreach ($queries as $sql) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
            $this->logQuery($logger, $sql, $params, $types);
84
            if (!$dryRun) {
85
                $this->connection->executeUpdate($sql, $params, $types);
86
            }
87
        }
88
89
        $params = ['old_workflow_name' => 'b2b_flow_sales'];
90
        $types  = ['old_workflow_name' => Type::STRING];
91
92
        // Delete old workflow definition
93
        $sql    = 'DELETE FROM oro_workflow_definition WHERE name = :old_workflow_name ';
94
        $this->logQuery($logger, $sql, $params, $types);
95
        if (!$dryRun) {
96
            $this->connection->executeUpdate($sql, $params, $types);
97
        }
98
99
    }
100
101
    /**
102
     * @param LoggerInterface $logger
103
     * @param bool            $dryRun
104
     */
105
    protected function updateWorkflowSteps(LoggerInterface $logger, $dryRun)
0 ignored issues
show
Unused Code introduced by
The parameter $dryRun is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
106
    {
107
        $params = [
108
            [
109
                'old_name'      => 'qualify',
110
                'new_name'      => 'open',
111
                'workflow_name' => 'opportunity_flow',
112
            ],
113
            [
114
                'old_name'      => 'develop',
115
                'new_name'      => 'won',
116
                'workflow_name' => 'opportunity_flow',
117
            ],
118
            [
119
                'old_name'      => 'close',
120
                'new_name'      => 'lost',
121
                'workflow_name' => 'opportunity_flow',
122
            ],
123
        ];
124
125
        $types = [
126
            'old_name'      => Type::STRING,
127
            'new_name'      => Type::STRING,
128
            'workflow_name' => Type::STRING,
129
        ];
130
131
        $sql = 'UPDATE oro_workflow_step SET name = :new_name' .
132
               ' WHERE workflow_name = :workflow_name AND name = :old_name';
133
        foreach ($params as $param) {
134
            $this->logQuery($logger, $sql, $param, $types);
135
            $this->connection->executeUpdate($sql, $param, $types);
136
        }
137
    }
138
139
    /**
140
     * @param LoggerInterface $logger
141
     * @param bool            $dryRun
142
     */
143
    protected function updateWorkflowTransitionLogs(LoggerInterface $logger, $dryRun)
144
    {
145
        // Delete old workflow transition logs
146
        $params = [
147
            'step_from_id' => $this->getStepIdByName($logger, 'open'),
148
            'step_to_id'   => $this->getStepIdByName($logger, 'won'),
149
        ];
150
        $types = [
151
            'step_from_id' => Type::INTEGER,
152
            'step_to_id'   => Type::INTEGER,
153
        ];
154
        $sql = 'DELETE FROM oro_workflow_transition_log' .
155
               ' WHERE step_from_id = :step_from_id AND step_to_id = :step_to_id';
156
        $this->logQuery($logger, $sql, $params, $types);
157
        if (!$dryRun) {
158
            $this->connection->executeUpdate($sql, $params, $types);
159
        }
160
161
        // Update current step for workflow items from won to open
162
        $params = [
163
            'new_current_step_id' => $this->getStepIdByName($logger, 'open'),
164
            'old_current_step_id' => $this->getStepIdByName($logger, 'won'),
165
        ];
166
        $types = [
167
            'new_current_step_id' => Type::INTEGER,
168
            'old_current_step_id' => Type::INTEGER,
169
        ];
170
        $sql = 'UPDATE oro_workflow_item SET current_step_id = :new_current_step_id' .
171
               ' WHERE current_step_id = :old_current_step_id';
172
        $this->logQuery($logger, $sql, $params, $types);
173
        if (!$dryRun) {
174
            $this->connection->executeUpdate($sql, $params, $types);
175
        }
176
177
        // Update old requalify transition to reopen
178
        $params = [
179
            'new_transition'  => 'reopen',
180
            'old_transitions' => ['requalify_lost', 'requalify_won'],
181
            'step_to_id'      => $this->getStepIdByName($logger, 'open'),
182
        ];
183
        $types = [
184
            'new_transition'  => Type::STRING,
185
            'old_transitions' => Connection::PARAM_STR_ARRAY,
186
            'step_to_id'      => Type::INTEGER,
187
        ];
188
        $sql = 'UPDATE oro_workflow_transition_log SET transition = :new_transition' .
189
               ' WHERE transition IN (:old_transitions) AND step_to_id = :step_to_id';
190
        $this->logQuery($logger, $sql, $params, $types);
191
        if (!$dryRun) {
192
            $this->connection->executeUpdate($sql, $params, $types);
193
        }
194
195
        // Define and specify won step
196
        $params = [
197
            'new_transition' => 'close_won',
198
            'old_transition' => 'close_as_won',
199
            'new_step_to_id' => $this->getStepIdByName($logger, 'won'),
200
            'old_step_to_id' => $this->getStepIdByName($logger, 'lost'),
201
            'step_from_id'   => $this->getStepIdByName($logger, 'open')
202
        ];
203
        $types = [
204
            'new_transition' => Type::STRING,
205
            'old_transition' => Type::STRING,
206
            'new_step_to_id' => Type::INTEGER,
207
            'old_step_to_id' => Type::INTEGER,
208
            'step_from_id'   => Type::INTEGER,
209
        ];
210
        $sql = 'UPDATE oro_workflow_transition_log' .
211
               ' SET transition = :new_transition, step_to_id = :new_step_to_id, step_from_id = :step_from_id' .
212
               ' WHERE step_to_id = :old_step_to_id AND transition = :old_transition';
213
        $this->logQuery($logger, $sql, $params, $types);
214
        if (!$dryRun) {
215
            $this->connection->executeUpdate($sql, $params, $types);
216
        }
217
218
        // Update old lost transition
219
        $params = [
220
            'new_transition' => 'close_lost',
221
            'old_transition' => 'close_as_lost',
222
            'step_to_id'     => $this->getStepIdByName($logger, 'lost'),
223
            'step_from_id'   => $this->getStepIdByName($logger, 'open')
224
        ];
225
        $types = [
226
            'new_transition' => Type::STRING,
227
            'old_transition' => Type::STRING,
228
            'step_to_id'     => Type::INTEGER,
229
            'step_from_id'   => Type::INTEGER,
230
        ];
231
        $sql = 'UPDATE oro_workflow_transition_log SET transition = :new_transition, step_from_id = :step_from_id' .
232
               ' WHERE step_to_id = :step_to_id AND transition = :old_transition';
233
        $this->logQuery($logger, $sql, $params, $types);
234
        if (!$dryRun) {
235
            $this->connection->executeUpdate($sql, $params, $types);
236
        }
237
238
        // Update current steps in won workflows items
239
        $params = [
240
            'transition'      => 'close_won',
241
            'current_step_id' => $this->getStepIdByName($logger, 'won'),
242
        ];
243
        $types = [
244
            'transition'      => Type::STRING,
245
            'current_step_id' => Type::INTEGER,
246
        ];
247
        $sql = 'UPDATE oro_workflow_item SET current_step_id = :current_step_id WHERE id IN(' .
248
                    ' SELECT workflow_item_id FROM oro_workflow_transition_log WHERE id IN(' .
249
                        ' SELECT MAX(id) FROM oro_workflow_transition_log ' .
250
                        ' GROUP BY workflow_item_id' .
251
                    ') AND transition = :transition' .
252
               ')';
253
        $this->logQuery($logger, $sql, $params, $types);
254
        if (!$dryRun) {
255
            $this->connection->executeUpdate($sql, $params, $types);
256
        }
257
    }
258
259
    /**
260
     * @param LoggerInterface $logger
261
     * @param bool            $dryRun
262
     */
263
    protected function updateOpportunitySteps(LoggerInterface $logger, $dryRun)
264
    {
265
        $params = [
266
            [
267
                'new_workflow_step_id' => $this->getStepIdByName($logger, 'open'),
268
                'old_workflow_step_id' => $this->getStepIdByName($logger, 'won'),
269
                'status_id'            => 'in_progress',
270
            ],
271
            [
272
                'new_workflow_step_id' => $this->getStepIdByName($logger, 'won'),
273
                'old_workflow_step_id' => $this->getStepIdByName($logger, 'lost'),
274
                'status_id'            => 'won',
275
            ]
276
        ];
277
278
        $types = [
279
            'new_workflow_step_id' => Type::INTEGER,
280
            'old_workflow_step_id' => Type::INTEGER,
281
            'status_id'            => Type::STRING,
282
        ];
283
284
        $sql = 'UPDATE orocrm_sales_opportunity SET workflow_step_id = :new_workflow_step_id' .
285
               ' WHERE workflow_step_id = :old_workflow_step_id AND status_id = :status_id';
286
287 View Code Duplication
        foreach ($params as $param) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
            $this->logQuery($logger, $sql, $param, $types);
289
            if (!$dryRun) {
290
                $this->connection->executeUpdate($sql, $param, $types);
291
            }
292
        }
293
    }
294
295
    /**
296
     * @param LoggerInterface $logger
297
     * @param string          $name
298
     *
299
     * @return int
300
     */
301
    protected function getStepIdByName(LoggerInterface $logger, $name)
302
    {
303
        if (empty($this->steps)) {
304
            $this->steps = $this->getWorkflowSteps($logger);
305
        }
306
307
        $steps = array_filter(
308
            $this->steps,
309
            function ($val) use ($name) {
310
                return $val['name'] === $name;
311
            }
312
        );
313
314
        return reset($steps)['id'];
315
    }
316
317
    /**
318
     * @param LoggerInterface $logger
319
     *
320
     * @return array of ['id' => 'workflow step id', 'name' => 'workflow step name' ]
321
     */
322
    protected function getWorkflowSteps(LoggerInterface $logger)
323
    {
324
        $params = [
325
            'workflow_name' => 'opportunity_flow',
326
        ];
327
        $types  = [
328
            'workflow_name' => Type::STRING,
329
        ];
330
        $sql    = 'SELECT s.id, s.name FROM oro_workflow_step s WHERE s.workflow_name = :workflow_name';
331
        $this->logQuery($logger, $sql, $params, $types);
332
333
        return $this->connection->fetchAll($sql, $params, $types);
334
    }
335
}
336