dolibarr  13.0.2
api_bankaccounts.class.php
1 <?php
2 /*
3  * Copyright (C) 2016 Xebax Christy <xebax@wanadoo.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 use Luracast\Restler\RestException;
20 
21 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
22 
31 {
32 
36  static $FIELDS = array(
37  'ref',
38  'label',
39  'type',
40  'currency_code',
41  'country_id'
42  );
43 
47  public function __construct()
48  {
49  global $db;
50  $this->db = $db;
51  }
52 
66  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $category = 0, $sqlfilters = '')
67  {
68  $list = array();
69 
70  if (!DolibarrApiAccess::$user->rights->banque->lire) {
71  throw new RestException(401);
72  }
73 
74  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_account as t";
75  if ($category > 0) {
76  $sql .= ", ".MAIN_DB_PREFIX."categorie_account as c";
77  }
78  $sql .= ' WHERE t.entity IN ('.getEntity('bank_account').')';
79  // Select accounts of given category
80  if ($category > 0) {
81  $sql .= " AND c.fk_categorie = ".$this->db->escape($category)." AND c.fk_account = t.rowid ";
82  }
83  // Add sql filters
84  if ($sqlfilters)
85  {
86  if (!DolibarrApi::_checkFilters($sqlfilters))
87  {
88  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
89  }
90  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
91  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
92  }
93 
94  $sql .= $this->db->order($sortfield, $sortorder);
95  if ($limit) {
96  if ($page < 0)
97  {
98  $page = 0;
99  }
100  $offset = $limit * $page;
101 
102  $sql .= $this->db->plimit($limit + 1, $offset);
103  }
104 
105  dol_syslog("API Rest request");
106  $result = $this->db->query($sql);
107 
108  if ($result) {
109  $num = $this->db->num_rows($result);
110  $min = min($num, ($limit <= 0 ? $num : $limit));
111  for ($i = 0; $i < $min; $i++) {
112  $obj = $this->db->fetch_object($result);
113  $account = new Account($this->db);
114  if ($account->fetch($obj->rowid) > 0) {
115  $list[] = $this->_cleanObjectDatas($account);
116  }
117  }
118  } else {
119  throw new RestException(503, 'Error when retrieving list of accounts: '.$this->db->lasterror());
120  }
121 
122  return $list;
123  }
124 
133  public function get($id)
134  {
135  if (!DolibarrApiAccess::$user->rights->banque->lire) {
136  throw new RestException(401);
137  }
138 
139  $account = new Account($this->db);
140  $result = $account->fetch($id);
141  if (!$result) {
142  throw new RestException(404, 'account not found');
143  }
144 
145  return $this->_cleanObjectDatas($account);
146  }
147 
154  public function post($request_data = null)
155  {
156  if (!DolibarrApiAccess::$user->rights->banque->configurer) {
157  throw new RestException(401);
158  }
159  // Check mandatory fields
160  $result = $this->_validate($request_data);
161 
162  $account = new Account($this->db);
163  foreach ($request_data as $field => $value) {
164  $account->$field = $value;
165  }
166  // Date of the initial balance (required to create an account).
167  $account->date_solde = time();
168  // courant and type are the same thing but the one used when
169  // creating an account is courant
170  $account->courant = $account->type;
171 
172  if ($account->create(DolibarrApiAccess::$user) < 0) {
173  throw new RestException(500, 'Error creating bank account', array_merge(array($account->error), $account->errors));
174  }
175  return $account->id;
176  }
177 
199  public function transfer($bankaccount_from_id = 0, $bankaccount_to_id = 0, $date = null, $description = "", $amount = 0.0, $amount_to = 0.0)
200  {
201  if (!DolibarrApiAccess::$user->rights->banque->configurer) {
202  throw new RestException(401);
203  }
204 
205  if ($bankaccount_from_id === $bankaccount_to_id) {
206  throw new RestException(422, 'bankaccount_from_id and bankaccount_to_id must be different !');
207  }
208 
209  require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
210 
211  $accountfrom = new Account($this->db);
212  $resultAccountFrom = $accountfrom->fetch($bankaccount_from_id);
213 
214  if ($resultAccountFrom === 0) {
215  throw new RestException(404, 'The BankAccount for bankaccount_from_id provided does not exist.');
216  }
217 
218  $accountto = new Account($this->db);
219  $resultAccountTo = $accountto->fetch($bankaccount_to_id);
220 
221  if ($resultAccountTo === 0) {
222  throw new RestException(404, 'The BankAccount for bankaccount_to_id provided does not exist.');
223  }
224 
225  if ($accountto->currency_code == $accountfrom->currency_code)
226  {
227  $amount_to = $amount;
228  } else {
229  if (!$amount_to || empty($amount_to))
230  {
231  throw new RestException(422, 'You must provide amount_to value since bankaccount_from and bankaccount_to does not share the same currency.');
232  }
233  }
234 
235  $this->db->begin();
236 
237  $error = 0;
238  $bank_line_id_from = 0;
239  $bank_line_id_to = 0;
240  $result = 0;
241  $user = DolibarrApiAccess::$user;
242 
243  // By default, electronic transfert from bank to bank
244  $typefrom = 'PRE';
245  $typeto = 'VIR';
246 
247  if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH)
248  {
249  // This is transfer of change
250  $typefrom = 'LIQ';
251  $typeto = 'LIQ';
252  }
253 
258  if (!$error) {
259  $bank_line_id_from = $accountfrom->addline($date, $typefrom, $description, -1 * price2num($amount), '', '', $user);
260  }
261  if (!($bank_line_id_from > 0)) {
262  $error++;
263  }
264 
265  if (!$error) {
266  $bank_line_id_to = $accountto->addline($date, $typeto, $description, price2num($amount_to), '', '', $user);
267  }
268  if (!($bank_line_id_to > 0)) {
269  $error++;
270  }
271 
276  $url = DOL_URL_ROOT.'/compta/bank/line.php?rowid=';
277  $label = '(banktransfert)';
278  $type = 'banktransfert';
279 
280  if (!$error) {
281  $result = $accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, $url, $label, $type);
282  }
283  if (!($result > 0)) {
284  $error++;
285  }
286 
287  if (!$error) {
288  $result = $accountto->add_url_line($bank_line_id_to, $bank_line_id_from, $url, $label, $type);
289  }
290  if (!($result > 0)) {
291  $error++;
292  }
293 
294  if (!$error)
295  {
296  $this->db->commit();
297 
298  return array(
299  'success' => array(
300  'code' => 201,
301  'message' => 'Internal wire transfer created successfully.'
302  )
303  );
304  } else {
305  $this->db->rollback();
306  throw new RestException(500, $accountfrom->error.' '.$accountto->error);
307  }
308  }
309 
317  public function put($id, $request_data = null)
318  {
319  if (!DolibarrApiAccess::$user->rights->banque->configurer) {
320  throw new RestException(401);
321  }
322 
323  $account = new Account($this->db);
324  $result = $account->fetch($id);
325  if (!$result) {
326  throw new RestException(404, 'account not found');
327  }
328 
329  foreach ($request_data as $field => $value) {
330  if ($field == 'id') continue;
331  $account->$field = $value;
332  }
333 
334  if ($account->update(DolibarrApiAccess::$user) > 0)
335  {
336  return $this->get($id);
337  } else {
338  throw new RestException(500, $account->error);
339  }
340  }
341 
348  public function delete($id)
349  {
350  if (!DolibarrApiAccess::$user->rights->banque->configurer) {
351  throw new RestException(401);
352  }
353  $account = new Account($this->db);
354  $result = $account->fetch($id);
355  if (!$result) {
356  throw new RestException(404, 'account not found');
357  }
358 
359  if ($account->delete(DolibarrApiAccess::$user) < 0) {
360  throw new RestException(401, 'error when deleting account');
361  }
362 
363  return array(
364  'success' => array(
365  'code' => 200,
366  'message' => 'account deleted'
367  )
368  );
369  }
370 
379  private function _validate($data)
380  {
381  $account = array();
382  foreach (BankAccounts::$FIELDS as $field) {
383  if (!isset($data[$field]))
384  throw new RestException(400, "$field field missing");
385  $account[$field] = $data[$field];
386  }
387  return $account;
388  }
389 
390  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
397  protected function _cleanObjectDatas($object)
398  {
399  // phpcs:enable
400  $object = parent::_cleanObjectDatas($object);
401 
402  unset($object->rowid);
403 
404  return $object;
405  }
406 
418  public function getLines($id, $sqlfilters = '')
419  {
420  $list = array();
421 
422  if (!DolibarrApiAccess::$user->rights->banque->lire) {
423  throw new RestException(401);
424  }
425 
426  $account = new Account($this->db);
427  $result = $account->fetch($id);
428  if (!$result) {
429  throw new RestException(404, 'account not found');
430  }
431 
432  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank ";
433  $sql .= " WHERE fk_account = ".$id;
434 
435  // Add sql filters
436  if ($sqlfilters)
437  {
438  if (!DolibarrApi::_checkFilters($sqlfilters))
439  {
440  throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
441  }
442  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
443  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
444  }
445 
446  $sql .= " ORDER BY rowid";
447 
448  $result = $this->db->query($sql);
449 
450  if ($result) {
451  $num = $this->db->num_rows($result);
452  for ($i = 0; $i < $num; $i++) {
453  $obj = $this->db->fetch_object($result);
454  $accountLine = new AccountLine($this->db);
455  if ($accountLine->fetch($obj->rowid) > 0) {
456  $list[] = $this->_cleanObjectDatas($accountLine);
457  }
458  }
459  } else {
460  throw new RestException(503, 'Error when retrieving list of account lines: '.$accountLine->error);
461  }
462 
463  return $list;
464  }
465 
482  public function addLine($id, $date, $type, $label, $amount, $category = 0, $cheque_number = '', $cheque_writer = '', $cheque_bank = '')
483  {
484  if (!DolibarrApiAccess::$user->rights->banque->modifier) {
485  throw new RestException(401);
486  }
487 
488  $account = new Account($this->db);
489  $result = $account->fetch($id);
490  if (!$result) {
491  throw new RestException(404, 'account not found');
492  }
493 
494  $result = $account->addline(
495  $date,
496  $type,
497  $label,
498  $amount,
499  $cheque_number,
500  $category,
501  DolibarrApiAccess::$user,
502  $cheque_writer, $cheque_bank
503  );
504  if ($result < 0) {
505  throw new RestException(503, 'Error when adding line to account: '.$account->error);
506  }
507  return $result;
508  }
509 
523  public function addLink($id, $line_id, $url_id, $url, $label, $type)
524  {
525  if (!DolibarrApiAccess::$user->rights->banque->modifier) {
526  throw new RestException(401);
527  }
528 
529  $account = new Account($this->db);
530  $result = $account->fetch($id);
531  if (!$result) {
532  throw new RestException(404, 'account not found');
533  }
534 
535  $accountLine = new AccountLine($this->db);
536  $result = $accountLine->fetch($line_id);
537  if (!$result) {
538  throw new RestException(404, 'account line not found');
539  }
540 
541  $result = $account->add_url_line($line_id, $url_id, $url, $label, $type);
542  if ($result < 0) {
543  throw new RestException(503, 'Error when adding link to account line: '.$account->error);
544  }
545  return $result;
546  }
547 }
addLine($id, $date, $type, $label, $amount, $category=0, $cheque_number= '', $cheque_writer= '', $cheque_bank= '')
Add a line to an account.
post($request_data=null)
Create account object.
addLink($id, $line_id, $url_id, $url, $label, $type)
Add a link to an account line.
_validate($data)
Validate fields before creating an object.
put($id, $request_data=null)
Update account.
__construct()
Constructor.
Class to manage bank transaction lines.
$conf db
API class for accounts.
Definition: inc.php:54
Class to manage bank accounts.
_checkFilters($sqlfilters)
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:278
Class for API REST v1.
Definition: api.class.php:30
static $FIELDS
array $FIELDS Mandatory fields, checked when creating an object
getLines($id, $sqlfilters= '')
Get the list of lines of the account.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
const TYPE_CASH
Cash account.
index($sortfield="t.rowid", $sortorder= 'ASC', $limit=100, $page=0, $category=0, $sqlfilters= '')
Get the list of accounts.
transfer($bankaccount_from_id=0, $bankaccount_to_id=0, $date=null, $description="", $amount=0.0, $amount_to=0.0)
Create an internal wire transfer between two bank accounts.
_cleanObjectDatas($object)
Clean sensible object datas.