1 <?php
2
3 namespace Balance\InputFilter;
4
5 use Balance\Model\EntryType;
6 use Balance\Model\Persistence\ValueOptionsInterface;
7 use Balance\Posting\Checker;
8 use NumberFormatter;
9 use Zend\Filter;
10 use Zend\InputFilter\CollectionInputFilter;
11 use Zend\InputFilter\Input;
12 use Zend\InputFilter\InputFilter;
13 use Zend\ServiceManager\ServiceLocatorAwareInterface;
14 use Zend\ServiceManager\ServiceLocatorAwareTrait;
15 use Zend\Validator;
16
17 18 19
20 class Postings extends InputFilter implements ServiceLocatorAwareInterface
21 {
22 use ServiceLocatorAwareTrait;
23
24 25 26
27 public function init()
28 {
29
30 $pAccounts = $this->getServiceLocator()->getServiceLocator()->get('Balance\Model\Persistence\Accounts');
31
32
33 if (! $pAccounts instanceof ValueOptionsInterface) {
34 throw new InputFilterException('Invalid Model');
35 }
36
37
38 $input = new Input();
39 $input->getFilterChain()
40 ->attach(new Filter\ToInt());
41 $this->add($input, 'id');
42
43
44 $input = new Input();
45 $input->getValidatorChain()
46 ->attach(new Validator\Date(array('format' => 'd/m/Y H:i:s')));
47 $this->add($input, 'datetime');
48
49
50 $this->add(new Input(), 'description');
51
52
53 $filter = new InputFilter();
54
55
56 $input = new Input();
57 $input->getValidatorChain()
58 ->attach(new Validator\InArray(array('haystack' => array_keys((new EntryType())->getDefinition()))));
59 $filter->add($input, 'type');
60
61
62 $options = array();
63 foreach ($pAccounts->getValueOptions() as $identifier => $option) {
64 if (is_array($option)) {
65 $options = array_merge($options, array_keys($option['options']));
66 } else {
67 $options = array_merge($options, array($identifier));
68 }
69 }
70
71
72 $input = new Input();
73 $input->getValidatorChain()
74 ->attach(new Validator\InArray(array('haystack' => $options)))
75 ->attach(new Validator\Callback(array(
76 'callback' => array($this, 'doValidateAccountId'),
77 'message' => 'O valor de entrada foi configurado em outra entrada de lançamento',
78 )));
79 $input->getFilterChain()
80 ->attach(new Filter\ToInt());
81 $filter->add($input, 'account_id');
82
83
84 $input = new Input();
85 $input->getValidatorChain()
86 ->attach(new Validator\Regex(array(
87 'pattern' => '/^[1-9]*[0-9]+,[0-9]{2}$/',
88 'message' => 'O valor informado não está no formato esperado',
89 )))
90 ->attach(new Validator\Callback(array(
91 'callback' => array($this, 'doValidateValue'),
92 'message' => 'O valor de entrada não está balanceado',
93 )));
94 $filter->add($input, 'value');
95
96
97 $collection = (new CollectionInputFilter())
98 ->setInputFilter($filter)
99 ->setCount(2);
100 $this->add($collection, 'entries');
101 }
102
103 104 105 106 107 108
109 public function doValidateAccountId($value)
110 {
111
112 $accounts = array();
113
114 if (isset($this->data['entries']) && is_array($this->data['entries'])) {
115 foreach ($this->data['entries'] as $entry) {
116 if (is_array($entry) && isset($entry['account_id'])) {
117 $accounts[] = (int) $entry['account_id'];
118 }
119 }
120 }
121
122 $counter = array_count_values($accounts);
123
124 return isset($counter[$value]) && $counter[$value] === 1;
125 }
126
127 128 129 130 131 132
133 public function doValidateValue($value)
134 {
135
136 $checker = new Checker();
137 $formatter = new NumberFormatter(null, NumberFormatter::CURRENCY);
138
139 $formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
140
141 if (isset($this->data['entries']) && is_array($this->data['entries'])) {
142 foreach ($this->data['entries'] as $entry) {
143 if (is_array($entry) && isset($entry['type']) && isset($entry['value'])) {
144
145 $value = $formatter->parseCurrency($entry['value'], $currency);
146
147 unset($currency);
148
149 switch ($entry['type']) {
150 case Checker::CREDIT:
151 case Checker::DEBIT:
152 $checker->addValue($entry['type'], $value);
153 break;
154 }
155 }
156 }
157 }
158
159 return $checker->isValid();
160 }
161 }
162