Evgeniy Ierusalimov 2 недель назад
Родитель
Сommit
2ba067b68f

+ 2
- 0
src/Command/FetchEmailsCommand.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Command;
5
 namespace App\Command;
4
 
6
 
5
 use App\Service\MailFetcher;
7
 use App\Service\MailFetcher;

+ 2
- 1
src/Command/ImportFromXmlCommand.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Command;
5
 namespace App\Command;
4
 
6
 
5
 use App\Presentation\PortfolioPresenter;
7
 use App\Presentation\PortfolioPresenter;
30
     protected function configure(): void
32
     protected function configure(): void
31
     {
33
     {
32
         $this
34
         $this
33
-            //->addArgument('xml-file', null, InputArgument::REQUIRED, 'XML file with portfolio data')
34
             ->addOption('xml-file', null, InputOption::VALUE_REQUIRED, 'XML file with Portfolio data')
35
             ->addOption('xml-file', null, InputOption::VALUE_REQUIRED, 'XML file with Portfolio data')
35
             ->addOption('notify', null, InputOption::VALUE_NONE, 'Notify to telegram');
36
             ->addOption('notify', null, InputOption::VALUE_NONE, 'Notify to telegram');
36
     }
37
     }

+ 2
- 0
src/Entity/Portfolio.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Entity;
5
 namespace App\Entity;
4
 
6
 
5
 use App\Repository\PortfolioRepository;
7
 use App\Repository\PortfolioRepository;

+ 2
- 0
src/Entity/PortfolioDetail.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Entity;
5
 namespace App\Entity;
4
 
6
 
5
 use App\Repository\PortfolioDetailRepository;
7
 use App\Repository\PortfolioDetailRepository;

+ 2
- 0
src/Entity/PortfolioMovement.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Entity;
5
 namespace App\Entity;
4
 
6
 
5
 use App\Repository\PortfolioMovementRepository;
7
 use App\Repository\PortfolioMovementRepository;

+ 2
- 25
src/Repository/PortfolioDetailRepository.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Repository;
5
 namespace App\Repository;
4
 
6
 
5
 use App\Entity\PortfolioDetail;
7
 use App\Entity\PortfolioDetail;
15
     {
17
     {
16
         parent::__construct($registry, PortfolioDetail::class);
18
         parent::__construct($registry, PortfolioDetail::class);
17
     }
19
     }
18
-
19
-    //    /**
20
-    //     * @return PortfolioDetail[] Returns an array of PortfolioDetail objects
21
-    //     */
22
-    //    public function findByExampleField($value): array
23
-    //    {
24
-    //        return $this->createQueryBuilder('p')
25
-    //            ->andWhere('p.exampleField = :val')
26
-    //            ->setParameter('val', $value)
27
-    //            ->orderBy('p.id', 'ASC')
28
-    //            ->setMaxResults(10)
29
-    //            ->getQuery()
30
-    //            ->getResult()
31
-    //        ;
32
-    //    }
33
-
34
-    //    public function findOneBySomeField($value): ?PortfolioDetail
35
-    //    {
36
-    //        return $this->createQueryBuilder('p')
37
-    //            ->andWhere('p.exampleField = :val')
38
-    //            ->setParameter('val', $value)
39
-    //            ->getQuery()
40
-    //            ->getOneOrNullResult()
41
-    //        ;
42
-    //    }
43
 }
20
 }

+ 2
- 25
src/Repository/PortfolioMovementRepository.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Repository;
5
 namespace App\Repository;
4
 
6
 
5
 use App\Entity\PortfolioMovement;
7
 use App\Entity\PortfolioMovement;
15
     {
17
     {
16
         parent::__construct($registry, PortfolioMovement::class);
18
         parent::__construct($registry, PortfolioMovement::class);
17
     }
19
     }
18
-
19
-    //    /**
20
-    //     * @return PortfolioMovement[] Returns an array of PortfolioMovement objects
21
-    //     */
22
-    //    public function findByExampleField($value): array
23
-    //    {
24
-    //        return $this->createQueryBuilder('p')
25
-    //            ->andWhere('p.exampleField = :val')
26
-    //            ->setParameter('val', $value)
27
-    //            ->orderBy('p.id', 'ASC')
28
-    //            ->setMaxResults(10)
29
-    //            ->getQuery()
30
-    //            ->getResult()
31
-    //        ;
32
-    //    }
33
-
34
-    //    public function findOneBySomeField($value): ?PortfolioMovement
35
-    //    {
36
-    //        return $this->createQueryBuilder('p')
37
-    //            ->andWhere('p.exampleField = :val')
38
-    //            ->setParameter('val', $value)
39
-    //            ->getQuery()
40
-    //            ->getOneOrNullResult()
41
-    //        ;
42
-    //    }
43
 }
20
 }

+ 2
- 25
src/Repository/PortfolioRepository.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Repository;
5
 namespace App\Repository;
4
 
6
 
5
 use App\Entity\Portfolio;
7
 use App\Entity\Portfolio;
15
     {
17
     {
16
         parent::__construct($registry, Portfolio::class);
18
         parent::__construct($registry, Portfolio::class);
17
     }
19
     }
18
-
19
-//    /**
20
-//     * @return ReportHeader[] Returns an array of ReportHeader objects
21
-//     */
22
-//    public function findByExampleField($value): array
23
-//    {
24
-//        return $this->createQueryBuilder('r')
25
-//            ->andWhere('r.exampleField = :val')
26
-//            ->setParameter('val', $value)
27
-//            ->orderBy('r.id', 'ASC')
28
-//            ->setMaxResults(10)
29
-//            ->getQuery()
30
-//            ->getResult()
31
-//        ;
32
-//    }
33
-
34
-//    public function findOneBySomeField($value): ?ReportHeader
35
-//    {
36
-//        return $this->createQueryBuilder('r')
37
-//            ->andWhere('r.exampleField = :val')
38
-//            ->setParameter('val', $value)
39
-//            ->getQuery()
40
-//            ->getOneOrNullResult()
41
-//        ;
42
-//    }
43
 }
20
 }

+ 2
- 0
src/Service/TelegramNotifier.php Просмотреть файл

1
 <?php
1
 <?php
2
 
2
 
3
+declare(strict_types=1);
4
+
3
 namespace App\Service;
5
 namespace App\Service;
4
 
6
 
5
 use Psr\Log\LoggerInterface;
7
 use Psr\Log\LoggerInterface;

+ 65
- 30
src/Service/XmlParser.php Просмотреть файл

11
 
11
 
12
 class XmlParser
12
 class XmlParser
13
 {
13
 {
14
+    private const XML_HEADER_AGRMT        = 'ШапкаГенСог';
15
+    private const XML_HEADER_PERIOD       = 'ШапкаПериод';
16
+    private const XML_PORTFOLIO_TABLE     = 'ШапкаПортфель';
17
+    private const XML_PORTFOLIO_SECTION   = 'ЗаголовокПортфель';
18
+    private const XML_MOVEMENTS_SECTION   = 'ШапкаДвиженияИОстаткиЦБ';
19
+    private const PREFIX_DETAILS          = 'Детали';
20
+
21
+    private const ATTR_CLIENT              = 'Клиент';
22
+    private const ATTR_START_DATE          = 'НачПериода';
23
+    private const ATTR_END_DATE            = 'КонПериода';
24
+    private const ATTR_PERIOD_LINE         = 'СтрокаПериода';
25
+    private const ATTR_PERIOD              = 'Период';
26
+    private const ATTR_SECURITY            = 'ЦБ';
27
+    private const ATTR_ISSUER              = 'Эмитент';
28
+    private const ATTR_PRICE_START         = 'НОЦена';
29
+    private const ATTR_PRICE_END           = 'КОЦена';
30
+    private const ATTR_QTY_START           = 'КоличествоНО';
31
+    private const ATTR_QTY_END             = 'КоличествоКО';
32
+    private const ATTR_SUM_START           = 'СуммаНКДНО';
33
+    private const ATTR_SUM_END             = 'СуммаНКДКО';
34
+    private const ATTR_SUM_TOTAL           = 'КОСумма';
35
+    private const ATTR_QTY_START_MV        = 'НО';
36
+    private const ATTR_QTY_END_MV          = 'КО';
37
+    private const ATTR_QTY_INCOME          = 'Приход';
38
+    private const ATTR_QTY_OUTCOME         = 'Расход';
39
+    private const DATE_FORMAT              = 'd.m.Y';
40
+
14
     public function processXml(\SimpleXMLElement $xml): ParsedPortfolio
41
     public function processXml(\SimpleXMLElement $xml): ParsedPortfolio
15
     {
42
     {
16
         return new ParsedPortfolio(
43
         return new ParsedPortfolio(
17
             header: $this->processXmlHeader($xml),
44
             header: $this->processXmlHeader($xml),
18
-            details: $this->processDetails($xml->{'ЗаголовокПортфель'}->{'ШапкаПортфель'}),
19
-            movements: $this->processMovements($xml->{'ШапкаДвиженияИОстаткиЦБ'}),
45
+            details: $this->processDetails(
46
+                $xml->{self::XML_PORTFOLIO_SECTION}->{self::XML_PORTFOLIO_TABLE}
47
+            ),
48
+            movements: $this->processMovements(
49
+                $xml->{self::XML_MOVEMENTS_SECTION}
50
+            ),
20
         );
51
         );
21
     }
52
     }
22
 
53
 
23
     private function processXmlHeader(\SimpleXMLElement $xml): PortfolioHeader
54
     private function processXmlHeader(\SimpleXMLElement $xml): PortfolioHeader
24
     {
55
     {
25
         $attrs = [];
56
         $attrs = [];
26
-        foreach (['ШапкаГенСог', 'ШапкаПериод'] as $section) {
57
+        foreach ([self::XML_HEADER_AGRMT, self::XML_HEADER_PERIOD] as $section) {
27
             foreach ($xml->{$section}->attributes() as $key => $value) {
58
             foreach ($xml->{$section}->attributes() as $key => $value) {
28
                 $attrs[$key] = get_object_vars($value)[0];
59
                 $attrs[$key] = get_object_vars($value)[0];
29
             }
60
             }
30
         }
61
         }
31
 
62
 
32
-        if (array_key_exists('НачПериода', $attrs)) {
33
-            $startDate = \DateTimeImmutable::createFromFormat('d.m.Y', $attrs['НачПериода']);
34
-            $endDate   = \DateTimeImmutable::createFromFormat('d.m.Y', $attrs['КонПериода']);
35
-        } elseif (array_key_exists('СтрокаПериода', $attrs)) {
36
-            $chunks = explode(' ', $attrs['СтрокаПериода']);
63
+        if (array_key_exists(self::ATTR_START_DATE, $attrs)) {
64
+            $startDate = \DateTimeImmutable::createFromFormat(
65
+                self::DATE_FORMAT,
66
+                $attrs[self::ATTR_START_DATE],
67
+            );
68
+            $endDate = \DateTimeImmutable::createFromFormat(
69
+                self::DATE_FORMAT,
70
+                $attrs[self::ATTR_END_DATE],
71
+            );
72
+        } elseif (array_key_exists(self::ATTR_PERIOD_LINE, $attrs)) {
73
+            $chunks = explode(' ', $attrs[self::ATTR_PERIOD_LINE]);
37
             if (count($chunks) !== 4) {
74
             if (count($chunks) !== 4) {
38
                 throw new \RuntimeException('Unexpected period format');
75
                 throw new \RuntimeException('Unexpected period format');
39
             }
76
             }
40
-            $startDate = \DateTimeImmutable::createFromFormat('d.m.Y', $chunks[1]);
41
-            $endDate   = \DateTimeImmutable::createFromFormat('d.m.Y', $chunks[3]);
77
+            $startDate = \DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $chunks[1]);
78
+            $endDate   = \DateTimeImmutable::createFromFormat(self::DATE_FORMAT, $chunks[3]);
42
         } else {
79
         } else {
43
             throw new \RuntimeException('Cannot detect XML header version');
80
             throw new \RuntimeException('Cannot detect XML header version');
44
         }
81
         }
48
         }
85
         }
49
 
86
 
50
         return new PortfolioHeader(
87
         return new PortfolioHeader(
51
-            clientAgreement: $attrs['Клиент'],
88
+            clientAgreement: $attrs[self::ATTR_CLIENT],
52
             startDate: $startDate,
89
             startDate: $startDate,
53
             endDate: $endDate,
90
             endDate: $endDate,
54
         );
91
         );
59
         $items = [];
96
         $items = [];
60
 
97
 
61
         foreach (get_object_vars($xml) as $key => $value) {
98
         foreach (get_object_vars($xml) as $key => $value) {
62
-            if (mb_strpos($key, 'Детали') === false) {
99
+            if (mb_strpos($key, self::PREFIX_DETAILS) === false) {
63
                 continue;
100
                 continue;
64
             }
101
             }
65
 
102
 
74
                 }
111
                 }
75
 
112
 
76
                 $items[] = new PortfolioDetailItem(
113
                 $items[] = new PortfolioDetailItem(
77
-                    issuer:        $attr['Эмитент'],
78
-                    security:      $attr['ЦБ'],
79
-                    priceStart:    $attr['НОЦена'],
80
-                    priceEnd:      $attr['КОЦена'],
81
-                    quantityStart: (int) $attr['КоличествоНО'],
82
-                    quantityEnd:   (int) $attr['КоличествоКО'],
83
-                    sumStart:      $attr['СуммаНКДНО'],
84
-                    sumEnd:        $attr['СуммаНКДКО'],
85
-                    sumTotal:      $attr['КОСумма'],
114
+                    issuer:        $attr[self::ATTR_ISSUER],
115
+                    security:      $attr[self::ATTR_SECURITY],
116
+                    priceStart:    $attr[self::ATTR_PRICE_START],
117
+                    priceEnd:      $attr[self::ATTR_PRICE_END],
118
+                    quantityStart: (int) $attr[self::ATTR_QTY_START],
119
+                    quantityEnd:   (int) $attr[self::ATTR_QTY_END],
120
+                    sumStart:      $attr[self::ATTR_SUM_START],
121
+                    sumEnd:        $attr[self::ATTR_SUM_END],
122
+                    sumTotal:      $attr[self::ATTR_SUM_TOTAL],
86
                 );
123
                 );
87
             }
124
             }
88
         }
125
         }
95
         $items = [];
132
         $items = [];
96
 
133
 
97
         foreach (get_object_vars($xml) as $key => $value) {
134
         foreach (get_object_vars($xml) as $key => $value) {
98
-            if (mb_strpos($key, 'Детали') === false) {
135
+            if (mb_strpos($key, self::PREFIX_DETAILS) === false) {
99
                 continue;
136
                 continue;
100
             }
137
             }
101
 
138
 
109
                     $attr[$attrName] = get_object_vars($attrValue)[0];
146
                     $attr[$attrName] = get_object_vars($attrValue)[0];
110
                 }
147
                 }
111
 
148
 
112
-                $period = new \DateTimeImmutable($attr['Период']);
113
-
114
                 $items[] = new PortfolioMovementItem(
149
                 $items[] = new PortfolioMovementItem(
115
-                    security:       $attr['ЦБ'],
116
-                    period:         $period,
117
-                    quantityStart:  (int) $attr['НО'],
118
-                    quantityEnd:    (int) $attr['КО'],
119
-                    quantityIncome: (int) $attr['Приход'],
120
-                    quantityOutcome:(int) $attr['Расход'],
150
+                    security:       $attr[self::ATTR_SECURITY],
151
+                    period:         new \DateTimeImmutable($attr[self::ATTR_PERIOD]),
152
+                    quantityStart:  (int) $attr[self::ATTR_QTY_START_MV],
153
+                    quantityEnd:    (int) $attr[self::ATTR_QTY_END_MV],
154
+                    quantityIncome: (int) $attr[self::ATTR_QTY_INCOME],
155
+                    quantityOutcome:(int) $attr[self::ATTR_QTY_OUTCOME],
121
                 );
156
                 );
122
             }
157
             }
123
         }
158
         }

Загрузка…
Отмена
Сохранить