You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

947 lines
27 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * Configuration.php
  5. * Copyright (c) 2021 james@firefly-iii.org
  6. *
  7. * This file is part of the Firefly III Data Importer
  8. * (https://github.com/firefly-iii/data-importer).
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  22. */
  23. namespace App\Services\Shared\Configuration;
  24. use Carbon\Carbon;
  25. use Log;
  26. use UnexpectedValueException;
  27. /**
  28. * Class Configuration
  29. */
  30. class Configuration
  31. {
  32. public const VERSION = 3;
  33. private string $date;
  34. private int $defaultAccount;
  35. private string $delimiter;
  36. private bool $headers;
  37. private bool $rules;
  38. private bool $skipForm;
  39. private array $specifics;
  40. private array $roles;
  41. private int $version;
  42. private array $doMapping;
  43. private bool $mapAllData;
  44. private bool $addImportTag;
  45. // nordigen configuration
  46. private string $nordigenCountry;
  47. private string $nordigenBank;
  48. private array $nordigenRequisitions;
  49. // spectre + nordigen configuration
  50. private array $accounts;
  51. // spectre configuration
  52. private string $identifier;
  53. private string $connection;
  54. private bool $ignoreSpectreCategories;
  55. // date range settings
  56. private string $dateRange;
  57. private int $dateRangeNumber;
  58. private string $dateRangeUnit;
  59. private string $dateNotBefore;
  60. private string $dateNotAfter;
  61. // what type of import?
  62. private string $flow;
  63. // how to do double transaction detection?
  64. private array $mapping; // 'classic' or 'cell'
  65. // configuration for "classic" method:
  66. private string $duplicateDetectionMethod;
  67. private bool $ignoreDuplicateTransactions;
  68. // configuration for "cell" method:
  69. private bool $ignoreDuplicateLines;
  70. private int $uniqueColumnIndex;
  71. private string $uniqueColumnType;
  72. // configuration for utf-8
  73. private bool $conversion;
  74. /**
  75. * Configuration constructor.
  76. */
  77. private function __construct()
  78. {
  79. $this->date = 'Y-m-d';
  80. $this->defaultAccount = 1;
  81. $this->delimiter = 'comma';
  82. $this->headers = false;
  83. $this->rules = true;
  84. $this->skipForm = false;
  85. $this->addImportTag = true;
  86. $this->specifics = [];
  87. $this->roles = [];
  88. $this->mapping = [];
  89. $this->doMapping = [];
  90. $this->flow = 'csv';
  91. // date range settings
  92. $this->dateRange = 'all';
  93. $this->dateRangeNumber = 30;
  94. $this->dateRangeUnit = 'd';
  95. $this->dateNotBefore = '';
  96. $this->dateNotAfter = '';
  97. // nordigen configuration
  98. $this->nordigenCountry = '';
  99. $this->nordigenBank = '';
  100. $this->nordigenRequisitions = [];
  101. // spectre + nordigen configuration
  102. $this->accounts = [];
  103. // spectre
  104. $this->identifier = '0';
  105. $this->connection = '0';
  106. $this->ignoreSpectreCategories = false;
  107. // mapping for spectre + nordigen
  108. $this->mapAllData = false;
  109. // double transaction detection:
  110. $this->duplicateDetectionMethod = 'classic';
  111. // config for "classic":
  112. $this->ignoreDuplicateTransactions = true;
  113. $this->ignoreDuplicateLines = true;
  114. // config for "cell":
  115. $this->uniqueColumnIndex = 0;
  116. $this->uniqueColumnType = 'internal_reference';
  117. // utf8
  118. $this->conversion = false;
  119. $this->version = self::VERSION;
  120. }
  121. /**
  122. * Create a standard empty configuration.
  123. *
  124. * @return Configuration
  125. */
  126. public static function make(): self
  127. {
  128. return new self;
  129. }
  130. /**
  131. * @param array $array
  132. *
  133. * @return $this
  134. */
  135. public static function fromRequest(array $array): self
  136. {
  137. $delimiters = config('csv.delimiters_reversed');
  138. $object = new self;
  139. $object->version = self::VERSION;
  140. $object->headers = $array['headers'];
  141. $object->date = $array['date'];
  142. $object->defaultAccount = $array['default_account'];
  143. $object->delimiter = $delimiters[$array['delimiter']] ?? 'comma';
  144. $object->rules = $array['rules'];
  145. $object->skipForm = $array['skip_form'];
  146. $object->addImportTag = $array['add_import_tag'] ?? true;
  147. $object->roles = $array['roles'] ?? [];
  148. $object->mapping = $array['mapping'] ?? [];
  149. $object->doMapping = $array['do_mapping'] ?? [];
  150. // mapping for spectre + nordigen
  151. $object->mapAllData = $array['map_all_data'] ?? false;
  152. // spectre
  153. $object->identifier = $array['identifier'] ?? '0';
  154. $object->connection = $array['connection'] ?? '0';
  155. $object->ignoreSpectreCategories = $array['ignore_spectre_categories'] ?? false;
  156. // nordigen:
  157. $object->nordigenCountry = $array['nordigen_country'] ?? '';
  158. $object->nordigenBank = $array['nordigen_bank'] ?? '';
  159. $object->nordigenRequisitions = $array['nordigen_requisitions'] ?? [];
  160. // spectre + nordigen
  161. $object->accounts = $array['accounts'] ?? [];
  162. // date range settings
  163. $object->dateRange = $array['date_range'] ?? 'all';
  164. $object->dateRangeNumber = $array['date_range_number'] ?? 30;
  165. $object->dateRangeUnit = $array['date_range_unit'] ?? 'd';
  166. $object->dateNotBefore = $array['date_not_before'] ?? '';
  167. $object->dateNotAfter = $array['date_not_after'] ?? '';
  168. // duplicate transaction detection
  169. $object->duplicateDetectionMethod = $array['duplicate_detection_method'] ?? 'classic';
  170. // config for "classic":
  171. $object->ignoreDuplicateLines = $array['ignore_duplicate_lines'];
  172. $object->ignoreDuplicateTransactions = true;
  173. // config for "cell":
  174. $object->uniqueColumnIndex = $array['unique_column_index'] ?? 0;
  175. $object->uniqueColumnType = $array['unique_column_type'] ?? '';
  176. // utf8 conversion
  177. $object->conversion = $array['conversion'] ?? false;
  178. // flow
  179. $object->flow = $array['flow'] ?? 'csv';
  180. // overrule a setting:
  181. if ('none' === $object->duplicateDetectionMethod) {
  182. $object->ignoreDuplicateTransactions = false;
  183. }
  184. $object->specifics = [];
  185. foreach ($array['specifics'] as $key => $enabled) {
  186. if (true === $enabled) {
  187. $object->specifics[] = $key;
  188. }
  189. }
  190. return $object;
  191. }
  192. /**
  193. * @param array $data
  194. *
  195. * @return $this
  196. */
  197. public static function fromFile(array $data): self
  198. {
  199. Log::debug('Now in Configuration::fromFile. Data is omitted and will not be printed.');
  200. $version = $data['version'] ?? 1;
  201. if (1 === $version) {
  202. Log::debug('v1, going for classic.');
  203. return self::fromClassicFile($data);
  204. }
  205. if (2 === $version) {
  206. Log::debug('v2 config file!');
  207. return self::fromVersionTwo($data);
  208. }
  209. if (3 === $version) {
  210. Log::debug('v3 config file!');
  211. return self::fromVersionThree($data);
  212. }
  213. throw new UnexpectedValueException(sprintf('Configuration file version "%s" cannot be parsed.', $version));
  214. }
  215. /**
  216. * @param array $data
  217. *
  218. * @return static
  219. */
  220. private static function fromClassicFile(array $data): self
  221. {
  222. $delimiters = config('csv.delimiters_reversed');
  223. $classicRoleNames = config('csv.classic_roles');
  224. $object = new self;
  225. $object->headers = $data['has-headers'] ?? false;
  226. $object->date = $data['date-format'] ?? $object->date;
  227. $object->delimiter = $delimiters[$data['delimiter']] ?? 'comma';
  228. $object->defaultAccount = $data['import-account'] ?? $object->defaultAccount;
  229. $object->rules = $data['apply-rules'] ?? true;
  230. $object->flow = $data['flow'] ?? 'csv';
  231. // other settings
  232. $object->dateRange = $data['date_range'] ?? 'all';
  233. $object->dateRangeNumber = $data['date_range_number'] ?? 30;
  234. $object->dateRangeUnit = $data['date_range_unit'] ?? 'd';
  235. $object->dateNotBefore = $data['date_not_before'] ?? '';
  236. $object->dateNotAfter = $data['date_not_after'] ?? '';
  237. // spectre
  238. $object->identifier = $data['identifier'] ?? '0';
  239. $object->connection = $data['connection'] ?? '0';
  240. $object->ignoreSpectreCategories = $data['ignore_spectre_categories'] ?? false;
  241. // nordigen information:
  242. $object->nordigenCountry = $data['nordigen_country'] ?? '';
  243. $object->nordigenBank = $data['nordigen_bank'] ?? '';
  244. $object->nordigenRequisitions = $data['nordigen_requisitions'] ?? [];
  245. // settings for spectre + nordigen
  246. $object->mapAllData = $data['map_all_data'] ?? false;
  247. $object->accounts = $data['accounts'] ?? [];
  248. $object->ignoreDuplicateTransactions = $data['ignore_duplicate_transactions'] ?? true;
  249. if (isset($data['ignore_duplicates']) && true === $data['ignore_duplicates']) {
  250. Log::debug('Will ignore duplicates.');
  251. $object->ignoreDuplicateTransactions = true;
  252. $object->duplicateDetectionMethod = 'classic';
  253. }
  254. if (isset($data['ignore_duplicates']) && false === $data['ignore_duplicates']) {
  255. Log::debug('Will NOT ignore duplicates.');
  256. $object->ignoreDuplicateTransactions = false;
  257. $object->duplicateDetectionMethod = 'none';
  258. }
  259. if (isset($data['ignore_lines']) && true === $data['ignore_lines']) {
  260. Log::debug('Will ignore duplicate lines.');
  261. $object->ignoreDuplicateLines = true;
  262. }
  263. // array values
  264. $object->specifics = [];
  265. $object->roles = [];
  266. $object->doMapping = [];
  267. $object->mapping = [];
  268. $object->accounts = [];
  269. // utf8
  270. $object->conversion = $data['conversion'] ?? false;
  271. // loop roles from classic file:
  272. $roles = $data['column-roles'] ?? [];
  273. foreach ($roles as $role) {
  274. // some roles have been given a new name some time in the past.
  275. $role = $classicRoleNames[$role] ?? $role;
  276. $config = config(sprintf('csv.import_roles.%s', $role));
  277. if (null !== $config) {
  278. $object->roles[] = $role;
  279. }
  280. }
  281. // loop do mapping from classic file.
  282. $doMapping = $data['column-do-mapping'] ?? [];
  283. foreach ($doMapping as $index => $map) {
  284. $index = (int) $index;
  285. $object->doMapping[$index] = $map;
  286. }
  287. // loop mapping from classic file.
  288. $mapping = $data['column-mapping-config'] ?? [];
  289. foreach ($mapping as $index => $map) {
  290. $index = (int) $index;
  291. $object->mapping[$index] = $map;
  292. }
  293. // set version to "2" and return.
  294. $object->version = 2;
  295. return $object;
  296. }
  297. /**
  298. * @param array $data
  299. *
  300. * @return static
  301. */
  302. private static function fromVersionTwo(array $data): self
  303. {
  304. return self::fromArray($data);
  305. }
  306. /**
  307. * @param array $array
  308. *
  309. * @return static
  310. */
  311. public static function fromArray(array $array): self
  312. {
  313. $version = $array['version'] ?? 1;
  314. $delimiters = config('csv.delimiters_reversed');
  315. $object = new self;
  316. $object->headers = $array['headers'] ?? false;
  317. $object->date = $array['date'] ?? '';
  318. $object->defaultAccount = $array['default_account'] ?? 0;
  319. $object->delimiter = $delimiters[$array['delimiter'] ?? ','] ?? 'comma';
  320. $object->rules = $array['rules'] ?? true;
  321. $object->skipForm = $array['skip_form'] ?? false;
  322. $object->addImportTag = $array['add_import_tag'] ?? true;
  323. $object->roles = $array['roles'] ?? [];
  324. $object->mapping = $array['mapping'] ?? [];
  325. $object->doMapping = $array['do_mapping'] ?? [];
  326. $object->version = $version;
  327. $object->flow = $array['flow'] ?? 'csv';
  328. // settings for spectre + nordigen
  329. $object->mapAllData = $array['map_all_data'] ?? false;
  330. $object->accounts = $array['accounts'] ?? [];
  331. // spectre
  332. $object->identifier = $array['identifier'] ?? '0';
  333. $object->connection = $array['connection'] ?? '0';
  334. $object->ignoreSpectreCategories = $array['ignore_spectre_categories'] ?? false;
  335. // date range settings
  336. $object->dateRange = $array['date_range'] ?? 'all';
  337. $object->dateRangeNumber = $array['date_range_number'] ?? 30;
  338. $object->dateRangeUnit = $array['date_range_unit'] ?? 'd';
  339. $object->dateNotBefore = $array['date_not_before'] ?? '';
  340. $object->dateNotAfter = $array['date_not_after'] ?? '';
  341. // nordigen information:
  342. $object->nordigenCountry = $array['nordigen_country'] ?? '';
  343. $object->nordigenBank = $array['nordigen_bank'] ?? '';
  344. $object->nordigenRequisitions = $array['nordigen_requisitions'] ?? [];
  345. // duplicate transaction detection
  346. $object->duplicateDetectionMethod = $array['duplicate_detection_method'] ?? 'classic';
  347. // config for "classic":
  348. $object->ignoreDuplicateLines = $array['ignore_duplicate_lines'] ?? false;
  349. $object->ignoreDuplicateTransactions = $array['ignore_duplicate_transactions'] ?? true;
  350. if (!array_key_exists('duplicate_detection_method', $array)) {
  351. if (false === $object->ignoreDuplicateTransactions) {
  352. Log::debug('Set the duplicate method to "none".');
  353. $object->duplicateDetectionMethod = 'none';
  354. }
  355. }
  356. // overrule a setting:
  357. if ('none' === $object->duplicateDetectionMethod) {
  358. $object->ignoreDuplicateTransactions = false;
  359. }
  360. // config for "cell":
  361. $object->uniqueColumnIndex = $array['unique_column_index'] ?? 0;
  362. $object->uniqueColumnType = $array['unique_column_type'] ?? '';
  363. // utf8
  364. $object->conversion = $array['conversion'] ?? false;
  365. return $object;
  366. }
  367. /**
  368. * @param array $data
  369. *
  370. * @return static
  371. */
  372. private static function fromVersionThree(array $data): self
  373. {
  374. $object = self::fromArray($data);
  375. $object->specifics = [];
  376. return $object;
  377. }
  378. /**
  379. * @return bool
  380. */
  381. public function isSkipForm(): bool
  382. {
  383. return $this->skipForm;
  384. }
  385. /**
  386. * @param string $name
  387. *
  388. * @return bool
  389. */
  390. public function hasSpecific(string $name): bool
  391. {
  392. return in_array($name, $this->specifics, true);
  393. }
  394. /**
  395. * @return bool
  396. */
  397. public function isAddImportTag(): bool
  398. {
  399. return $this->addImportTag;
  400. }
  401. /**
  402. * @return array
  403. */
  404. public function getRoles(): array
  405. {
  406. return $this->roles ?? [];
  407. }
  408. /**
  409. * @param array $roles
  410. */
  411. public function setRoles(array $roles): void
  412. {
  413. $this->roles = $roles;
  414. }
  415. /**
  416. * @return bool
  417. */
  418. public function isIgnoreDuplicateLines(): bool
  419. {
  420. return $this->ignoreDuplicateLines;
  421. }
  422. /**
  423. * @return bool
  424. */
  425. public function isIgnoreDuplicateTransactions(): bool
  426. {
  427. return $this->ignoreDuplicateTransactions;
  428. }
  429. /**
  430. * Return the array but drop some potentially massive arrays.
  431. * @return array
  432. */
  433. public function toSessionArray(): array
  434. {
  435. $array = $this->toArray();
  436. unset($array['mapping'], $array['do_mapping'], $array['roles']);
  437. return $array;
  438. }
  439. /**
  440. * @return array
  441. */
  442. public function toArray(): array
  443. {
  444. $array = [
  445. 'date' => $this->date,
  446. 'default_account' => $this->defaultAccount,
  447. 'delimiter' => $this->delimiter,
  448. 'headers' => $this->headers,
  449. 'rules' => $this->rules,
  450. 'skip_form' => $this->skipForm,
  451. 'add_import_tag' => $this->addImportTag,
  452. 'roles' => $this->roles,
  453. 'do_mapping' => $this->doMapping,
  454. 'mapping' => $this->mapping,
  455. 'duplicate_detection_method' => $this->duplicateDetectionMethod,
  456. 'ignore_duplicate_lines' => $this->ignoreDuplicateLines,
  457. 'ignore_duplicate_transactions' => $this->ignoreDuplicateTransactions,
  458. 'unique_column_index' => $this->uniqueColumnIndex,
  459. 'unique_column_type' => $this->uniqueColumnType,
  460. 'version' => $this->version,
  461. 'flow' => $this->flow,
  462. // spectre
  463. 'identifier' => $this->identifier,
  464. 'connection' => $this->connection,
  465. 'ignore_spectre_categories' => $this->ignoreSpectreCategories,
  466. // mapping for spectre + nordigen
  467. 'map_all_data' => $this->mapAllData,
  468. // settings for spectre + nordigen
  469. 'accounts' => $this->accounts,
  470. // date range settings:
  471. 'date_range' => $this->dateRange,
  472. 'date_range_number' => $this->dateRangeNumber,
  473. 'date_range_unit' => $this->dateRangeUnit,
  474. 'date_not_before' => $this->dateNotBefore,
  475. 'date_not_after' => $this->dateNotAfter,
  476. // nordigen information:
  477. 'nordigen_country' => $this->nordigenCountry,
  478. 'nordigen_bank' => $this->nordigenBank,
  479. 'nordigen_requisitions' => $this->nordigenRequisitions,
  480. // utf8
  481. 'conversion' => $this->conversion,
  482. ];
  483. // make sure that "ignore duplicate transactions" is turned off
  484. // to deliver a consistent file.
  485. $array['ignore_duplicate_transactions'] = false;
  486. if ('classic' === $this->duplicateDetectionMethod) {
  487. $array['ignore_duplicate_transactions'] = true;
  488. }
  489. return $array;
  490. }
  491. /**
  492. * @return bool
  493. */
  494. public function isIgnoreSpectreCategories(): bool
  495. {
  496. return $this->ignoreSpectreCategories;
  497. }
  498. /**
  499. * @return string
  500. */
  501. public function getDate(): string
  502. {
  503. return $this->date;
  504. }
  505. /**
  506. * @return int|null
  507. */
  508. public function getDefaultAccount(): ?int
  509. {
  510. return $this->defaultAccount;
  511. }
  512. /**
  513. * @return string
  514. */
  515. public function getDelimiter(): string
  516. {
  517. return $this->delimiter;
  518. }
  519. /**
  520. * @return bool
  521. */
  522. public function isHeaders(): bool
  523. {
  524. return $this->headers;
  525. }
  526. /**
  527. * @return string
  528. */
  529. public function getConnection(): string
  530. {
  531. return $this->connection;
  532. }
  533. /**
  534. * @param string $connection
  535. */
  536. public function setConnection(string $connection): void
  537. {
  538. $this->connection = $connection;
  539. }
  540. /**
  541. * @return string
  542. */
  543. public function getIdentifier(): string
  544. {
  545. return $this->identifier;
  546. }
  547. /**
  548. * @param string $identifier
  549. */
  550. public function setIdentifier(string $identifier): void
  551. {
  552. $this->identifier = $identifier;
  553. }
  554. /**
  555. * @return bool
  556. */
  557. public function isRules(): bool
  558. {
  559. return $this->rules;
  560. }
  561. /**
  562. * @return array
  563. */
  564. public function getDoMapping(): array
  565. {
  566. return $this->doMapping ?? [];
  567. }
  568. /**
  569. * @param array $doMapping
  570. */
  571. public function setDoMapping(array $doMapping): void
  572. {
  573. $this->doMapping = $doMapping;
  574. }
  575. /**
  576. * @return bool
  577. */
  578. public function isMapAllData(): bool
  579. {
  580. return $this->mapAllData;
  581. }
  582. /**
  583. * @return array
  584. */
  585. public function getMapping(): array
  586. {
  587. return $this->mapping ?? [];
  588. }
  589. /**
  590. * @param array $mapping
  591. */
  592. public function setMapping(array $mapping): void
  593. {
  594. $newMap = [];
  595. foreach ($mapping as $column => $map) {
  596. ksort($map);
  597. $newMap[$column] = $map;
  598. }
  599. $this->mapping = $newMap;
  600. }
  601. /**
  602. * @return array
  603. */
  604. public function getSpecifics(): array
  605. {
  606. return $this->specifics;
  607. }
  608. /**
  609. * @return string
  610. */
  611. public function getDuplicateDetectionMethod(): string
  612. {
  613. return $this->duplicateDetectionMethod;
  614. }
  615. /**
  616. * @return int
  617. */
  618. public function getUniqueColumnIndex(): int
  619. {
  620. return $this->uniqueColumnIndex;
  621. }
  622. /**
  623. * @return string
  624. */
  625. public function getUniqueColumnType(): string
  626. {
  627. return $this->uniqueColumnType;
  628. }
  629. /**
  630. * @return string
  631. */
  632. public function getFlow(): string
  633. {
  634. return $this->flow;
  635. }
  636. /**
  637. * @param string $flow
  638. */
  639. public function setFlow(string $flow): void
  640. {
  641. $this->flow = $flow;
  642. }
  643. /**
  644. * @return string
  645. */
  646. public function getNordigenCountry(): string
  647. {
  648. return $this->nordigenCountry;
  649. }
  650. /**
  651. * @param string $nordigenCountry
  652. */
  653. public function setNordigenCountry(string $nordigenCountry): void
  654. {
  655. $this->nordigenCountry = $nordigenCountry;
  656. }
  657. /**
  658. * @return bool
  659. */
  660. public function isConversion(): bool
  661. {
  662. return $this->conversion;
  663. }
  664. /**
  665. * @return string
  666. */
  667. public function getNordigenBank(): string
  668. {
  669. return $this->nordigenBank;
  670. }
  671. /**
  672. * @param string $nordigenBank
  673. */
  674. public function setNordigenBank(string $nordigenBank): void
  675. {
  676. $this->nordigenBank = $nordigenBank;
  677. }
  678. /**
  679. * @param string $identifier
  680. */
  681. public function addRequisition(string $key, string $identifier)
  682. {
  683. $this->nordigenRequisitions[$key] = $identifier;
  684. }
  685. /**
  686. * @param string $key
  687. * @return string|null
  688. */
  689. public function getRequisition(string $key): ?string
  690. {
  691. return array_key_exists($key, $this->nordigenRequisitions) ? $this->nordigenRequisitions[$key] : null;
  692. }
  693. /**
  694. * @return array
  695. */
  696. public function getNordigenRequisitions(): array
  697. {
  698. return $this->nordigenRequisitions;
  699. }
  700. /**
  701. * @return string
  702. */
  703. public function getDateRange(): string
  704. {
  705. return $this->dateRange;
  706. }
  707. /**
  708. * @return int
  709. */
  710. public function getDateRangeNumber(): int
  711. {
  712. return $this->dateRangeNumber;
  713. }
  714. /**
  715. * @return string
  716. */
  717. public function getDateRangeUnit(): string
  718. {
  719. return $this->dateRangeUnit;
  720. }
  721. /**
  722. * @return string
  723. */
  724. public function getDateNotBefore(): string
  725. {
  726. return $this->dateNotBefore;
  727. }
  728. /**
  729. * @return string
  730. */
  731. public function getDateNotAfter(): string
  732. {
  733. return $this->dateNotAfter;
  734. }
  735. /**
  736. * @return array
  737. */
  738. public function getAccounts(): array
  739. {
  740. return $this->accounts;
  741. }
  742. /**
  743. * @param array $accounts
  744. */
  745. public function setAccounts(array $accounts): void
  746. {
  747. $this->accounts = $accounts;
  748. }
  749. /**
  750. *
  751. */
  752. public function updateDateRange(): void
  753. {
  754. Log::debug('Now in updateDateRange()');
  755. // set date and time:
  756. switch ($this->dateRange) {
  757. default:
  758. case 'all':
  759. Log::debug('Range is null, set all to NULL.');
  760. $this->dateRangeUnit = 'd';
  761. $this->dateRangeNumber = 30;
  762. $this->dateNotBefore = '';
  763. $this->dateNotAfter = '';
  764. break;
  765. case 'partial':
  766. Log::debug('Range is partial, after is NULL, dateNotBefore will be calculated.');
  767. $this->dateNotAfter = '';
  768. $this->dateNotBefore = self::calcDateNotBefore($this->dateRangeUnit, $this->dateRangeNumber);
  769. Log::debug(sprintf('dateNotBefore is now "%s"', $this->dateNotBefore));
  770. break;
  771. case 'range':
  772. Log::debug('Range is "range", both will be created from a string.');
  773. $before = $this->dateNotBefore; // string
  774. $after = $this->dateNotAfter; // string
  775. if (null !== $before) {
  776. $before = Carbon::createFromFormat('Y-m-d', $before);
  777. }
  778. if (null !== $after) {
  779. $after = Carbon::createFromFormat('Y-m-d', $after);
  780. }
  781. if (null !== $before && null !== $after && $before > $after) {
  782. [$before, $after] = [$after, $before];
  783. }
  784. $this->dateNotBefore = null === $before ? '' : $before->format('Y-m-d');
  785. $this->dateNotAfter = null === $after ? '' : $after->format('Y-m-d');
  786. Log::debug(sprintf('dateNotBefore is now "%s", dateNotAfter is "%s"', $this->dateNotBefore, $this->dateNotAfter));
  787. }
  788. }
  789. /**
  790. * @param string $unit
  791. * @param int $number
  792. *
  793. * @return string|null
  794. */
  795. private static function calcDateNotBefore(string $unit, int $number): ?string
  796. {
  797. $functions = [
  798. 'd' => 'subDays',
  799. 'w' => 'subWeeks',
  800. 'm' => 'subMonths',
  801. 'y' => 'subYears',
  802. ];
  803. if (isset($functions[$unit])) {
  804. $today = Carbon::now();
  805. $function = $functions[$unit];
  806. $today->$function($number);
  807. return $today->format('Y-m-d');
  808. }
  809. app('log')->error(sprintf('Could not parse date setting. Unknown key "%s"', $unit));
  810. return null;
  811. }
  812. }