dolibarr  20.0.0-beta
paymentmodes.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4  * Copyright (C) 2004-2022 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2013 Peter Fontaine <contact@peterfontaine.fr>
7  * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
8  * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
9  * Copyright (C) 2018-2023 Thibault FOUCART <support@ptibogxiv.net>
10  * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
11  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
12  * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <https://www.gnu.org/licenses/>.
26  */
27 
35 // Load Dolibarr environment
36 require '../main.inc.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php';
43 require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
45 require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
46 
47 
48 // Load translation files required by the page
49 $langs->loadLangs(array("companies", "commercial", "banks", "bills", 'paypal', 'stripe', 'withdrawals'));
50 
51 
52 // Get parameters
53 $action = GETPOST("action", 'alpha', 3);
54 $cancel = GETPOST('cancel', 'alpha');
55 $backtopage = GETPOST('backtopage');
56 
57 $id = GETPOSTINT("id");
58 $source = GETPOST("source", "alpha"); // source can be a source or a paymentmode
59 $ribid = GETPOSTINT("ribid");
60 
61 // Security check
62 $socid = GETPOSTINT("socid");
63 if ($user->socid) {
64  $socid = $user->socid;
65 }
66 
67 // Initialize objects
68 $object = new Societe($db);
69 $object->fetch($socid);
70 
71 $companybankaccount = new CompanyBankAccount($db);
72 $companypaymentmode = new CompanyPaymentMode($db);
73 $prelevement = new BonPrelevement($db);
74 
75 $extrafields = new ExtraFields($db);
76 
77 // fetch optionals attributes and labels
78 $extrafields->fetch_name_optionals_label($object->table_element);
79 
80 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
81 $hookmanager->initHooks(array('thirdpartybancard', 'globalcard'));
82 
83 // Permissions
84 $permissiontoread = $user->hasRight('societe', 'lire');
85 $permissiontoadd = $user->hasRight('societe', 'creer'); // Used by the include of actions_addupdatedelete.inc.php and actions_builddoc.inc.php
86 
87 $permissiontoaddupdatepaymentinformation = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $permissiontoadd) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('societe', 'thirdparty_paymentinformation_advance', 'write')));
88 
89 
90 // Check permission on company
91 $result = restrictedArea($user, 'societe', '', '');
92 
93 
94 // Init Stripe objects
95 if (isModEnabled('stripe')) {
96  $service = 'StripeTest';
97  $servicestatus = 0;
98  if (getDolGlobalString('STRIPE_LIVE') && !GETPOST('forcesandbox', 'alpha')) {
99  $service = 'StripeLive';
100  $servicestatus = 1;
101  }
102 
103  // Force to use the correct API key
104  global $stripearrayofkeysbyenv;
105  $site_account = $stripearrayofkeysbyenv[$servicestatus]['publishable_key'];
106 
107  $stripe = new Stripe($db);
108  $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account (no remote access to Stripe here)
109  $stripecu = $stripe->getStripeCustomerAccount($object->id, $servicestatus, $site_account); // Get remote Stripe customer 'cus_...' (no remote access to Stripe here)
110 }
111 
112 $error = 0;
113 
114 
115 /*
116  * Actions
117  */
118 
119 if ($cancel) {
120  $action = '';
121 }
122 
123 $morehtmlright = '';
124 $parameters = array('id' => $socid);
125 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
126 if ($reshook < 0) {
127  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
128 }
129 
130 if (empty($reshook)) {
131  if ($cancel) {
132  $action = '';
133  if (!empty($backtopage)) {
134  header("Location: ".$backtopage);
135  exit;
136  }
137  }
138 
139  if ($action == 'update') {
140  // Update the bank account
141  if (!GETPOST('label', 'alpha') || !GETPOST('bank', 'alpha')) {
142  if (!GETPOST('label', 'alpha')) {
143  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
144  }
145  if (!GETPOST('bank', 'alpha')) {
146  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankName")), null, 'errors');
147  }
148  $action = 'edit';
149  $error++;
150  }
151  $companybankaccount->fetch($id);
152  if ($companybankaccount->needIBAN() == 1) {
153  if (!GETPOST('iban')) {
154  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("IBAN")), null, 'errors');
155  $action = 'edit';
156  $error++;
157  }
158  if (!GETPOST('bic')) {
159  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BIC")), null, 'errors');
160  $action = 'edit';
161  $error++;
162  }
163  }
164 
165  if (!$error) {
166  $companybankaccount->oldcopy = dol_clone($companybankaccount, 2);
167 
168  $companybankaccount->socid = $object->id;
169 
170  $companybankaccount->bank = GETPOST('bank', 'alpha');
171  $companybankaccount->label = GETPOST('label', 'alpha');
172  $companybankaccount->status = GETPOSTINT('clos');
173  $companybankaccount->clos = $companybankaccount->status;
174  $companybankaccount->code_banque = GETPOST('code_banque', 'alpha');
175  $companybankaccount->code_guichet = GETPOST('code_guichet', 'alpha');
176  $companybankaccount->number = GETPOST('number', 'alpha');
177  $companybankaccount->cle_rib = GETPOST('cle_rib', 'alpha');
178  $companybankaccount->bic = GETPOST('bic', 'alpha');
179  $companybankaccount->iban = GETPOST('iban', 'alpha');
180 
181  $companybankaccount->address = GETPOST('address', 'alpha');
182  $companybankaccount->domiciliation = $companybankaccount->address;
183 
184  $companybankaccount->owner_name = GETPOST('proprio', 'alpha');
185  $companybankaccount->proprio = $companybankaccount->owner_name;
186  $companybankaccount->owner_address = GETPOST('owner_address', 'alpha');
187  $companybankaccount->frstrecur = GETPOST('frstrecur', 'alpha');
188  $companybankaccount->rum = GETPOST('rum', 'alpha');
189  $companybankaccount->date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear'));
190  if (empty($companybankaccount->rum)) {
191  $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id);
192  }
193 
194  if (GETPOST('stripe_card_ref', 'alpha') && GETPOST('stripe_card_ref', 'alpha') != $companypaymentmode->stripe_card_ref) {
195  // If we set a stripe value that is different than previous one, we also set the stripe account
196  $companypaymentmode->stripe_account = $stripecu.'@'.$site_account;
197  }
198  $companybankaccount->stripe_card_ref = GETPOST('stripe_card_ref', 'alpha');
199 
200  $result = $companybankaccount->update($user);
201  if ($result <= 0) {
202  // Display error message and get back to edit mode
203  setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
204  $action = 'edit';
205  } else {
206  // If this account is the default bank account, we disable others
207  if ($companybankaccount->default_rib) {
208  $companybankaccount->setAsDefault($id); // This will make sure there is only one default rib
209  }
210 
211  if ($companypaymentmode->oldcopy->stripe_card_ref != $companypaymentmode->stripe_card_ref) {
212  if ($companybankaccount->oldcopy->iban != $companybankaccount->iban) {
213  // TODO If we modified the iban, we must also update the pm_ on Stripe side, or break the link completely ?
214  }
215  }
216 
217  $url = $_SERVER["PHP_SELF"].'?socid='.$object->id;
218  header('Location: '.$url);
219  exit;
220  }
221  }
222  }
223 
224  if ($action == 'updatecard') {
225  // Update credit card
226  if (!GETPOST('label', 'alpha') || !GETPOST('proprio', 'alpha') || !GETPOST('exp_date_month', 'alpha') || !GETPOST('exp_date_year', 'alpha')) {
227  if (!GETPOST('label', 'alpha')) {
228  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
229  }
230  if (!GETPOST('proprio', 'alpha')) {
231  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NameOnCard")), null, 'errors');
232  }
233  //if (!GETPOST('cardnumber', 'alpha')) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CardNumber")), null, 'errors');
234  if (!(GETPOST('exp_date_month', 'alpha') > 0) || !(GETPOST('exp_date_year', 'alpha') > 0)) {
235  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpiryDate")), null, 'errors');
236  }
237  //if (!GETPOST('cvn', 'alpha')) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CVN")), null, 'errors');
238  $action = 'createcard';
239  $error++;
240  }
241 
242  $companypaymentmode->fetch($id);
243  if (!$error) {
244  $companybankaccount->oldcopy = dol_clone($companybankaccount, 2);
245 
246  $companypaymentmode->fk_soc = $object->id;
247 
248  $companypaymentmode->bank = GETPOST('bank', 'alpha');
249  $companypaymentmode->label = GETPOST('label', 'alpha');
250  $companypaymentmode->number = GETPOST('cardnumber', 'alpha');
251  $companypaymentmode->last_four = substr(GETPOST('cardnumber', 'alpha'), -4);
252  $companypaymentmode->proprio = GETPOST('proprio', 'alpha');
253  $companypaymentmode->exp_date_month = GETPOSTINT('exp_date_month');
254  $companypaymentmode->exp_date_year = GETPOSTINT('exp_date_year');
255  $companypaymentmode->cvn = GETPOST('cvn', 'alpha');
256  $companypaymentmode->country_code = $object->country_code;
257 
258  if (GETPOST('stripe_card_ref', 'alpha') && GETPOST('stripe_card_ref', 'alpha') != $companypaymentmode->stripe_card_ref) {
259  // If we set a stripe value that is different than previous one, we also set the stripe account
260  $companypaymentmode->stripe_account = $stripecu.'@'.$site_account;
261  }
262  $companypaymentmode->stripe_card_ref = GETPOST('stripe_card_ref', 'alpha');
263 
264  $result = $companypaymentmode->update($user);
265  if (!$result) {
266  setEventMessages($companypaymentmode->error, $companypaymentmode->errors, 'errors');
267  } else {
268  // If this account is the default bank account, we disable others
269  if ($companypaymentmode->default_rib) {
270  $companypaymentmode->setAsDefault($id); // This will make sure there is only one default rib
271  }
272 
273  if ($companypaymentmode->oldcopy->stripe_card_ref != $companypaymentmode->stripe_card_ref) {
274  if ($companybankaccount->oldcopy->number != $companybankaccount->number) {
275  // TODO If we modified the card, we must also update the pm_ on Stripe side, or break the link completely ?
276  }
277  }
278 
279  $url = $_SERVER["PHP_SELF"].'?socid='.$object->id;
280  header('Location: '.$url);
281  exit;
282  }
283  }
284  }
285 
286  // Add bank account
287  if ($action == 'add') {
288  $error = 0;
289 
290  if (!GETPOST('label', 'alpha')) {
291  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
292  $action = 'create';
293  $error++;
294  }
295 
296  if (!$error) {
297  // Ajout
298  $companybankaccount = new CompanyBankAccount($db);
299 
300  $companybankaccount->socid = $object->id;
301 
302  $companybankaccount->fetch_thirdparty();
303 
304  $companybankaccount->bank = GETPOST('bank', 'alpha');
305  $companybankaccount->label = GETPOST('label', 'alpha');
306  $companybankaccount->code_banque = GETPOST('code_banque', 'alpha');
307  $companybankaccount->code_guichet = GETPOST('code_guichet', 'alpha');
308  $companybankaccount->number = GETPOST('number', 'alpha');
309  $companybankaccount->cle_rib = GETPOST('cle_rib', 'alpha');
310  $companybankaccount->bic = GETPOST('bic', 'alpha');
311  $companybankaccount->iban = GETPOST('iban', 'alpha');
312 
313  $companybankaccount->domiciliation = GETPOST('address', 'alpha');
314  $companybankaccount->address = GETPOST('address', 'alpha');
315 
316  $companybankaccount->proprio = GETPOST('proprio', 'alpha');
317  $companybankaccount->owner_address = GETPOST('owner_address', 'alpha');
318  $companybankaccount->frstrecur = GETPOST('frstrecur', 'alpha');
319  $companybankaccount->rum = GETPOST('rum', 'alpha');
320  $companybankaccount->date_rum = dol_mktime(0, 0, 0, GETPOSTINT('date_rummonth'), GETPOSTINT('date_rumday'), GETPOSTINT('date_rumyear'));
321  $companybankaccount->datec = dol_now();
322 
323  //$companybankaccount->clos = GETPOSTINT('clos');
324  $companybankaccount->status = GETPOSTINT('clos');
325 
326  $companybankaccount->bank = trim($companybankaccount->bank);
327  if (empty($companybankaccount->bank) && !empty($companybankaccount->thirdparty)) {
328  $companybankaccount->bank = $langs->trans("Bank").' '.$companybankaccount->thirdparty->name;
329  }
330  $companybankaccount->bic = str_replace(' ', '', $companybankaccount->bic);
331 
332  $db->begin();
333 
334  // This test can be done only once properties were set
335  if ($companybankaccount->needIBAN() == 1) {
336  if (!GETPOST('iban')) {
337  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("IBAN")), null, 'errors');
338  $action = 'create';
339  $error++;
340  }
341  if (!GETPOST('bic')) {
342  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BIC")), null, 'errors');
343  $action = 'create';
344  $error++;
345  }
346  }
347 
348  if (!$error) {
349  $result = $companybankaccount->create($user);
350  if ($result < 0) {
351  $error++;
352  setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
353  $action = 'create'; // Force chargement page création
354  }
355 
356  if (empty($companybankaccount->rum)) {
357  $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id);
358  }
359  }
360 
361  if (!$error) {
362  $result = $companybankaccount->update($user); // This will set the UMR number.
363  if ($result < 0) {
364  $error++;
365  setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
366  $action = 'create';
367  }
368  }
369 
370  if (!$error) {
371  $db->commit();
372 
373  $url = $_SERVER["PHP_SELF"].'?socid='.$object->id;
374  header('Location: '.$url);
375  exit;
376  } else {
377  $db->rollback();
378  }
379  }
380  }
381 
382  // Add credit card
383  if ($action == 'addcard') {
384  $error = 0;
385 
386  if (!GETPOST('label', 'alpha') || !GETPOST('proprio', 'alpha') || !GETPOST('exp_date_month', 'alpha') || !GETPOST('exp_date_year', 'alpha')) {
387  if (!GETPOST('label', 'alpha')) {
388  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
389  }
390  if (!GETPOST('proprio', 'alpha')) {
391  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NameOnCard")), null, 'errors');
392  }
393  //if (!GETPOST('cardnumber', 'alpha')) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CardNumber")), null, 'errors');
394  if (!(GETPOST('exp_date_month', 'alpha') > 0) || !(GETPOST('exp_date_year', 'alpha') > 0)) {
395  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpiryDate")), null, 'errors');
396  }
397  //if (!GETPOST('cvn', 'alpha')) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CVN")), null, 'errors');
398  $action = 'createcard';
399  $error++;
400  }
401 
402  if (!$error) {
403  // Ajout
404  $companypaymentmode = new CompanyPaymentMode($db);
405 
406  $companypaymentmode->fk_soc = $object->id;
407  $companypaymentmode->bank = GETPOST('bank', 'alpha');
408  $companypaymentmode->label = GETPOST('label', 'alpha');
409  $companypaymentmode->number = GETPOST('cardnumber', 'alpha');
410  $companypaymentmode->last_four = substr(GETPOST('cardnumber', 'alpha'), -4);
411  $companypaymentmode->proprio = GETPOST('proprio', 'alpha');
412  $companypaymentmode->exp_date_month = GETPOSTINT('exp_date_month');
413  $companypaymentmode->exp_date_year = GETPOSTINT('exp_date_year');
414  $companypaymentmode->cvn = GETPOST('cvn', 'alpha');
415  $companypaymentmode->datec = dol_now();
416  $companypaymentmode->default_rib = 0;
417  $companypaymentmode->type = 'card';
418  $companypaymentmode->country_code = $object->country_code;
419  $companypaymentmode->status = $servicestatus;
420 
421  if (GETPOST('stripe_card_ref', 'alpha')) {
422  // If we set a stripe value, we also set the stripe account
423  $companypaymentmode->stripe_account = $stripecu.'@'.$site_account;
424  }
425  $companypaymentmode->stripe_card_ref = GETPOST('stripe_card_ref', 'alpha');
426 
427  $db->begin();
428 
429  if (!$error) {
430  $result = $companypaymentmode->create($user);
431  if ($result < 0) {
432  $error++;
433  setEventMessages($companypaymentmode->error, $companypaymentmode->errors, 'errors');
434  $action = 'createcard'; // Force chargement page création
435  }
436  }
437 
438  if (!$error) {
439  $db->commit();
440 
441  $url = $_SERVER["PHP_SELF"].'?socid='.$object->id;
442  header('Location: '.$url);
443  exit;
444  } else {
445  $db->rollback();
446  }
447  }
448  }
449 
450  if ($action == 'setasbankdefault' && GETPOSTINT('ribid') > 0) {
451  $companybankaccount = new CompanyBankAccount($db);
452  $res = $companybankaccount->setAsDefault(GETPOSTINT('ribid'));
453  if ($res) {
454  $url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
455  header('Location: '.$url);
456  exit;
457  } else {
458  setEventMessages($db->lasterror, null, 'errors');
459  }
460  }
461 
462  if ($action == 'confirm_deletecard' && GETPOST('confirm', 'alpha') == 'yes') {
463  // Delete the credi card
464  $companypaymentmode = new CompanyPaymentMode($db);
465  if ($companypaymentmode->fetch($ribid ? $ribid : $id)) {
466  // TODO This is currently done at bottom of page instead of asking confirm
467  /*if ($companypaymentmode->stripe_card_ref && preg_match('/pm_/', $companypaymentmode->stripe_card_ref))
468  {
469  $payment_method = \Stripe\PaymentMethod::retrieve($companypaymentmode->stripe_card_ref);
470  if ($payment_method)
471  {
472  $payment_method->detach();
473  }
474  }*/
475 
476  $result = $companypaymentmode->delete($user);
477  if ($result > 0) {
478  $url = $_SERVER['PHP_SELF']."?socid=".$object->id;
479 
480  header('Location: '.$url);
481  exit;
482  } else {
483  setEventMessages($companypaymentmode->error, $companypaymentmode->errors, 'errors');
484  }
485  } else {
486  setEventMessages($companypaymentmode->error, $companypaymentmode->errors, 'errors');
487  }
488  }
489  if ($action == 'confirm_deletebank' && GETPOST('confirm', 'alpha') == 'yes') {
490  // Delete the bank account
491  $companybankaccount = new CompanyBankAccount($db);
492  if ($companybankaccount->fetch($ribid ? $ribid : $id) > 0) {
493  // TODO This is currently done at bottom of page instead of asking confirm
494  /*if ($companypaymentmode->stripe_card_ref && preg_match('/pm_/', $companypaymentmode->stripe_card_ref))
495  {
496  $payment_method = \Stripe\PaymentMethod::retrieve($companypaymentmode->stripe_card_ref);
497  if ($payment_method)
498  {
499  $payment_method->detach();
500  }
501  }*/
502 
503  $result = $companybankaccount->delete($user);
504 
505  if ($result > 0) {
506  $url = $_SERVER['PHP_SELF']."?socid=".$object->id;
507 
508  header('Location: '.$url);
509  exit;
510  } else {
511  setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
512  }
513  } else {
514  setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
515  }
516  }
517 
518  $savid = $id;
519 
520  // Actions to build doc
521  if ($action == 'builddocrib') {
522  $action = 'builddoc';
523  $moreparams = array(
524  'use_companybankid' => GETPOST('companybankid'),
525  'force_dir_output' => $conf->societe->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->id)
526  );
527  $_POST['lang_id'] = GETPOST('lang_idrib'.GETPOSTINT('companybankid'), 'alphanohtml'); // This is required by core/action_builddoc.inc.php
528  $_POST['model'] = GETPOST('modelrib'.GETPOSTINT('companybankid'), 'alphanohtml'); // This is required by core/action_builddoc.inc.php
529  }
530 
531  $id = $socid;
532  $upload_dir = $conf->societe->multidir_output[$object->entity];
533  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
534 
535  $id = $savid;
536 
537  // Action for stripe
538  if (isModEnabled('stripe') && class_exists('Stripe')) {
539  if ($action == 'synccustomertostripe' || $action == 'synccustomertostripetest') {
540  if ($object->client == 0) {
541  $error++;
542  setEventMessages('ThisThirdpartyIsNotACustomer', null, 'errors');
543  } else {
544  if ($action == 'synccustomertostripe') {
545  $tmpservicestatus = 1;
546  $tmpservice = 'StripeLive';
547  } else {
548  $tmpservicestatus = 0;
549  $tmpservice = 'StripeTest';
550  }
551 
552  $stripe = new Stripe($db);
553  $tmpstripeacc = $stripe->getStripeAccount($tmpservice); // Get Stripe OAuth connect account (no remote access to Stripe here)
554 
555  // Creation of Stripe customer + update of societe_account
556  $tmpcu = $stripe->customerStripe($object, $tmpstripeacc, $tmpservicestatus, 1);
557 
558  if (empty($tmpcu)) {
559  $error++;
560  setEventMessages($stripe->error, $stripe->errors, 'errors');
561  } else {
562  if ($tmpservicestatus == $servicestatus) {
563  $stripecu = $tmpcu->id;
564  }
565  }
566  }
567  }
568  if ($action == 'synccardtostripe') {
569  // Create the credit card on current Stripe env
570  $companypaymentmode = new CompanyPaymentMode($db);
571  $companypaymentmode->fetch($id);
572 
573  if ($companypaymentmode->type != 'card') {
574  $error++;
575  setEventMessages('ThisPaymentModeIsNotACard', null, 'errors');
576  } else {
577  // Get the Stripe customer
578  $cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
579  if (!$cu) {
580  $error++;
581  setEventMessages($stripe->error, $stripe->errors, 'errors');
582  }
583 
584  if (!$error) {
585  // Creation of Stripe card + update of llx_societe_rib
586  // Note that with the new Stripe API, option to create a card is no more available, instead an error message will be returned to
587  // ask to create the crdit card from Stripe backoffice.
588  $card = $stripe->cardStripe($cu, $companypaymentmode, $stripeacc, $servicestatus, 1);
589  if (!$card) {
590  $error++;
591  setEventMessages($stripe->error, $stripe->errors, 'errors');
592  }
593  }
594  }
595  }
596  if ($action == 'syncsepatostripe') {
597  // Create the bank account on current Stripe env
598  $companypaymentmode = new CompanyPaymentMode($db); // Get record in llx_societe_rib
599  $companypaymentmode->fetch($id);
600 
601  if ($companypaymentmode->type != 'ban') {
602  $error++;
603  $langs->load("errors");
604  setEventMessages('ThisPaymentModeIsNotABan', null, 'errors');
605  } else {
606  // Get the Stripe customer
607  $cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
608  // print json_encode($cu);
609  if (empty($cu)) {
610  $error++;
611  $langs->load("errors");
612  setEventMessages($langs->trans("ErrorStripeCustomerNotFoundCreateFirst"), null, 'errors');
613  }
614  if (!$error) {
615  // Creation of Stripe SEPA + update of llx_societe_rib
616  $card = $stripe->sepaStripe($cu, $companypaymentmode, $stripeacc, $servicestatus, 1);
617  if (!$card) {
618  $error++;
619  setEventMessages($stripe->error, $stripe->errors, 'errors');
620  } else {
621  setEventMessages("", array("Bank Account on Stripe", "BAN is now linked to the Stripe customer account !"));
622  }
623  }
624  }
625  }
626 
627  // Set the customer Stripe account (for Live or Test env)
628  if ($action == 'setkey_account' || $action == 'setkey_accounttest') {
629  $error = 0;
630 
631  $tmpservice = 'StripeTest';
632  $tmpservicestatus = 0;
633  if ($action == 'setkey_account') {
634  $tmpservice = 'StripeLive';
635  $tmpservicestatus = 1;
636  }
637 
638  // Force to use the correct API key
639  global $stripearrayofkeysbyenv;
640  $tmpsite_account = $stripearrayofkeysbyenv[$tmpservicestatus]['publishable_key'];
641 
642  if ($action == 'setkey_account') {
643  $newcu = GETPOST('key_account', 'alpha');
644  } else {
645  $newcu = GETPOST('key_accounttest', 'alpha');
646  }
647 
648  $db->begin();
649 
650  if (empty($newcu)) {
651  $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".$object->id." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity;
652  } else {
653  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX."societe_account";
654  $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified !
655  }
656 
657  $resql = $db->query($sql);
658  $num = $db->num_rows($resql); // Note: $num is always 0 on an update and delete, it is defined for select only.
659  if (!empty($newcu)) {
660  if (empty($num)) {
661  $societeaccount = new SocieteAccount($db);
662  $societeaccount->fk_soc = $object->id;
663  $societeaccount->login = '';
664  $societeaccount->pass_encoding = '';
665  $societeaccount->site = 'stripe';
666  $societeaccount->status = $servicestatus;
667  $societeaccount->key_account = $newcu;
668  $societeaccount->site_account = $tmpsite_account;
669  $result = $societeaccount->create($user);
670  if ($result < 0) {
671  $error++;
672  }
673  } else {
674  $sql = 'UPDATE '.MAIN_DB_PREFIX."societe_account";
675  $sql .= " SET key_account = '".$db->escape($newcu)."', site_account = '".$db->escape($tmpsite_account)."'";
676  $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '' or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND status = ".((int) $tmpservicestatus)." AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified !
677  $resql = $db->query($sql);
678  }
679  }
680  //var_dump($sql);
681  //var_dump($newcu);
682  //var_dump($num); exit;
683 
684  if (!$error) {
685  if ($tmpservicestatus == $servicestatus) {
686  $stripecu = $newcu;
687  }
688  $db->commit();
689  } else {
690  $db->rollback();
691  }
692  }
693 
694  // Set the supplier Stripe account (for Live or Test env)
695  if ($action == 'setkey_account_supplier' || $action == 'setkey_account_suppliertest') {
696  $error = 0;
697 
698  $tmpservice = 'StripeTest';
699  $tmpservicestatus = 0;
700  if ($action == 'setkey_account_supplier') {
701  $tmpservice = 'StripeLive';
702  $tmpservicestatus = 1;
703  }
704 
705  // Force to use the correct API key
706  global $stripearrayofkeysbyenv;
707  $tmpsite_account = $stripearrayofkeysbyenv[$tmpservicestatus]['publishable_key'];
708 
709  if ($action == 'setkey_account_supplier') {
710  $newsup = GETPOST('key_account_supplier', 'alpha');
711  } else {
712  $newsup = GETPOST('key_account_suppliertest', 'alpha');
713  }
714 
715  $db->begin();
716 
717  if (empty($newsup)) {
718  $sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token WHERE fk_soc = ".$object->id." AND service = '".$db->escape($tmpservice)."' AND entity = ".$conf->entity;
719  // TODO Add site and site_account on oauth_token table
720  //$sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($site_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($service)."' AND entity = ".$conf->entity;
721  } else {
722  try {
723  $stripesup = \Stripe\Account::retrieve($newsup);
724  $tokenstring = array();
725  $tokenstring['stripe_user_id'] = $stripesup->id;
726  $tokenstring['type'] = $stripesup->type;
727  $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
728  $sql .= " SET tokenstring = '".$db->escape(json_encode($tokenstring))."'";
729  $sql .= " WHERE site = 'stripe' AND (site_account IS NULL or site_account = '".$db->escape($tmpsite_account)."') AND fk_soc = ".((int) $object->id)." AND service = '".$db->escape($tmpservice)."' AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified !
730  // TODO Add site and site_account on oauth_token table
731  $sql .= " WHERE fk_soc = ".$object->id." AND service = '".$db->escape($tmpservice)."' AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified !
732  } catch (Exception $e) {
733  $error++;
734  setEventMessages($e->getMessage(), null, 'errors');
735  }
736  }
737 
738  $resql = $db->query($sql);
739  $num = $db->num_rows($resql);
740  if (empty($num) && !empty($newsup)) {
741  try {
742  $stripesup = \Stripe\Account::retrieve($newsup);
743  $tokenstring['stripe_user_id'] = $stripesup->id;
744  $tokenstring['type'] = $stripesup->type;
745  $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, fk_soc, entity, tokenstring)";
746  $sql .= " VALUES ('".$db->escape($tmpservice)."', ".((int) $object->id).", ".((int) $conf->entity).", '".$db->escape(json_encode($tokenstring))."')";
747  // TODO Add site and site_account on oauth_token table
748  } catch (Exception $e) {
749  $error++;
750  setEventMessages($e->getMessage(), null, 'errors');
751  }
752  $resql = $db->query($sql);
753  }
754 
755  if (!$error) {
756  if ($tmpservicestatus == $servicestatus) {
757  $stripesupplieracc = $newsup;
758  }
759  $db->commit();
760  } else {
761  $db->rollback();
762  }
763  }
764 
765  if ($action == 'setlocalassourcedefault') { // Set as default when payment mode defined locally (and may be also remotely)
766  try {
767  $companypaymentmode->setAsDefault($id);
768 
769  $url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
770  header('Location: '.$url);
771  exit;
772  } catch (Exception $e) {
773  $error++;
774  setEventMessages($e->getMessage(), null, 'errors');
775  }
776  } elseif ($action == 'setassourcedefault') { // Set as default when payment mode defined remotely only
777  try {
778  $cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
779  if (preg_match('/pm_|src_/', $source)) {
780  $cu->invoice_settings->default_payment_method = (string) $source; // New
781  } else {
782  $cu->default_source = (string) $source; // Old
783  }
784  // @phan-suppress-next-line PhanDeprecatedFunction
785  $result = $cu->save();
786 
787  $url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
788  header('Location: '.$url);
789  exit;
790  } catch (Exception $e) {
791  $error++;
792  setEventMessages($e->getMessage(), null, 'errors');
793  }
794  } elseif ($action == 'deletecard' && $source) {
795  // Delete the credit card on Stripe side
796  try {
797  if (preg_match('/pm_/', $source)) {
798  $payment_method = \Stripe\PaymentMethod::retrieve($source, array("stripe_account" => $stripeacc));
799  if ($payment_method) {
800  $payment_method->detach();
801  }
802  } else {
803  $cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
804  $card = $cu->sources->retrieve("$source");
805  if ($card) {
806  // $card->detach(); Does not work with card_, only with src_
807  if (method_exists($card, 'detach')) {
808  $card->detach();
809  $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib as sr ";
810  $sql .= " SET stripe_card_ref = null";
811  $sql .= " WHERE sr.stripe_card_ref = '".$db->escape($source)."'";
812  $resql = $db->query($sql);
813  } else {
814  $card->delete($user);
815  }
816  }
817  }
818 
819  $url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
820  header('Location: '.$url);
821  exit;
822  } catch (Exception $e) {
823  $error++;
824  setEventMessages($e->getMessage(), null, 'errors');
825  }
826  } elseif ($action == 'deletebank' && $source) {
827  // Delete the bank account on Stripe side
828  try {
829  if (preg_match('/pm_/', $source)) {
830  $payment_method = \Stripe\PaymentMethod::retrieve($source, array("stripe_account" => $stripeacc));
831  if ($payment_method) {
832  $payment_method->detach();
833  }
834  } else {
835  $cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
836  $card = $cu->sources->retrieve("$source");
837  if ($card) {
838  // $card->detach(); Does not work with card_, only with src_
839  if (method_exists($card, 'detach')) {
840  $card->detach();
841  $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib as sr ";
842  $sql .= " SET stripe_card_ref = null";
843  $sql .= " WHERE sr.stripe_card_ref = '".$db->escape($source)."'";
844 
845  $resql = $db->query($sql);
846  } else {
847  $card->delete($user);
848  }
849  }
850  }
851 
852  $url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
853  if (GETPOSTINT('page_y')) {
854  $url .= '&page_y='.GETPOSTINT('page_y');
855  }
856 
857  header('Location: '.$url);
858  exit;
859  } catch (Exception $e) {
860  $error++;
861  setEventMessages($e->getMessage(), null, 'errors');
862  }
863  }
864  }
865 }
866 
867 
868 
869 /*
870  * View
871  */
872 
873 $form = new Form($db);
874 $formother = new FormOther($db);
875 $formfile = new FormFile($db);
876 
877 $title = $langs->trans("ThirdParty");
878 if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/thirdpartynameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
879  $title = $object->name." - ".$langs->trans('PaymentInformation');
880 }
881 $help_url = '';
882 
883 llxHeader('', $title, $help_url);
884 
886 
887 // Show sandbox warning
888 /*if (isModEnabled('paypal') && (!empty($conf->global->PAYPAL_API_SANDBOX) || GETPOST('forcesandbox','alpha'))) // We can force sand box with param 'forcesandbox'
889 {
890  dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode','Paypal'),'','warning');
891 }*/
892 if (isModEnabled('stripe') && (!getDolGlobalString('STRIPE_LIVE') || GETPOST('forcesandbox', 'alpha'))) {
893  dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
894 }
895 
896 // Load Bank account
897 if (!$id) {
898  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
899  $companybankaccount->fetch(0, '', $object->id);
900  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
901  $companypaymentmode->fetch(0, null, $object->id, 'card');
902 } else {
903  $companybankaccount->fetch($id);
904  $companypaymentmode->fetch($id);
905 }
906 if (empty($companybankaccount->socid)) {
907  $companybankaccount->socid = $object->id;
908 }
909 
910 if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoaddupdatepaymentinformation) {
911  print '<form action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="post">';
912  print '<input type="hidden" name="token" value="'.newToken().'">';
913  $actionforadd = 'update';
914  if ($action == 'editcard') {
915  $actionforadd = 'updatecard';
916  }
917  print '<input type="hidden" name="action" value="'.$actionforadd.'">';
918  print '<input type="hidden" name="id" value="'.GETPOSTINT("id").'">';
919 }
920 if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoaddupdatepaymentinformation) {
921  print '<form action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="post">';
922  print '<input type="hidden" name="token" value="'.newToken().'">';
923  $actionforadd = 'add';
924  if ($action == 'createcard') {
925  $actionforadd = 'addcard';
926  }
927  print '<input type="hidden" name="action" value="'.$actionforadd.'">';
928 }
929 
930 
931 // View
932 if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' && $action != 'createcard') {
933  print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company');
934 
935  // Confirm delete ban
936  if ($action == 'deletebank') {
937  print $form->formconfirm($_SERVER["PHP_SELF"]."?socid=".$object->id."&ribid=".($ribid ? $ribid : $id), $langs->trans("DeleteARib"), $langs->trans("ConfirmDeleteRib", $companybankaccount->getRibLabel()), "confirm_deletebank", '', 0, 1);
938  }
939  // Confirm delete card
940  if ($action == 'deletecard') {
941  print $form->formconfirm($_SERVER["PHP_SELF"]."?socid=".$object->id."&ribid=".($ribid ? $ribid : $id), $langs->trans("DeleteACard"), $langs->trans("ConfirmDeleteCard", $companybankaccount->getRibLabel()), "confirm_deletecard", '', 0, 1);
942  }
943 
944  $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
945 
946  dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
947 
948  print '<div class="fichecenter">';
949 
950  print '<div class="underbanner clearboth"></div>';
951  print '<table class="border tableforfield centpercent">';
952 
953  // Type Prospect/Customer/Supplier
954  print '<tr><td class="titlefield">'.$langs->trans('NatureOfThirdParty').'</td><td colspan="2">';
955  print $object->getTypeUrl(1);
956  print '</td></tr>';
957 
958  if (getDolGlobalString('SOCIETE_USEPREFIX')) { // Old not used prefix field
959  print '<tr><td class="titlefield">'.$langs->trans('Prefix').'</td><td colspan="2">'.$object->prefix_comm.'</td></tr>';
960  }
961 
962  if ($object->client) {
963  print '<tr><td class="titlefield">';
964  print $langs->trans('CustomerCode').'</td><td colspan="2">';
966  $tmpcheck = $object->check_codeclient();
967  if ($tmpcheck != 0 && $tmpcheck != -5) {
968  print ' <span class="error">('.$langs->trans("WrongCustomerCode").')</span>';
969  }
970  print '</td></tr>';
971  $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."facture where fk_soc = ".((int) $socid);
972  $resql = $db->query($sql);
973  if (!$resql) {
974  dol_print_error($db);
975  }
976 
977  $obj = $db->fetch_object($resql);
978  $nbFactsClient = $obj->nb;
979  $thirdTypeArray = array();
980  $elementTypeArray = array();
981  $thirdTypeArray['customer'] = $langs->trans("customer");
982  if (isModEnabled("propal") && $user->hasRight('propal', 'lire')) {
983  $elementTypeArray['propal'] = $langs->transnoentitiesnoconv('Proposals');
984  }
985  if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
986  $elementTypeArray['order'] = $langs->transnoentitiesnoconv('Orders');
987  }
988  if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
989  $elementTypeArray['invoice'] = $langs->transnoentitiesnoconv('Invoices');
990  }
991  if (isModEnabled('contract') && $user->hasRight('contrat', 'lire')) {
992  $elementTypeArray['contract'] = $langs->transnoentitiesnoconv('Contracts');
993  }
994 
995  if (isModEnabled('stripe')) {
996  // Force to use the correct API key
997  global $stripearrayofkeysbyenv;
998 
999  $tmpservice = 0;
1000  $tmpsite_account = $stripearrayofkeysbyenv[$tmpservice]['publishable_key'];
1001  $tmpstripeacc = $stripe->getStripeAccount($tmpservice); // Get Stripe OAuth connect account (no remote access to Stripe here)
1002  $tmpstripecu = $stripe->getStripeCustomerAccount($object->id, $tmpservice, $tmpsite_account); // Get remote Stripe customer 'cus_...' (no remote access to Stripe here)
1003 
1004  // Stripe customer key 'cu_....' stored into llx_societe_account
1005  print '<tr><td class="titlefield">';
1006  print $form->editfieldkey($langs->trans("StripeCustomerId").' (Test)', 'key_accounttest', $tmpstripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', 0, 2, 'socid');
1007  print '</td><td>';
1008  print $form->editfieldval($langs->trans("StripeCustomerId").' (Test)', 'key_accounttest', $tmpstripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', null, null, '', 2, '', 'socid');
1009  if ($tmpstripecu && $action != 'editkey_accounttest') {
1010  $connect = '';
1011  if (!empty($stripeacc)) {
1012  $connect = $stripeacc.'/';
1013  }
1014  $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$tmpstripecu;
1015  print ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe').' - Publishable key = '.$tmpsite_account, 'globe').'</a>';
1016  }
1017  print '</td><td class="right">';
1018  if (empty($tmpstripecu)) {
1019  print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
1020  print '<input type="hidden" name="action" value="synccustomertostripetest">';
1021  print '<input type="hidden" name="token" value="'.newToken().'">';
1022  print '<input type="hidden" name="socid" value="'.$object->id.'">';
1023  print img_picto($langs->trans("CreateCustomerOnStripe"), 'stripe');
1024  print '<input type="submit" class="buttonlink nomargintop nomarginbottom noborderbottom nopaddingtopimp nopaddingbottomimp" name="syncstripecustomertest" value="'.$langs->trans("CreateCustomerOnStripe").'">';
1025  print '</form>';
1026  }
1027  print '</td></tr>';
1028 
1029  $tmpservice = 1;
1030  $tmpsite_account = $stripearrayofkeysbyenv[$tmpservice]['publishable_key'];
1031  $tmpstripeacc = $stripe->getStripeAccount($tmpservice); // Get Stripe OAuth connect account (no remote access to Stripe here)
1032  $tmpstripecu = $stripe->getStripeCustomerAccount($object->id, $tmpservice, $tmpsite_account); // Get remote Stripe customer 'cus_...' (no remote access to Stripe here)
1033 
1034  // Stripe customer key 'cu_....' stored into llx_societe_account
1035  print '<tr><td class="titlefield">';
1036  print $form->editfieldkey($langs->trans("StripeCustomerId").' (Live)', 'key_account', $tmpstripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', 0, 2, 'socid');
1037  print '</td><td>';
1038  print $form->editfieldval($langs->trans("StripeCustomerId").' (Live)', 'key_account', $tmpstripecu, $object, $permissiontoaddupdatepaymentinformation, 'string', '', null, null, '', 2, '', 'socid');
1039  if ($tmpstripecu && $action != 'editkey_account') {
1040  $connect = '';
1041  if (!empty($stripeacc)) {
1042  $connect = $stripeacc.'/';
1043  }
1044  $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$tmpstripecu;
1045  print ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe').' - Publishable key = '.$tmpsite_account, 'globe').'</a>';
1046  }
1047  print '</td><td class="right">';
1048  if (empty($tmpstripecu)) {
1049  print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
1050  print '<input type="hidden" name="action" value="synccustomertostripe">';
1051  print '<input type="hidden" name="token" value="'.newToken().'">';
1052  print '<input type="hidden" name="socid" value="'.$object->id.'">';
1053  print img_picto($langs->trans("CreateCustomerOnStripe"), 'stripe');
1054  print '<input type="submit" class="buttonlink nomargintop nomarginbottom noborderbottom nopaddingtopimp nopaddingbottomimp" name="syncstripecustomer" value="'.$langs->trans("CreateCustomerOnStripe").'">';
1055  print '</form>';
1056  }
1057  print '</td></tr>';
1058  }
1059  }
1060 
1061  if ($object->fournisseur) {
1062  print '<tr><td class="titlefield">';
1063  print $langs->trans('SupplierCode').'</td><td colspan="2">';
1064  print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_fournisseur));
1065  $tmpcheck = $object->check_codefournisseur();
1066  if ($tmpcheck != 0 && $tmpcheck != -5) {
1067  print ' <span class="error">('.$langs->trans("WrongSupplierCode").')</span>';
1068  }
1069  print '</td></tr>';
1070  $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."facture where fk_soc = ".((int) $socid);
1071  $resql = $db->query($sql);
1072  if (!$resql) {
1073  dol_print_error($db);
1074  }
1075  $obj = $db->fetch_object($resql);
1076  $nbFactsClient = $obj->nb;
1077  $thirdTypeArray['customer'] = $langs->trans("customer");
1078  if (isModEnabled('propal') && $user->hasRight('propal', 'lire')) {
1079  $elementTypeArray['propal'] = $langs->transnoentitiesnoconv('Proposals');
1080  }
1081  if (isModEnabled('order') && $user->hasRight('commande', 'lire')) {
1082  $elementTypeArray['order'] = $langs->transnoentitiesnoconv('Orders');
1083  }
1084  if (isModEnabled('invoice') && $user->hasRight('facture', 'lire')) {
1085  $elementTypeArray['invoice'] = $langs->transnoentitiesnoconv('Invoices');
1086  }
1087  if (isModEnabled('contract') && $user->hasRight('contrat', 'lire')) {
1088  $elementTypeArray['contract'] = $langs->transnoentitiesnoconv('Contracts');
1089  }
1090  }
1091 
1092  // Stripe connect
1093  if (isModEnabled('stripe') && !empty($conf->stripeconnect->enabled) && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
1094  $stripesupplieracc = $stripe->getStripeAccount($service, $object->id); // Get Stripe OAuth connect account (no network access here)
1095 
1096  // Stripe customer key 'cu_....' stored into llx_societe_account
1097  print '<tr><td class="titlefield">';
1098  print $form->editfieldkey("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoaddupdatepaymentinformation, 'string', '', 0, 2, 'socid');
1099  print '</td><td>';
1100  print $form->editfieldval("StripeConnectAccount", 'key_account_supplier', $stripesupplieracc, $object, $permissiontoaddupdatepaymentinformation, 'string', '', null, null, '', 2, '', 'socid');
1101  if (isModEnabled('stripe') && $stripesupplieracc && $action != 'editkey_account_supplier') {
1102  $connect = '';
1103 
1104  $url = 'https://dashboard.stripe.com/test/connect/accounts/'.$stripesupplieracc;
1105  if ($servicestatus) {
1106  $url = 'https://dashboard.stripe.com/connect/accounts/'.$stripesupplieracc;
1107  }
1108  print ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe').' - Publishable key '.$site_account, 'globe').'</a>';
1109  }
1110  print '</td><td class="right">';
1111  if (empty($stripesupplieracc)) {
1112  print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
1113  print '<input type="hidden" name="action" value="syncsuppliertostripe">';
1114  print '<input type="hidden" name="token" value="'.newToken().'">';
1115  print '<input type="hidden" name="socid" value="'.$object->id.'">';
1116  print '<input type="hidden" name="companybankid" value="'.$rib->id.'">';
1117  //print '<input type="submit" class="button buttongen" name="syncstripecustomer" value="'.$langs->trans("CreateSupplierOnStripe").'">';
1118  print '</form>';
1119  }
1120  print '</td></tr>';
1121  }
1122 
1123  print '</table>';
1124  print '</div>';
1125 
1126  print dol_get_fiche_end();
1127 
1128  print '<br>';
1129 
1130  $showcardpaymentmode = 0;
1131  if (isModEnabled('stripe')) {
1132  $showcardpaymentmode++;
1133  }
1134 
1135  // Get list of remote payment modes
1136  $listofsources = array();
1137 
1138  if (isset($stripe) && is_object($stripe)) {
1139  try {
1140  $customerstripe = $stripe->customerStripe($object, $stripeacc, $servicestatus);
1141  if (!empty($customerstripe->id)) {
1142  // When using the Charge API architecture
1143  if (!getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
1144  $listofsources = $customerstripe->sources->data;
1145  } else {
1146  $service = 'StripeTest';
1147  $servicestatus = 0;
1148  if (getDolGlobalString('STRIPE_LIVE') && !GETPOST('forcesandbox', 'alpha')) {
1149  $service = 'StripeLive';
1150  $servicestatus = 1;
1151  }
1152 
1153  // Force to use the correct API key
1154  global $stripearrayofkeysbyenv;
1155  \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
1156 
1157  try {
1158  if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
1159  $paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"));
1160  $paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"));
1161  } else {
1162  $paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"), array("stripe_account" => $stripeacc));
1163  $paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"), array("stripe_account" => $stripeacc));
1164  }
1165 
1166  if ($paymentmethodobjsA->data != null && $paymentmethodobjsB->data != null) {
1167  $listofsources = array_merge((array) $paymentmethodobjsA->data, (array) $paymentmethodobjsB->data);
1168  } elseif ($paymentmethodobjsB->data != null) {
1169  $listofsources = $paymentmethodobjsB->data;
1170  } else {
1171  $listofsources = $paymentmethodobjsA->data;
1172  }
1173  } catch (Exception $e) {
1174  $error++;
1175  setEventMessages($e->getMessage(), null, 'errors');
1176  }
1177  }
1178  }
1179  } catch (Exception $e) {
1180  dol_syslog("Error when searching/loading Stripe customer for thirdparty id =".$object->id);
1181  }
1182  }
1183 
1184 
1185  // List of Card payment modes
1186  if ($showcardpaymentmode && $object->client) {
1187  $morehtmlright = '';
1188  if (getDolGlobalString('STRIPE_ALLOW_LOCAL_CARD')) {
1189  $morehtmlright .= dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?socid='.$object->id.'&amp;action=createcard');
1190  }
1191  print load_fiche_titre($langs->trans('CreditCard'), $morehtmlright, 'fa-credit-card');
1192  //($stripeacc ? ' (Stripe connection with StripeConnect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)')
1193 
1194  print '<!-- List of card payments -->'."\n";
1195  print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
1196  print '<table class="liste centpercent">'."\n";
1197  print '<tr class="liste_titre">';
1198  print '<td>'.$langs->trans('Label').'</td>';
1199  print '<td>'.$form->textwithpicto($langs->trans('ExternalSystemID'), $langs->trans("IDOfPaymentInAnExternalSystem")).'</td>'; // external system ID
1200  print '<td>'.$langs->trans('Type').'</td>';
1201  print '<td>'.$langs->trans('Informations').'</td>';
1202  print '<td></td>';
1203  print '<td class="center">'.$langs->trans('Default').'</td>';
1204  print '<td>'.$langs->trans('Note').'</td>';
1205  print '<td>'.$langs->trans('DateModification').'</td>';
1206  // Hook fields
1207  $parameters = array('arrayfields' => array(), 'param' => '', 'sortfield' => '', 'sortorder' => '', 'linetype' => 'stripetitle');
1208  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
1209  print $hookmanager->resPrint;
1210  // Action column
1211  print "<td></td>";
1212  print "</tr>\n";
1213 
1214  $nbremote = 0;
1215  $nblocal = 0;
1216  $arrayofremotecard = array();
1217 
1218  // Show local sources
1219  if (getDolGlobalString('STRIPE_ALLOW_LOCAL_CARD')) {
1220  //$societeaccount = new SocieteAccount($db);
1221  $companypaymentmodetemp = new CompanyPaymentMode($db);
1222 
1223  $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX."societe_rib";
1224  $sql .= " WHERE type in ('card')";
1225  $sql .= " AND fk_soc = ".((int) $object->id);
1226  $sql .= " AND status = ".((int) $servicestatus);
1227 
1228  $resql = $db->query($sql);
1229  if ($resql) {
1230  $num_rows = $db->num_rows($resql);
1231  if ($num_rows) {
1232  $i = 0;
1233  while ($i < $num_rows) {
1234  $nblocal++;
1235 
1236  $obj = $db->fetch_object($resql);
1237  if ($obj) {
1238  $companypaymentmodetemp->fetch($obj->rowid);
1239 
1240  $arrayofremotecard[$companypaymentmodetemp->stripe_card_ref] = $companypaymentmodetemp->stripe_card_ref;
1241 
1242  print '<tr class="oddeven" data-rowid="'.((int) $companypaymentmodetemp->id).'">';
1243  // Label
1244  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($companypaymentmodetemp->label).'">';
1245  print dol_escape_htmltag($companypaymentmodetemp->label);
1246  print '</td>';
1247  // External system card ID
1248  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($companypaymentmodetemp->stripe_card_ref.(empty($companypaymentmodetemp->stripe_account) ? '' : ' - '.$companypaymentmodetemp->stripe_account)).'">';
1249  if (!empty($companypaymentmodetemp->stripe_card_ref) && !empty($companypaymentmodetemp->ext_payment_site)) {
1250  if (isModEnabled('stripe') && in_array($companypaymentmodetemp->ext_payment_site, array('StripeTest', 'StripeLive'))) {
1251  $connect = '';
1252  if (!empty($stripeacc)) {
1253  $connect = $stripeacc.'/';
1254  }
1255  if ($companypaymentmodetemp->ext_payment_site == 'StripeLive') {
1256  $url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$companypaymentmodetemp->stripe_card_ref;
1257  } else {
1258  $url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$companypaymentmodetemp->stripe_card_ref;
1259  }
1260  print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe').' - '.$companypaymentmodetemp->stripe_account, 'globe')."</a> ";
1261  }
1262  // TODO Add hook here for other payment services
1263  }
1264  print dol_escape_htmltag($companypaymentmodetemp->stripe_card_ref);
1265  print '</td>';
1266  // Type
1267  print '<td>';
1268  print img_credit_card($companypaymentmodetemp->type);
1269  print '</td>';
1270  // Information (Owner, ...)
1271  print '<td class="minwidth100">';
1272  if ($companypaymentmodetemp->proprio) {
1273  print '<span class="opacitymedium">'.$companypaymentmodetemp->proprio.'</span><br>';
1274  }
1275  if ($companypaymentmodetemp->last_four) {
1276  print '....'.$companypaymentmodetemp->last_four;
1277  }
1278  if ($companypaymentmodetemp->exp_date_month || $companypaymentmodetemp->exp_date_year) {
1279  print ' - '.sprintf("%02d", $companypaymentmodetemp->exp_date_month).'/'.$companypaymentmodetemp->exp_date_year;
1280  }
1281  print '</td>';
1282  // Country
1283  print '<td class="tdoverflowmax100">';
1284  if ($companypaymentmodetemp->country_code) {
1285  $img = picto_from_langcode($companypaymentmodetemp->country_code);
1286  print $img ? $img.' ' : '';
1287  print getCountry($companypaymentmodetemp->country_code, 1);
1288  } else {
1289  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1290  }
1291  print '</td>';
1292  // Default
1293  print '<td class="center">';
1294  if (empty($companypaymentmodetemp->default_rib)) {
1295  print '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&id='.$companypaymentmodetemp->id.'&action=setlocalassourcedefault&token='.newToken().'">';
1296  print img_picto($langs->trans("Default"), 'off');
1297  print '</a>';
1298  } else {
1299  print img_picto($langs->trans("Default"), 'on');
1300  }
1301  print '</td>';
1302  if (empty($companypaymentmodetemp->stripe_card_ref)) {
1303  $s = $langs->trans("Local");
1304  } else {
1305  $s = $langs->trans("LocalAndRemote");
1306  }
1307  print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($s).'">';
1308  print $s;
1309  print '</td>';
1310  print '<td>';
1311  print dol_print_date($companypaymentmodetemp->tms, 'dayhour');
1312  print '</td>';
1313  // Fields from hook
1314  $parameters = array('arrayfields' => array(), 'obj' => $obj, 'linetype' => 'stripecard');
1315  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1316  print $hookmanager->resPrint;
1317  // Action column
1318  print '<td class="right minwidth50 nowraponall">';
1319  if ($permissiontoaddupdatepaymentinformation) {
1320  if ($stripecu && empty($companypaymentmodetemp->stripe_card_ref)) {
1321  print '<a href="'.$_SERVER['PHP_SELF'].'?action=synccardtostripe&socid='.$object->id.'&id='.$companypaymentmodetemp->id.'" class="paddingrightonly marginrightonly">'.$langs->trans("CreateCardOnStripe").'</a>';
1322  }
1323 
1324  print '<a class="editfielda marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&id='.$companypaymentmodetemp->id.'&action=editcard&token='.newToken().'">';
1325  print img_picto($langs->trans("Modify"), 'edit');
1326  print '</a>';
1327  print '<a class="marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&id='.$companypaymentmodetemp->id.'&action=deletecard&token='.newToken().'">'; // source='.$companypaymentmodetemp->stripe_card_ref.'&
1328  print img_picto($langs->trans("Delete"), 'delete');
1329  print '</a>';
1330  }
1331  print '</td>';
1332  print '</tr>';
1333  }
1334  $i++;
1335  }
1336  }
1337  } else {
1338  dol_print_error($db);
1339  }
1340  }
1341 
1342  // Show remote sources (not already shown as local source)
1343  if (is_array($listofsources) && count($listofsources)) {
1344  foreach ($listofsources as $src) {
1345  if (!empty($arrayofremotecard[$src->id])) {
1346  continue; // Already in previous list
1347  }
1348 
1349  $nbremote++;
1350 
1351  $imgline = '';
1352  if ($src->object == 'card') {
1353  $imgline = img_credit_card($src->brand);
1354  } elseif ($src->object == 'source' && $src->type == 'card') {
1355  $imgline = img_credit_card($src->card->brand);
1356  } elseif ($src->object == 'payment_method' && $src->type == 'card') {
1357  $imgline = img_credit_card($src->card->brand);
1358  } elseif ($src->object == 'source' && $src->type == 'sepa_debit') {
1359  continue;
1360  } elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
1361  continue;
1362  }
1363 
1364  print '<tr class="oddeven">';
1365  print '<td>';
1366  print '</td>';
1367  // Src ID
1368  print '<td class="tdoverflowmax150">';
1369  $connect = '';
1370  if (!empty($stripeacc)) {
1371  $connect = $stripeacc.'/';
1372  }
1373  //$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
1374  $url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$src->id;
1375  if ($servicestatus) {
1376  //$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
1377  $url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$src->id;
1378  }
1379  print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
1380  print $src->id;
1381  print '</td>';
1382  // Img
1383  print '<td>';
1384  print $imgline;
1385  print'</td>';
1386  // Information
1387  print '<td valign="middle">';
1388  if ($src->object == 'card') {
1389  print '....'.$src->last4.' - '.$src->exp_month.'/'.$src->exp_year;
1390  print '</td><td>';
1391  if ($src->country) {
1392  $img = picto_from_langcode($src->country);
1393  print $img ? $img.' ' : '';
1394  print getCountry($src->country, 1);
1395  } else {
1396  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1397  }
1398  } elseif ($src->object == 'source' && $src->type == 'card') {
1399  print '<span class="opacitymedium">'.$src->owner->name.'</span><br>....'.$src->card->last4.' - '.$src->card->exp_month.'/'.$src->card->exp_year;
1400  print '</td><td>';
1401 
1402  if ($src->card->country) {
1403  $img = picto_from_langcode($src->card->country);
1404  print $img ? $img.' ' : '';
1405  print getCountry($src->card->country, 1);
1406  } else {
1407  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1408  }
1409  } elseif ($src->object == 'source' && $src->type == 'sepa_debit') {
1410  print '<span class="opacitymedium">'.$src->billing_details->name.'</span><br>....'.$src->sepa_debit->last4;
1411  print '</td><td>';
1412  if ($src->sepa_debit->country) {
1413  $img = picto_from_langcode($src->sepa_debit->country);
1414  print $img ? $img.' ' : '';
1415  print getCountry($src->sepa_debit->country, 1);
1416  } else {
1417  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1418  }
1419  } elseif ($src->object == 'payment_method' && $src->type == 'card') {
1420  print '<span class="opacitymedium">'.$src->billing_details->name.'</span><br>....'.$src->card->last4.' - '.$src->card->exp_month.'/'.$src->card->exp_year;
1421  print '</td><td>';
1422 
1423  if ($src->card->country) {
1424  $img = picto_from_langcode($src->card->country);
1425  print $img ? $img.' ' : '';
1426  print getCountry($src->card->country, 1);
1427  } else {
1428  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1429  }
1430  } elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
1431  print '<span class="opacitymedium">'.$src->billing_details->name.'</span><br>....'.$src->sepa_debit->last4;
1432  print '</td><td>';
1433  if ($src->sepa_debit->country) {
1434  $img = picto_from_langcode($src->sepa_debit->country);
1435  print $img ? $img.' ' : '';
1436  print getCountry($src->sepa_debit->country, 1);
1437  } else {
1438  print img_warning().' <span class="error">'.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).'</span>';
1439  }
1440  } else {
1441  print '</td><td>';
1442  }
1443  print '</td>';
1444  // Default
1445  print '<td class="center" width="50">';
1446  if ((empty($customerstripe->invoice_settings) && $customerstripe->default_source != $src->id) ||
1447  (!empty($customerstripe->invoice_settings) && $customerstripe->invoice_settings->default_payment_method != $src->id)) {
1448  print '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=setassourcedefault&token='.newToken().'">';
1449  print img_picto($langs->trans("Default"), 'off');
1450  print '</a>';
1451  } else {
1452  print img_picto($langs->trans("Default"), 'on');
1453  }
1454  print '</td>';
1455  print '<td>';
1456  print $langs->trans("Remote");
1457  //if ($src->cvc_check == 'fail') print ' - CVC check fail';
1458  print '</td>';
1459 
1460  print '<td>';
1461  //var_dump($src);
1462  print '</td>';
1463 
1464  // Fields from hook
1465  $parameters = array('arrayfields' => array(), 'stripesource' => $src, 'linetype' => 'stripecardremoteonly');
1466  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1467  print $hookmanager->resPrint;
1468 
1469  // Action column
1470  print '<td class="right nowraponall">';
1471  if ($permissiontoaddupdatepaymentinformation) {
1472  print '<a class="marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=deletecard&token='.newToken().'">';
1473  print img_picto($langs->trans("Delete"), 'delete');
1474  print '</a>';
1475  }
1476  print '</td>';
1477 
1478  print '</tr>';
1479  }
1480  }
1481 
1482  if ($nbremote == 0 && $nblocal == 0) {
1483  $colspan = (getDolGlobalString('STRIPE_ALLOW_LOCAL_CARD') ? 10 : 9);
1484  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
1485  }
1486  print "</table>";
1487  print "</div>";
1488  print '<br>';
1489  }
1490 
1491  // List of Stripe connect accounts
1492  if (isModEnabled('stripe') && !empty($conf->stripeconnect->enabled) && !empty($stripesupplieracc)) {
1493  print load_fiche_titre($langs->trans('StripeBalance').($stripesupplieracc ? ' (Stripe connection with StripeConnect account '.$stripesupplieracc.')' : ' (Stripe connection with keys from Stripe module setup)'), $morehtmlright, 'stripe-s');
1494  $balance = \Stripe\Balance::retrieve(array("stripe_account" => $stripesupplieracc));
1495  print '<table class="liste centpercent">'."\n";
1496  print '<tr class="liste_titre">';
1497  print '<td>'.$langs->trans('Currency').'</td>';
1498  print '<td>'.$langs->trans('Available').'</td>';
1499  print '<td>'.$langs->trans('Pending').'</td>';
1500  print '<td>'.$langs->trans('Total').'</td>';
1501  print '</tr>';
1502 
1503  $currencybalance = array();
1504  if (is_array($balance->available) && count($balance->available)) {
1505  foreach ($balance->available as $cpt) {
1506  $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
1507  if (!in_array($cpt->currency, $arrayzerounitcurrency)) {
1508  $currencybalance[$cpt->currency]['available'] = $cpt->amount / 100;
1509  } else {
1510  $currencybalance[$cpt->currency]['available'] = $cpt->amount;
1511  }
1512  $currencybalance[$cpt->currency]['currency'] = $cpt->currency;
1513  }
1514  }
1515 
1516  if (is_array($balance->pending) && count($balance->pending)) {
1517  foreach ($balance->pending as $cpt) {
1518  $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
1519  if (!in_array($cpt->currency, $arrayzerounitcurrency)) {
1520  $currencybalance[$cpt->currency]['pending'] = $currencybalance[$cpt->currency]['available'] + $cpt->amount / 100;
1521  } else {
1522  $currencybalance[$cpt->currency]['pending'] = $currencybalance[$cpt->currency]['available'] + $cpt->amount;
1523  }
1524  }
1525  }
1526 
1527  if (is_array($currencybalance)) {
1528  foreach ($currencybalance as $cpt) {
1529  print '<tr><td>'.$langs->trans("Currency".strtoupper($cpt['currency'])).'</td><td>'.price($cpt['available'], 0, '', 1, - 1, - 1, strtoupper($cpt['currency'])).'</td><td>'.price(isset($cpt->pending) ? $cpt->pending : 0, 0, '', 1, - 1, - 1, strtoupper($cpt['currency'])).'</td><td>'.price($cpt['available'] + (isset($cpt->pending) ? $cpt->pending : 0), 0, '', 1, - 1, - 1, strtoupper($cpt['currency'])).'</td></tr>';
1530  }
1531  }
1532 
1533  print '</table>';
1534  print '<br>';
1535  }
1536 
1537  // List of bank accounts
1538  if ($permissiontoaddupdatepaymentinformation) {
1539  $morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&amp;action=create');
1540  }
1541 
1542  print load_fiche_titre($langs->trans("BankAccounts"), $morehtmlright, 'bank');
1543 
1544  $nblocal = 0;
1545  $nbremote = 0;
1546  $arrayofremoteban = array();
1547 
1548  $rib_list = $object->get_all_rib();
1549 
1550  if (is_array($rib_list)) {
1551  print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
1552  print '<table class="liste centpercent">';
1553 
1554  print '<tr class="liste_titre">';
1555  print_liste_field_titre("Label");
1556  print_liste_field_titre($form->textwithpicto($langs->trans('ExternalSystemID'), $langs->trans("IDOfPaymentInAnExternalSystem"))); // external system ID
1557  print_liste_field_titre("Bank");
1558  print_liste_field_titre("RIB");
1559  print_liste_field_titre("IBAN");
1560  print_liste_field_titre("BIC");
1561  if (isModEnabled('prelevement')) {
1562  print_liste_field_titre("RUM");
1563  print_liste_field_titre("DateRUM");
1564  print_liste_field_titre("WithdrawMode");
1565  }
1566  print_liste_field_titre("Default", '', '', '', '', '', '', '', 'center ');
1567  if (!getDolGlobalInt('SOCIETE_DISABLE_BANKACCOUNT') && getDolGlobalInt("SOCIETE_RIB_ALLOW_ONLINESIGN")) {
1568  print_liste_field_titre('', '', '', '', '', '', '', '', 'center ');
1569  }
1570  print_liste_field_titre('', '', '', '', '', '', '', '', 'center ');
1571  // Fields from hook
1572  $parameters = array('arrayfields' => array(), 'linetype' => 'stripebantitle');
1573  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1574  print $hookmanager->resPrint;
1575  print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', '', '', 'maxwidthsearch ');
1576  print "</tr>\n";
1577 
1578  // List of local BAN
1579  foreach ($rib_list as $rib) {
1580  $arrayofremoteban[$rib->stripe_card_ref] = $rib->stripe_card_ref;
1581 
1582  $nblocal++;
1583 
1584  print '<tr class="oddeven">';
1585  // Label
1586  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($rib->label).'">'.dol_escape_htmltag($rib->label).'</td>';
1587  // External system ID
1588  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($rib->stripe_card_ref.(empty($rib->stripe_account) ? '' : ' - '.$rib->stripe_account)).'">';
1589  if (!empty($rib->stripe_card_ref) && !empty($rib->ext_payment_site)) {
1590  if (isModEnabled('stripe') && in_array($rib->ext_payment_site, array('StripeTest', 'StripeLive'))) {
1591  $connect = '';
1592  if (!empty($stripeacc)) {
1593  $connect = $stripeacc.'/';
1594  }
1595  if ($rib->ext_payment_site == 'StripeLive') {
1596  $url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$rib->stripe_card_ref;
1597  } else {
1598  $url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$rib->stripe_card_ref;
1599  }
1600  print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
1601  }
1602  // TODO Add hook here for other payment services
1603  }
1604  print dol_escape_htmltag($rib->stripe_card_ref);
1605  print '</td>';
1606  // Bank name
1607  print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->bank).'">'.dol_escape_htmltag($rib->bank).'</td>';
1608  // Account number
1609  $string = '';
1610  foreach ($rib->getFieldsToShow() as $val) {
1611  if ($val == 'BankCode') {
1612  $string .= $rib->code_banque.' ';
1613  } elseif ($val == 'BankAccountNumber') {
1614  $string .= $rib->number.' ';
1615  } elseif ($val == 'DeskCode') {
1616  $string .= $rib->code_guichet.' ';
1617  } elseif ($val == 'BankAccountNumberKey') {
1618  $string .= $rib->cle_rib.' ';
1619  }
1620  // Already output after
1621  // } elseif ($val == 'BIC') {
1622  // $string .= $rib->bic.' ';
1623  // } elseif ($val == 'IBAN') {
1624  // $string .= $rib->iban.' ';*/
1625  //}
1626  }
1627  if (!empty($rib->label) && $rib->number) {
1628  if (!checkBanForAccount($rib)) {
1629  $string .= ' '.img_picto($langs->trans("ValueIsNotValid"), 'warning');
1630  } else {
1631  $string .= ' '.img_picto($langs->trans("ValueIsValid"), 'info');
1632  }
1633  }
1634  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($string).'">';
1635  print $string;
1636  print '</td>';
1637  // IBAN
1638  print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->iban).'">';
1639  if (!empty($rib->iban)) {
1640  if (!checkIbanForAccount($rib)) {
1641  print img_picto($langs->trans("IbanNotValid"), 'warning').' ';
1642  }
1643  }
1644  print dol_escape_htmltag($rib->iban);
1645  print '</td>';
1646  // BIC
1647  print '<td>';
1648  if (!empty($rib->bic)) {
1649  if (!checkSwiftForAccount($rib)) {
1650  print img_picto($langs->trans("SwiftNotValid"), 'warning').' ';
1651  }
1652  }
1653  print dol_escape_htmltag($rib->bic);
1654  print '</td>';
1655 
1656  if (isModEnabled('prelevement')) {
1657  // RUM
1658  //print '<td>'.$prelevement->buildRumNumber($object->code_client, $rib->datec, $rib->id).'</td>';
1659  print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->rum).'">'.dol_escape_htmltag($rib->rum).'</td>';
1660 
1661  print '<td>'.dol_print_date($rib->date_rum, 'day').'</td>';
1662 
1663  // FRST or RCUR
1664  print '<td>'.dol_escape_htmltag($rib->frstrecur).'</td>';
1665  }
1666 
1667  // Default
1668  print '<td class="center" width="70">';
1669  if (!$rib->default_rib) {
1670  print '<a href="'.$_SERVER["PHP_SELF"].'?socid='.((int) $object->id).'&ribid='.((int) $rib->id).'&action=setasbankdefault&token='.newToken().'">';
1671  print img_picto($langs->trans("Disabled"), 'off');
1672  print '</a>';
1673  } else {
1674  print img_picto($langs->trans("Enabled"), 'on');
1675  }
1676  print '</td>';
1677 
1678  // Generate doc
1679  print '<td class="center">';
1680 
1681  $buttonlabel = $langs->trans("BuildDoc");
1682  $forname = 'builddocrib'.$rib->id;
1683 
1684  include_once DOL_DOCUMENT_ROOT.'/core/modules/bank/modules_bank.php';
1685  $modellist = ModeleBankAccountDoc::liste_modeles($db);
1686 
1687  $out = '';
1688  if (is_array($modellist) && count($modellist)) {
1689  $out .= '<form action="'.$_SERVER["PHP_SELF"].(!getDolGlobalString('MAIN_JUMP_TAG') ? '' : '#builddoc').'" name="'.$forname.'" id="'.$forname.'_form" method="post">';
1690  $out .= '<input type="hidden" name="action" value="builddocrib">';
1691  $out .= '<input type="hidden" name="token" value="'.newToken().'">';
1692  $out .= '<input type="hidden" name="socid" value="'.$object->id.'">';
1693  $out .= '<input type="hidden" name="companybankid" value="'.$rib->id.'">';
1694 
1695  $modelselected = '';
1696  if (count($modellist) == 1) { // If there is only one element
1697  $arraykeys = array_keys($modellist);
1698  $modelselected = $arraykeys[0];
1699  }
1700  if (getDolGlobalString('BANKADDON_PDF')) {
1701  $modelselected = getDolGlobalString('BANKADDON_PDF');
1702  }
1703 
1704  $out .= $form->selectarray('modelrib'.$rib->id, $modellist, $modelselected, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100 maxwidth125');
1705  $out .= ajax_combobox('modelrib'.$rib->id);
1706 
1707  // Language code (if multilang)
1708  if (getDolGlobalInt('MAIN_MULTILANGS')) {
1709  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
1710  $formadmin = new FormAdmin($db);
1711  $defaultlang = $langs->getDefaultLang();
1712  $morecss = 'maxwidth150';
1713  if ($conf->browser->layout == 'phone') {
1714  $morecss = 'maxwidth100';
1715  }
1716  $out .= $formadmin->select_language($defaultlang, 'lang_idrib'.$rib->id, 0, 0, 0, 0, 0, $morecss);
1717  }
1718  // Button
1719  $out .= '<input class="button buttongen reposition nomargintop nomarginbottom" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
1720  $out .= ' type="submit" value="'.$buttonlabel.'"';
1721  $out .= '>';
1722  $out .= '</form>';
1723  }
1724  print $out;
1725  print '</td>';
1726 
1727  // Fields from hook
1728  $parameters = array('arrayfields' => array(), 'stripe_card_ref' => $rib->stripe_card_ref, 'stripe_account' => $rib->stripe_account, 'linetype' => 'stripeban');
1729  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1730  print $hookmanager->resPrint;
1731 
1732  if (!getDolGlobalInt('SOCIETE_DISABLE_BANKACCOUNT') && getDolGlobalInt("SOCIETE_RIB_ALLOW_ONLINESIGN")) {
1733  // Show online signature link
1734  print '<td class="width200">';
1735  $useonlinesignature = 1;
1736  if ($useonlinesignature) {
1737  require_once DOL_DOCUMENT_ROOT . '/core/lib/signature.lib.php';
1738  print showOnlineSignatureUrl($companybankaccount->element, $rib->id, $rib, 'short');
1739  }
1740  print '</td>';
1741  }
1742 
1743  // Edit/Delete
1744  print '<td class="right nowraponall">';
1745  if ($permissiontoaddupdatepaymentinformation) {
1746  if (isModEnabled('stripe')) {
1747  if (empty($rib->stripe_card_ref)) {
1748  if ($object->client) {
1749  // Add link to create BAN on Stripe
1750  print '<a class="editfielda marginrightonly marginleftonly" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=syncsepatostripe&token='.newToken().'">';
1751  print img_picto($langs->trans("CreateBANOnStripe"), 'stripe');
1752  print '</a>';
1753  } else {
1754  print '<span class="opacitymedium marginrightonly marginleftonly">';
1755  print img_picto($langs->trans("ThirdPartyMustBeACustomerToCreateBANOnStripe"), 'stripe');
1756  print '</span>';
1757  }
1758  }
1759  }
1760 
1761  print '<a class="editfielda marginrightonly marginleftonly" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=edit">';
1762  print img_picto($langs->trans("Modify"), 'edit');
1763  print '</a>';
1764 
1765  print '<a class="marginrightonly marginleftonly reposition" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=deletebank&token='.newToken().'">';
1766  print img_picto($langs->trans("Delete"), 'delete');
1767  print '</a>';
1768  }
1769  print '</td>';
1770 
1771  print '</tr>';
1772  }
1773 
1774 
1775  // List of remote BAN (if not already added as local)
1776  foreach ($listofsources as $src) {
1777  if (!empty($arrayofremoteban[$src->id])) {
1778  continue; // Already in previous list
1779  }
1780 
1781  $imgline = '';
1782  if ($src->object == 'source' && $src->type == 'sepa_debit') {
1783  $imgline = '<span class="fa fa-university fa-2x fa-fw"></span>';
1784  } elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
1785  $imgline = '<span class="fa fa-university fa-2x fa-fw"></span>';
1786  } else {
1787  continue;
1788  }
1789 
1790  $nbremote++;
1791 
1792  print '<tr class="oddeven">';
1793  print '<td>';
1794  print '</td>';
1795  // Src ID
1796  print '<td class="tdoverflowmax150">';
1797  $connect = '';
1798  if (!empty($stripeacc)) {
1799  $connect = $stripeacc.'/';
1800  }
1801  //$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
1802  $url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$src->id;
1803  if ($servicestatus) {
1804  //$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
1805  $url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$src->id;
1806  }
1807  print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
1808  print $src->id;
1809  print '</td>';
1810  // Bank
1811  print '<td>';
1812  print'</td>';
1813  // Account number
1814  print '<td valign="middle">';
1815  print '</td>';
1816  // IBAN
1817  print '<td valign="middle">';
1818  //var_dump($src);
1819  print '</td>';
1820  // BIC
1821  print '<td valign="middle">';
1822  //var_dump($src);
1823  print '</td>';
1824 
1825  if (isModEnabled('prelevement')) {
1826  // RUM
1827  print '<td valign="middle">';
1828  //var_dump($src);
1829  print '</td>';
1830  // Date
1831  print '<td valign="middle">';
1832  //var_dump($src);
1833  print '</td>';
1834  // Mode mandate
1835  print '<td valign="middle">';
1836  //var_dump($src);
1837  print '</td>';
1838  }
1839 
1840  // Default
1841  print '<td class="center" width="50">';
1842  if ((empty($customerstripe->invoice_settings) && $customerstripe->default_source != $src->id) ||
1843  (!empty($customerstripe->invoice_settings) && $customerstripe->invoice_settings->default_payment_method != $src->id)) {
1844  print '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=setassourcedefault&token='.newToken().'">';
1845  print img_picto($langs->trans("Default"), 'off');
1846  print '</a>';
1847  } else {
1848  print img_picto($langs->trans("Default"), 'on');
1849  }
1850  print '</td>';
1851  /*
1852  print '<td>';
1853  print $langs->trans("Remote");
1854  //if ($src->cvc_check == 'fail') print ' - CVC check fail';
1855  print '</td>';
1856  */
1857 
1858  print '<td>';
1859  print '</td>';
1860 
1861  // Fields from hook
1862  $parameters = array('arrayfields' => array(), 'stripe_card_ref' => $rib->stripe_card_ref, 'stripe_account' => $rib->stripe_account, 'linetype' => 'stripebanremoteonly');
1863  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
1864  print $hookmanager->resPrint;
1865 
1866  // Action column
1867  print '<td class="right nowraponall">';
1868  if ($permissiontoaddupdatepaymentinformation) {
1869  print '<a class="marginleftonly marginrightonly reposition" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=deletebank&token='.newToken().'">';
1870  print img_picto($langs->trans("Delete"), 'delete');
1871  print '</a>';
1872  }
1873  print '</td>';
1874 
1875  print '</tr>';
1876  }
1877 
1878  if ($nbremote == 0 && $nblocal == 0) {
1879  $colspan = 10;
1880  if (isModEnabled('prelevement')) {
1881  $colspan += 3;
1882  }
1883  print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoBANRecord").'</span></td></tr>';
1884  }
1885 
1886  print '</table>';
1887  print '</div>';
1888  } else {
1889  dol_print_error($db);
1890  }
1891 
1892  //Hook to display your print listing (list of CB card from Stancer Plugin for example)
1893  $parameters = array('arrayfields' => array(), 'param' => '', 'sortfield' => '', 'sortorder' => '', 'linetype' => '');
1894  $reshook = $hookmanager->executeHooks('printNewTable', $parameters, $object);
1895  print $hookmanager->resPrint;
1896 
1897  if (!getDolGlobalString('SOCIETE_DISABLE_BUILDDOC')) {
1898  print '<br>';
1899 
1900  print '<div class="fichecenter"><div class="fichehalfleft">';
1901  print '<a name="builddoc"></a>'; // ancre
1902 
1903  /*
1904  * Generated documents
1905  */
1906  $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id;
1907  $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id;
1908 
1909  print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $permissiontoread, $permissiontoaddupdatepaymentinformation, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang);
1910 
1911  // Show direct download link
1912  if (getDolGlobalString('BANK_ACCOUNT_ALLOW_EXTERNAL_DOWNLOAD')) {
1913  $companybankaccounttemp = new CompanyBankAccount($db);
1914  $companypaymentmodetemp = new CompanyPaymentMode($db);
1915  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1916  $result = $companypaymentmodetemp->fetch(0, null, $object->id, 'ban');
1917 
1918  include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
1919  $ecmfile = new EcmFiles($db);
1920  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1921  $result = $ecmfile->fetch(0, '', '', '', '', $companybankaccounttemp->table_element, $companypaymentmodetemp->id);
1922  if ($result > 0) {
1923  $companybankaccounttemp->last_main_doc = $ecmfile->filepath.'/'.$ecmfile->filename;
1924  print '<br><!-- Link to download main doc -->'."\n";
1925  print showDirectDownloadLink($companybankaccounttemp).'<br>';
1926  }
1927  }
1928 
1929  print '</div><div class="fichehalfright">';
1930 
1931 
1932  print '</div></div>';
1933 
1934  print '<br>';
1935  }
1936  /*
1937  include_once DOL_DOCUMENT_ROOT.'/core/modules/bank/modules_bank.php';
1938  $modellist=ModeleBankAccountDoc::liste_modeles($db);
1939  //print '<td>';
1940  if (is_array($modellist) && count($modellist) == 1) // If there is only one element
1941  {
1942  $arraykeys=array_keys($modellist);
1943  $modelselected=$arraykeys[0];
1944  }
1945  $out.= $form->selectarray('model', $modellist, $modelselected, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100');
1946  $out.= ajax_combobox('model');
1947  //print $out;
1948  $buttonlabel=$langs->trans("Generate");
1949  $genbutton = '<input class="button buttongen reposition nomargintop nomarginbottom" id="'.$forname.'_generatebutton" name="'.$forname.'_generatebutton"';
1950  $genbutton.= ' type="submit" value="'.$buttonlabel.'"';
1951  $genbutton.= '>';
1952  print $genbutton;
1953  //print '</td>'; // TODO Add link to generate doc
1954  */
1955 }
1956 
1957 // Edit BAN
1958 if ($socid && $action == 'edit' && $permissiontoaddupdatepaymentinformation) {
1959  print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company');
1960 
1961  $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1962 
1963  dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
1964 
1965  print '<div class="underbanner clearboth"></div>';
1966 
1967  print '<br>';
1968 
1969  print '<div class="div-table-responsive-no-min">';
1970  print '<table class="border centpercent">';
1971 
1972  print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Label").'</td>';
1973  print '<td><input class="minwidth300" type="text" name="label" value="'.$companybankaccount->label.'"></td></tr>';
1974 
1975  print '<tr><td class="fieldrequired">'.$langs->trans("BankName").'</td>';
1976  print '<td><input class="minwidth200" type="text" name="bank" value="'.$companybankaccount->bank.'"></td></tr>';
1977 
1978  // Show fields of bank account
1979  $bankaccount = $companybankaccount;
1980  // Code here is similar as in bank.php for users
1981  foreach ($bankaccount->getFieldsToShow(1) as $val) {
1982  $require = false;
1983  $tooltip = '';
1984  if ($val == 'BankCode') {
1985  $name = 'code_banque';
1986  $size = 8;
1987  $content = $bankaccount->code_banque;
1988  } elseif ($val == 'DeskCode') {
1989  $name = 'code_guichet';
1990  $size = 8;
1991  $content = $bankaccount->code_guichet;
1992  } elseif ($val == 'BankAccountNumber') {
1993  $name = 'number';
1994  $size = 18;
1995  $content = $bankaccount->number;
1996  } elseif ($val == 'BankAccountNumberKey') {
1997  $name = 'cle_rib';
1998  $size = 3;
1999  $content = $bankaccount->cle_rib;
2000  } elseif ($val == 'IBAN') {
2001  $name = 'iban';
2002  $size = 30;
2003  $content = $bankaccount->iban;
2004  if ($bankaccount->needIBAN()) {
2005  $require = true;
2006  }
2007  $tooltip = $langs->trans("Example").':<br>CH93 0076 2011 6238 5295 7<br>LT12 1000 0111 0100 1000<br>FR14 2004 1010 0505 0001 3M02 606<br>LU28 0019 4006 4475 0000<br>DE89 3704 0044 0532 0130 00';
2008  } elseif ($val == 'BIC') {
2009  $name = 'bic';
2010  $size = 12;
2011  $content = $bankaccount->bic;
2012  if ($bankaccount->needIBAN()) {
2013  $require = true;
2014  }
2015  $tooltip = $langs->trans("Example").': LIABLT2XXXX';
2016  }
2017 
2018  print '<tr>';
2019  print '<td'.($require ? ' class="fieldrequired" ' : '').'>';
2020  if ($tooltip) {
2021  print $form->textwithpicto($langs->trans($val), $tooltip, 4, 'help', '', 0, 3, $name);
2022  } else {
2023  print $langs->trans($val);
2024  }
2025  print '</td>';
2026  print '<td><input size="'.$size.'" type="text" class="flat" name="'.$name.'" value="'.$content.'"></td>';
2027  print '</tr>';
2028  }
2029 
2030  print '<tr><td class="tdtop">'.$langs->trans("BankAccountDomiciliation").'</td><td>';
2031  print '<textarea name="address" rows="4" cols="40" maxlength="255">';
2032  print $companybankaccount->address;
2033  print "</textarea></td></tr>";
2034 
2035  print '<tr><td>'.$langs->trans("BankAccountOwner").'</td>';
2036  print '<td><input class="minwidth300" type="text" name="proprio" value="'.$companybankaccount->owner_name.'"></td></tr>';
2037  print "</td></tr>\n";
2038 
2039  print '<tr><td class="tdtop">'.$langs->trans("BankAccountOwnerAddress").'</td><td>';
2040  print '<textarea name="owner_address" rows="'.ROWS_4.'" cols="40" maxlength="255">';
2041  print $companybankaccount->owner_address;
2042  print "</textarea></td></tr>";
2043 
2044  print '</table>';
2045  print '</div>';
2046 
2047  if (isModEnabled('prelevement')) {
2048  print '<br>';
2049 
2050  print '<div class="div-table-responsive-no-min">';
2051  print '<table class="border centpercent">';
2052 
2053  if (empty($companybankaccount->rum)) {
2054  $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id);
2055  }
2056 
2057  // RUM
2058  print '<tr><td class="titlefield">'.$langs->trans("RUM").'</td>';
2059  print '<td><input class="minwidth300" type="text" name="rum" value="'.dol_escape_htmltag($companybankaccount->rum).'"></td></tr>';
2060 
2061  $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear'));
2062 
2063  print '<tr><td class="titlefield">'.$langs->trans("DateRUM").'</td>';
2064  print '<td>'.$form->selectDate($date_rum ? $date_rum : $companybankaccount->date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).'</td></tr>';
2065 
2066  print '<tr><td>'.$langs->trans("WithdrawMode").'</td><td>';
2067  $tblArraychoice = array("FRST" => $langs->trans("FRST"), "RCUR" => $langs->trans("RECUR"));
2068  print $form->selectarray("frstrecur", $tblArraychoice, dol_escape_htmltag(GETPOST('frstrecur', 'alpha') ? GETPOST('frstrecur', 'alpha') : $companybankaccount->frstrecur), 0);
2069  print '</td></tr>';
2070 
2071  print '<tr><td>'.$langs->trans("ExternalSystemID")." ('pm_...' or 'src_...')</td>";
2072  print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.$companypaymentmode->stripe_card_ref.'"></td></tr>';
2073 
2074  print '</table>';
2075  print '</div>';
2076  }
2077 
2078 
2079  print dol_get_fiche_end();
2080 
2081  print $form->buttonsSaveCancel("Modify");
2082 }
2083 
2084 // Edit Card
2085 if ($socid && $action == 'editcard' && $permissiontoaddupdatepaymentinformation) {
2086  print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company');
2087 
2088  $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
2089 
2090  dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
2091 
2092  print '<div class="nofichecenter">';
2093 
2094  print '<div class="underbanner clearboth"></div>';
2095 
2096  print '<br>';
2097 
2098  print '<table class="border centpercent">';
2099 
2100  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
2101  print '<td><input class="minwidth300" type="text" id="label" name="label" value="'.$companypaymentmode->label.'"></td></tr>';
2102 
2103  print '<tr><td class="fieldrequired">'.$langs->trans("NameOnCard").'</td>';
2104  print '<td><input class="minwidth200" type="text" name="proprio" value="'.$companypaymentmode->proprio.'"></td></tr>';
2105 
2106  print '<tr><td>'.$langs->trans("CardNumber").'</td>';
2107  print '<td><input class="minwidth200" type="text" name="cardnumber" value="'.$companypaymentmode->number.'"></td></tr>';
2108 
2109  print '<tr><td class="fieldrequired">'.$langs->trans("ExpiryDate").'</td>';
2110  print '<td>';
2111  print $formother->select_month($companypaymentmode->exp_date_month, 'exp_date_month', 1);
2112  print $formother->selectyear($companypaymentmode->exp_date_year, 'exp_date_year', 1, 5, 10, 0, 0, '', 'marginleftonly');
2113  print '</td></tr>';
2114 
2115  print '<tr><td>'.$langs->trans("CVN").'</td>';
2116  print '<td><input size="8" type="text" name="cvn" value="'.$companypaymentmode->cvn.'"></td></tr>';
2117 
2118  print '<tr><td>'.$langs->trans("ExternalSystemID")." ('pm_... ".$langs->trans("or")." card_....')</td>";
2119  print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.$companypaymentmode->stripe_card_ref.'"></td></tr>';
2120 
2121  print '</table>';
2122  print '</div>';
2123 
2124  print dol_get_fiche_end();
2125 
2126  print $form->buttonsSaveCancel("Modify");
2127 }
2128 
2129 
2130 // Create BAN
2131 if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) {
2132  print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company');
2133 
2134  $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
2135 
2136  dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
2137 
2138  print '<div class="nofichecenter">';
2139 
2140  print '<div class="underbanner clearboth"></div>';
2141 
2142  print '<br>';
2143 
2144  print '<table class="border centpercent">';
2145 
2146  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
2147  print '<td><input class="minwidth200" type="text" id="label" name="label" value="'.(GETPOSTISSET('label') ? GETPOST('label') : $object->name).'"></td></tr>';
2148 
2149  print '<tr><td>'.$langs->trans("Bank").'</td>';
2150  print '<td><input class="minwidth200" type="text" id="bank" name="bank" value="'.GETPOST('bank').'"></td></tr>';
2151 
2152  // Show fields of bank account
2153  foreach ($companybankaccount->getFieldsToShow(1) as $val) {
2154  $require = false;
2155  $tooltip = '';
2156  if ($val == 'BankCode') {
2157  $name = 'code_banque';
2158  $size = 8;
2159  $content = $companybankaccount->code_banque;
2160  } elseif ($val == 'DeskCode') {
2161  $name = 'code_guichet';
2162  $size = 8;
2163  $content = $companybankaccount->code_guichet;
2164  } elseif ($val == 'BankAccountNumber') {
2165  $name = 'number';
2166  $size = 18;
2167  $content = $companybankaccount->number;
2168  } elseif ($val == 'BankAccountNumberKey') {
2169  $name = 'cle_rib';
2170  $size = 3;
2171  $content = $companybankaccount->cle_rib;
2172  } elseif ($val == 'IBAN') {
2173  $name = 'iban';
2174  $size = 30;
2175  $content = $companybankaccount->iban;
2176  if ($companybankaccount->needIBAN()) {
2177  $require = true;
2178  }
2179  $tooltip = $langs->trans("Example").':<br>CH93 0076 2011 6238 5295 7<br>LT12 1000 0111 0100 1000<br>FR14 2004 1010 0505 0001 3M02 606<br>LU28 0019 4006 4475 0000<br>DE89 3704 0044 0532 0130 00';
2180  } elseif ($val == 'BIC') {
2181  $name = 'bic';
2182  $size = 12;
2183  $content = $companybankaccount->bic;
2184  if ($companybankaccount->needIBAN()) {
2185  $require = true;
2186  }
2187  $tooltip = $langs->trans("Example").': LIABLT2XXXX';
2188  }
2189 
2190  print '<tr><td'.($require ? ' class="fieldrequired" ' : '').'>';
2191  if ($tooltip) {
2192  print $form->textwithpicto($langs->trans($val), $tooltip, 4, 'help', '', 0, 3, $name);
2193  } else {
2194  print $langs->trans($val);
2195  }
2196  print '</td>';
2197  print '<td><input size="'.$size.'" type="text" class="flat" name="'.$name.'" value="'.GETPOST($name).'"></td>';
2198  print '</tr>';
2199  }
2200 
2201  print '<tr><td class="tdtop">'.$langs->trans("BankAccountDomiciliation").'</td><td>';
2202  print '<textarea name="address" rows="'.ROWS_4.'" class="quatrevingtpercent" maxlength="255">';
2203  print GETPOST('address');
2204  print "</textarea></td></tr>";
2205 
2206  print '<tr><td>'.$langs->trans("BankAccountOwner").'</td>';
2207  print '<td><input class="minwidth200" type="text" name="proprio" value="'.GETPOST('proprio').'"></td></tr>';
2208  print "</td></tr>\n";
2209 
2210  print '<tr><td class="tdtop">'.$langs->trans("BankAccountOwnerAddress").'</td><td>';
2211  print '<textarea name="owner_address" rows="'.ROWS_4.'" class="quatrevingtpercent" maxlength="255">';
2212  print GETPOST('owner_address');
2213  print "</textarea></td></tr>";
2214 
2215  print '</table>';
2216 
2217  if (isModEnabled('prelevement')) {
2218  print '<br>';
2219 
2220  print '<table class="border centpercent">';
2221 
2222  // RUM
2223  print '<tr><td class="titlefieldcreate">'.$form->textwithpicto($langs->trans("RUM"), $langs->trans("RUMLong").'<br>'.$langs->trans("RUMWillBeGenerated")).'</td>';
2224  print '<td colspan="4"><input type="text" class="minwidth300" name="rum" value="'.GETPOST('rum', 'alpha').'"></td></tr>';
2225 
2226  $date_rum = dol_mktime(0, 0, 0, GETPOST('date_rummonth'), GETPOST('date_rumday'), GETPOST('date_rumyear'));
2227 
2228  print '<tr><td class="titlefieldcreate">'.$langs->trans("DateRUM").'</td>';
2229  print '<td colspan="4">'.$form->selectDate($date_rum, 'date_rum', 0, 0, 1, 'date_rum', 1, 1).'</td></tr>';
2230 
2231  print '<tr><td>'.$langs->trans("WithdrawMode").'</td><td>';
2232  $tblArraychoice = array("FRST" => $langs->trans("FRST"), "RCUR" => $langs->trans("RECUR"));
2233  print $form->selectarray("frstrecur", $tblArraychoice, (GETPOSTISSET('frstrecur') ? GETPOST('frstrecur') : 'FRST'), 0);
2234  print '</td></tr>';
2235 
2236  print '<tr><td>'.$langs->trans("ExternalSystemID")." ('src_....')</td>";
2237  print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.GETPOST('stripe_card_ref', 'alpha').'"></td></tr>';
2238 
2239  print '</table>';
2240  }
2241 
2242  print '</div>';
2243 
2244  print dol_get_fiche_end();
2245 
2246  dol_set_focus('#bank');
2247 
2248  print $form->buttonsSaveCancel("Add");
2249 }
2250 
2251 // Create Card
2252 if ($socid && $action == 'createcard' && $permissiontoaddupdatepaymentinformation) {
2253  print dol_get_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company');
2254 
2255  $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
2256 
2257  dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
2258 
2259  print '<div class="nofichecenter">';
2260 
2261  print '<div class="underbanner clearboth"></div>';
2262 
2263  print '<br>';
2264 
2265  print '<table class="border centpercent">';
2266 
2267  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
2268  print '<td><input class="minwidth200" type="text" id="label" name="label" value="'.GETPOST('label', 'alpha').'"></td></tr>';
2269 
2270  print '<tr><td class="fieldrequired">'.$langs->trans("NameOnCard").'</td>';
2271  print '<td><input class="minwidth200" type="text" name="proprio" value="'.GETPOST('proprio', 'alpha').'"></td></tr>';
2272 
2273  print '<tr><td>'.$langs->trans("CardNumber").'</td>';
2274  print '<td><input class="minwidth200" type="text" name="cardnumber" value="'.GETPOST('cardnumber', 'alpha').'"></td></tr>';
2275 
2276  print '<tr><td class="fieldrequired">'.$langs->trans("ExpiryDate").'</td>';
2277  print '<td>';
2278  print $formother->select_month(GETPOSTINT('exp_date_month'), 'exp_date_month', 1);
2279  print $formother->selectyear(GETPOSTINT('exp_date_year'), 'exp_date_year', 1, 5, 10, 0, 0, '', 'marginleftonly');
2280  print '</td></tr>';
2281 
2282  print '<tr><td>'.$langs->trans("CVN").'</td>';
2283  print '<td><input class="width50" type="text" name="cvn" value="'.GETPOST('cvn', 'alpha').'"></td></tr>';
2284 
2285  print '<tr><td>'.$langs->trans("ExternalSystemID")." ('card_....')</td>";
2286  print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.GETPOST('stripe_card_ref', 'alpha').'"></td></tr>';
2287 
2288  print '</table>';
2289 
2290  print '</div>';
2291 
2292  print dol_get_fiche_end();
2293 
2294  dol_set_focus('#label');
2295 
2296  print $form->buttonsSaveCancel("Add");
2297 }
2298 
2299 if ($socid && ($action == 'edit' || $action == 'editcard') && $permissiontoaddupdatepaymentinformation) {
2300  print '</form>';
2301 }
2302 if ($socid && ($action == 'create' || $action == 'createcard') && $permissiontoaddupdatepaymentinformation) {
2303  print '</form>';
2304 }
2305 
2306 // End of page
2307 llxFooter();
2308 $db->close();
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:456
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
checkSwiftForAccount(Account $account=null, $swift=null)
Check SWIFT information for a bank account.
Definition: bank.lib.php:284
checkIbanForAccount(Account $account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition: bank.lib.php:305
checkBanForAccount($account)
Check account number information for a bank account.
Definition: bank.lib.php:348
Class to manage withdrawal receipts.
Class to manage bank accounts description of third parties.
Class for CompanyPaymentMode.
Class to manage ECM files.
Class to manage standard extra fields.
Class to generate html code for admin pages.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class for SocieteAccount.
Class to manage third parties objects (customers, suppliers, prospects...)
Stripe class @TODO No reason to extends CommonObject.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
societe_prepare_head(Societe $object)
Return array of tabs to used on pages for third parties cards.
Definition: company.lib.php:43
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
showDirectDownloadLink($object)
Return string with full Url.
dol_htmloutput_mesg($mesgstring='', $mesgarray=array(), $style='ok', $keepembedded=0)
Print formatted messages to output (Used to show messages on html output).
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_credit_card($brand, $morecss=null)
Return image of a credit card according to its brand name.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:126
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.