From 3e02dc2465533591ffa45a78fa0563de72a78566 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 26 Apr 2019 13:23:30 +0200 Subject: [PATCH 01/75] FIX : dolibarrize fk_soc ->socid for member --- htdocs/adherents/class/adherent.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 201b6610817..00534dd3879 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -86,6 +86,7 @@ class Adherent extends CommonObject * @var int Thirdparty ID */ public $fk_soc; + public $socid; /** * @var string Address @@ -1275,6 +1276,7 @@ class Adherent extends CommonObject $this->societe = $obj->company; $this->company = $obj->company; $this->fk_soc = $obj->fk_soc; + $this->socid = $obj->fk_soc; $this->address = $obj->address; $this->zip = $obj->zip; $this->town = $obj->town; From 9b9295ab50d544f91189c54cab21a8704ded4790 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 26 Apr 2019 14:25:58 +0200 Subject: [PATCH 02/75] Update adherent.class.php --- htdocs/adherents/class/adherent.class.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 00534dd3879..9c32417efb4 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -10,6 +10,7 @@ * Copyright (C) 2015-2018 Frédéric France * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Juanjo Menent + * Copyright (C) 2018-2019 Thibault FOUCART * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +87,6 @@ class Adherent extends CommonObject * @var int Thirdparty ID */ public $fk_soc; - public $socid; /** * @var string Address @@ -558,7 +558,7 @@ class Adherent extends CommonObject $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman' $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); - $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); + $sql.= ", fk_soc = ".($this->socid > 0?$this->db->escape($this->socid):"null"); $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); @@ -1276,7 +1276,6 @@ class Adherent extends CommonObject $this->societe = $obj->company; $this->company = $obj->company; $this->fk_soc = $obj->fk_soc; - $this->socid = $obj->fk_soc; $this->address = $obj->address; $this->zip = $obj->zip; $this->town = $obj->town; From 423c5c3ac8adadaddd39d4ed9297104591175a13 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 26 Apr 2019 14:26:50 +0200 Subject: [PATCH 03/75] Update card.php --- htdocs/adherents/card.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 9903255e52f..5d57208eb0e 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -82,7 +82,7 @@ if (! empty($canvas)) } // Security check -$result=restrictedArea($user, 'adherent', $id, '', '', 'fk_soc', 'rowid', $objcanvas); +$result=restrictedArea($user, 'adherent', $id, '', '', 'socid', 'rowid', $objcanvas); if ($id > 0) { @@ -163,10 +163,10 @@ if (empty($reshook)) $error=0; if (! $error) { - if ($socid != $object->fk_soc) // If link differs from currently in database + if ($socid != $object->socid) // If link differs from currently in database { $sql ="SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql.=" WHERE fk_soc = '".$socid."'"; + $sql.=" WHERE socid = '".$socid."'"; $sql.=" AND entity = ".$conf->entity; $resql = $db->query($sql); if ($resql) @@ -492,7 +492,7 @@ if (empty($reshook)) //$object->note = $comment; $object->morphy = $morphy; $object->user_id = $userid; - $object->fk_soc = $socid; + $object->socid = $socid; $object->public = $public; // Fill array 'array_options' with data from add form @@ -1333,10 +1333,10 @@ else if (! empty($conf->societe->enabled)) { print ''.$langs->trans("LinkedToDolibarrThirdParty").''; - if ($object->fk_soc) + if ($object->socid) { $company=new Societe($db); - $result=$company->fetch($object->fk_soc); + $result=$company->fetch($object->socid); print $company->getNomUrl(1); } else @@ -1421,7 +1421,7 @@ else $text=$langs->trans("ConfirmCreateLogin").'
'; if (! empty($conf->societe->enabled)) { - if ($object->fk_soc > 0) $text.=$langs->trans("UserWillBeExternalUser"); + if ($object->socid > 0) $text.=$langs->trans("UserWillBeExternalUser"); else $text.=$langs->trans("UserWillBeInternalUser"); } print $form->formconfirm($_SERVER["PHP_SELF"]."?rowid=".$object->id, $langs->trans("CreateDolibarrLogin"), $text, "confirm_create_user", $formquestion, 'yes'); @@ -1688,17 +1688,17 @@ else print ''; print ''; print ''; print ''; print '
'; - print $form->select_company($object->fk_soc, 'socid', '', 1); + print $form->select_company($object->socid, 'socid', '', 1); print '
'; } else { - if ($object->fk_soc) + if ($object->socid) { $company=new Societe($db); - $result=$company->fetch($object->fk_soc); + $result=$company->fetch($object->socid); print $company->getNomUrl(1); } else @@ -1848,7 +1848,7 @@ else } // Create third party - if (! empty($conf->societe->enabled) && ! $object->fk_soc) + if (! empty($conf->societe->enabled) && ! $object->socid) { if ($user->rights->societe->creer) { From 485bc8cd7c964393a197e4dcb974eedaff2105f1 Mon Sep 17 00:00:00 2001 From: Mavyre Date: Fri, 26 Apr 2019 14:45:59 +0200 Subject: [PATCH 04/75] Corrected syncRates parameter --- htdocs/multicurrency/class/multicurrency.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index ea39cb85b8e..2abfb0e2624 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -629,7 +629,7 @@ class MultiCurrency extends CommonObject * @param array $response array of reponse from api to sync dolibarr rates * @return void */ - public static function syncRates($response) + public static function syncRates($key) { global $conf, $db, $langs; From 3e99a40b9e09e2e660cbb1cecea5d2acbfd5a9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 26 Apr 2019 17:47:47 +0200 Subject: [PATCH 05/75] Update website.lib.php --- htdocs/core/lib/website.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 56f6cdf97a3..198f91a4446 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -145,7 +145,7 @@ function dolKeepOnlyPhpCode($str) $newstr = ''; //split on each opening tag - $parts = explode(' Date: Fri, 26 Apr 2019 17:57:23 +0200 Subject: [PATCH 06/75] Update confirm_payment.php --- htdocs/public/stripe/confirm_payment.php | 49 ++++++++++++++---------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/htdocs/public/stripe/confirm_payment.php b/htdocs/public/stripe/confirm_payment.php index 90f21da6b6b..ea59b13dcb9 100644 --- a/htdocs/public/stripe/confirm_payment.php +++ b/htdocs/public/stripe/confirm_payment.php @@ -97,14 +97,14 @@ dol_syslog("POST=".var_export($_POST, true)); header('Content-Type: application/json'); -# retrieve json from POST body +// retrieve json from POST body $json_str = file_get_contents('php://input'); $json_obj = json_decode($json_str); $intent = null; try { if (isset($json_obj->payment_method_id)) { - # Create the PaymentIntent + // Create the PaymentIntent $intent = \Stripe\PaymentIntent::create([ 'payment_method' => $json_obj->payment_method_id, 'amount' => 1099, @@ -121,32 +121,39 @@ try { } generatePaymentResponse($intent); } catch (\Stripe\Error\Base $e) { - # Display error on client + // Display error on client echo json_encode([ 'error' => $e->getMessage() ]); } -function generatePaymentResponse($intent) { +/* + * generate payment response + * + * @param \Stripe\PaymentIntent $intent PaymentIntent + * @return void + */ +function generatePaymentResponse($intent) +{ if ($intent->status == 'requires_source_action' && $intent->next_action->type == 'use_stripe_sdk') { - # Tell the client to handle the action - echo json_encode([ - 'requires_action' => true, - 'payment_intent_client_secret' => $intent->client_secret - ]); - } else if ($intent->status == 'succeeded') { - # The payment didn’t need any additional actions and completed! - # Handle post-payment fulfillment + // Tell the client to handle the action + echo json_encode([ + 'requires_action' => true, + 'payment_intent_client_secret' => $intent->client_secret + ]); + } elseif ($intent->status == 'succeeded') { + // The payment didn’t need any additional actions and completed! + // Handle post-payment fulfillment - // TODO + // TODO - echo json_encode([ - "success" => true - ]); - } else { - # Invalid status - http_response_code(500); - echo json_encode(['error' => 'Invalid PaymentIntent status']); - } + echo json_encode([ + "success" => true + ]); + } else { + // Invalid status + http_response_code(500); + echo json_encode(['error' => 'Invalid PaymentIntent status']); + } } From d8d462e36f2c5a64f0909ba58a8f407ec028edaa Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sat, 27 Apr 2019 14:53:14 +0200 Subject: [PATCH 07/75] FIX: dolibarrize civility for fetch member same code as contact or other object --- htdocs/adherents/class/adherent.class.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 201b6610817..5b446ceb047 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1223,7 +1223,7 @@ class Adherent extends CommonObject { global $langs; - $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,"; + $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,"; $sql.= " d.note_public,"; $sql.= " d.email, d.skype, d.twitter, d.facebook, d.linkedin, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,"; $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,"; @@ -1267,7 +1267,11 @@ class Adherent extends CommonObject $this->ref = $obj->rowid; $this->id = $obj->rowid; $this->ref_ext = $obj->ref_ext; - $this->civility_id = $obj->civility_id; + + $this->civility_id = $obj->civility_code; + $this->civility_code = $obj->civility_code; + $this->civility = $obj->civility_code?($langs->trans("Civility".$obj->civility_code) != ("Civility".$obj->civility_code) ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code):''; + $this->firstname = $obj->firstname; $this->lastname = $obj->lastname; $this->gender = $obj->gender; From f33b7fc744b94084fbe0652ab3e5b22c0ae7a560 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sat, 27 Apr 2019 15:19:39 +0200 Subject: [PATCH 08/75] Update adherent.class.php --- htdocs/adherents/class/adherent.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 5b446ceb047..799e3518865 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1268,7 +1268,7 @@ class Adherent extends CommonObject $this->id = $obj->rowid; $this->ref_ext = $obj->ref_ext; - $this->civility_id = $obj->civility_code; + $this->civility_id = $obj->civility_code; $this->civility_code = $obj->civility_code; $this->civility = $obj->civility_code?($langs->trans("Civility".$obj->civility_code) != ("Civility".$obj->civility_code) ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code):''; From 61f2b84f5f366800db8256dce4e97cc44ca86ba2 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sun, 28 Apr 2019 00:49:21 +0200 Subject: [PATCH 09/75] FIX : error with call IsInEEC --- htdocs/product/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 39e98730365..0a5508ae725 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -35,6 +35,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; if (! empty($conf->categorie->enabled)) require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; From 2154b4a654d7ccad503e7ab685145a8fd39339f4 Mon Sep 17 00:00:00 2001 From: Sof Date: Sun, 28 Apr 2019 12:09:59 +0200 Subject: [PATCH 10/75] FIX : Typo $seearch_cti = $search_cti --- htdocs/contact/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 246fd172dc7..febc613434d 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -400,7 +400,7 @@ $num = $db->num_rows($result); $arrayofselected=is_array($toselect)?$toselect:array(); -if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && ($sall != '' || $seearch_cti != '')) +if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && ($sall != '' || $search_cti != '')) { $obj = $db->fetch_object($resql); $id = $obj->rowid; From 00db27495633e8a590c27fa107d6bcebe6b2545a Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Sun, 28 Apr 2019 18:12:33 +0200 Subject: [PATCH 11/75] Add history to view and print previous sales. --- htdocs/compta/facture/list.php | 21 +++++++++++++++++++-- htdocs/langs/en_US/cashdesk.lang | 3 ++- htdocs/takepos/invoice.php | 9 ++++++++- htdocs/takepos/takepos.php | 7 +++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index d978ddb62e5..42baaab436d 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -67,6 +67,11 @@ $confirm=GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); $contextpage=GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'invoicelist'; +if ($contextpage == 'poslist') +{ + $_GET['optioncss'] = 'print'; +} + $lineid=GETPOST('lineid', 'int'); $userid=GETPOST('userid', 'int'); $search_product_category=GETPOST('search_product_category', 'int'); @@ -950,7 +955,12 @@ if ($resql) $totalpay = $facturestatic->total_ttc - $remaintopay; } - print ''; + print ''; if (! empty($arrayfields['f.ref']['checked'])) { print ''; @@ -958,7 +968,14 @@ if ($resql) print ''; print ''; From cef5bb15b1e8f876d0cacd70269cab05356bff40 Mon Sep 17 00:00:00 2001 From: Ludovic Canivet Date: Mon, 29 Apr 2019 11:43:25 +0200 Subject: [PATCH 13/75] Search ticket by thirdparty name instead of id --- htdocs/ticket/list.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 3cd594b3eb9..ad6ac18d386 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -52,7 +52,7 @@ $id = GETPOST('id', 'int'); $msg_id = GETPOST('msg_id', 'int'); $socid = GETPOST('socid', 'int'); $projectid = GETPOST('projectid', 'int'); -$search_fk_soc=GETPOST('$search_fk_soc', 'int')?GETPOST('$search_fk_soc', 'int'):GETPOST('socid', 'int'); +$search_societe = GETPOST('search_societe', 'alpha'); $search_fk_project=GETPOST('search_fk_project', 'int')?GETPOST('search_fk_project', 'int'):GETPOST('projectid', 'int'); $search_fk_status = GETPOST('search_fk_statut', 'array'); $mode = GETPOST('mode', 'alpha'); @@ -210,6 +210,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity($object->element).")"; else $sql.=" WHERE 1 = 1"; +$sql.= " AND t.fk_soc = s.rowid"; foreach($search as $key => $val) { @@ -231,7 +232,7 @@ foreach($search as $key => $val) if ($search[$key] != '') $sql.=natural_search($key, $search[$key], $mode_search); } if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all); -if ($search_fk_soc) $sql.= natural_search('fk_soc', $search_fk_soc, 2); +if ($search_societe) $sql .= natural_search('s.nom', $search_societe); if ($search_fk_project) $sql.= natural_search('fk_project', $search_fk_project, 2); if (! $user->societe_id && ($mode == "mine" || (!$user->admin && $conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY))) { $sql.= " AND (t.fk_user_assign = ".$user->id; @@ -538,6 +539,10 @@ foreach($object->fields as $key => $val) print Form::multiselectarray('search_fk_statut', $arrayofstatus, array_values($search[$key]), 0, 0, 'minwidth150', 1, 0, '', '', ''); print ''; } + elseif ($key == "fk_soc") + { + print ''; + } else { print ''; } From dfd0e97d20e0e7419e6fb8092f0265ac519bb620 Mon Sep 17 00:00:00 2001 From: Ludovic Canivet Date: Mon, 29 Apr 2019 11:46:14 +0200 Subject: [PATCH 14/75] Search ticket by thirdparty name instead of id 2/2 --- htdocs/ticket/list.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index ad6ac18d386..402f3b717a4 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -208,9 +208,10 @@ $sql.=$hookmanager->resPrint; $sql=preg_replace('/, $/', '', $sql); $sql.= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (t.fk_soc = s.rowid)"; if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity($object->element).")"; else $sql.=" WHERE 1 = 1"; -$sql.= " AND t.fk_soc = s.rowid"; + foreach($search as $key => $val) { From e3af373cd35bcf6c81b49c7300db1cf6cef8d210 Mon Sep 17 00:00:00 2001 From: Ludovic Canivet Date: Mon, 29 Apr 2019 15:43:34 +0200 Subject: [PATCH 15/75] Fix tms date format on ticket list --- htdocs/ticket/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 402f3b717a4..96af20dc591 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -638,6 +638,7 @@ while ($i < min($num, $limit)) elseif ($key == 'category_code') print $langs->getLabelFromKey($db, $object->category_code, 'c_ticket_category', 'code', 'label'); elseif ($key == 'severity_code') print $langs->getLabelFromKey($db, $object->severity_code, 'c_ticket_severity', 'code', 'label'); elseif ($key == 'type_code') print $langs->getLabelFromKey($db, $object->type_code, 'c_ticket_type', 'code', 'label'); + elseif ($key == 'tms') print dol_print_date($db->jdate($obj->$key), 'dayhour', 'tzuser'); elseif (in_array($val['type'], array('date','datetime','timestamp'))) print $object->showOutputField($val, $key, $db->jdate($obj->$key), ''); else print $object->showOutputField($val, $key, $obj->$key, ''); print ''; From bbc6c0fe0ccfb4dacfac787f89a5fdd8cd9e560e Mon Sep 17 00:00:00 2001 From: Supermanu Date: Sat, 27 Apr 2019 18:44:52 +0200 Subject: [PATCH 16/75] Show help text for extrafields in forms --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/class/extrafields.class.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 60bfd1e5305..d25f5d80cba 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6523,7 +6523,7 @@ abstract class CommonObject $out .= $extrafields->showOutputField($key, $value); break; case "edit": - $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id); + $out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element); break; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 26acdf50fcc..caea57280b9 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1567,6 +1567,9 @@ class ExtraFields if ($type == 'date') $out.=' (YYYY-MM-DD)'; elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; */ + if (! empty($help)) { + $out .= $form->textwithpicto("", $help); + } return $out; } From f8f40a9239a979714181e1b229b17b3ea9e86177 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:27:33 +0200 Subject: [PATCH 17/75] planned_timespent not present on task duration is the good one --- htdocs/core/modules/project/doc/pdf_timespent.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php index 007bf9c8e1d..2c69fbd6bab 100644 --- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php @@ -260,7 +260,7 @@ class pdf_timespent extends ModelePDFProjects //$progress=($object->lines[$i]->progress?$object->lines[$i]->progress.'%':''); $datestart=dol_print_date($object->lines[$i]->date_start, 'day'); $dateend=dol_print_date($object->lines[$i]->date_end, 'day'); - $planned_timespent=convertSecondToTime((int) $object->lines[$i]->planned_timespent, 'allhourmin'); + $duration=convertSecondToTime((int) $object->lines[$i]->duration, 'allhourmin'); $showpricebeforepagebreak=1; @@ -348,7 +348,7 @@ class pdf_timespent extends ModelePDFProjects $pdf->MultiCell($this->posxlabel-$this->posxref, 3, $outputlangs->convToOutputCharset($ref), 0, 'L'); // timespent $pdf->SetXY($this->posxtimespent, $curY); - $pdf->MultiCell($this->posxdatestart-$this->posxtimespent, 3, $planned_timespent?$planned_timespent:'', 0, 'R'); + $pdf->MultiCell($this->posxdatestart-$this->posxtimespent, 3, $duration?$duration:'', 0, 'R'); // Progress //$pdf->SetXY($this->posxprogress, $curY); //$pdf->MultiCell($this->posxdatestart-$this->posxprogress, 3, $progress, 0, 'R'); From b13bc0e698ce0a0577b33ae66e2e2c4e4c89f5e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 30 Apr 2019 13:50:03 +0200 Subject: [PATCH 18/75] Fix loading of website page object not done for home page --- htdocs/core/website.inc.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 1338104de0b..4a2b267fe3a 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -25,6 +25,8 @@ // Load website class include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; +include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; + // Define $website if (! is_object($website)) { @@ -40,11 +42,14 @@ if (! is_object($weblangs)) if (! $pageid && ! empty($websitepagefile)) { $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile)); + if ($pageid == 'index.php') $pageid = $website->fk_default_home; +} +if (! is_object($websitepage)) +{ + $websitepage=new WebsitePage($db); } if ($pageid > 0) { - include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; - $websitepage=new WebsitePage($db); $websitepage->fetch($pageid); } From d9a1c2b235bf574c714b7be9b5f37583a164320b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 30 Apr 2019 13:54:50 +0200 Subject: [PATCH 19/75] Fix do not delete all discount when splitting --- htdocs/comm/remx.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index a66e8e66500..eb1c14a4beb 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -1,7 +1,8 @@ - * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2008 Raphael Bertrand (Resultic) +/* Copyright (C) 2001-2004 Rodolphe Quiedeville + * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -127,6 +128,8 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $db->begin(); $discount->fk_facture_source=0; // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_facture_source + // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_invoice_supplier_source + $discount->fk_invoice_supplier_source=0; $res=$discount->delete($user); $newid1=$newdiscount1->create($user); $newid2=$newdiscount2->create($user); From 2136bce4b052bca83c79e82055fee83cc16581c5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 30 Apr 2019 15:10:38 +0200 Subject: [PATCH 20/75] FIX missing situation invoice in list --- htdocs/compta/facture/card.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ebc4695dde8..82b876666db 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1326,7 +1326,7 @@ if (empty($reshook)) } elseif ($typeamount=='variable') { $descline.= ' ('. $valuedeposit.'%)'; } - + $descline.= ' - '.$srcobject->ref; $result = $object->addline( $descline, @@ -2952,7 +2952,7 @@ if ($action == 'create') { // First situation invoice print '
'; - $tmp=' '; + $tmp=' '; $tmp = $tmp.''; $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); print $desc; @@ -3007,7 +3007,23 @@ if ($action == 'create') } else { - print '
'; + print '
'; + $tmp=' '; + $text = ' '; + $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; + $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); + print $desc; + print '
'; + + print '
'; + $tmp=' '; + $text = ' '; + $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; + $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); + print $desc; + print '
'; + + print '
'; $tmp=' '; $text = ' '; $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; From ac304f58b078475f6c3c3c04eb9ec41face9bb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 30 Apr 2019 20:37:59 +0200 Subject: [PATCH 21/75] clean new commits --- htdocs/core/lib/price.lib.php | 57 ++++++++--------- htdocs/core/modules/modProduct.class.php | 35 +++++----- htdocs/core/modules/modService.class.php | 78 +++++++++++------------ htdocs/core/tpl/objectline_create.tpl.php | 21 ++---- 4 files changed, 93 insertions(+), 98 deletions(-) diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index a649d9d225e..04c9b806c9c 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -82,7 +82,7 @@ * 25=multicurrency_total_tax1 for total_ht * 26=multicurrency_total_tax2 for total_ht */ -function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0) +function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array = '', $progress = 100, $multicurrency_tx = 1, $pu_devise = 0) { global $conf,$mysoc,$db; @@ -188,9 +188,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'HT', we need to have the totals with main VAT for a correct calculation if ($price_base_type != 'TTC') { - $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)),'MU'); - $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)),'MU'); - $pu_wt = price2num($pu * (1 + ($txtva / 100)),'MU'); + $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)), 'MU'); + $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)), 'MU'); + $pu_wt = price2num($pu * (1 + ($txtva / 100)), 'MU'); } else { @@ -203,7 +203,7 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt $localtaxes = array(0,0,0); $apply_tax = false; - switch($localtax1_type) { + switch($localtax1_type) { case '2': // localtax on product or service $apply_tax = true; break; @@ -227,16 +227,16 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt } $apply_tax = false; - switch($localtax2_type) { - case '2': // localtax on product or service - $apply_tax = true; - break; - case '4': // localtax on product - if ($type == 0) $apply_tax = true; - break; - case '6': // localtax on service - if ($type == 1) $apply_tax = true; - break; + switch($localtax2_type) { + case '2': // localtax on product or service + $apply_tax = true; + break; + case '4': // localtax on product + if ($type == 0) $apply_tax = true; + break; + case '6': // localtax on service + if ($type == 1) $apply_tax = true; + break; } if ($uselocaltax2_rate && $apply_tax) { $result[15] = price2num(($tot_sans_remise_wt * (1 + ( $localtax2_rate / 100))) - $tot_sans_remise_wt, 'MT'); @@ -292,9 +292,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'TTC', we need to have the totals without main VAT for a correct calculation if ($price_base_type == 'TTC') { - $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)),'MU'); - $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)),'MU'); - $pu = price2num($pu / (1 + ($txtva / 100)),'MU'); + $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)), 'MU'); + $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)), 'MU'); + $pu = price2num($pu / (1 + ($txtva / 100)), 'MU'); } $apply_tax = false; @@ -321,16 +321,16 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt } $apply_tax = false; - switch($localtax2_type) { - case '1': // localtax on product or service - $apply_tax = true; - break; - case '3': // localtax on product - if ($type == 0) $apply_tax = true; - break; - case '5': // localtax on service - if ($type == 1) $apply_tax = true; - break; + switch($localtax2_type) { + case '1': // localtax on product or service + $apply_tax = true; + break; + case '3': // localtax on product + if ($type == 0) $apply_tax = true; + break; + case '5': // localtax on service + if ($type == 1) $apply_tax = true; + break; } if ($uselocaltax2_rate && $apply_tax) { $result[15] = price2num(($tot_sans_remise * (1 + ( $localtax2_rate / 100))) - $tot_sans_remise, 'MT'); // amount tax2 for total_ht_without_discount @@ -411,4 +411,3 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt return $result; } - diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 3358728d095..5ee2a6ba8a3 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -201,10 +201,10 @@ class modProduct extends DolibarrModules if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; @@ -349,7 +349,7 @@ class modProduct extends DolibarrModules 'p.note_public' => "PublicNote",//public note 'p.note' => "PrivateNote",//private note 'p.customcode' => 'CustomCode', - 'p.price' => "SellingPriceHT",//without tax + 'p.price' => "SellingPriceHT",//without 'p.price_min' => "MinPrice", 'p.price_ttc' => "SellingPriceTTC",//with tax 'p.price_min_ttc' => "SellingMinPriceTTC", @@ -518,19 +518,22 @@ class modProduct extends DolibarrModules if (is_object($mysoc) && $mysoc->useLocalTax(1)) $import_sample=array_merge($import_sample, array('p.localtax1_tx'=>'', 'p.localtax1_type'=>'')); if (is_object($mysoc) && $mysoc->useLocalTax(2)) $import_sample=array_merge($import_sample, array('p.localtax2_tx'=>'', 'p.localtax2_type'=>'')); if (! empty($conf->barcode->enabled)) $import_sample=array_merge($import_sample, array('p.barcode'=>'')); - if (! empty($conf->global->PRODUCT_USE_UNITS)) { - $import_sample = array_merge($import_sample, array( - 'p.fk_unit' => 'use a unit of measure from the dictionary. G/KG/M2/M3 etc....matches field "code" in table "' . MAIN_DB_PREFIX . 'c_units"' - )); + if (! empty($conf->global->PRODUCT_USE_UNITS)) { + $import_sample = array_merge( + $import_sample, + array( + 'p.fk_unit' => 'use a unit of measure from the dictionary. G/KG/M2/M3 etc....matches field "code" in table "' . MAIN_DB_PREFIX . 'c_units"' + ) + ); $this->import_convertvalue_array[$r] = array_merge($this->import_convertvalue_array[$r], array( - 'p.fk_unit' => array( - 'rule' => 'fetchidfromcodeorlabel', - 'classfile' => '/core/class/cunits.class.php', - 'class' => 'CUnits', - 'method' => 'fetch', - 'dict' => 'DictionaryUnits' - ) + 'p.fk_unit' => array( + 'rule' => 'fetchidfromcodeorlabel', + 'classfile' => '/core/class/cunits.class.php', + 'class' => 'CUnits', + 'method' => 'fetch', + 'dict' => 'DictionaryUnits' + ) )); } $this->import_examplevalues_array[$r]=array_merge($import_sample, $import_extrafield_sample); diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 119339d6022..022e0c74a54 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -143,32 +143,32 @@ class modService extends DolibarrModules $this->export_permission[$r]=array(array("service","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR'; - if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); - if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); - if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.cost_price'=>'CostPrice')); + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice')); $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('group_concat(cat.label)'=>'Categories')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); + if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit'; $this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); - if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric')); - if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); - if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array("group_concat(cat.label)"=>'Text')); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); + if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text')); $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array("group_concat(cat.label)"=>'category')); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]= array('category'=>'p.rowid'); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; @@ -260,18 +260,18 @@ class modService extends DolibarrModules 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell", 'p.tobuy'=>"OnBuy",'p.datec'=>'DateCreation','p.tms'=>'DateModification' ); - if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); - if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); - $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); $this->export_TypeFields_array[$r]=array( 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text", 'p.note'=>"Text",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.weight'=>"Numeric",'p.customcode'=>'Text', 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", 'p.datec'=>'Date','p.tms'=>'Date' ); - if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric')); - if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); - $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('pa.qty'=>'Numeric')); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric','p.seuil_stock_alerte'=>'Numeric','p.desiredstock'=>'Numeric','p.pmp'=>'Numeric','p.cost_price'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); + $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('pa.qty'=>'Numeric')); $this->export_entities_array[$r]=array( 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct", 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct", @@ -279,13 +279,13 @@ class modService extends DolibarrModules 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct", 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct" ); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'virtualproduct')); - $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'virtualproduct','p.seuil_stock_alerte'=>'virtualproduct','p.desiredstock'=>'virtualproduct','p.pmp'=>'virtualproduct')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'virtualproduct')); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pa.qty'=>"subproduct",'pa.incdec'=>'subproduct')); $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description")); - $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct")); + $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p2.rowid'=>"Id",'p2.ref'=>"Ref",'p2.label'=>"Label",'p2.description'=>"Description")); + $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p2.rowid'=>"subproduct",'p2.ref'=>"subproduct",'p2.label'=>"subproduct",'p2.description'=>"subproduct")); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON p.rowid = extra.fk_object,'; @@ -363,11 +363,11 @@ class modService extends DolibarrModules 'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation' ); //if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); - if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); - if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); - if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); - if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); - if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.cost_price'=>'CostPrice')); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); + if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields $import_extrafield_sample=array(); @@ -394,7 +394,7 @@ class modService extends DolibarrModules 'p.recuperableonly'=>'^[0|1]$' ); $import_sample=array('p.ref'=>"SERVICE_REF or id:123456",'p.label'=>"My product",'p.description'=>"This is a description example for record",'p.note'=>"Some note",'p.price'=>"100",'p.price_ttc'=>"110",'p.tva_tx'=>'10','p.tosell'=>"0 or 1",'p.tobuy'=>"0 or 1",'p.fk_product_type'=>"0 for product/1 for service",'p.finished'=>'','p.duration'=>"1y",'p.datec'=>'2008-12-31','p.recuperableonly'=>'0 or 1'); - $this->import_examplevalues_array[$r]=array_merge($import_sample,$import_extrafield_sample); + $this->import_examplevalues_array[$r]=array_merge($import_sample, $import_extrafield_sample); $this->import_updatekeys_array[$r] = array('p.ref'=>'Ref'); if (! empty($conf->barcode->enabled)) $this->import_updatekeys_array[$r]=array_merge($this->import_updatekeys_array[$r], array('p.barcode'=>'BarCode'));//only show/allow barcode as update key if Barcode module enabled @@ -470,7 +470,7 @@ class modService extends DolibarrModules 'pr.price_min'=>"MinPriceLevelUnitPriceHT",'pr.price_min_ttc'=>"MinPriceLevelUnitPriceTTC", 'pr.date_price'=>'DateCreation*'); if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) $this->import_fields_array[$r]['pr.tva_tx']='VATRate'; - if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('pr.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r], array('pr.recuperableonly'=>'NPR')); $this->import_regex_array[$r]=array('pr.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','pr.recuperableonly'=>'^[0|1]$'); $this->import_convertvalue_array[$r]=array( 'pr.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'Product') diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 04911584809..df8301f4104 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -136,7 +136,8 @@ if ($nolinesbefore) { print '
'; print ''; } - if (! empty($usemargins)) + if (! empty($usemargins)) + { if (!empty($user->rights->margins->creer)) { ?> @@ -149,9 +150,7 @@ if ($nolinesbefore) { echo $langs->trans('BuyingPrice'); else echo $langs->trans('CostPrice'); - ?> - - '; if ($user->rights->margins->creer && ! empty($conf->global->DISPLAY_MARGIN_RATES)) echo ''; if ($user->rights->margins->creer && ! empty($conf->global->DISPLAY_MARK_RATES)) echo ''; } @@ -168,10 +167,8 @@ $coldisplay=0; // Adds a line numbering column if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { $coldisplay++; - ?> - - '; +} $coldisplay++; ?> @@ -348,14 +345,12 @@ if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { echo $form->selectyesno('date_end_fill', $line->date_end_fill, 1); echo ''; } - ?> - + echo ''; - element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') // We must have same test in printObjectLines { - ?> $coldisplay++; + ?> @@ -458,9 +453,7 @@ if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { if (is_object($objectline)) { print $objectline->showOptionals($extrafieldsline, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1); } -?> -service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required { ?> From 3bda9be775659683fcafd4df0ea95b4a09748ec1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 13:46:45 +0200 Subject: [PATCH 22/75] Fix error 500 --- htdocs/admin/dolistore/class/dolistore.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index 553ce2e54e0..e82eec71fec 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -17,7 +17,10 @@ */ include_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class.php'; +if (! class_exists('PrestaShopWebservice')) // We keep this because some modules add this lib too into a different path. This is to avoid "Cannot declare class PrestaShopWebservice" errors. +{ + include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class.php'; +} /** From 50b1a54dca17aa67a705eeac0cf18f2403ce74c7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 14:06:30 +0200 Subject: [PATCH 23/75] FIX Update/delete currency on same languages --- htdocs/admin/multicurrency.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 467ffffeb41..4e06f7a5edf 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -108,9 +108,7 @@ elseif ($action == 'update_currency') { $error = 0; - $submit = GETPOST('submit', 'alpha'); - - if ($submit == $langs->trans('Modify')) + if (GETPOST('updatecurrency', 'alpha')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); $rate = price2num(GETPOST('rate', 'alpha')); @@ -129,7 +127,7 @@ elseif ($action == 'update_currency') } } } - elseif ($submit == $langs->trans('Delete')) + elseif (GETPOST('deletecurrency', 'alpha')) { $fk_multicurrency = GETPOST('fk_multicurrency', 'int'); $currency = new MultiCurrency($db); @@ -357,8 +355,8 @@ foreach ($TCurrency as &$currency) print ''; print '1 '.$conf->currency.' = '; print ' '.$currency->code.' '; - print ' '; - print ''; + print ' '; + print ''; print ''; print ''; From a75c6a81d16312580e2847002e606dc822631686 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 17:15:42 +0200 Subject: [PATCH 24/75] FIX Follow rule to create a new page --- htdocs/core/class/html.formticket.class.php | 11 +- htdocs/core/lib/functions.lib.php | 2 +- htdocs/ticket/card.php | 24 ++- htdocs/ticket/class/ticket.class.php | 155 +------------------- 4 files changed, 22 insertions(+), 170 deletions(-) diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 59996942cd3..f6cf1c33e9f 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -834,7 +834,7 @@ class FormTicket if ($user->rights->ticket->write && !$user->socid) { print ''; @@ -863,18 +863,19 @@ class FormTicket print ""; } + // Private message or not. TODO What does this means ? + /* if (! $user->socid) { print ''; - } + }*/ - - print ''; + print ''; $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE; print ''; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 4c0b15c8d46..12b38068c87 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -307,7 +307,7 @@ function GETPOST($paramname, $check = 'none', $method = 0, $filter = null, $opti } if (! empty($conf->global->MAIN_ENABLE_DEFAULT_VALUES)) { - if (! empty($_GET['action']) && $_GET['action'] == 'create' && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) + if (! empty($_GET['action']) && preg_match('/^create/', $_GET['action']) && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) { // Now search in setup to overwrite default values if (! empty($user->default_values)) // $user->default_values defined from menu 'Setup - Default values' diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 44abe008d34..299607c9cde 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -75,7 +75,7 @@ if (empty($action) && empty($id) && empty($ref)) $action='view'; //Select mail models is same action as add_message if (GETPOST('modelselected', 'alpha')) { - $action = 'add_message'; + $action = 'create_message'; } // Load object @@ -369,9 +369,9 @@ if ($action == "assign_user" && GETPOST('btn_assign_user', 'aplha') && $user->ri $action = 'view'; } -if ($action == "new_message" && GETPOST('btn_add_message') && $user->rights->ticket->read) { - $ret = $object->newMessage($user, $action); - if ($ret) { +if ($action == "add_message" && GETPOST('btn_create_message') && $user->rights->ticket->read) { + $ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "on" ? 1 : 0)); + if ($ret > 0) { if (!empty($backtopage)) { $url = $backtopage; } else { @@ -382,14 +382,10 @@ if ($action == "new_message" && GETPOST('btn_add_message') && $user->rights->tic exit; } else { setEventMessages($object->error, null, 'errors'); - $action = 'add_message'; + $action = 'create_message'; } } -if ($action == "new_public_message" && GETPOST('btn_add_message')) { - $object->newMessagePublic($user, $action); -} - if ($action == "confirm_close" && GETPOST('confirm', 'alpha') == 'yes' && $user->rights->ticket->write) { $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')); @@ -641,7 +637,7 @@ if ($action == 'create' || $action == 'presend') $formticket->showForm(1); } -if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'add_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' +if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'create_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen' || $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') { if ($res > 0) @@ -1173,8 +1169,8 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd if (empty($reshook)) { // Show link to add a message (if read and not closed) - if ($object->fk_statut < Ticket::STATUS_CLOSED && $action != "add_message") { - print ''; + if ($object->fk_statut < Ticket::STATUS_CLOSED && $action != "create_message") { + print ''; } // Link to create an intervention @@ -1210,7 +1206,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd $action = 'presend'; } - if ($action != 'add_message') + if ($action != 'create_message') { print '
'; print ''; // ancre @@ -1232,7 +1228,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd } else { - $action='new_message'; + $action='add_message'; $modelmail='ticket_send'; print '
'; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index cab2eab92ed..15dd77cf64f 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2486,11 +2486,12 @@ class Ticket extends CommonObject /** * Add new message on a ticket (private area) * - * @param User $user User for action - * @param string $action Action string - * @return int + * @param User $user User for action + * @param string $action Action string + * @param int $private 1=Message is private. TODO Implement this. What does this means ? + * @return int */ - public function newMessage($user, &$action) + public function newMessage($user, &$action, $private = 1) { global $mysoc, $conf, $langs; @@ -2777,152 +2778,6 @@ class Ticket extends CommonObject setEventMessages($langs->trans('ErrorMailRecipientIsEmptyForSendTicketMessage'), null, 'warnings'); } } - - /** - * Add new message on a ticket (public area) - * - * @param User $user User for action - * @param string $action Action string - * @return void - */ - public function newMessagePublic($user, &$action) - { - global $mysoc, $conf, $langs; - - $object = new Ticket($this->db); - - $error = 0; - $ret = $object->fetch('', '', GETPOST('track_id', 'alpha')); - $object->socid = $object->fk_soc; - $object->fetch_thirdparty(); - if ($ret < 0) { - $error++; - array_push($this->errors, $langs->trans("ErrorTicketIsNotValid")); - $action = ''; - } - - if (!GETPOST("message")) { - $error++; - array_push($this->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("message"))); - $action = 'add_message'; - } - - if (!$error) { - $object->message = (string) GETPOST("message"); - $id = $object->createTicketMessage($user); - if ($id <= 0) { - $error++; - $this->error = $object->error; - $this->errors = $object->errors; - $action = 'add_message'; - } - - if (!$error && $id > 0) { - setEventMessages($langs->trans('TicketMessageSuccessfullyAdded'), null, 'mesgs'); - - // Retrieve internal contact datas - $internal_contacts = $object->getInfosTicketInternalContact(); - $sendto = array(); - if (is_array($internal_contacts) && count($internal_contacts) > 0) { - $subject = '[' . $mysoc->name . '- ticket #' . $object->track_id . '] ' . $langs->trans('TicketNewMessage'); - - $message = $langs->trans('TicketMessageMailIntroAutoNewPublicMessage', $object->subject); - $message .= "\n"; - $message .= GETPOST('message'); - $message .= "\n"; - - // Coordonnées client - if ($object->thirdparty->id > 0) { - $message .= "\n\n"; - $message .= "==============================================\n"; - $message .= $langs->trans('Thirparty') . " : " . $object->thirdparty->name; - $message .= !empty($object->thirdparty->town) ? $langs->trans('Town') . " : " . $object->thirdparty->town : ''; - $message .= "\n"; - $message .= !empty($object->thirdparty->phone) ? $langs->trans('Phone') . " : " . $object->thirdparty->phone : ''; - $message .= "\n"; - } - - // Build array to display recipient list - foreach ($internal_contacts as $key => $info_sendto) { - if ($info_sendto['email'] != '') { - $sendto[] = trim($info_sendto['firstname'] . " " . $info_sendto['lastname']) . " <" . $info_sendto['email'] . ">"; - } - - // Contact type - $recipient = dolGetFirstLastname($info_sendto['firstname'], $info_sendto['lastname'], '-1') . ' (' . strtolower($info_sendto['libelle']) . ')'; - $message .= (!empty($recipient) ? $langs->trans('TicketNotificationRecipient') . ' : ' . $recipient . "\n" : ''); - $message .= "\n"; - } - - // URL ticket - $url_internal_ticket = dol_buildpath('/ticket/card.php', 2) . '?track_id=' . $object->track_id; - $message .= "\n" . $langs->trans('TicketNotificationEmailBodyInfosTrackUrlinternal') . ' : ' . $url_internal_ticket . "\n"; - - $message .= "\n\n"; - - $message_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE; - - // Add global email address reciepient - if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !in_array($conf->global->TICKET_NOTIFICATION_EMAIL_FROM, $sendto)) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_FROM; - } - - $this->sendTicketMessageByEmail($subject, $message, '', $sendto); - } - - /* - * Email for externals users if not private - */ - - // Retrieve email of all contacts external - $external_contacts = $object->getInfosTicketExternalContact(); - $sendto = array(); - if (is_array($external_contacts) && count($external_contacts) > 0) { - $subject = '[' . $mysoc->name . '- ticket #' . $object->track_id . '] ' . $langs->trans('TicketNewMessage'); - - $message = $langs->trans('TicketMessageMailIntroAutoNewPublicMessage', $object->subject); - $message .= "\n"; - - $message .= GETPOST('message'); - $message .= "\n\n"; - - $message_signature = GETPOST('mail_signature') ? GETPOST('mail_signature') : $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE; - foreach ($external_contacts as $key => $info_sendto) { - if ($info_sendto['email'] != '') { - $sendto[] = trim($info_sendto['firstname'] . " " . $info_sendto['lastname']) . " <" . $info_sendto['email'] . ">"; - } - $recipient = ''; - $recipient = dolGetFirstLastname($info_sendto['firstname'], $info_sendto['lastname'], '-1') . ' (' . strtolower($info_sendto['libelle']) . ')'; - $message .= (!empty($recipient) ? $langs->trans('TicketNotificationRecipient') . ' : ' . $recipient . "\n" : ''); - } - - $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE . '/view.php' : dol_buildpath('/public/ticket/view.php', 2)) . '?track_id=' . $object->track_id; - $message .= "\n\n" . $langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer') . ' : ' . $url_public_ticket . "\n"; - - // Add signature - $message .= '\n\n' . $message_signature; - - if (!empty($object->origin_email) && !in_array($object->origin_email, $sendto)) { - $sendto[] = $object->origin_email; - } - if ($object->fk_soc > 0 && !in_array($object->origin_email, $sendto)) { - $sendto[] = $object->thirdparty->email; - } - $this->sendTicketMessageByEmail($subject, $message, '', $sendto); - } - - $object->copyFilesForTicket(); - - $url = 'view.php?action=view_ticket&track_id=' . $object->track_id; - header("Location: " . $url); - exit; - } else { - setEventMessages($object->error, $object->errors, 'errors'); - } - } else { - setEventMessages($this->error, $this->errors, 'errors'); - } - } } From 9955af5194f2a90828a64cd638426d7db6e48935 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 17:53:41 +0200 Subject: [PATCH 25/75] Debug ticket module --- htdocs/admin/defaultvalues.php | 1 + htdocs/core/class/html.formticket.class.php | 16 +----- htdocs/langs/en_US/admin.lang | 1 + htdocs/ticket/card.php | 64 ++++++++++++--------- htdocs/ticket/class/ticket.class.php | 20 ++----- 5 files changed, 45 insertions(+), 57 deletions(-) diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index 8e4334c6214..1f0ada4a6f3 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -251,6 +251,7 @@ print '
'; $texthelp=$langs->trans("PageUrlForDefaultValues"); if ($mode == 'createform') $texthelp.=$langs->trans("PageUrlForDefaultValuesCreate", 'societe/card.php', 'societe/card.php?abc=val1&def=val2'); else $texthelp.=$langs->trans("PageUrlForDefaultValuesList", 'societe/list.php', 'societe/list.php?abc=val1&def=val2'); +$texthelp.='

'.$langs->trans("AlsoDefaultValuesAreEffectiveForActionCreate"); $texturl=$form->textwithpicto($langs->trans("Url"), $texthelp); print_liste_field_titre($texturl, $_SERVER["PHP_SELF"], 'page,param', '', $param, '', $sortfield, $sortorder); // Field diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index f6cf1c33e9f..1d681d2672b 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -852,19 +852,7 @@ class FormTicket print ''; } - // Substitution array - if ($this->withsubstit) { - print '"; - } - - // Private message or not. TODO What does this means ? - /* + // Private message (not visible by customer/external user) if (! $user->socid) { print ''; - }*/ + } print ''; $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 90abbe90fc6..daba22fe660 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -470,6 +470,7 @@ TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. Technical knowled PageUrlForDefaultValues=You must enter the relative path of the page URL. If you include parameters in URL, the default values will be effective if all parameters are set to same value. PageUrlForDefaultValuesCreate=
Example:
For the form to create a new third party, it is %s.
For URL of external modules installed into custom directory, do not include the "custom/", so use path like mymodule/mypage.php and not custom/mymodule/mypage.php.
If you want default value only if url has some parameter, you can use %s PageUrlForDefaultValuesList=
Example:
For the page that lists third parties, it is %s.
For URL of external modules installed into custom directory, do not include the "custom/" so use a path like mymodule/mypagelist.php and not custom/mymodule/mypagelist.php.
If you want default value only if url has some parameter, you can use %s +AlsoDefaultValuesAreEffectiveForActionCreate=Also note that overwritting default values for form creation works only for pages that were correctly designed (so with parameter action=create...) EnableDefaultValues=Enable customization of default values EnableOverwriteTranslation=Enable usage of overwritten translation GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code. To change this value, you must edit it from Home-Setup-translation. diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 299607c9cde..dab1b896a67 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -369,8 +369,9 @@ if ($action == "assign_user" && GETPOST('btn_assign_user', 'aplha') && $user->ri $action = 'view'; } -if ($action == "add_message" && GETPOST('btn_create_message') && $user->rights->ticket->read) { +if ($action == "add_message" && GETPOST('btn_add_message') && $user->rights->ticket->read) { $ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "on" ? 1 : 0)); + if ($ret > 0) { if (!empty($backtopage)) { $url = $backtopage; @@ -1228,11 +1229,43 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd } else { - $action='add_message'; + $action='add_message'; // action to use to post the message $modelmail='ticket_send'; + // Substitution array + $morehtmlright=''; + $help=""; + $substitutionarray=array(); + if ($object->fk_soc > 0) { + $object->fetch_thirdparty(); + $substitutionarray['__THIRDPARTY_NAME__'] = $object->thirdparty->name; + } + $substitutionarray['__SIGNATURE__'] = $user->signature; + $substitutionarray['__TICKETSUP_TRACKID__'] = $object->track_id; + $substitutionarray['__TICKETSUP_REF__'] = $object->ref; + $substitutionarray['__TICKETSUP_SUBJECT__'] = $object->subject; + $substitutionarray['__TICKETSUP_TYPE__'] = $object->type_code; + $substitutionarray['__TICKETSUP_SEVERITY__'] = $object->severity_code; + $substitutionarray['__TICKETSUP_CATEGORY__'] = $object->category_code; // For backward compatibility + $substitutionarray['__TICKETSUP_ANALYTIC_CODE__'] = $object->category_code; + $substitutionarray['__TICKETSUP_MESSAGE__'] = $object->message; + $substitutionarray['__TICKETSUP_PROGRESSION__'] = $object->progress; + if ($object->fk_user_assign > 0) { + $userstat->fetch($object->fk_user_assign); + $substitutionarray['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); + } + + if ($object->fk_user_create > 0) { + $userstat->fetch($object->fk_user_create); + $substitutionarray['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); + } + foreach ($substitutionarray as $key => $val) { + $help.=$key.' -> '.$langs->trans($val).'
'; + } + $morehtmlright.=$form->textwithpicto($langs->trans("TicketMessageSubstitutionReplacedByGenericValues"), $help); + print '
'; - print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticket'); + print load_fiche_titre($langs->trans('TicketAddMessage'), $morehtmlright, 'messages@ticket'); print '
'; @@ -1265,30 +1298,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd $formticket->withsubstit = 1; - - if ($object->fk_soc > 0) { - $object->fetch_thirdparty(); - $formticket->substit['__THIRDPARTY_NAME__'] = $object->thirdparty->name; - } - $formticket->substit['__SIGNATURE__'] = $user->signature; - $formticket->substit['__TICKETSUP_TRACKID__'] = $object->track_id; - $formticket->substit['__TICKETSUP_REF__'] = $object->ref; - $formticket->substit['__TICKETSUP_SUBJECT__'] = $object->subject; - $formticket->substit['__TICKETSUP_TYPE__'] = $object->type_code; - $formticket->substit['__TICKETSUP_SEVERITY__'] = $object->severity_code; - $formticket->substit['__TICKETSUP_CATEGORY__'] = $object->category_code; // For backward compatibility - $formticket->substit['__TICKETSUP_ANALYTIC_CODE__'] = $object->category_code; - $formticket->substit['__TICKETSUP_MESSAGE__'] = $object->message; - $formticket->substit['__TICKETSUP_PROGRESSION__'] = $object->progress; - if ($object->fk_user_assign > 0) { - $userstat->fetch($object->fk_user_assign); - $formticket->substit['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); - } - - if ($object->fk_user_create > 0) { - $userstat->fetch($object->fk_user_create); - $formticket->substit['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname); - } + $formticket->substit = $substitutionarray; $formticket->showMessageForm('100%'); print '
'; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 15dd77cf64f..b68628d0c9b 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -1654,21 +1654,9 @@ class Ticket extends CommonObject $this->message = trim($this->message); } - // Insert request - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "ticket_msg("; + // Insert entry into agenda with code 'TICKET_MSG' + $sql.='...'; - $sql .= "fk_track_id,"; - $sql .= "fk_user_action,"; - $sql .= "datec,"; - $sql .= "message,"; - $sql .= "private"; - $sql .= ") VALUES ("; - $sql .= " " . (!isset($this->fk_track_id) ? "'" . $this->db->escape($this->track_id) . "'" : "'" . $this->db->escape($this->fk_track_id) . "'") . ","; - $sql .= " " . ($this->fk_user_action > 0 ? $this->fk_user_action : $user->id) . ","; - $sql .= " '" . $this->db->idate(dol_now()) . "',"; - $sql .= " " . (!isset($this->message) ? 'NULL' : "'" . $this->db->escape($this->message) . "'") . ","; - $sql .= " " . (empty($this->private) ? '0' : "'" . $this->db->escape($this->private) . "'") . ""; - $sql .= ")"; $this->db->begin(); @@ -2520,8 +2508,8 @@ class Ticket extends CommonObject } if (!$error) { - $object->message = GETPOST("message"); - $object->private = GETPOST("private_message"); + $object->message = GETPOST("message", "none"); + $object->private = GETPOST("private_message", "alpha"); $send_email = GETPOST('send_email', 'int'); $id = $object->createTicketMessage($user); From 90a1181dc52575c553045f24cdc111dadc4404eb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 20:41:03 +0200 Subject: [PATCH 26/75] Debug module Ticket --- htdocs/comm/action/class/actioncomm.class.php | 1 + htdocs/core/lib/functions.lib.php | 1 + htdocs/langs/en_US/ticket.lang | 3 +- htdocs/ticket/agenda.php | 157 ++++++++-------- htdocs/ticket/card.php | 10 +- htdocs/ticket/class/actions_ticket.class.php | 3 +- htdocs/ticket/class/ticket.class.php | 173 ++++++++---------- htdocs/ticket/img/statut0.png | Bin 329 -> 234 bytes htdocs/ticket/img/statut1.png | Bin 470 -> 380 bytes .../ticket/img/{statut4.png => statut2.png} | Bin htdocs/ticket/img/statut3.png | Bin 380 -> 363 bytes htdocs/ticket/img/statut5.png | Bin 363 -> 329 bytes htdocs/ticket/img/statut6.png | Bin 341 -> 470 bytes htdocs/ticket/img/statut8.png | Bin 272 -> 341 bytes htdocs/ticket/img/statut9.png | Bin 0 -> 272 bytes 15 files changed, 160 insertions(+), 188 deletions(-) rename htdocs/ticket/img/{statut4.png => statut2.png} (100%) create mode 100644 htdocs/ticket/img/statut9.png diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index b543d6790c6..ebe4e48f264 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -281,6 +281,7 @@ class ActionComm extends CommonObject if (! empty($this->datep) && ! empty($this->datef) && $this->datep > $this->datef) $this->datef=$this->datep; //if (! empty($this->date) && ! empty($this->dateend) && $this->date > $this->dateend) $this->dateend=$this->date; if (! isset($this->fk_project) || $this->fk_project < 0) $this->fk_project = 0; + // For backward compatibility if ($this->elementtype=='facture') $this->elementtype='invoice'; if ($this->elementtype=='commande') $this->elementtype='order'; if ($this->elementtype=='contrat') $this->elementtype='contract'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 12b38068c87..3f5480ee455 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1299,6 +1299,7 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi if ($object->element == 'member') $modulepart='memberphoto'; if ($object->element == 'user') $modulepart='userphoto'; if ($object->element == 'product') $modulepart='product'; + if ($object->element == 'ticket') $modulepart='ticket'; if (class_exists("Imagick")) { diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 8265df1b370..c84dc17f087 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -58,9 +58,10 @@ Notify_TICKET_SENTBYMAIL=Send ticket message by email # Status NotRead=Not read Read=Read -Answered=Answered Assigned=Assigned InProgress=In progress +NeedMoreInformation=Waiting more information +Answered=Answered Waiting=Waiting Closed=Closed Deleted=Deleted diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index eb863adbfbc..bad8e58497b 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -125,103 +125,102 @@ if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/ticketnameonly/', $c $help_url = 'FR:DocumentationModuleTicket'; llxHeader('', $title, $help_url); - if ($socid > 0) { - $object->fetch_thirdparty(); - $head = societe_prepare_head($object->thirdparty); +if ($socid > 0) { + $object->fetch_thirdparty(); + $head = societe_prepare_head($object->thirdparty); - dol_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), 0, 'company'); + dol_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), 0, 'company'); - dol_banner_tab($object->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom'); + dol_banner_tab($object->thirdparty, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom'); - dol_fiche_end(); - } + dol_fiche_end(); +} - if (!$user->societe_id && $conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) { - $object->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'"; - } elseif ($user->societe_id > 0) { - $object->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'"; - } - $head = ticket_prepare_head($object); +if (!$user->societe_id && $conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) { + $object->next_prev_filter = "te.fk_user_assign = '" . $user->id . "'"; +} elseif ($user->societe_id > 0) { + $object->next_prev_filter = "te.fk_soc = '" . $user->societe_id . "'"; +} +$head = ticket_prepare_head($object); - dol_fiche_head($head, 'tabTicketLogs', $langs->trans("Ticket"), 0, 'ticket'); +dol_fiche_head($head, 'tabTicketLogs', $langs->trans("Ticket"), 0, 'ticket'); - $morehtmlref ='
'; - $morehtmlref.= $object->subject; - // Author - if ($object->fk_user_create > 0) { - $morehtmlref .= '
' . $langs->trans("CreatedBy") . ' '; +$morehtmlref ='
'; +$morehtmlref.= $object->subject; +// Author +if ($object->fk_user_create > 0) { + $morehtmlref .= '
' . $langs->trans("CreatedBy") . ' : '; - $langs->load("users"); - $fuser = new User($db); - $fuser->fetch($object->fk_user_create); - $morehtmlref .= $fuser->getNomUrl(0); - } - if (!empty($object->origin_email)) { - $morehtmlref .= '
' . $langs->trans("CreatedBy") . ' : '; - $morehtmlref .= $object->origin_email . ' (' . $langs->trans("TicketEmailOriginIssuer") . ')'; - } + $langs->load("users"); + $fuser = new User($db); + $fuser->fetch($object->fk_user_create); + $morehtmlref .= $fuser->getNomUrl(0); +} +if (!empty($object->origin_email)) { + $morehtmlref .= '
' . $langs->trans("CreatedBy") . ' : '; + $morehtmlref .= $object->origin_email . ' (' . $langs->trans("TicketEmailOriginIssuer") . ')'; +} - // Thirdparty - if (! empty($conf->societe->enabled)) - { - $morehtmlref.='
'.$langs->trans('ThirdParty'); - /*if ($action != 'editcustomer' && $object->fk_statut < 8 && !$user->societe_id && $user->rights->ticket->write) { - $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; - }*/ - $morehtmlref.=' : '; - if ($action == 'editcustomer') { - $morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'editcustomer', '', 1, 0, 0, array(), 1); - } else { - $morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'none', '', 1, 0, 0, array(), 1); - } - } +// Thirdparty +if (! empty($conf->societe->enabled)) +{ + $morehtmlref.='
'.$langs->trans('ThirdParty'); + /*if ($action != 'editcustomer' && $object->fk_statut < 8 && !$user->societe_id && $user->rights->ticket->write) { + $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; + }*/ + $morehtmlref.=' : '; + if ($action == 'editcustomer') { + $morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'editcustomer', '', 1, 0, 0, array(), 1); + } else { + $morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'none', '', 1, 0, 0, array(), 1); + } +} - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project'); - if ($user->rights->ticket->write) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; - $morehtmlref.=' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.=''; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref.=$proj->getNomUrl(1); - } else { - $morehtmlref.=''; - } - } - } +// Project +if (! empty($conf->projet->enabled)) +{ + $langs->load("projects"); + $morehtmlref.='
'.$langs->trans('Project'); + if ($user->rights->ticket->write) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + $morehtmlref.=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
'; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.=''; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref.=$proj->getNomUrl(1); + } else { + $morehtmlref.=''; + } + } +} - $morehtmlref.='
'; +$morehtmlref.='
'; - $linkback = '' . $langs->trans("BackToList") . ' '; +$linkback = '' . $langs->trans("BackToList") . ' '; - dol_banner_tab($object, 'ref', $linkback, ($user->societe_id ? 0 : 1), 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); +dol_banner_tab($object, 'ref', $linkback, ($user->societe_id ? 0 : 1), 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); - dol_fiche_end(); +dol_fiche_end(); - print '
'; +print '
'; if (!empty($object->id)) { - print '
'; $param='&id='.$object->id; if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index dab1b896a67..26fec804370 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -818,7 +818,7 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd $morehtmlref.=''; - $linkback = '' . $langs->trans("BackToList") . ' '; + $linkback = '' . $langs->trans("BackToList") . ' '; dol_banner_tab($object, 'ref', $linkback, ($user->societe_id ? 0 : 1), 'ref', 'ref', $morehtmlref); @@ -1218,10 +1218,10 @@ if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'd print '
'; - // Message list - print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticket'); - $show_private_message = ($user->societe_id ? 0 : 1); - $actionobject->viewTicketTimelineMessages($show_private_message, true, $object); + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'ticket', $socid, 1); print '
'; print ''; diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php index 76049a18a4e..b10f8ebe7da 100644 --- a/htdocs/ticket/class/actions_ticket.class.php +++ b/htdocs/ticket/class/actions_ticket.class.php @@ -443,8 +443,7 @@ class ActionsTicket // Sort results to be similar to status object list //sort($exclude_status); - //print '
'; - foreach ($object->statuts_short as $status => $statut_label) { + foreach ($object->statuts_short as $status => $status_label) { if (!in_array($status, $exclude_status)) { print '
'; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index b68628d0c9b..750354e3356 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -207,10 +207,10 @@ class Ticket extends CommonObject */ const STATUS_NOT_READ = 0; const STATUS_READ = 1; - const STATUS_ANSWERED = 3; - const STATUS_ASSIGNED = 4; - const STATUS_IN_PROGRESS = 5; - const STATUS_WAITING = 6; + const STATUS_ASSIGNED = 2; + const STATUS_IN_PROGRESS = 3; + const STATUS_NEED_MORE_INFO = 5; + const STATUS_WAITING = 7; const STATUS_CLOSED = 8; const STATUS_CANCELED = 9; @@ -224,8 +224,8 @@ class Ticket extends CommonObject { $this->db = $db; - $this->statuts_short = array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'Closed', 9 => 'Deleted'); - $this->statuts = array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'Closed', 9 => 'Deleted'); + $this->statuts_short = array(self::STATUS_NOT_READ => 'Unread', self::STATUS_READ => 'Read', self::STATUS_ASSIGNED => 'Assigned', self::STATUS_IN_PROGRESS => 'InProgress', self::STATUS_NEED_MORE_INFO => 'NeedMoreInformation', self::STATUS_WAITING => 'Waiting', self::STATUS_CLOSED => 'Closed', self::STATUS_CANCELED => 'Canceled'); + $this->statuts = array(self::STATUS_NOT_READ => 'Unread', self::STATUS_READ => 'Read', self::STATUS_ASSIGNED => 'Assigned', self::STATUS_IN_PROGRESS => 'InProgress', self::STATUS_NEED_MORE_INFO => 'NeedMoreInformation', self::STATUS_WAITING => 'Waiting', self::STATUS_CLOSED => 'Closed', self::STATUS_CANCELED => 'Canceled'); } /** @@ -1176,7 +1176,7 @@ class Ticket extends CommonObject * Return status label of object * * @param string $statut id statut - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label */ public function LibStatut($statut, $mode = 0) @@ -1191,134 +1191,106 @@ class Ticket extends CommonObject return $langs->trans($this->statuts_short[$statut]); } elseif ($mode == 2) { - if ($statut == 0) { + if ($statut == self::STATUS_NOT_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 1) { + elseif ($statut == self::STATUS_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 3) { + elseif ($statut == self::STATUS_ASSIGNED) { + return img_picto($langs->trans($this->statuts_short[$statut]), 'statut2.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); + } + elseif ($statut == self::STATUS_IN_PROGRESS) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 4) { - return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); - } - - elseif ($statut == 5) { + elseif ($statut == self::STATUS_NEED_MORE_INFO) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 6) { + elseif ($statut == self::STATUS_WAITING) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 8) { + elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 9) { + elseif ($statut == self::STATUS_CANCELED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } } elseif ($mode == 3) { - if ($statut == 0) { + if ($statut == self::STATUS_NOT_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket'); } - - elseif ($statut == 1) { + elseif ($statut == self::STATUS_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket'); } - - elseif ($statut == 3) { + elseif ($statut == self::STATUS_ASSIGNED) { + return img_picto($langs->trans($this->statuts_short[$statut]), 'statut2.png@ticket'); + } + elseif ($statut == self::STATUS_IN_PROGRESS) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket'); } - - elseif ($statut == 4) { - return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket'); - } - - elseif ($statut == 5) { + elseif ($statut == self::STATUS_NEED_MORE_INFO) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket'); } - - elseif ($statut == 6) { + elseif ($statut == self::STATUS_WAITING) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket'); } - - elseif ($statut == 8) { + elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket'); } - - elseif ($statut == 9) { + elseif ($statut == self::STATUS_CANCELED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket'); } } elseif ($mode == 4) { - if ($statut == 0) { + if ($statut == self::STATUS_NOT_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 1) { + elseif ($statut == self::STATUS_READ) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 3) { + elseif ($statut == self::STATUS_ASSIGNED) { + return img_picto($langs->trans($this->statuts_short[$statut]), 'statut2.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); + } + elseif ($statut == self::STATUS_IN_PROGRESS) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 4) { - return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); - } - - elseif ($statut == 5) { + elseif ($statut == self::STATUS_NEED_MORE_INFO) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 6) { + elseif ($statut == self::STATUS_WAITING) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 8) { + elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } - - elseif ($statut == 9) { + elseif ($statut == self::STATUS_CANCELED) { return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]); } } - elseif ($mode == 5) { - if ($statut == 0) { + elseif ($mode == 5 || $mode == 6) { + if ($statut == self::STATUS_NOT_READ) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket'); } - - elseif ($statut == 1) { + elseif ($statut == self::STATUS_READ) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket'); } - - elseif ($statut == 3) { + elseif ($statut == self::STATUS_ASSIGNED) { + return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut2.png@ticket'); + } + elseif ($statut == self::STATUS_IN_PROGRESS) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket'); } - - elseif ($statut == 4) { - return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket'); - } - - elseif ($statut == 5) { + elseif ($statut == self::STATUS_NEED_MORE_INFO) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket'); } - - elseif ($statut == 6) { + elseif ($statut == self::STATUS_WAITING) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket'); } - - elseif ($statut == 8) { + elseif ($statut == self::STATUS_CLOSED) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket'); } - - elseif ($statut == 9) { + elseif ($statut == self::STATUS_CANCELED) { return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket'); } } @@ -1645,6 +1617,8 @@ class Ticket extends CommonObject global $conf, $langs; $error = 0; + $now = dol_now(); + // Clean parameters if (isset($this->fk_track_id)) { $this->fk_track_id = trim($this->fk_track_id); @@ -1654,38 +1628,33 @@ class Ticket extends CommonObject $this->message = trim($this->message); } - // Insert entry into agenda with code 'TICKET_MSG' - $sql.='...'; - - $this->db->begin(); - dol_syslog(get_class($this) . "::create_ticket_message sql=" . $sql, LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $error++; - $this->errors[] = "Error " . $this->db->lasterror(); - } + // Insert entry into agenda with code 'TICKET_MSG' + include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + $actioncomm=new ActionComm($this->db); + $actioncomm->type_code = 'AC_OTH_AUTO'; + $actioncomm->code = 'TICKET_MSG'; + $actioncomm->socid = $this->socid; + $actioncomm->label = $this->subject; + $actioncomm->note = $this->message; + $actioncomm->userassigned = array($user->id); + $actioncomm->userownerid = $user->id; + $actioncomm->datep = $now; + $actioncomm->percentage = 100; + $actioncomm->elementtype = 'ticket'; + $actioncomm->fk_element = $this->id; - if (!$error) { - if (!$notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - //// Call triggers - //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - //$interface=new Interfaces($this->db); - //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf); - //if ($result < 0) { $error++; $this->errors=$interface->errors; } - //// End call triggers - } + $actionid = $actioncomm->create($user); + if ($actionid <= 0) + { + $error++; + $this->error = $actioncomm->error; + $this->errors = $actioncomm->errors; } // Commit or rollback if ($error) { - foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this) . "::create_ticket_message " . $errmsg, LOG_ERR); - $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); - } $this->db->rollback(); return -1 * $error; } else { @@ -2493,6 +2462,7 @@ class Ticket extends CommonObject $error = 0; $ret = $object->fetch('', '', GETPOST('track_id', 'alpha')); + $object->socid = $object->fk_soc; $object->fetch_thirdparty(); if ($ret < 0) { @@ -2508,6 +2478,7 @@ class Ticket extends CommonObject } if (!$error) { + $object->subject = GETPOST('subject', 'alphanohtml'); $object->message = GETPOST("message", "none"); $object->private = GETPOST("private_message", "alpha"); $send_email = GETPOST('send_email', 'int'); diff --git a/htdocs/ticket/img/statut0.png b/htdocs/ticket/img/statut0.png index 6e631dc0086a9fae78a8486c3a55b4b0096b1488..b1cf5df0e7580226f61d129d2ebbd93506c0ee75 100644 GIT binary patch delta 186 zcmX@f^ontU3O`$tx4R1i82ohJT|d!KqMp6P)7O>#5eq-3ksiyLBYi;0a!(h>5R21y zCvW6pHso=h-~4~Itka43*mvtqQZoLnR+-D^^|E!F`*h(7ffH^_HyMh~HNOv3S-a2B z^V`cbuS`xw1_6r>VVMu0002% zNklWKfsLT5s#`N# zU*K-t{R6;_yCZ~fT}pZVroi1N56L7V2URryCL)Iz zs{Jqwt5VAIq9+`*ZF>Z;2e3ckKMK+>zH~i;PhsSD8U4JLTmS$707*qoM6N<$g8OHJ A*8l(j diff --git a/htdocs/ticket/img/statut1.png b/htdocs/ticket/img/statut1.png index 5bff8090beba27faa75233b12e1e80934a310434..4e72abd23cc2732ed9bd6cee69f81afc0a70481d 100644 GIT binary patch delta 316 zcmV-C0mJ^*1N;JzNq-(mL_t(Ijir;ZPQx$|hCf?TrMv|X!oXyE0}0-MiLD)w7?9cy zY)IrGy0S4OX@}-LI(B4ah$?!=lAt71Nh*HHlFxVd-+w;aIOpcp+68AKO;ZC9RrVrH z)8*LY5Q5fwdv4_}{!I`y4d>jvFIYsjo6V*G@ZNi1-y+EKe1G&k03Ux8gb;ca0Ncai zumdp0M5>y!2t=eeTSS;lCMy6{U1eD|>utd~cdM%Ldc9s%3h#j{fU+zf23t_oXKQWb zy}t(bz!dlfqM|6ipfg4hX)Rz^xh{c=iuARaGc<*z_x{ZoGX-u`^|LI?mpG1}>VUzA zlx5khu4;@)YBlMj2`Z9D5xF}ak4e`Tok}=`JkQ@xo&WyE5W-?CSrb31xqSEexw`29 O0000tvxr!3`(Wm+J6S#`_}+QAt!mJs_)k_ zu-5L0$PW>z7w}M3`v728!EqedMC5aT0esK0>}}{jT4fML(Gb9PG5I>nvR;~|e?xzE zgI25cbRPEJKL>CeauGRA({xhSm;hHQm7mVJ7opMZb|aD>O4_R=Nj}XFF#u4lRxd>4 z34m{%PG=tgrhn7vfr#t|VV>vxMJtN;ev9NpL>?D=-igQ?l4l~)ENWj=_0=K+lO)L> zW6VpEx5b`y0HXjG(=QjnKNFI@#6f1rGpTW{-x7!VC?a3Q z0el01QflJsYrk0F3;=>4m}sp>B<}%?hZMX60Le>|5RngG?0-EWNsZKDa*2>t}w9liO#u4lA9j&*%tjvFIYsjo6V*G@ZNi1-y+EKe1G&k03Ux8gb;ca0Ncai zumdp0M5>y!2t=eeTSS;lCMy6{U1eD|>utd~cdM%Ldc9s%3h#j{fU+zf23t_oXKQWb zy}t(bz!dlfqM|6ipfg4hX)Rz^xh{c=iuARaGc<*z_x{ZoGX-u`^|LI?mpG1}>VUzA zlx5khu4;@)YBlMj2`Z9D5xF}ak4e`Tok}=`JkQ@xo&WyE5W-?CSrb31xqSEexw`29 O0000s{Jqwt5VAIq8zksdjzltus`8H3eqpWbUlJkVdQri{k)c3 Q00000NkvXXt^-0~f)S*9zyJUM delta 300 zcmV+{0n`4;0_y^hNPhthNkl@we z$N_uubMQ;0yqQAed;aMqpmQp^oh>7N0OT!_1PB&ex9%n;6z030D$Dy ypaPOAP16Svc_nVB`Kp3eSZim-n8QDXhhhPiGEh8V3-TiX0000F>4z^5QX3DMRFm5QUubbFt{ldZpB$hk>sg% zX5RN^hh5+S5yx>YoMltkIrk30A<03b(HL%IV68nj#tcfO-hbK#-uu@8Mj&7R>5%`*F@xVfB}5Zvg~c>KU!rFMbQwzb}{)n%d%dYrhh|! zc7s-{^>iNg-aiL$9C8skP1AHz)|dcSDwUtkxfh|)?RF!QA4=M*BuPHa4>15xtyV8Y z_>4Avs24SA({Y5K^_kN4yL_{7Jd)|r28c1U@I=hL z{J?w21_lN)yMYZC`hW`!&AntBp-pB7h2z{*D;cJ!>T0TiKMzh3HBDpt_!uMolmRiu z927!$Ah`gr0RVp}A>ls8xCDT@uCGZh%xt5or+L8lge1Im&VQ}acbh^k0IbbytEy)r zvIF*X5JETx@Jw=MX6vr&ZmOy}ch0o{-cHp2rzQ526P=VrE3)vKxIyus8n c{!@GbXT59qCl6lXMgRZ+07*qoM6N<$f^JiR1ONa4 diff --git a/htdocs/ticket/img/statut8.png b/htdocs/ticket/img/statut8.png index 84f3c5e7fc505eac2b593d7005623dd6294e53cb..af7f6d433dc839f6d416e67af74dd2fd2ec9cf74 100644 GIT binary patch delta 277 zcmV+w0qXvc0@VVLNq_fAL_t(Ijonc(N(4a=teTzh9&kVK5n{0H&Vqp$ilHy?M9jVX zzfC~-Hy<{7qO=bs$#pl=s;WA7&b0vERP{te-bX!uGbjEdaZhIUI_mqrU*;0avOEIN zlAHl(RrM~XkgN29{JAtov-kdm$w^!vjE36ptk5X0}t+tEuL^!PGPU bQ+xquy=(X&zG2Cj4#ST8ZBK7ZJ^67LftKyV-z< z=IyQWEuPh29LI-qZfG?u*d;KtQzA1%MB-*OnAy)@S(X*RdPpQLLS{~<39c%bS>3BD z<^Jhbg@O=51W=Q-Rsev*bUhC#?WVh*Nkn3<(Vbui*OLO98ecuVI9;WzMpys<002ov JPDHLkV1hEeUi1I} diff --git a/htdocs/ticket/img/statut9.png b/htdocs/ticket/img/statut9.png new file mode 100644 index 0000000000000000000000000000000000000000..84f3c5e7fc505eac2b593d7005623dd6294e53cb GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@RfovbtYqx$@+i%8#?A8yk<&yERH^7WrTH!AT&Fc7 z^6qM_r~h7twKfSju>?%s62{PQxWtxU^X;1D+r1XCOV_wX Q0A0`E>FVdQ&MBb@052G5fdBvi literal 0 HcmV?d00001 From 3a8d645fb9c25b3cd89173d208bb15e0a5d679e2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 May 2019 20:55:46 +0200 Subject: [PATCH 27/75] Debug module ticket --- .../install/mysql/migration/9.0.0-10.0.0.sql | 3 +++ .../install/mysql/tables/llx_actioncomm.sql | 3 ++- .../mysql/tables/llx_ticket_msg.key.sql | 17 ------------ .../install/mysql/tables/llx_ticket_msg.sql | 26 ------------------- htdocs/ticket/class/api_tickets.class.php | 7 +---- htdocs/ticket/class/ticket.class.php | 18 +++++-------- 6 files changed, 13 insertions(+), 61 deletions(-) delete mode 100755 htdocs/install/mysql/tables/llx_ticket_msg.key.sql delete mode 100755 htdocs/install/mysql/tables/llx_ticket_msg.sql diff --git a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql index 9aa395c22d6..e5b925b0d83 100644 --- a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql +++ b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql @@ -94,6 +94,9 @@ ALTER TABLE llx_bank_url DROP INDEX uk_bank_url; ALTER TABLE llx_bank_url ADD UNIQUE INDEX uk_bank_url (fk_bank, url_id, type); ALTER TABLE llx_actioncomm ADD COLUMN calling_duration integer; +ALTER TABLE llx_actioncomm ADD COLUMN visibility varchar(12) DEFAULT 'default'; + +DROP TABLE llx_ticket_msg; ALTER TABLE llx_don ADD COLUMN fk_soc integer NULL; diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index 046b8c155bd..ad6ea20115c 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -46,7 +46,8 @@ create table llx_actioncomm transparency integer, -- transparency (ical standard). used to say if user assigned to event are busy or not by event. This field may be deprecated if we want to store transparency for each assigned user, moved into table llx_actioncomm_resources. priority smallint, -- priority (ical standard) - fulldayevent smallint NOT NULL default 0, -- priority (ical standard) + visibility varchar(12) DEFAULT 'default', -- visibility (ical standard) - 'default', 'public', 'private', 'confidential' + fulldayevent smallint NOT NULL default 0, -- full day (ical standard) punctual smallint NOT NULL default 1, -- deprecated. milestone is event with date start (datep) = date end (datep2) percent smallint NOT NULL default 0, location varchar(128), diff --git a/htdocs/install/mysql/tables/llx_ticket_msg.key.sql b/htdocs/install/mysql/tables/llx_ticket_msg.key.sql deleted file mode 100755 index f6ff6fc5e88..00000000000 --- a/htdocs/install/mysql/tables/llx_ticket_msg.key.sql +++ /dev/null @@ -1,17 +0,0 @@ --- SQL definition for module ticket --- Copyright (C) 2013 Jean-François FERRY --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - ---ALTER TABLE llx_ticket_msg ADD CONSTRAINT fk_ticket_msg_fk_track_id FOREIGN KEY (fk_track_id) REFERENCES llx_ticket (track_id); diff --git a/htdocs/install/mysql/tables/llx_ticket_msg.sql b/htdocs/install/mysql/tables/llx_ticket_msg.sql deleted file mode 100755 index 7ff3297b0cc..00000000000 --- a/htdocs/install/mysql/tables/llx_ticket_msg.sql +++ /dev/null @@ -1,26 +0,0 @@ --- SQL definition for module ticket --- Copyright (C) 2013 Jean-François FERRY --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -CREATE TABLE llx_ticket_msg -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - entity integer DEFAULT 1, - fk_track_id varchar(128), - fk_user_action integer, - datec datetime, - message text, - private integer DEFAULT 0 -)ENGINE=innodb; diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index fedadd2c96e..818514868c2 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -123,19 +123,14 @@ class Tickets extends DolibarrApi /** * Get properties of a Ticket object - * * Return an array with ticket informations * * @param int $id ID of ticket * @param string $track_id Tracking ID of ticket * @param string $ref Reference for ticket * @return array|mixed Data without useless information - * - * @throws 401 - * @throws 403 - * @throws 404 */ - public function getCommon($id = 0, $track_id = '', $ref = '') + private function getCommon($id = 0, $track_id = '', $ref = '') { if (! DolibarrApiAccess::$user->rights->ticket->read) { throw new RestException(403); diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 750354e3356..bae523b1819 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -906,12 +906,6 @@ class Ticket extends CommonObject if ($res < 0) $error++; } - if (!$error) { - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "ticket_msg"; - $sql .= " WHERE fk_track_id = '" . $this->db->escape($this->track_id) . "'"; - $resql = $this->db->query($sql); - } - // Removed extrafields if (!$error) { $result = $this->deleteExtraFields(); @@ -1677,12 +1671,13 @@ class Ticket extends CommonObject } // Cache deja charge - $sql = "SELECT rowid, fk_user_action, datec, message, private"; - $sql .= " FROM " . MAIN_DB_PREFIX . "ticket_msg"; - $sql .= " WHERE fk_track_id ='" . $this->db->escape($this->track_id) . "'"; + $sql = "SELECT rowid, fk_user_author, datec, label, message, visibility"; + $sql .= " FROM " . MAIN_DB_PREFIX . "actioncomm"; + $sql .= " WHERE fk_element = " . (int) $this->id; + $sql .= " AND elementtype = 'ticket'"; $sql .= " ORDER BY datec DESC"; - dol_syslog(get_class($this) . "::load_cache_actions_ticket sql=" . $sql, LOG_DEBUG); + dol_syslog(get_class($this) . "::load_cache_actions_ticket sql=" . $sql, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -1692,8 +1687,9 @@ class Ticket extends CommonObject $this->cache_msgs_ticket[$i]['id'] = $obj->rowid; $this->cache_msgs_ticket[$i]['fk_user_action'] = $obj->fk_user_action; $this->cache_msgs_ticket[$i]['datec'] = $this->db->jdate($obj->datec); + $this->cache_msgs_ticket[$i]['subject'] = $obj->label; $this->cache_msgs_ticket[$i]['message'] = $obj->message; - $this->cache_msgs_ticket[$i]['private'] = $obj->private; + $this->cache_msgs_ticket[$i]['private'] = ($obj->visibility == 'private' ? 1 : 0); $i++; } return $num; From 4756499a81da5598d3dae3fbfc4addc2ecb04ed8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 12:03:14 +0200 Subject: [PATCH 28/75] Debug module builder for generation of APIs --- htdocs/api/class/api.class.php | 2 +- htdocs/langs/en_US/main.lang | 2 +- htdocs/langs/en_US/modulebuilder.lang | 24 ++- htdocs/modulebuilder/index.php | 195 +++++++++++++----- .../template/class/api_mymodule.class.php | 59 +++--- .../core/modules/modMyModule.class.php | 32 ++- ..._99_modMyModule_MyModuleTriggers.class.php | 6 +- 7 files changed, 219 insertions(+), 101 deletions(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index df7054ca162..de5a1e75d0a 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -216,7 +216,7 @@ class DolibarrApi * * @param string $resource element to check * @param int $resource_id Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). - * @param type $dbtablename 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity. Not used if objectid is null (optional) + * @param string $dbtablename 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity. Not used if objectid is null (optional) * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'. * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 3aec931714b..463cf828b29 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -855,7 +855,7 @@ Download=Download DownloadDocument=Download document ActualizeCurrency=Update currency rate Fiscalyear=Fiscal year -ModuleBuilder=Module Builder +ModuleBuilder=Module and Application Builder SetMultiCurrencyCode=Set currency BulkActions=Bulk actions ClickToShowHelp=Click to show tooltip help diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 8e2d57a03fc..5cb927dc8b7 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -1,5 +1,5 @@ # Dolibarr language file - Source file is en_US - loan -ModuleBuilderDesc=This tool must be used only by experienced users or developers. It provides utilities to build or edit your own module.
Documentation for alternative manual development is here. +ModuleBuilderDesc=This tool must be used only by experienced users or developers. It provides utilities to build or edit your own module. Documentation for alternative manual development is here. EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...) EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated. ModuleBuilderDesc2=Path where modules are generated/edited (first directory for external modules defined into %s): %s @@ -21,13 +21,14 @@ ModuleBuilderDesctriggers=This is the view of triggers provided by your module. ModuleBuilderDeschooks=This tab is dedicated to hooks. ModuleBuilderDescwidgets=This tab is dedicated to manage/build widgets. ModuleBuilderDescbuildpackage=You can generate here a "ready to distribute" package file (a normalized .zip file) of your module and a "ready to distribute" documentation file. Just click on button to build the package or documentation file. -EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: ALL files of module AND structured data and documentation will be deleted! -EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be deleted! +EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: All coding files of module (generated or created manually) AND structured data and documentation will be deleted! +EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All coding files (generated or created manually) related to object will be deleted! DangerZone=Danger zone BuildPackage=Build package +BuildPackageDesc=You can generate a zip package or your application so your are ready to distribute it on any Dolibarr. You can also distribute it or sell it on marketplace like DoliStore.com. BuildDocumentation=Build documentation ModuleIsNotActive=This module is not activated yet. Go to %s to make it live or click here: -ModuleIsLive=This module has been activated. Any change on it may break a current active feature. +ModuleIsLive=This module has been activated. Any change may break a current live feature. DescriptionLong=Long description EditorName=Name of editor EditorUrl=URL of editor @@ -43,10 +44,11 @@ PathToModulePackage=Path to zip of module/application package PathToModuleDocumentation=Path to file of module/application documentation (%s) SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed. FileNotYetGenerated=File not yet generated -RegenerateClassAndSql=Erase and regenerate class and sql files +RegenerateClassAndSql=Force update of .class and .sql files RegenerateMissingFiles=Generate missing files SpecificationFile=File of documentation LanguageFile=File for language +ObjectProperties=Object Properties ConfirmDeleteProperty=Are you sure you want to delete the property %s? This will change code in PHP class but also remove column from table definition of object. NotNull=Not NULL NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0). @@ -62,7 +64,8 @@ ReadmeFile=Readme file ChangeLog=ChangeLog file TestClassFile=File for PHP Unit Test class SqlFile=Sql file -PageForLib=File for PHP libraries +PageForLib=File for PHP library +PageForObjLib=File for PHP library dedicated to object SqlFileExtraFields=Sql file for complementary attributes SqlFileKey=Sql file for keys AnObjectAlreadyExistWithThisNameAndDiffCase=An object already exists with this name and a different case @@ -81,8 +84,10 @@ IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Ex SearchAllDesc=Is the field used to make a search from the quick search tool? (Examples: 1 or 0) SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax. LanguageDefDesc=Enter in this files, all the key and the translation for each language file. -MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s) -PermissionsDefDesc=Define here the new permissions provided by your module (once defined, they are visible into the default permissions setup %s) +MenusDefDesc=Define here the menus provided by your module +PermissionsDefDesc=Define here the new permissions provided by your module +MenusDefDescTooltip=The menus provided by your module/application are defined into the array $this->menus into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and module re-activated), menus are also visible into the menu editor available to administrator users on %s. +PermissionsDefDescTooltip=The permissions provided by your module/application are defined into the array $this->rights into the module descriptor file. You can edit manually this file or use the embedded editor.

Note: Once defined (and module re-activated), permissions are visible into the default permissions setup %s. HooksDefDesc=Define in the module_parts['hooks'] property, in the module descriptor, the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed. SeeIDsInUse=See IDs in use in your installation @@ -109,4 +114,5 @@ UseSpecificEditorName = Use a specific editor name UseSpecificEditorURL = Use a specific editor URL UseSpecificFamily = Use a specific family UseSpecificAuthor = Use a specific author -UseSpecificVersion = Use a specific initial version \ No newline at end of file +UseSpecificVersion = Use a specific initial version +ModuleMustBeEnabled=The module/application must be enabled first \ No newline at end of file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 0e80c0ba4ac..0ad297221be 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -156,8 +156,7 @@ if ($dirins && $action == 'initmodule' && $modulename) dol_delete_file($destdir.'/scripts/'.strtolower($modulename).'.php'); dol_delete_dir($destdir.'/scripts'); - - // Delete some files related to Object (because the dolCopyDir has copied everything) + // Delete some files related to Object (because the previous dolCopyDir has copied everything) dol_delete_file($destdir.'/myobject_card.php'); dol_delete_file($destdir.'/myobject_note.php'); dol_delete_file($destdir.'/myobject_document.php'); @@ -222,6 +221,39 @@ if ($dirins && $action == 'initmodule' && $modulename) } } +if ($dirins && $action == 'initapi' && !empty($module)) +{ + dol_mkdir($dirins.'/'.strtolower($module).'/class'); + $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template'; + $srcfile = $srcdir.'/class/api_mymodule.class.php'; + $destfile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php'; + //var_dump($srcfile);var_dump($destfile); + $result = dol_copy($srcfile, $destfile, 0, 0); + + if ($result > 0) + { + $modulename = ucfirst($module); // Force first letter in uppercase + $objectname = $tabobj; + + //var_dump($phpfileval['fullname']); + $arrayreplacement=array( + 'mymodule'=>strtolower($modulename), + 'MyModule'=>$modulename, + 'MYMODULE'=>strtoupper($modulename), + 'My module'=>$modulename, + 'my module'=>$modulename, + 'Mon module'=>$modulename, + 'mon module'=>$modulename, + 'htdocs/modulebuilder/template'=>strtolower($modulename), + 'myobject'=>strtolower($objectname), + 'MyObject'=>$objectname, + 'MYOBJECT'=>strtoupper($objectname), + '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'') + ); + + dolReplaceInFile($destfile, $arrayreplacement); + } +} if ($dirins && $action == 'inithook' && !empty($module)) { dol_mkdir($dirins.'/'.strtolower($module).'/class'); @@ -230,6 +262,26 @@ if ($dirins && $action == 'inithook' && !empty($module)) $destfile = $dirins.'/'.strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; //var_dump($srcfile);var_dump($destfile); $result = dol_copy($srcfile, $destfile, 0, 0); + + if ($result > 0) + { + $modulename = ucfirst($module); // Force first letter in uppercase + + //var_dump($phpfileval['fullname']); + $arrayreplacement=array( + 'mymodule'=>strtolower($modulename), + 'MyModule'=>$modulename, + 'MYMODULE'=>strtoupper($modulename), + 'My module'=>$modulename, + 'my module'=>$modulename, + 'Mon module'=>$modulename, + 'mon module'=>$modulename, + 'htdocs/modulebuilder/template'=>strtolower($modulename), + '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'') + ); + + dolReplaceInFile($destfile, $arrayreplacement); + } } if ($dirins && $action == 'inittrigger' && !empty($module)) { @@ -500,10 +552,10 @@ if ($dirins && $action == 'initobject' && $module && $objectname) 'sql/llx_mymodule_myobject.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql', 'sql/llx_mymodule_myobject_extrafields.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql', 'sql/llx_mymodule_myobject.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql', - 'scripts/myobject.php'=>'scripts/'.strtolower($objectname).'.php', + //'scripts/mymodule.php'=>'scripts/'.strtolower($objectname).'.php', 'img/object_myobject.png'=>'img/object_'.strtolower($objectname).'.png', 'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php', - 'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php' + //'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php' ); foreach($filetogenerate as $srcfile => $destfile) @@ -524,8 +576,8 @@ if ($dirins && $action == 'initobject' && $module && $objectname) } } - if (! $error) - { + //if (! $error) // If there is error copying 1 file, we still have to make the replacement + //{ // Scan for object class files $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); @@ -536,6 +588,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) if (preg_match('/^actions_/', $fileobj['name'])) continue; $tmpcontent=file_get_contents($fileobj['fullname']); + $reg=array(); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { $objectnameloop = $reg[1]; @@ -587,7 +640,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) // TODO } - } + //} } if (! $error) @@ -730,11 +783,11 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj)) } } - if (GETPOST('regeneratemissing')) + /*if (GETPOST('regeneratemissing')) { setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings'); $error++; - } + }*/ // Edit the class file to write properties if (! $error) @@ -760,7 +813,7 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj)) clearstatcache(true); // Make a redirect to reload all data - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname.'&nocache='.time()); + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname.'&nocache='.time()); exit; } @@ -795,7 +848,7 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey) clearstatcache(true); // Make a redirect to reload all data - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname); + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname); exit; } @@ -1030,9 +1083,9 @@ if ($action == 'savefile' && empty($cancel)) if ($action == 'set' && $user->admin) { $param=''; - if ($module) $param.='&module='.$module; - if ($tab) $param.='&tab='.$tab; - if ($tabobj) $param.='&tabobj='.$tabobj; + if ($module) $param.='&module='.urlencode($module); + if ($tab) $param.='&tab='.urlencode($tab); + if ($tabobj) $param.='&tabobj='.urlencode($tabobj); $value = GETPOST('value', 'alpha'); $resarray = activateModule($value); @@ -1065,9 +1118,9 @@ if ($action == 'set' && $user->admin) if ($action == 'reset' && $user->admin) { $param=''; - if ($module) $param.='&module='.$module; - if ($tab) $param.='&tab='.$tab; - if ($tabobj) $param.='&tabobj='.$tabobj; + if ($module) $param.='&module='.urlencode($module); + if ($tab) $param.='&tab='.urlencode($tab); + if ($tabobj) $param.='&tabobj='.urlencode($tabobj); $value = GETPOST('value', 'alpha'); $result=unActivateModule($value); @@ -1105,7 +1158,7 @@ $text=$langs->trans("ModuleBuilder"); print load_fiche_titre($text, '', 'title_setup'); -print $langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
'; +print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
'; $dirsrootforscan=array($dirread); if ($dirread != DOL_DOCUMENT_ROOT && $conf->global->MAIN_FEATURES_LEVEL >=2) { $dirsrootforscan[]=DOL_DOCUMENT_ROOT; } @@ -1310,9 +1363,9 @@ elseif (! empty($module)) $const_name = 'MAIN_MODULE_'.strtoupper($module); $param=''; - if ($tab) $param.= '&tab='.$tab; - if ($module) $param.='&module='.$module; - if ($tabobj) $param.='&tabobj='.$tabobj; + if ($tab) $param.='&tab='.urlencode($tab); + if ($module) $param.='&module='.urlencode($module); + if ($tabobj) $param.='&tabobj='.urlencode($tabobj); $urltomodulesetup=''.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").''; $linktoenabledisable=''; @@ -1595,8 +1648,8 @@ elseif (! empty($module)) { $pathtofile = $modulelowercase.'/langs/'.$langfile['relativename']; print '
'; } print '
'; - print $facturestatic->getNomUrl(1, '', 200, 0, '', 0, 1); + if ($contextpage == 'poslist') + { + print $obj->ref; + } + else + { + print $facturestatic->getNomUrl(1, '', 200, 0, '', 0, 1); + } print empty($obj->increment)?'':' ('.$obj->increment.')'; $filename=dol_sanitizeFileName($obj->ref); diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 4c71ce4b564..dd077e54045 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -61,4 +61,5 @@ NoPaimementModesDefined=No paiment mode defined in TakePOS configuration TicketVatGrouped=Group VAT by rate in tickets AutoPrintTickets=Automatically print tickets EnableBarOrRestaurantFeatures=Enable features for Bar or Restaurant -ConfirmDeletionOfThisPOSSale=Do your confirm the deletion of this current sale ? \ No newline at end of file +ConfirmDeletionOfThisPOSSale=Do your confirm the deletion of this current sale ? +History=History \ No newline at end of file diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 09a60ffc3e9..2fc99b1a587 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -171,6 +171,13 @@ if ($action == 'valid' && $user->rights->facture->creer) } } +if ($action == 'history') +{ + $placeid = GETPOST('placeid', 'int'); + $invoice = new Facture($db); + $invoice->fetch($placeid); +} + if (($action=="addline" || $action=="freezone") && $placeid == 0) { $invoice->socid = $conf->global->CASHDESK_ID_THIRDPARTY; @@ -336,7 +343,7 @@ if ($action == "order" and $placeid != 0) } $sectionwithinvoicelink=''; -if ($action=="valid") +if ($action=="valid" || $action=="history") { $sectionwithinvoicelink.=''."\n"; $sectionwithinvoicelink.=''; diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php index e5991b50702..143c6abf063 100644 --- a/htdocs/takepos/takepos.php +++ b/htdocs/takepos/takepos.php @@ -352,6 +352,12 @@ function Customer() { $.colorbox({href:"../societe/list.php?contextpage=poslist&nomassaction=1&place="+place, width:"90%", height:"80%", transition:"none", iframe:"true", title:"trans("Customer");?>"}); } +function History() +{ + console.log("Open box to select the history"); + $.colorbox({href:"../compta/facture/list.php?contextpage=poslist", width:"90%", height:"80%", transition:"none", iframe:"true", title:"trans("History");?>"}); +} + function CloseBill() { invoiceid = $("#invoiceid").val(); console.log("Open popup to enter payment on invoiceid="+invoiceid); @@ -607,6 +613,7 @@ else } $menus[$r++]=array('title'=>'
'.$langs->trans("Customer").'
', 'action'=>'Customer();'); +$menus[$r++]=array('title'=>'
'.$langs->trans("History").'
', 'action'=>'History();'); $menus[$r++]=array('title'=>'
'.$langs->trans("FreeZone").'
', 'action'=>'FreeZone();'); $menus[$r++]=array('title'=>'
'.$langs->trans("Payment").'
', 'action'=>'CloseBill();'); From 8f6f3d764f6661247e6b05100706dae91ac70575 Mon Sep 17 00:00:00 2001 From: Ludovic Canivet Date: Mon, 29 Apr 2019 10:58:00 +0200 Subject: [PATCH 12/75] Display category/Severity/type label instead of code --- htdocs/ticket/list.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 989bbda8072..3cd594b3eb9 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -629,6 +629,9 @@ while ($i < min($num, $limit)) if ($cssforfield || $val['css']) print '"'; print '>'; if ($key == 'fk_statut') print $object->getLibStatut(5); + elseif ($key == 'category_code') print $langs->getLabelFromKey($db, $object->category_code, 'c_ticket_category', 'code', 'label'); + elseif ($key == 'severity_code') print $langs->getLabelFromKey($db, $object->severity_code, 'c_ticket_severity', 'code', 'label'); + elseif ($key == 'type_code') print $langs->getLabelFromKey($db, $object->type_code, 'c_ticket_type', 'code', 'label'); elseif (in_array($val['type'], array('date','datetime','timestamp'))) print $object->showOutputField($val, $key, $db->jdate($obj->$key), ''); else print $object->showOutputField($val, $key, $obj->$key, ''); print '
' . $langs->trans('Progress') . ''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'">
'; - $checkbox_selected = ( GETPOST('send_email') == "1" ? ' checked' : ''); + $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : ''); print ' '; print ''; print '
'; - $checkbox_selected = ( GETPOST('private_message') == "1" ? ' checked' : ''); + $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : ''); print ' '; print ''; print ''; print $form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help'); print '
'; $checkbox_selected = (GETPOST('private_message', 'alpha') == "1" ? ' checked' : ''); @@ -873,7 +861,7 @@ class FormTicket print ''; print $form->textwithpicto('', $langs->trans("TicketMessagePrivateHelp"), 1, 'help'); print '
'.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print '
'; @@ -1698,7 +1751,7 @@ elseif (! empty($module)) print '
'; print '
'; print '
'; - print $langs->trans("Or"); + print $langs->trans("or"); print '
'; print '
'; print '
'; @@ -1782,8 +1835,26 @@ elseif (! empty($module)) print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("ApiClassFile").' : '.($realpathtoapi?'':'').$pathtoapi.($realpathtoapi?'':'').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '   '.$langs->trans("GoToApiExplorer").''; + if ($realpathtoapi) + { + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '   '; + print ''.img_picto($langs->trans("Delete"), 'delete').''; + print '   '; + if (empty($conf->global->$const_name)) // If module is not activated + { + print ''.$langs->trans("GoToApiExplorer").''; + } + else + { + print ''.$langs->trans("GoToApiExplorer").''; + } + } + else + { + //print ''.$langs->trans("FileNotYetGenerated").' '; + print ''; + } print '
'; print ' '.$langs->trans("TestClassFile").' : '.($realpathtophpunit?'':'').$pathtophpunit.($realpathtophpunit?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -1824,7 +1895,7 @@ elseif (! empty($module)) $urlofcard = dol_buildpath($pathtocard, 1); print '
'; - print ' '.$langs->trans("PageForList").' : '.($realpathtosql?'':'').$pathtolist.($realpathtosql?'':'').''; + print ' '.$langs->trans("PageForList").' : '.($realpathtolist?'':'').$pathtolist.($realpathtolist?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print ' '.$langs->trans("PageForCreateEditView").' : '.($realpathtocard?'':'').$pathtocard.($realpathtocard?'':'').'?action=create'; @@ -1840,10 +1911,11 @@ elseif (! empty($module)) print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; + /* This is already on Tab CLI print '
'; print ' '.$langs->trans("ScriptFile").' : '.($realpathtoscript?'':'').$pathtoscript.($realpathtoscript?'':'').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; + print '
';*/ print '
'; @@ -1888,10 +1960,10 @@ elseif (! empty($module)) print ''; print ''; - print ''; + //print ''; print '

'; - print load_fiche_titre($langs->trans("Properties"), '', ''); + print load_fiche_titre($langs->trans("ObjectProperties"), '', ''); print '
'; @@ -2040,7 +2112,7 @@ elseif (! empty($module)) $format='asciidoc'; if (preg_match('/\.md$/i', $spec['name'])) $format='markdown'; print ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; } } @@ -2137,17 +2209,22 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("MenusDefDesc", ''.$langs->trans('Menus').'').'
'; + print ''; + $htmlhelp=$langs->trans("MenusDefDescTooltip", ''.$langs->trans('Setup').' - '.$langs->trans('Menus').''); + print $form->textwithpicto($langs->trans("MenusDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; + print '
'; print '
'; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '
'; print load_fiche_titre($langs->trans("ListOfMenusEntries"), '', ''); - print 'TODO...'; + // @TODO + print $langs->trans("FeatureNotYetAvailable"); + print '
'; print ''; print ''; @@ -2262,16 +2339,24 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("PermissionsDefDesc", ''.$langs->trans('DefaultPermissions').'').'
'; + + print ''; + $htmlhelp=$langs->trans("PermissionsDefDescTooltip", ''.$langs->trans('DefaultPermissions').''); + print $form->textwithpicto($langs->trans("PermissionsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; + print '
'; print '
'; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '
'; print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', ''); + + // @TODO + print $langs->trans("FeatureNotYetAvailable"); + print ''; print ''; print ''; @@ -2279,7 +2364,6 @@ elseif (! empty($module)) print ''; print ''; - print 'TODO...'; /* print '
'; print ''; @@ -2391,7 +2475,7 @@ elseif (! empty($module)) $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; print ''; print ''; - print ''; + print ''; + print ''; } else { print ''.$langs->trans("FileNotYetGenerated").''; - print ''; + print ''; } print ''; } @@ -2458,8 +2542,8 @@ elseif (! empty($module)) print ''; - print ''; + print ''; + print ''; print ''; } } @@ -2467,7 +2551,7 @@ elseif (! empty($module)) { print ''; + print ''; print ''; } print '
'; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
'; @@ -2400,13 +2484,13 @@ elseif (! empty($module)) if (dol_is_file($dirins.'/'.$pathtohook)) { print ''.$pathtohook.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
'; print ' '.$langs->trans("TriggersFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
'; print ' '.$langs->trans("NoTrigger"); - print '
'; @@ -2518,16 +2602,16 @@ elseif (! empty($module)) $pathtofile = $widget['relpath']; print ' '.$langs->trans("WidgetFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print ''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print ''; } } else { print ' '.$langs->trans("NoWidget"); - print ''; + print ''; print ''; } print ''; @@ -2605,15 +2689,15 @@ elseif (! empty($module)) $pathtofile = $clifile['relpath']; print ' '.$langs->trans("CLIFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print ''; } } else { print ' '.$langs->trans("NoCLIFile"); - print ''; + print ''; print ''; } print ''; @@ -2657,7 +2741,7 @@ elseif (! empty($module)) print '
'; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '
'; @@ -2786,8 +2870,8 @@ elseif (! empty($module)) if (preg_match('/\.md$/i', $spec['name'])) $format='markdown'; print ''; print ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print ''; } } @@ -2795,7 +2879,7 @@ elseif (! empty($module)) { print ''; print ' '.$langs->trans("FileNotYetGenerated"); - print ''; + print ''; print ''; } print ''; @@ -2880,6 +2964,9 @@ elseif (! empty($module)) if ($tab == 'buildpackage') { + print ''.$langs->trans("BuildPackageDesc").''; + print '
'; + if (! class_exists('ZipArchive') && ! defined('ODTPHP_PATHTOPCLZIP')) { print img_warning().' '.$langs->trans("ErrNoZipEngine"); diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index acf7f65454d..c37a0dba0e1 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -36,14 +36,6 @@ dol_include_once('/mymodule/class/myobject.class.php'); */ class MyModuleApi extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - 'name', - ); - - /** * @var MyObject $myobject {@type MyObject} */ @@ -75,7 +67,7 @@ class MyModuleApi extends DolibarrApi */ public function get($id) { - if(! DolibarrApiAccess::$user->rights->myobject->read) { + if(! DolibarrApiAccess::$user->rights->mymodule->read) { throw new RestException(401); } @@ -84,8 +76,8 @@ class MyModuleApi extends DolibarrApi throw new RestException(404, 'MyObject not found'); } - if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) { + throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login); } return $this->_cleanObjectDatas($this->myobject); @@ -113,33 +105,37 @@ class MyModuleApi extends DolibarrApi global $db, $conf; $obj_ret = array(); + $tmpobject = new MyObject($db); + + if(! DolibarrApiAccess::$user->rights->bbb->read) { + throw new RestException(401); + } $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; - $restictonsocid = 0; // Set to 1 if there is a field socid in table of object + $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object // If the internal user must only see his customers, force searching by him $search_sale = 0; - if ($restictonsocid && ! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + if ($restrictonsocid && ! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) - $sql.= " FROM ".MAIN_DB_PREFIX."myobject_mytable as t"; + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX.$tmpobject->table_element." as t"; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= " WHERE 1 = 1"; // Example of use $mode //if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; //if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; - $tmpobject = new MyObject($db); if ($tmpobject->ismultientitymanaged) $sql.= ' AND t.entity IN ('.getEntity('myobject').')'; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; - if ($restictonsocid && $socid) $sql.= " AND t.fk_soc = ".$socid; - if ($restictonsocid && $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($restrictonsocid && $socid) $sql.= " AND t.fk_soc = ".$socid; + if ($restrictonsocid && $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale // Insert sale filter - if ($restictonsocid && $search_sale > 0) { + if ($restrictonsocid && $search_sale > 0) { $sql .= " AND sc.fk_user = ".$search_sale; } if ($sqlfilters) @@ -176,7 +172,7 @@ class MyModuleApi extends DolibarrApi } } else { - throw new RestException(503, 'Error when retrieve myobject list'); + throw new RestException(503, 'Error when retrieving myobject list: '.$db->lasterror()); } if( ! count($obj_ret)) { throw new RestException(404, 'No myobject found'); @@ -194,7 +190,7 @@ class MyModuleApi extends DolibarrApi */ public function post($request_data = null) { - if(! DolibarrApiAccess::$user->rights->myobject->create) { + if(! DolibarrApiAccess::$user->rights->mymodule->write) { throw new RestException(401); } // Check mandatory fields @@ -220,7 +216,7 @@ class MyModuleApi extends DolibarrApi */ public function put($id, $request_data = null) { - if(! DolibarrApiAccess::$user->rights->myobject->create) { + if(! DolibarrApiAccess::$user->rights->mymodule->write) { throw new RestException(401); } @@ -229,8 +225,8 @@ class MyModuleApi extends DolibarrApi throw new RestException(404, 'MyObject not found'); } - if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) { + throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login); } foreach($request_data as $field => $value) { @@ -254,11 +250,11 @@ class MyModuleApi extends DolibarrApi * @param int $id MyObject ID * @return array * - * @url DELETE myobject/{id} + * @url DELETE myobjects/{id} */ public function delete($id) { - if (! DolibarrApiAccess::$user->rights->myobject->delete) { + if (! DolibarrApiAccess::$user->rights->mymodule->delete) { throw new RestException(401); } $result = $this->myobject->fetch($id); @@ -266,8 +262,8 @@ class MyModuleApi extends DolibarrApi throw new RestException(404, 'MyObject not found'); } - if (! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + if (! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) { + throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login); } if (! $this->myobject->delete(DolibarrApiAccess::$user)) @@ -317,7 +313,8 @@ class MyModuleApi extends DolibarrApi private function _validate($data) { $myobject = array(); - foreach (MyObjectApi::$FIELDS as $field) { + foreach ($this->myobject->fields as $field => $propfield) { + if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) continue; // Not a mandatory field if (!isset($data[$field])) throw new RestException(400, "$field field missing"); $myobject[$field] = $data[$field]; diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 8a11a6c87b4..2dd29d10195 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -170,6 +170,7 @@ class modMyModule extends DolibarrModules // 'stock' to add a tab in stock view // 'thirdparty' to add a tab in third party view // 'user' to add a tab in user view + // Dictionaries $this->dictionaries=array(); /* Example: @@ -195,6 +196,7 @@ class modMyModule extends DolibarrModules 'tabcond'=>array($conf->mymodule->enabled,$conf->mymodule->enabled,$conf->mymodule->enabled) ); */ + // Boxes/Widgets // Add here list of php file(s) stored in mymodule/core/boxes that contains class to show a widget. $this->boxes = array( @@ -206,6 +208,7 @@ class modMyModule extends DolibarrModules //1=>array('file'=>'mymodulewidget2.php@mymodule','note'=>'Widget provided by MyModule'), //2=>array('file'=>'mymodulewidget3.php@mymodule','note'=>'Widget provided by MyModule') ); + // Cronjobs (List of cron jobs entries to add when module is enabled) // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week $this->cronjobs = array( @@ -228,26 +231,28 @@ class modMyModule extends DolibarrModules // 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50), // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50) // ); + // Permissions $this->rights = array(); // Permission array used by this module $r=0; $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) - $this->rights[$r][1] = 'Read myobject of MyModule'; // Permission label + $this->rights[$r][1] = 'Read objects of MyModule'; // Permission label $this->rights[$r][3] = 1; // Permission by default for new user (0/1) $this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) $this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) $r++; $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) - $this->rights[$r][1] = 'Create/Update myobject of MyModule'; // Permission label + $this->rights[$r][1] = 'Create/Update objects of MyModule'; // Permission label $this->rights[$r][3] = 1; // Permission by default for new user (0/1) $this->rights[$r][4] = 'write'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) $this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) $r++; $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) - $this->rights[$r][1] = 'Delete myobject of MyModule'; // Permission label + $this->rights[$r][1] = 'Delete objects of MyModule'; // Permission label $this->rights[$r][3] = 1; // Permission by default for new user (0/1) $this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) $this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2) + // Main menu entries $this->menu = array(); // List of menus to add $r=0; @@ -298,6 +303,7 @@ class modMyModule extends DolibarrModules 'user'=>2, // 0=Menu for internal users, 1=external users, 2=both ); END MODULEBUILDER LEFTMENU MYOBJECT */ + // Exports $r=1; /* BEGIN MODULEBUILDER EXPORT MYOBJECT */ @@ -317,6 +323,26 @@ class modMyModule extends DolibarrModules $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')'; $r++; */ /* END MODULEBUILDER EXPORT MYOBJECT */ + + // Imports + $r=1; + /* BEGIN MODULEBUILDER IMPORT MYOBJECT */ + /* + $langs->load("mymodule@mymodule"); + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='MyObjectLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r]='myobject@mymodule'; + $keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject'; + include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php'; + $keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + //$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t'; + $this->export_sql_end[$r] .=' WHERE 1 = 1'; + $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')'; + $r++; */ + /* END MODULEBUILDER IMPORT MYOBJECT */ } /** * Function called when module is enabled. diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 4388c6399db..1718a6a72d5 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -97,7 +97,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - if (empty($conf->mymodule->enabled)) return 0; // Module not active, we do nothing + if (empty($conf->mymodule->enabled)) return 0; // If module is not enabled, we do nothing // Put here code you want to execute when a Dolibarr business events occurs. // Data and type of action are stored into $object and $action @@ -302,7 +302,9 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'SHIPPING_CLOSED': //case 'SHIPPING_REOPEN': //case 'SHIPPING_DELETE': - // break; + + // and more... + default: dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); break; From 0f8c7df6fe005b92d2436befb388eac8ac91a623 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 12:19:43 +0200 Subject: [PATCH 29/75] Debug api of module BOM --- htdocs/api/index.php | 3 +- htdocs/bom/class/api_boms.class.php | 59 ++++++++----------- htdocs/core/lib/functions2.lib.php | 3 + .../template/class/api_mymodule.class.php | 6 +- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 4207618d125..3f47731316c 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -234,12 +234,13 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/swagger.json' && $classname = ucwords($module); - dol_syslog('Search /' . $moduledirforclass . '/class/api_' . $classfile . '.class.php => dir_part_file=' . $dir_part_file . ' classname=' . $classname); + dol_syslog('Search api file /' . $moduledirforclass . '/class/api_' . $classfile . '.class.php => dir_part_file=' . $dir_part_file . ' classname=' . $classname); $res = false; if ($dir_part_file) $res = include_once $dir_part_file; if (! $res) { + dol_syslog('Failed to make include_once '.$dir_part_file, LOG_WARNING); print 'API not found (failed to include API file)'; header('HTTP/1.1 501 API not found (failed to include API file)'); exit(0); diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index 47e22a3bf62..54f289a5b23 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -28,21 +28,13 @@ require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; */ /** - * API class for bom bom + * API class for bom * * @access protected * @class DolibarrApiAccess {@requires user,external} */ -class BOMs extends DolibarrApi +class Boms extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - 'label' - ); - - /** * @var BOM $bom {@type BOM} */ @@ -71,16 +63,16 @@ class BOMs extends DolibarrApi */ public function get($id) { - if(! DolibarrApiAccess::$user->rights->bom->read) { + if (! DolibarrApiAccess::$user->rights->bom->read) { throw new RestException(401); } $result = $this->bom->fetch($id); - if( ! $result ) { + if (! $result) { throw new RestException(404, 'BOM not found'); } - if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) { + if (! DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -107,33 +99,33 @@ class BOMs extends DolibarrApi global $db, $conf; $obj_ret = array(); - + $tmpobject = new BOM($db); + $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; - $restictonsocid = 0; // Set to 1 if there is a field socid in table of object + $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object // If the internal user must only see his customers, force searching by him $search_sale = 0; - if ($restictonsocid && ! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + if ($restrictonsocid && ! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; $sql = "SELECT t.rowid"; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) - $sql.= " FROM ".MAIN_DB_PREFIX."bom_mytable as t"; + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX.$tmpobject->table_element." as t"; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= " WHERE 1 = 1"; // Example of use $mode //if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; //if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; - $tmpobject = new BOM($db); if ($tmpobject->ismultientitymanaged) $sql.= ' AND t.entity IN ('.getEntity('bom').')'; - if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; - if ($restictonsocid && $socid) $sql.= " AND t.fk_soc = ".$socid; - if ($restictonsocid && $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc"; + if ($restrictonsocid && $socid) $sql.= " AND t.fk_soc = ".$socid; + if ($restrictonsocid && $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale // Insert sale filter - if ($restictonsocid && $search_sale > 0) + if ($restrictonsocid && $search_sale > 0) { $sql .= " AND sc.fk_user = ".$search_sale; } @@ -190,7 +182,7 @@ class BOMs extends DolibarrApi */ public function post($request_data = null) { - if(! DolibarrApiAccess::$user->rights->bom->create) { + if(! DolibarrApiAccess::$user->rights->bom->write) { throw new RestException(401); } // Check mandatory fields @@ -215,7 +207,7 @@ class BOMs extends DolibarrApi */ public function put($id, $request_data = null) { - if(! DolibarrApiAccess::$user->rights->bom->create) { + if(! DolibarrApiAccess::$user->rights->bom->write) { throw new RestException(401); } @@ -224,7 +216,7 @@ class BOMs extends DolibarrApi throw new RestException(404, 'BOM not found'); } - if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) { + if( ! DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -239,7 +231,7 @@ class BOMs extends DolibarrApi } else { - throw new RestException(500, $this->commande->error); + throw new RestException(500, $this->bom->error); } } @@ -259,7 +251,7 @@ class BOMs extends DolibarrApi throw new RestException(404, 'BOM not found'); } - if (! DolibarrApi::_checkAccessToResource('bom', $this->bom->id)) { + if (! DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -309,12 +301,13 @@ class BOMs extends DolibarrApi */ private function _validate($data) { - $bom = array(); - foreach (BOMs::$FIELDS as $field) { + $myobject = array(); + foreach ($this->myobject->fields as $field => $propfield) { + if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) continue; // Not a mandatory field if (!isset($data[$field])) throw new RestException(400, "$field field missing"); - $bom[$field] = $data[$field]; + $myobject[$field] = $data[$field]; } - return $bom; + return $myobject; } } diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 16fb210ee4d..e5c765383af 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2436,6 +2436,9 @@ function getModuleDirForApiClass($module) elseif ($module == 'tickets') { $moduledirforclass = 'ticket'; } + elseif ($module == 'boms') { + $moduledirforclass = 'bom'; + } return $moduledirforclass; } diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index c37a0dba0e1..0fcd9a8afd4 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -67,16 +67,16 @@ class MyModuleApi extends DolibarrApi */ public function get($id) { - if(! DolibarrApiAccess::$user->rights->mymodule->read) { + if (! DolibarrApiAccess::$user->rights->mymodule->read) { throw new RestException(401); } $result = $this->myobject->fetch($id); - if( ! $result ) { + if (! $result) { throw new RestException(404, 'MyObject not found'); } - if( ! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) { + if (! DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) { throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login); } From ceeb9752ce3f10deb72c0103aab03652856a35bb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 12:28:40 +0200 Subject: [PATCH 30/75] Fix PHPCS --- htdocs/core/lib/price.lib.php | 15 ++++----- htdocs/core/lib/website.lib.php | 2 +- htdocs/core/modules/modProduct.class.php | 8 ++--- htdocs/core/modules/modService.class.php | 40 +++++++++++------------ htdocs/core/tpl/objectline_create.tpl.php | 14 ++++---- htdocs/public/stripe/confirm_payment.php | 29 +++++++++------- 6 files changed, 57 insertions(+), 51 deletions(-) diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index a649d9d225e..d2b9ee56685 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -82,7 +82,7 @@ * 25=multicurrency_total_tax1 for total_ht * 26=multicurrency_total_tax2 for total_ht */ -function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0) +function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array = '', $progress = 100, $multicurrency_tx = 1, $pu_devise = 0) { global $conf,$mysoc,$db; @@ -188,9 +188,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'HT', we need to have the totals with main VAT for a correct calculation if ($price_base_type != 'TTC') { - $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)),'MU'); - $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)),'MU'); - $pu_wt = price2num($pu * (1 + ($txtva / 100)),'MU'); + $tot_sans_remise_wt = price2num($tot_sans_remise * (1 + ($txtva / 100)), 'MU'); + $tot_avec_remise_wt = price2num($tot_avec_remise * (1 + ($txtva / 100)), 'MU'); + $pu_wt = price2num($pu * (1 + ($txtva / 100)), 'MU'); } else { @@ -292,9 +292,9 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt //If input unit price is 'TTC', we need to have the totals without main VAT for a correct calculation if ($price_base_type == 'TTC') { - $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)),'MU'); - $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)),'MU'); - $pu = price2num($pu / (1 + ($txtva / 100)),'MU'); + $tot_sans_remise= price2num($tot_sans_remise / (1 + ($txtva / 100)), 'MU'); + $tot_avec_remise= price2num($tot_avec_remise / (1 + ($txtva / 100)), 'MU'); + $pu = price2num($pu / (1 + ($txtva / 100)), 'MU'); } $apply_tax = false; @@ -411,4 +411,3 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt return $result; } - diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 56f6cdf97a3..198f91a4446 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -145,7 +145,7 @@ function dolKeepOnlyPhpCode($str) $newstr = ''; //split on each opening tag - $parts = explode('fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 119339d6022..4ac6999b8d5 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -143,32 +143,32 @@ class modService extends DolibarrModules $this->export_permission[$r]=array(array("service","export")); $this->export_fields_array[$r]=array('p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell",'p.tobuy'=>"OnBuy",'p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification'); if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly']='NPR'; - if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); - if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.barcode'=>'BarCode')); - if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('p.cost_price'=>'CostPrice')); + if (! empty($conf->stock->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock','p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); + if (! empty($conf->barcode->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); + if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice')); $keyforselect='product'; $keyforelement='product'; $keyforaliasextra='extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('group_concat(cat.label)'=>'Categories')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r],array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); + if (! empty($conf->fournisseur->enabled)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('s.nom'=>'Supplier','pf.ref_fourn'=>'SupplierRef','pf.quantity'=>'QtyMin','pf.remise_percent'=>'DiscountQtyMin','pf.unitprice'=>'BuyingPrice','pf.delivery_time_days'=>'NbDaysToDelivery')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('group_concat(cat.label)'=>'Categories')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('l.lang'=>'Language', 'l.label'=>'TranslatedLabel','l.description'=>'TranslatedDescription','l.note'=>'TranslatedNote')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->export_fields_array[$r]['p.fk_unit'] = 'Unit'; $this->export_TypeFields_array[$r]=array('p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text",'p.accountancy_code_buy'=>"Text",'p.note'=>"Text",'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date'); - if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.stock'=>'Numeric')); - if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('p.barcode'=>'Text')); - if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r],array("group_concat(cat.label)"=>'Text')); + if (! empty($conf->stock->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric')); + if (! empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); + if (! empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text','pf.ref_fourn'=>'Text','pf.unitprice'=>'Numeric','pf.quantity'=>'Numeric','pf.remise_percent'=>'Numeric','pf.delivery_time_days'=>'Numeric')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text','l.description'=>'Text','l.note'=>'Text')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_TypeFields_array[$r]=array_merge($this->export_TypeFields_array[$r], array("group_concat(cat.label)"=>'Text')); $this->export_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array("group_concat(cat.label)"=>'category')); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array("group_concat(cat.label)"=>'category')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); - if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.stock'=>'product','p.pmp'=>'product')); - if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('p.barcode'=>'product')); - if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); - if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r],array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); + if (! empty($conf->stock->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.stock'=>'product','p.pmp'=>'product')); + if (! empty($conf->barcode->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('p.barcode'=>'product')); + if (! empty($conf->fournisseur->enabled)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('s.nom'=>'product_supplier_ref','pf.ref_fourn'=>'product_supplier_ref','pf.unitprice'=>'product_supplier_ref','pf.quantity'=>'product_supplier_ref','pf.remise_percent'=>'product_supplier_ref','pf.delivery_time_days'=>'product_supplier_ref')); + if (! empty($conf->global->MAIN_MULTILANGS)) $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('l.lang'=>'translation', 'l.label'=>'translation','l.description'=>'translation','l.note'=>'translation')); if (! empty($conf->global->EXPORTTOOL_CATEGORIES)) $this->export_dependencies_array[$r]=array('category'=>'p.rowid'); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p'; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 04911584809..be493fd97a7 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -163,14 +163,14 @@ if ($nolinesbefore) { ?> global->MAIN_VIEW_LINE_NUMBER)) { - $coldisplay++; - ?> - - global->MAIN_VIEW_LINE_NUMBER)) { + $coldisplay++; + ?> + + payment_method_id)) { - # Create the PaymentIntent + // Create the PaymentIntent $intent = \Stripe\PaymentIntent::create([ 'payment_method' => $json_obj->payment_method_id, 'amount' => 1099, @@ -121,32 +121,39 @@ try { } generatePaymentResponse($intent); } catch (\Stripe\Error\Base $e) { - # Display error on client + // Display error on client echo json_encode([ 'error' => $e->getMessage() ]); } +/** + * generatePaymentResponse + * + * @param object $intent Intent + * @return void + */ function generatePaymentResponse($intent) { if ($intent->status == 'requires_source_action' && - $intent->next_action->type == 'use_stripe_sdk') { - # Tell the client to handle the action + $intent->next_action->type == 'use_stripe_sdk') + { + // Tell the client to handle the action echo json_encode([ 'requires_action' => true, 'payment_intent_client_secret' => $intent->client_secret ]); - } else if ($intent->status == 'succeeded') { - # The payment didn’t need any additional actions and completed! - # Handle post-payment fulfillment + } elseif ($intent->status == 'succeeded') { + // The payment didn’t need any additional actions and completed! + // Handle post-payment fulfillment // TODO echo json_encode([ "success" => true ]); - } else { - # Invalid status + } else { + // Invalid status http_response_code(500); echo json_encode(['error' => 'Invalid PaymentIntent status']); - } + } } From 590c6fb91f306cffa801297d98c1930ae34b9527 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 12:40:34 +0200 Subject: [PATCH 31/75] Update adherent.class.php --- htdocs/adherents/class/adherent.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 799e3518865..bb7c67dc52c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1268,7 +1268,7 @@ class Adherent extends CommonObject $this->id = $obj->rowid; $this->ref_ext = $obj->ref_ext; - $this->civility_id = $obj->civility_code; + $this->civility_id = $obj->civility_code; // Bad. Kept for backard compatibility $this->civility_code = $obj->civility_code; $this->civility = $obj->civility_code?($langs->trans("Civility".$obj->civility_code) != ("Civility".$obj->civility_code) ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code):''; From cf7b27786c01d7fc5646b814f17b8e93042f59bf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 12:43:01 +0200 Subject: [PATCH 32/75] Update multicurrency.class.php --- htdocs/multicurrency/class/multicurrency.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index 2abfb0e2624..479c71aa177 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -626,7 +626,7 @@ class MultiCurrency extends CommonObject /** * Sync rates from api * - * @param array $response array of reponse from api to sync dolibarr rates + * @param string $key Key to use. Come from $conf->global->MULTICURRENCY_APP_ID. * @return void */ public static function syncRates($key) From 4a81e8fd62aa3d39c50cb0cdab95148d700fe9ff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 13:24:28 +0200 Subject: [PATCH 33/75] Debug call to apilayer --- htdocs/admin/multicurrency.php | 100 ++++++++---------- htdocs/langs/en_US/multicurrency.lang | 6 +- .../class/multicurrency.class.php | 7 +- 3 files changed, 52 insertions(+), 61 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index fbf6603d139..fa622a7ee81 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -109,9 +109,18 @@ elseif ($action == 'update_currency') } } } -elseif ($action == 'synchronize') +elseif ($action == 'setapilayer') { - MultiCurrency::syncRates($conf->global->MULTICURRENCY_APP_ID); + if (GETPOSTISSET('modify_apilayer')) + { + dolibarr_set_const($db, 'MULTICURRENCY_APP_ID', GETPOST('MULTICURRENCY_APP_ID', 'alpha')); + dolibarr_set_const($db, 'MULTICURRENCY_APP_SOURCE', GETPOST('MULTICURRENCY_APP_SOURCE', 'alpha')); + dolibarr_set_const($db, 'MULTICURRENCY_ALTERNATE_SOURCE', GETPOST('MULTICURRENCY_ALTERNATE_SOURCE', 'alpha')); + } + else + { + MultiCurrency::syncRates($conf->global->MULTICURRENCY_APP_ID); + } } @@ -177,17 +186,20 @@ if ($conf->use_javascript_ajax) { } print ''; -//Online payment with currency on document -print ''; -print ''.$langs->transnoentitiesnoconv("multicurrency_useCurrency").''; -print ''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT'); -} else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT", $arrval, $conf->global->MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT); +// Online payment with currency on document. This option should be on by default. +if ($conf->global->MAIN_FEATURES_LEVEL >= 2) +{ + print ''; + print ''.$langs->transnoentitiesnoconv("MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT").''; + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT", $arrval, $conf->global->MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT); + } + print ''; } -print ''; /* TODO uncomment when the functionality will integrated @@ -224,59 +236,48 @@ print '
'; if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) { + print ''; + print ''; + print ''; + print '
'; print ''; - print ''; - print ''."\n"; - print ''; + $urlforapilayer='https://currencylayer.com'; //https://apilayer.net + print ''; + print ''."\n"; + print ''; print ''; - print ''; + print ''; print ''; - print ''; print ''; print ''; print ''; print ''; print ''; print '
'.$form->textwithpicto($langs->trans("CurrencyLayerAccount"), $langs->trans("CurrencyLayerAccount_help_to_synchronize")).''; - print ''; - print ''; - print ''; - print $langs->trans("Value").' '; - print ''; - print '
'.$form->textwithpicto($langs->trans("CurrencyLayerAccount"), $langs->trans("CurrencyLayerAccount_help_to_synchronize", $urlforapilayer)).''; + print ''; + print $langs->trans("Value").' '; + print ''; + print '
'.$langs->transnoentitiesnoconv("multicurrency_appId").''.$langs->transnoentitiesnoconv("multicurrency_appId").''; - print '
'; - print ''; - print ''; print ' '; - print ''; - print '
'; print '
'.$langs->transnoentitiesnoconv("multicurrency_appCurrencySource").''; - print '
'; - print ''; - print ''; print ' '; // Default: USD - print ''; print '
'; print '
'.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").''; - print '
'; - print ''; - print ''; print ' '; // Example: EUR - print ''; - print '
'; print '
'; print '
'; print '
'; -} + print ''; +} print '
'; print ''; @@ -287,15 +288,17 @@ print ''."\n"; print ''; print ''; +print ''; +print ''; + print ''; print ''; print ''; print ''; + print ''; print ''; @@ -325,23 +328,6 @@ foreach ($TCurrency as &$currency) print '
'.$langs->trans("Rate").'
'.$form->selectCurrency('', 'code').''; -print ''; -print ''; print ' '; print ''; print '
'; print '
'; -print ' - -'; // End of page llxFooter(); diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index 47c5590b862..68791b41320 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -7,10 +7,10 @@ multicurrency_syncronize_error=Synchronization error: %s MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE=Use the date of the document to find the currency rate, instead of using the latest known rate multicurrency_useOriginTx=When an object is created from another, keep the original rate from the source object (otherwise use the latest known rate) CurrencyLayerAccount=CurrencyLayer API -CurrencyLayerAccount_help_to_synchronize=You must create an account on their website to use this functionality.
Get your API key.
If you use a free account you can't change the currency source (USD by default).
If your main currency is not USD you can use the alternate currency source to force your main currency.

You are limited to 1000 synchronizations per month. +CurrencyLayerAccount_help_to_synchronize=You must create an account on website %s to use this functionality.
Get your API key.
If you use a free account you can't change the currency source (USD by default).
If your main currency is not USD you can use the alternate currency source to force your main currency.

You are limited to 1000 synchronizations per month. multicurrency_appId=API key -multicurrency_appCurrencySource=Currency source -multicurrency_alternateCurrencySource=Alternate currency source +multicurrency_appCurrencySource=Source currency +multicurrency_alternateCurrencySource=Alternate source currency CurrenciesUsed=Currencies used CurrenciesUsed_help_to_add=Add the different currencies and rates you need to use on your proposals, orders etc. rate=rate diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index ea39cb85b8e..7cb73686fc5 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -633,7 +633,11 @@ class MultiCurrency extends CommonObject { global $conf, $db, $langs; - $ch = curl_init('http://apilayer.net/api/live?access_key='.$key.''); + $urlendpoint = 'http://apilayer.net/api/live?access_key='.$key; + dol_syslog("Call url endpoint ".$urlendpoint); + + // TODO Use getURLContent() function instead. + $ch = curl_init($urlendpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); @@ -663,6 +667,7 @@ class MultiCurrency extends CommonObject } else { + dol_syslog("Failed to call endpoint ".$response->error->info, LOG_WARNING); setEventMessages($langs->trans('multicurrency_syncronize_error', $response->error->info), null, 'errors'); } } From 51456802792e2c470669b487a94e601e69c6314f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 13:31:47 +0200 Subject: [PATCH 34/75] Debug hidden option MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION --- htdocs/admin/multicurrency.php | 11 ++++++++++- htdocs/multicurrency/class/multicurrency.class.php | 10 +++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index fa622a7ee81..9602f9c383b 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -249,7 +249,7 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''.$form->textwithpicto($langs->trans("CurrencyLayerAccount"), $langs->trans("CurrencyLayerAccount_help_to_synchronize", $urlforapilayer)).''."\n"; print ''; print ''; - print $langs->trans("Value").' '; + print $langs->trans("Value").' '; print ''; print ''; @@ -328,6 +328,15 @@ foreach ($TCurrency as &$currency) print ''; print '
'; +print ' + +'; // End of page llxFooter(); diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index 42d53db20ad..faf05bdc571 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -626,14 +626,18 @@ class MultiCurrency extends CommonObject /** * Sync rates from api * - * @param string $key Key to use. Come from $conf->global->MULTICURRENCY_APP_ID. + * @param string $key Key to use. Come from $conf->global->MULTICURRENCY_APP_ID. + * @param int $addifnotfound Add if not found * @return void */ - public static function syncRates($key) + public static function syncRates($key, $addifnotfound = 0) { global $conf, $db, $langs; $urlendpoint = 'http://apilayer.net/api/live?access_key='.$key; + //$urlendpoint.='&format=1'; + $urlendpoint.=(empty($conf->global->MULTICURRENCY_APP_SOURCE) ? '' : '&source='.$conf->global->MULTICURRENCY_APP_SOURCE); + dol_syslog("Call url endpoint ".$urlendpoint); // TODO Use getURLContent() function instead. @@ -658,7 +662,7 @@ class MultiCurrency extends CommonObject { $obj->updateRate($rate); } - else + elseif ($addifnotfound) { self::addRateFromDolibarr($code, $rate); } From e81f10c79033ee9bcd4133e9cff2308918902692 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 13:45:49 +0200 Subject: [PATCH 35/75] Debug hidden option MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION --- htdocs/admin/multicurrency.php | 10 +++++----- htdocs/core/class/html.form.class.php | 12 ++++++++++-- htdocs/langs/en_US/multicurrency.lang | 2 +- htdocs/multicurrency/class/multicurrency.class.php | 4 ++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 9602f9c383b..4a10f663e34 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -115,7 +115,7 @@ elseif ($action == 'setapilayer') { dolibarr_set_const($db, 'MULTICURRENCY_APP_ID', GETPOST('MULTICURRENCY_APP_ID', 'alpha')); dolibarr_set_const($db, 'MULTICURRENCY_APP_SOURCE', GETPOST('MULTICURRENCY_APP_SOURCE', 'alpha')); - dolibarr_set_const($db, 'MULTICURRENCY_ALTERNATE_SOURCE', GETPOST('MULTICURRENCY_ALTERNATE_SOURCE', 'alpha')); + //dolibarr_set_const($db, 'MULTICURRENCY_ALTERNATE_SOURCE', GETPOST('MULTICURRENCY_ALTERNATE_SOURCE', 'alpha')); } else { @@ -249,8 +249,8 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''.$form->textwithpicto($langs->trans("CurrencyLayerAccount"), $langs->trans("CurrencyLayerAccount_help_to_synchronize", $urlforapilayer)).''."\n"; print ''; print ''; - print $langs->trans("Value").' '; print ''; + print ''; print ''; print ''; @@ -266,11 +266,11 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; - print ''; + /*print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").''; print ''; print ' '; // Example: EUR - print ''; + print '';*/ print ''; print '
'; @@ -292,7 +292,7 @@ print ''; print ''; print ''; -print ''.$form->selectCurrency('', 'code').''; +print ''.$form->selectCurrency('', 'code', 1).''; print ''; print ' '; print ''; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 93cbdb138a0..3c4ac0b9804 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4781,9 +4781,10 @@ class Form * * @param string $selected preselected currency code * @param string $htmlname name of HTML select list + * @param string $mode 0 = Add currency symbol into label, 1 = Add 3 letter iso code * @return string */ - public function selectCurrency($selected = '', $htmlname = 'currency_id') + public function selectCurrency($selected = '', $htmlname = 'currency_id', $mode = 0) { global $conf,$langs,$user; @@ -4805,7 +4806,14 @@ class Form $out.= ''; } $out.= ''; diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index 68791b41320..4dc04ff2622 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -7,7 +7,7 @@ multicurrency_syncronize_error=Synchronization error: %s MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE=Use the date of the document to find the currency rate, instead of using the latest known rate multicurrency_useOriginTx=When an object is created from another, keep the original rate from the source object (otherwise use the latest known rate) CurrencyLayerAccount=CurrencyLayer API -CurrencyLayerAccount_help_to_synchronize=You must create an account on website %s to use this functionality.
Get your API key.
If you use a free account you can't change the currency source (USD by default).
If your main currency is not USD you can use the alternate currency source to force your main currency.

You are limited to 1000 synchronizations per month. +CurrencyLayerAccount_help_to_synchronize=You must create an account on website %s to use this functionality.
Get your API key.
If you use a free account, you can't change the source currency (USD by default).
If your main currency is not USD, the application will automatically recalculate it.

You are limited to 1000 synchronizations per month. multicurrency_appId=API key multicurrency_appCurrencySource=Source currency multicurrency_alternateCurrencySource=Alternate source currency diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index faf05bdc571..a694b5396d7 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -603,9 +603,9 @@ class MultiCurrency extends CommonObject { global $conf; - if (!empty($conf->global->MULTICURRENCY_ALTERNATE_SOURCE)) + if ($conf->currency != $conf->global->MULTICURRENCY_APP_SOURCE) { - $alternate_source = 'USD'.$conf->global->MULTICURRENCY_ALTERNATE_SOURCE; + $alternate_source = 'USD'.$conf->currency; if (!empty($TRate->{$alternate_source})) { $coef = $TRate->USDUSD / $TRate->{$alternate_source}; From a75223c850487f55e814f0add4eb15acd80190dc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 13:53:13 +0200 Subject: [PATCH 36/75] Debug ticket module --- htdocs/langs/en_US/ticket.lang | 2 +- htdocs/ticket/class/ticket.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index c84dc17f087..030858eecce 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -60,7 +60,7 @@ NotRead=Not read Read=Read Assigned=Assigned InProgress=In progress -NeedMoreInformation=Waiting more information +NeedMoreInformation=Waiting for information Answered=Answered Waiting=Waiting Closed=Closed diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index bae523b1819..c049712d623 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -194,7 +194,7 @@ class Ticket extends CommonObject 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>1, 'enabled'=>1, 'position'=>500, 'notnull'=>1), 'date_read' => array('type'=>'datetime', 'label'=>'TicketReadOn', 'visible'=>1, 'enabled'=>1, 'position'=>500, 'notnull'=>1), 'fk_user_assign' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'AssignedTo', 'visible'=>1, 'enabled'=>1, 'position'=>505, 'notnull'=>1), - 'date_close' => array('type'=>'datetime', 'label'=>'TicketCloseOn', 'visible'=>1, 'enabled'=>1, 'position'=>510, 'notnull'=>1), + 'date_close' => array('type'=>'datetime', 'label'=>'TicketCloseOn', 'visible'=>-1, 'enabled'=>1, 'position'=>510, 'notnull'=>1), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-1, 'enabled'=>1, 'position'=>520, 'notnull'=>1), 'message' => array('type'=>'text', 'label'=>'Message', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1,), 'progress' => array('type'=>'varchar(100)', 'label'=>'Progression', 'visible'=>-1, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'css'=>'right', 'help'=>""), From 263b6cafbcb4748dfd1dd13492f73aae14d6be5b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 14:03:35 +0200 Subject: [PATCH 37/75] Fix var --- htdocs/core/actions_massactions.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 973dae1bbee..4d0a3c878db 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -216,7 +216,7 @@ if (! $error && $massaction == 'confirm_presend') $resaction.='
'.$langs->trans('ErrorOnlyProposalNotDraftCanBeSentInMassAction', $objectobj->ref).'

'; continue; // Payment done or started or canceled } - if ($objectclass == 'Commande' && $objectoj->statut == Commande::STATUS_DRAFT) + if ($objectclass == 'Commande' && $objectojb->statut == Commande::STATUS_DRAFT) { $langs->load("errors"); $nbignored++; From cbe23741ebe62ca978c516f70e1257587b921a44 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 2 May 2019 14:06:55 +0200 Subject: [PATCH 38/75] FIX Massive debug in lettering function --- .../thirdparty_lettering_customer.php | 155 +++++++++++------- .../thirdparty_lettering_supplier.php | 151 ++++++++++------- htdocs/accountancy/class/lettering.class.php | 20 +-- htdocs/langs/en_US/accountancy.lang | 1 + 4 files changed, 195 insertions(+), 132 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php index 1d370176613..fed41d70b53 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php @@ -3,8 +3,8 @@ * Copyright (C) 2005 Laurent Destailleur * Copyright (C) 2013 Olivier Geffroy * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2018 Alexandre Spangaro - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; @@ -53,26 +54,31 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if ($sortorder == "") - $sortorder = "DESC"; + $sortorder = "ASC"; if ($sortfield == "") $sortfield = "bk.doc_date"; -$search_year = GETPOST("search_year", 'int'); -$search_doc_type = GETPOST("search_doc_type", 'alpha'); +/* +$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); +$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); +//$search_doc_type = GETPOST("search_doc_type", 'alpha'); $search_doc_ref = GETPOST("search_doc_ref", 'alpha'); +*/ $lettering = GETPOST('lettering', 'alpha'); if (! empty($lettering)) { $action = $lettering; } -// Did we click on purge search criteria ? -// All tests are required to be compatible with all browsers -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { - $search_year = ''; - $search_doc_type = ''; +/* +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers +{ + $search_date_start = ''; + $search_date_end = ''; + //$search_doc_type = ''; $search_doc_ref = ''; } +*/ // Security check $socid = GETPOST("socid", 'int'); @@ -102,6 +108,7 @@ if ($action == 'lettering') { } } +/* if ($action == 'autolettrage') { $result = $lettering->letteringThirdparty($socid); @@ -111,9 +118,9 @@ if ($action == 'autolettrage') { $error++; } } +*/ - - /* +/* * View */ @@ -136,19 +143,17 @@ dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'n dol_fiche_end(); -print '
'; - $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.lettering_code "; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " WHERE (bk.subledger_account = '" . $object->code_compta . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER . "' )"; -if (dol_strlen($search_year)) { - $date_start = dol_mktime(0, 0, 0, 1, 1, $search_year); - $date_end = dol_mktime(23, 59, 59, 12, 31, $search_year); - $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($date_start) . "' AND '" . $db->idate($date_end) . "' )"; +/* +if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { + $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($search_date_start) . "' AND '" . $db->idate($search_date_end) . "' )"; } +*/ $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; $sql .= $db->order($sortfield, $sortorder); @@ -190,34 +195,57 @@ if ($resql) { print '
'; print ''; - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + $letteringbutton = ''; + //$letteringbutton = '' . $langs->trans("Lettering") . ''; + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); print ""; + + /* + print ''; + //print ''; + + // Date + print ''; + + // Piece + print ''; + + print ''; + print ''; + print ''; + */ + print ''; - print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); + //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("", "","",'','',"",$sortfield,$sortorder,'maxwidthsearch center '); print "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $solde = 0; $tmp = ''; + + if (empty($obj->lettering_code)) $rowaction++; while ( $obj = $db->fetch_object($resql) ) { if ($tmp != $obj->lettering_code || empty($tmp)) $tmp = $obj->lettering_code; @@ -225,48 +253,53 @@ if ($resql) { print ''; - if (empty($obj->lettering_code)) { - print '' . "\n"; - } else { - print '' . "\n"; - } - - print ''; + //print '' . "\n"; + print ''; print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; - if (empty($obj->lettering_code)) { - print ''; - } else - print ''; + // Journal + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('',$obj->code_journal); + $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0,0,0,'',0) : $obj->code_journal); + print ''; + + if (empty($obj->lettering_code)) { + print ''; + print '' . "\n"; + } else { + print ''; + print ''; + } print "\n"; } print ''; - print '' . "\n"; - print ''; - print ''; - print ''; + print '' . "\n"; + print ''; + print ''; + print ''; print "\n"; print ''; - print '' . "\n"; + print '' . "\n"; print ''; - print ''; - print ''; + print ''; + print ''; print "\n"; print "
'; + print '
'; + print $langs->trans('From') . ' '; + print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); + print '
'; + print '
'; + print $langs->trans('to') . ' '; + print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); + print '
'; + print '
 '; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'; - print img_edit(); - print ' ' . $obj->doc_type . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_ref . '' . $obj->label_compte . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->code_journal . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->lettering_code . '' . $journaltoshow . ''; + print img_edit(); + print '' . $obj->lettering_code . '
'.$langs->trans("Total").':' . price($debit) . '' . price($credit) . ''.$langs->trans("Total").':' . price($debit) . '' . price($credit) . '
'.$langs->trans("Balancing").':'.$langs->trans("Balancing").': ' . price($credit - $debit) . '' . price($credit - $debit) . '
"; - print ''; - //print '' . $langs->trans('AccountancyAutoLettering') . ''; + print '
'."\n"; + print $letteringbutton; + print '
'; + print "
"; $db->free($resql); } else { diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php index 1d80bda7710..3795099c78d 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php @@ -3,8 +3,8 @@ * Copyright (C) 2005 Laurent Destailleur * Copyright (C) 2013 Olivier Geffroy * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2018 Alexandre Spangaro - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; @@ -53,27 +54,31 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if ($sortorder == "") - $sortorder = "DESC"; + $sortorder = "ASC"; if ($sortfield == "") $sortfield = "bk.doc_date"; -$search_year = GETPOST("search_year",'int'); -$search_doc_type = GETPOST("search_doc_type",'alpha'); +/* +$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); +$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); +//$search_doc_type = GETPOST("search_doc_type",'alpha'); $search_doc_ref = GETPOST("search_doc_ref",'alpha'); +*/ $lettering = GETPOST('lettering', 'alpha'); if (!empty($lettering)) { $action=$lettering; } -// Did we click on purge search criteria ? -// All tests are required to be compatible with all browsers -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) +/* +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { - $search_year=''; - $search_doc_type=''; + $search_date_start = ''; + $search_date_end = ''; + //$search_doc_type=''; $search_doc_ref=''; } +*/ // Security check @@ -103,6 +108,7 @@ if ($action == 'lettering') { } } +/* if ($action == 'autolettrage') { $result = $lettering->letteringThirdparty($socid); @@ -112,7 +118,7 @@ if ($action == 'autolettrage') { $error++; } } - +*/ /* * View @@ -143,10 +149,8 @@ $sql .= " bk.credit, bk.montant , bk.sens , bk.code_journal , bk.piece_num, bk.l $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " WHERE (bk.subledger_account = '" . $object->code_compta_fournisseur . "' AND bk.numero_compte = '" . $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER . "' )"; -if (dol_strlen($search_year)) { - $date_start = dol_mktime(0, 0, 0, 1, 1, $search_year); - $date_end = dol_mktime(23, 59, 59, 12, 31, $search_year); - $sql .= " AND ( bk.doc_date BETWEEN '".$db->idate($date_start)."' AND '".$db->idate($date_end)."' )"; +if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { + $sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND '".$db->idate($search_date_end)."' )"; } $sql.= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; @@ -193,31 +197,51 @@ if ($resql) { print '
'; print ''; - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); + $letteringbutton = '\'; + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); print ""; - print ''; - print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder); - print "\n"; + + /* + print ''; + //print ''; + + // Date + print ''; + + // Piece + print ''; + + print ''; + print ''; + print ''; + */ print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; + //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); + print_liste_field_titre("", "","",'','',"",$sortfield,$sortorder,'maxwidthsearch center '); + print "\n"; $solde = 0; $tmp = ''; @@ -228,48 +252,53 @@ if ($resql) { print ''; - if (empty($obj->lettering_code)) { - print '' . "\n"; - } else { - print '' . "\n"; - } - - print ''; + //print '' . "\n"; + print ''; print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + + // Journal + $accountingjournal = new AccountingJournal($db); + $result = $accountingjournal->fetch('',$obj->code_journal); + $journaltoshow = (($result > 0)?$accountingjournal->getNomUrl(0,0,0,'',0) : $obj->code_journal); + print ''; if (empty($obj->lettering_code)) { - print ''; - } else - print ''; + print ''; + print '' . "\n"; + } else { + print ''; + print ''; + } print "\n"; } print ''; - print '' . "\n"; - print ''; - print ''; - print ''; + print '' . "\n"; + print ''; + print ''; + print ''; print "\n"; print ''; - print '' . "\n"; + print '' . "\n"; print ''; - print ''; - print ''; + print ''; + print ''; print "\n"; print "
'; + print '
'; + print $langs->trans('From') . ' '; + print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); + print '
'; + print '
'; + print $langs->trans('to') . ' '; + print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); + print '
'; + print '
 '; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
 '; - $searchpicto=$form->showFilterButtons(); - print $searchpicto; - print '
'; - print img_edit(); - print ' ' . $obj->doc_type . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_type . '' . dol_print_date($db->jdate($obj->doc_date), 'day') . '' . $obj->doc_ref . '' . $obj->label_compte . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $obj->code_journal . '' . price($obj->debit) . '' . price($obj->credit) . '' . price(round($solde, 2)) . '' . $journaltoshow . '' . $obj->lettering_code . ''; + print img_edit(); + print '' . $obj->lettering_code . '
'.$langs->trans("Total").':' . price($debit) . '' . price($credit) . ''.$langs->trans("Total").':' . price($debit) . '' . price($credit) . '
'.$langs->trans("Balancing").':'.$langs->trans("Balancing").': ' . price($credit - $debit) . '' . price($credit - $debit) . '
"; - print ''; - //print ''.$langs->trans('AccountancyAutoLettering').''; + print '
'."\n"; + print $letteringbutton; + print '
'; + print "
"; $db->free($resql); } else { diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index b0ad8150ad4..174f5fa42f5 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013-2018 Alexandre Spangaro + * Copyright (C) 2013-2019 Alexandre Spangaro * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -66,13 +66,13 @@ class Lettering extends BookKeeping $sql .= " , bk.sens , bk.code_journal , bk.piece_num, bk.date_lettering, bu.url_id , bu.type "; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as bk"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu ON(bk.fk_doc = bu.fk_bank AND bu.type IN ('payment', 'payment_supplier') ) "; - $sql .= " WHERE ( "; + $sql .= " WHERE ( "; if (! empty($object->code_compta)) - $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) - $sql .= " OR "; + $sql .= " OR "; if (! empty($object->code_compta_fournisseur)) - $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; $sql .= " ) AND (bk.date_lettering ='' OR bk.date_lettering IS NULL) "; $sql .= " AND (bk.lettering_code != '' OR bk.lettering_code IS NULL) "; @@ -128,15 +128,15 @@ class Lettering extends BookKeeping $sql .= " AND facf.entity = ".$conf->entity; $sql .= " AND ( "; if (! empty($object->code_compta)) { - $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta . "' "; } if (! empty($object->code_compta) && ! empty($object->code_compta_fournisseur)) { - $sql .= " OR "; + $sql .= " OR "; } if (! empty($object->code_compta_fournisseur)) { - $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; + $sql .= " bk.subledger_account = '" . $object->code_compta_fournisseur . "' "; } - $sql .= " ) "; + $sql .= ") "; $resql2 = $this->db->query($sql); if ($resql2) { @@ -253,7 +253,7 @@ class Lettering extends BookKeeping $error++; } - $sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE "; + $sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE "; $sql .= " rowid IN (" . implode(',', $ids) . ") "; $result = $this->db->query($sql); if ($result) { diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 31f3d5e264a..c7e9baa04ac 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -161,6 +161,7 @@ LabelAccount=Label account LabelOperation=Label operation Sens=Sens LetteringCode=Lettering code +Lettering=Lettering Codejournal=Journal NumPiece=Piece number TransactionNumShort=Num. transaction From 7bd99c0eee588e8135a9b671ddfabc69cb23fbdd Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 2 May 2019 14:08:28 +0200 Subject: [PATCH 39/75] fix --- .../accountancy/bookkeeping/thirdparty_lettering_customer.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php index fed41d70b53..87377a189a6 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php @@ -245,8 +245,7 @@ if ($resql) { $solde = 0; $tmp = ''; - if (empty($obj->lettering_code)) $rowaction++; - while ( $obj = $db->fetch_object($resql) ) { + while ( $obj = $db->fetch_object($resql) ) { if ($tmp != $obj->lettering_code || empty($tmp)) $tmp = $obj->lettering_code; /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); From 8e936fda4f2b0d300a803787412df676965cccd3 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Thu, 2 May 2019 14:19:50 +0200 Subject: [PATCH 40/75] FIX : typo error --- htdocs/takepos/takepos.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php index 143c6abf063..d5d81880a4e 100644 --- a/htdocs/takepos/takepos.php +++ b/htdocs/takepos/takepos.php @@ -55,7 +55,7 @@ if ($conf->browser->layout == 'phone') $maxproductbydefaultforthisdevice=16; } $MAXCATEG = (empty($conf->global->TAKEPOS_NB_MAXCATEG)?$maxcategbydefaultforthisdevice:$conf->global->TAKEPOS_NB_MAXCATEG); -$MAXPRODUCT = (empty($conf->global->TAKEPOS_NB_MAXPRODUCT)?$maxproductbydefaultforthisdevice:$conf->global->TAKEPOS_NB_MAXPRODUCT);; +$MAXPRODUCT = (empty($conf->global->TAKEPOS_NB_MAXPRODUCT)?$maxproductbydefaultforthisdevice:$conf->global->TAKEPOS_NB_MAXPRODUCT); /* From bcd96ba8d6793977b0fc04418e6d198d408b36e4 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Thu, 2 May 2019 14:42:02 +0200 Subject: [PATCH 41/75] inactive a var_dump --- htdocs/compta/cashcontrol/cashcontrol_card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 80572b40efc..76a265e842e 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -200,7 +200,7 @@ if ($action == 'confirm_delete' && ! empty($permissiontodelete)) } $result=$object->delete($user); - var_dump($result); + //var_dump($result); if ($result > 0) { // Delete OK From 8d7f24a6d9b52e321f797632b583bbdc6a3657f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 15:34:29 +0200 Subject: [PATCH 42/75] FIX Default value on form to send email --- htdocs/core/class/html.formmail.class.php | 4 ++-- htdocs/core/lib/functions.lib.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index bf03477643b..d455d1058fc 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -711,7 +711,7 @@ class FormMail extends Form } else { - $out.= 'withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />'; + $out.= 'withtocc) && ! is_numeric($this->withtocc)) ? $this->withtocc : '')).'" />'; if (! empty($this->withtocc) && is_array($this->withtocc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; @@ -762,7 +762,7 @@ class FormMail extends Form } else { - $out.= 'withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />'; + $out.= 'withtoccc) && ! is_numeric($this->withtoccc)) ? $this->withtoccc : '')).'" />'; if (! empty($this->withtoccc) && is_array($this->withtoccc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8c3393dd08e..570d00ef2bd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -349,7 +349,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu } if (! empty($conf->global->MAIN_ENABLE_DEFAULT_VALUES)) { - if (! empty($_GET['action']) && $_GET['action'] == 'create' && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) + if (! empty($_GET['action']) && (preg_match('/^create/', $_GET['action']) || preg_match('/^presend/', $_GET['action'])) && ! isset($_GET[$paramname]) && ! isset($_POST[$paramname])) { // Now search in setup to overwrite default values if (! empty($user->default_values)) // $user->default_values defined from menu 'Setup - Default values' From 2839eedbbfacd2a504711d0c3caef6451876bc20 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 16:06:14 +0200 Subject: [PATCH 43/75] Fix error on emailcollector for tickets --- htdocs/emailcollector/class/emailcollector.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 710afc05cec..e52b1bf156e 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1613,7 +1613,7 @@ class EmailCollector extends CommonObject if ($savesocid != $projecttocreate->socid) { $errorforactions++; - setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$projecttocreate->socid.') by setting socid in operation with a different value'); + setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$projecttocreate->socid.') by setting socid in operation with a different value', null, 'errors'); } } else { @@ -1721,14 +1721,14 @@ class EmailCollector extends CommonObject if ($filefound) { $result=dol_include_once($reldir."core/modules/ticket/".$modele.'.php'); - $modProject = new $classname; + $modTicket = new $classname; if ($savesocid > 0) { if ($savesocid != $tickettocreate->socid) { $errorforactions++; - setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$tickettocreate->socid.') by setting socid in operation with a different value'); + setEventMessages('You loaded a thirdparty (id='.$savesocid.') and you force another thirdparty id (id='.$tickettocreate->socid.') by setting socid in operation with a different value', null, 'errors'); } } else { @@ -1738,7 +1738,7 @@ class EmailCollector extends CommonObject } } - $defaultref = $modTicket->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $projecttocreate); + $defaultref = $modTicket->getNextValue(($thirdpartystatic->id > 0 ? $thirdpartystatic : null), $tickettocreate); } $tickettocreate->ref = $defaultref; } From a764a79c1f1eeb4f5c82eef877b480c2a27b9257 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 16:08:58 +0200 Subject: [PATCH 44/75] Fix scrutinizer error --- htdocs/categories/class/api_categories.class.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index 9b59e1f001b..c82d803f31c 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -391,8 +391,11 @@ class Categories extends DolibarrApi } elseif ($type == 'contact') { $objects_api = new Contacts(); } - foreach ($objects as $obj) { - $cleaned_objects[] = $objects_api->_cleanObjectDatas($obj); + if (is_object($objects_api)) + { + foreach ($objects as $obj) { + $cleaned_objects[] = $objects_api->_cleanObjectDatas($obj); + } } return $cleaned_objects; From 4899d03ff8a164f6b2c409f13f637c26cf8c43c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 17:15:24 +0200 Subject: [PATCH 45/75] FIX Confusion between expired and late --- htdocs/contrat/class/contrat.class.php | 27 ++++++++++++++++++++++---- htdocs/index.php | 8 ++++---- htdocs/langs/en_US/contracts.lang | 3 ++- htdocs/langs/fr_FR/main.lang | 2 +- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 0059609d071..4fdccd10883 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2108,7 +2108,7 @@ class Contrat extends CommonObject $this->from.= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$user->societe_id) $this->from.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - if ($mode == 'inactives') + if ($mode == 'inactive') { $sql = "SELECT cd.rowid, cd.date_ouverture_prevue as datefin"; $sql.= $this->from; @@ -2123,25 +2123,44 @@ class Contrat extends CommonObject $sql.= " WHERE c.statut = 1"; $sql.= " AND c.rowid = cd.fk_contrat"; $sql.= " AND cd.statut = 4"; - $sql.= " AND cd.date_fin_validite < '".$this->db->idate(time())."'"; + $sql.= " AND cd.date_fin_validite < '".$this->db->idate(dol_now())."'"; + } + elseif ($mode == 'active') + { + $sql = "SELECT cd.rowid, cd.date_fin_validite as datefin"; + $sql.= $this->from; + $sql.= " WHERE c.statut = 1"; + $sql.= " AND c.rowid = cd.fk_contrat"; + $sql.= " AND cd.statut = 4"; + //$datetouse = dol_now(); + //$sql.= " AND cd.date_fin_validite < '".$this->db->idate($datetouse)."'"; } $sql.= " AND c.fk_soc = s.rowid"; $sql.= " AND c.entity = ".$conf->entity; if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + + var_dump($sql); $resql=$this->db->query($sql); if ($resql) { $langs->load("contracts"); $now=dol_now(); - if ($mode == 'inactives') { + if ($mode == 'inactive') { $warning_delay = $conf->contrat->services->inactifs->warning_delay; $label = $langs->trans("BoardNotActivatedServices"); $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0'; + } + elseif ($mode == 'expired') { + $warning_delay = $conf->contrat->services->expires->warning_delay; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired'; + $label = $langs->trans("BoardExpiredServices"); } else { $warning_delay = $conf->contrat->services->expires->warning_delay; - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4'; + //$url.= '&op2day='.$arraydatetouse['mday'].'&op2month='.$arraydatetouse['mon'].'&op2year='.$arraydatetouse['year']; + //if ($warning_delay >= 0) $url.='&filter=expired'; $label = $langs->trans("BoardRunningServices"); } diff --git a/htdocs/index.php b/htdocs/index.php index 1ef48ea9bae..81503139d88 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -432,9 +432,9 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire) { include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $board=new Contrat($db); - $dashboardlines[] = $board->load_board($user,"inactives"); + $dashboardlines[] = $board->load_board($user, "inactive"); // Number of active services (expired) - $dashboardlines[] = $board->load_board($user,"expired"); + $dashboardlines[] = $board->load_board($user, "active"); } // Number of invoices customers (has paid) if (! empty($conf->facture->enabled) && $user->rights->facture->lire) @@ -553,7 +553,7 @@ $nbworkboardempty=0; if (! empty($valid_dashboardlines)) { $boxwork.='
'; - + foreach($valid_dashboardlines as $board) { if (empty($board->nbtodo)) $nbworkboardempty++; @@ -593,7 +593,7 @@ if (! empty($valid_dashboardlines)) $boxwork .='
'; $boxwork .='
'; $boxwork .='
'; - + $boxwork .='
'; $boxwork .=''; } diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index b4e8d7c96d9..efe6cae4667 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -64,7 +64,8 @@ DateStartRealShort=Real start date DateEndReal=Real end date DateEndRealShort=Real end date CloseService=Close service -BoardRunningServices=Expired running services +BoardRunningServices=Services running +BoardExpiredServices=Services expired ServiceStatus=Status of service DraftContracts=Drafts contracts CloseRefusedBecauseOneServiceActive=Contract can't be closed as there is at least one open service on it diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index c36882a2ad1..f17cbaed86c 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -456,7 +456,7 @@ Duration=Durée TotalDuration=Durée totale Summary=Résumé DolibarrStateBoard=Statistiques de la base -DolibarrWorkBoard=Éléments en attente +DolibarrWorkBoard=Tableau de bord des éléments ouverts NoOpenedElementToProcess=Aucun élément ouvert à traiter Available=Disponible NotYetAvailable=Pas encore disponible From 9b21c827c3ffc58a8e6ee28a087d1cde3e0c3be6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 17:17:52 +0200 Subject: [PATCH 46/75] Fix remove var_dump --- htdocs/contrat/class/contrat.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 4fdccd10883..545cd9716f0 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2140,7 +2140,6 @@ class Contrat extends CommonObject if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; - var_dump($sql); $resql=$this->db->query($sql); if ($resql) { From 4e94d92b703719d5d2dc373eb49d981509cb59f0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 17:24:05 +0200 Subject: [PATCH 47/75] Fix link --- htdocs/contrat/class/contrat.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 545cd9716f0..f21e7c06b65 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2149,15 +2149,15 @@ class Contrat extends CommonObject if ($mode == 'inactive') { $warning_delay = $conf->contrat->services->inactifs->warning_delay; $label = $langs->trans("BoardNotActivatedServices"); - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0&sortfield=cd.date_fin_validite&sortorder=asc'; } elseif ($mode == 'expired') { $warning_delay = $conf->contrat->services->expires->warning_delay; - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired&sortfield=cd.date_fin_validite&sortorder=asc'; $label = $langs->trans("BoardExpiredServices"); } else { $warning_delay = $conf->contrat->services->expires->warning_delay; - $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4'; + $url = DOL_URL_ROOT.'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&sortfield=cd.date_fin_validite&sortorder=asc'; //$url.= '&op2day='.$arraydatetouse['mday'].'&op2month='.$arraydatetouse['mon'].'&op2year='.$arraydatetouse['year']; //if ($warning_delay >= 0) $url.='&filter=expired'; $label = $langs->trans("BoardRunningServices"); From 10d853cdb3d1be96921ad9886a05b52347a66d41 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 May 2019 21:54:28 +0200 Subject: [PATCH 48/75] Work on stripe payment using intent with option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION --- htdocs/langs/en_US/paypal.lang | 3 +- htdocs/public/payment/newpayment.php | 265 +++++++++++++++++++++++++-- htdocs/stripe/class/stripe.class.php | 235 ++++++++++++------------ 3 files changed, 375 insertions(+), 128 deletions(-) diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang index 51e98ccc8a2..1f8a9c2bd35 100644 --- a/htdocs/langs/en_US/paypal.lang +++ b/htdocs/langs/en_US/paypal.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - paypal PaypalSetup=PayPal module setup PaypalDesc=This module allows payment by customers via PayPal. This can be used for a ad-hoc payment or for a payment related to a Dolibarr object (invoice, order, ...) -PaypalOrCBDoPayment=Pay with PayPal (Credit Card or PayPal) +PaypalOrCBDoPayment=Pay with PayPal (Card or PayPal) PaypalDoPayment=Pay with PayPal PAYPAL_API_SANDBOX=Mode test/sandbox PAYPAL_API_USER=API username @@ -33,3 +33,4 @@ PaypalImportPayment=Import PayPal payments PostActionAfterPayment=Post actions after payments ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary. ValidationOfPaymentFailed=Validation of payment has failed +CardOwner=Card owner diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index f06228291ef..8489f0ef071 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -803,6 +803,28 @@ if (! $source) print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = null; + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum // as they don't exists (buyer is unknown, tag is free). } @@ -896,6 +918,29 @@ if ($source == 'order') print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && empty($order->billed) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = $stripe->customerStripe($order->thirdparty, $stripeacc, $servicestatus, 1); + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } + // Shipping address $shipToName=$order->thirdparty->name; $shipToStreet=$order->thirdparty->address; @@ -1007,14 +1052,14 @@ if ($source == 'invoice') print ''; print ''; } - // Currency - print ' '.$langs->trans("Currency".$currency).''; - print ''; } else { - print price($object->total_ttc, 1, $langs); + print ''.price($object->total_ttc, 1, $langs).''; } + // Currency + print ' '.$langs->trans("Currency".$currency).''; + print ''; print ''."\n"; // Tag @@ -1024,6 +1069,28 @@ if ($source == 'invoice') print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && ($paymentmethod == 'stripe') && empty($object->paye) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = $stripe->customerStripe($invoice->thirdparty, $stripeacc, $servicestatus, 1); + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } + // Shipping address $shipToName=$invoice->thirdparty->name; $shipToStreet=$invoice->thirdparty->address; @@ -1149,6 +1216,7 @@ if ($source == 'contractline') // Debitor print ''.$langs->trans("ThirdParty"); print ''.$contract->thirdparty->name.''; + print ''."\n"; // Object $text=''.$langs->trans("PaymentRenewContractId", $contract->ref, $contractline->ref).''; @@ -1234,6 +1302,29 @@ if ($source == 'contractline') print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = null; + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } + // Shipping address $shipToName=$contract->thirdparty->name; $shipToStreet=$contract->thirdparty->address; @@ -1400,6 +1491,29 @@ if ($source == 'membersubscription') print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = null; + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } + // Shipping address $shipToName=$member->getFullName($langs); $shipToStreet=$member->address; @@ -1541,6 +1655,29 @@ if ($source == 'donation') print ''; print ''."\n"; + if (! empty($conf->stripe->enabled) && ($paymentmethod == 'stripe') && empty($object->paid) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + + $service = 'StripeLive'; + $servicestatus = 1; + + if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) + { + $service = 'StripeTest'; + $servicestatus = 0; + } + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $stripecu = $stripe->customerStripe($don->thirdparty, $stripeacc, $servicestatus, 1); + // for dev only + print ''.$langs->trans("PaymentIntent"); + print ''; + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); + print ''.$paymentintent->id.''; + print ''."\n"; + } + // Shipping address $shipToName=$don->getFullName($langs); $shipToStreet=$don->address; @@ -1724,25 +1861,38 @@ if (preg_match('/^dopayment/', $action)) print ''; print ' - - +
+ +
'; -
+ if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + print '
'; + } - -
+ print ' +
+ + '; + + if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + print '
'; + } + + print '
-
+
'; -
- + print '
+ -
+
'."\n"; @@ -1750,8 +1900,94 @@ if (preg_match('/^dopayment/', $action)) // Code to ask the credit card. This use the default "API version". No way to force API version when using JS code. print ''; } } diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index d604dcdd3f2..1f2f39719a8 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -140,7 +140,7 @@ class Stripe extends CommonObject if (empty($object->id)) { - dol_syslog("customerStripe is called with param object not loaded"); + dol_syslog("customerStripe is called with the parameter object that is not loaded"); return null; } @@ -240,6 +240,9 @@ class Stripe extends CommonObject /** * Get the Stripe payment intent. Create it with confirm=false * + * @param double $amount Amount + * @param string $currency_code Currency code + * @param string $tag Tag * @param Societe $object Object to pay with Stripe * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect @@ -249,127 +252,133 @@ class Stripe extends CommonObject * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found */ - public function getPaymentIntent($object, $customer, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) + public function getPaymentIntent($amount, $currency_code, $tag, $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) { global $conf, $user, $mysoc; - if (empty($object->id)) - { - dol_syslog("object not loaded"); - return null; - } - - $error = 0; - if (empty($status)) $service = 'StripeTest'; else $service = 'StripeLive'; + $arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); + if (! in_array($currency_code, $arrayzerounitcurrency)) $stripeamount = $amount * 100; + else $stripeamount = $amount; + + $fee = round(($$stripeamount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100); + if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { + $fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100); + } elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) { + $fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100); + } + $paymentintent = null; - $sql = "SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site"; - $sql.= " FROM " . MAIN_DB_PREFIX . "prelevement_facture_demande as pi"; - $sql.= " WHERE pi.fk_facture = " . $object->id; - $sql.= " AND pi.sourcetype = '" . $object->element . "'"; - $sql.= " AND pi.entity IN (".getEntity('societe').")"; - $sql.= " AND pi.ext_payment_site = '" . $service . "'"; - - dol_syslog(get_class($this) . "::getPaymentIntent search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - if ($num) - { - $obj = $this->db->fetch_object($resql); - $intent = $obj->ext_payment_id; - - dol_syslog(get_class($this) . "::getPaymentIntent found existing payment intent record"); - - // Force to use the correct API key - global $stripearrayofkeysbyenv; - \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); - - try { - if (empty($key)) { // If the Stripe connect account not set, we use common API usage - $paymentintent = \Stripe\PaymentIntent::retrieve($intent); - } else { - $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key)); - } - } - catch(Exception $e) - { - $this->error = $e->getMessage(); - } - } - else //if ($createifnotlinkedtostripe) - { - $arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); - if (! in_array($object->multicurrency_code, $arrayzerounitcurrency)) $stripeamount=$object->multicurrency_total_ttc * 100; - else $stripeamount = $object->multicurrency_total_ttc; - - $fee = round(($object->total_ttc * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100); - if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { - $fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100); - } elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) { - $fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100); - } - - $ipaddress=getUserRemoteIP(); - // Not enough space for a ref so we store id. Also with multicompany we can have same ref for 2 different - // object and we need a unique (this is used later as idempotency_key) - $description=$object->element.$object->id; - - $dataforintent = array( - "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent - "confirmation_method" => $mode, - "amount" => $stripeamount, - "currency" => $object->multicurrency_code, - "customer" => $customer, - "allowed_source_types" => ["card"], - "statement_descriptor" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) - "metadata" => array('dol_type'=>$object->element, 'dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress) - ); - // save_payment_method = true, - // payment_method_types = - // payment_method = - - if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0) - { - $dataforintent["application_fee"] = $fee; - } - if ($usethirdpartyemailforreceiptemail && $object->thirdparty->email) - { - $dataforintent["receipt_email"] = $object->thirdparty->email; - } - - try { - // Force to use the correct API key - global $stripearrayofkeysbyenv; - \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); - - if (empty($key)) { // If the Stripe connect account not set, we use common API usage - $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description")); - } else { - $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description","stripe_account" => $key)); - } - $now=dol_now(); - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_facture_demande (fk_soc, date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)"; - $sql .= " VALUES ('".$object->socid."','".$this->db->idate($now)."', '0', '".$this->db->escape($paymentintent->id)."', ".$object->id.", '".$this->db->escape($object->element)."', " . $conf->entity . ", '" . $service . "')"; - $resql = $this->db->query($sql); - if (! $resql) - { - $this->error = $this->db->lasterror(); - dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database."); - } - } - catch(Exception $e) - { - $this->error = $e->getMessage(); - } - } - } - else + if (is_object($object)) { - dol_print_error($this->db); + $sql = "SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site"; + $sql.= " FROM " . MAIN_DB_PREFIX . "prelevement_facture_demande as pi"; + $sql.= " WHERE pi.fk_facture = " . $object->id; + $sql.= " AND pi.sourcetype = '" . $object->element . "'"; + $sql.= " AND pi.entity IN (".getEntity('societe').")"; + $sql.= " AND pi.ext_payment_site = '" . $service . "'"; + + dol_syslog(get_class($this) . "::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + if ($num) + { + $obj = $this->db->fetch_object($resql); + $intent = $obj->ext_payment_id; + + dol_syslog(get_class($this) . "::getPaymentIntent found existing payment intent record"); + + // Force to use the correct API key + global $stripearrayofkeysbyenv; + \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); + + try { + if (empty($key)) { // If the Stripe connect account not set, we use common API usage + $paymentintent = \Stripe\PaymentIntent::retrieve($intent); + } else { + $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key)); + } + } + catch(Exception $e) + { + $this->error = $e->getMessage(); + } + } + } + } + + if (empty($paymentintent)) + { + $ipaddress=getUserRemoteIP(); + // Not enough space for a ref so we store id. Also with multicompany we can have same ref for 2 different + // object and we need a unique (this is used later as idempotency_key) + $description=$tag; + $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress); + if (is_object($object)) + { + $metadata['dol_type'] = $object->element; + $metadata['dol_id'] = $object->id; + } + + $dataforintent = array( + "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent + "confirmation_method" => $mode, + "amount" => $stripeamount, + "currency" => $currency_code, + "payment_method_types" => ["card"], + "statement_descriptor" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) + "metadata" => $metadata + ); + if (! is_null($customer)) $dataforintent["customer"]=$customer; + // save_payment_method = true, + // payment_method = + + if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0) + { + $dataforintent["application_fee"] = $fee; + } + if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) + { + $dataforintent["receipt_email"] = $object->thirdparty->email; + } + + try { + // Force to use the correct API key + global $stripearrayofkeysbyenv; + \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); + + if (empty($key)) { // If the Stripe connect account not set, we use common API usage + $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description")); + } else { + $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key)); + } + + // Store the payment intent + if (is_object($object)) + { + $now=dol_now(); + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_facture_demande (fk_soc, date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)"; + $sql .= " VALUES ('".$object->socid."','".$this->db->idate($now)."', '0', '".$this->db->escape($paymentintent->id)."', ".$object->id.", '".$this->db->escape($object->element)."', " . $conf->entity . ", '" . $service . "')"; + $resql = $this->db->query($sql); + if (! $resql) + { + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database."); + } + } + else + { + $_SESSION["stripe_payment_intent"] = $paymentintent; + } + } + catch(Exception $e) + { + $this->error = $e->getMessage(); + } } return $paymentintent; From eab49d4300983e97e8f658ff2e017485064351f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 May 2019 02:22:27 +0200 Subject: [PATCH 49/75] NEW Update Stripe library to 6.34.3 --- htdocs/core/lib/payments.lib.php | 2 +- htdocs/includes/stripe/.coveralls.yml | 4 - htdocs/includes/stripe/.travis.yml | 40 -- htdocs/includes/stripe/CHANGELOG.md | 216 ++++++ htdocs/includes/stripe/LICENSE | 2 +- htdocs/includes/stripe/README.md | 17 +- htdocs/includes/stripe/VERSION | 2 +- htdocs/includes/stripe/build.php | 2 +- htdocs/includes/stripe/composer.json | 5 +- htdocs/includes/stripe/init.php | 36 + htdocs/includes/stripe/lib/Account.php | 165 ++++- htdocs/includes/stripe/lib/AccountLink.php | 21 + htdocs/includes/stripe/lib/AlipayAccount.php | 3 + .../includes/stripe/lib/ApiOperations/All.php | 2 +- .../lib/ApiOperations/NestedResource.php | 3 + .../stripe/lib/ApiOperations/Request.php | 3 +- .../stripe/lib/ApiOperations/Retrieve.php | 2 +- htdocs/includes/stripe/lib/ApiRequestor.php | 187 ++++- htdocs/includes/stripe/lib/ApiResource.php | 28 +- htdocs/includes/stripe/lib/ApplePayDomain.php | 3 + htdocs/includes/stripe/lib/ApplicationFee.php | 24 +- .../stripe/lib/ApplicationFeeRefund.php | 3 + htdocs/includes/stripe/lib/Balance.php | 4 + .../stripe/lib/BalanceTransaction.php | 3 + htdocs/includes/stripe/lib/BankAccount.php | 3 + .../includes/stripe/lib/BitcoinReceiver.php | 3 + .../stripe/lib/BitcoinTransaction.php | 1 + htdocs/includes/stripe/lib/Card.php | 37 +- htdocs/includes/stripe/lib/Charge.php | 62 ++ .../includes/stripe/lib/Checkout/Session.php | 30 + htdocs/includes/stripe/lib/Collection.php | 14 +- htdocs/includes/stripe/lib/CountrySpec.php | 15 +- htdocs/includes/stripe/lib/Coupon.php | 6 +- htdocs/includes/stripe/lib/CreditNote.php | 73 ++ htdocs/includes/stripe/lib/Customer.php | 90 ++- htdocs/includes/stripe/lib/Discount.php | 21 + htdocs/includes/stripe/lib/Dispute.php | 6 +- htdocs/includes/stripe/lib/EphemeralKey.php | 14 +- .../stripe/lib/Error/OAuth/OAuthBase.php | 4 +- htdocs/includes/stripe/lib/Event.php | 227 ++++--- htdocs/includes/stripe/lib/ExchangeRate.php | 14 +- htdocs/includes/stripe/lib/File.php | 62 ++ htdocs/includes/stripe/lib/FileLink.php | 29 + htdocs/includes/stripe/lib/FileUpload.php | 30 +- .../stripe/lib/HttpClient/ClientInterface.php | 7 +- .../stripe/lib/HttpClient/CurlClient.php | 150 +++- htdocs/includes/stripe/lib/Invoice.php | 131 +++- htdocs/includes/stripe/lib/InvoiceItem.php | 5 + .../includes/stripe/lib/InvoiceLineItem.php | 32 + .../includes/stripe/lib/IssuerFraudRecord.php | 25 + .../stripe/lib/Issuing/Authorization.php | 68 ++ htdocs/includes/stripe/lib/Issuing/Card.php | 51 ++ .../stripe/lib/Issuing/CardDetails.php | 21 + .../stripe/lib/Issuing/Cardholder.php | 30 + .../includes/stripe/lib/Issuing/Dispute.php | 30 + .../stripe/lib/Issuing/Transaction.php | 33 + htdocs/includes/stripe/lib/LoginLink.php | 5 + htdocs/includes/stripe/lib/OAuth.php | 2 +- htdocs/includes/stripe/lib/Order.php | 5 +- htdocs/includes/stripe/lib/OrderItem.php | 22 + htdocs/includes/stripe/lib/OrderReturn.php | 24 +- htdocs/includes/stripe/lib/PaymentIntent.php | 94 +++ htdocs/includes/stripe/lib/PaymentMethod.php | 60 ++ htdocs/includes/stripe/lib/Payout.php | 52 +- htdocs/includes/stripe/lib/Person.php | 108 +++ htdocs/includes/stripe/lib/Plan.php | 10 + htdocs/includes/stripe/lib/Product.php | 14 +- .../includes/stripe/lib/Radar/ValueList.php | 32 + .../stripe/lib/Radar/ValueListItem.php | 26 + htdocs/includes/stripe/lib/Recipient.php | 18 + .../includes/stripe/lib/RecipientTransfer.php | 1 + htdocs/includes/stripe/lib/Refund.php | 37 +- .../stripe/lib/Reporting/ReportRun.php | 28 + .../stripe/lib/Reporting/ReportType.php | 24 + .../includes/stripe/lib/RequestTelemetry.php | 27 + htdocs/includes/stripe/lib/Review.php | 57 ++ htdocs/includes/stripe/lib/SKU.php | 3 + .../stripe/lib/Sigma/ScheduledQueryRun.php | 33 + .../stripe/lib/SingletonApiResource.php | 4 +- htdocs/includes/stripe/lib/Source.php | 46 +- .../includes/stripe/lib/SourceTransaction.php | 10 + htdocs/includes/stripe/lib/Stripe.php | 32 +- htdocs/includes/stripe/lib/StripeObject.php | 90 ++- htdocs/includes/stripe/lib/Subscription.php | 37 +- .../includes/stripe/lib/SubscriptionItem.php | 19 +- .../stripe/lib/SubscriptionSchedule.php | 111 +++ .../lib/SubscriptionScheduleRevision.php | 77 +++ htdocs/includes/stripe/lib/TaxId.php | 80 +++ htdocs/includes/stripe/lib/TaxRate.php | 31 + .../stripe/lib/Terminal/ConnectionToken.php | 17 + .../includes/stripe/lib/Terminal/Location.php | 25 + .../includes/stripe/lib/Terminal/Reader.php | 30 + htdocs/includes/stripe/lib/ThreeDSecure.php | 3 + htdocs/includes/stripe/lib/Token.php | 16 +- htdocs/includes/stripe/lib/Topup.php | 28 + htdocs/includes/stripe/lib/Transfer.php | 23 +- .../includes/stripe/lib/TransferReversal.php | 5 + htdocs/includes/stripe/lib/UsageRecord.php | 44 ++ .../stripe/lib/UsageRecordSummary.php | 22 + .../stripe/lib/Util/CaseInsensitiveArray.php | 62 ++ .../stripe/lib/Util/RequestOptions.php | 17 +- htdocs/includes/stripe/lib/Util/Util.php | 253 +++++-- .../includes/stripe/lib/WebhookEndpoint.php | 29 + .../includes/stripe/phpunit.no_autoload.xml | 15 - htdocs/includes/stripe/phpunit.xml | 15 - .../stripe/tests/Stripe/AccountTest.php | 365 ---------- .../stripe/tests/Stripe/AlipayAccountTest.php | 76 --- .../stripe/tests/Stripe/ApiRequestorTest.php | 572 ---------------- .../tests/Stripe/ApplePayDomainTest.php | 52 -- .../tests/Stripe/ApplicationFeeRefundTest.php | 21 - .../tests/Stripe/ApplicationFeeTest.php | 83 --- .../stripe/tests/Stripe/BalanceTest.php | 16 - .../tests/Stripe/BalanceTransactionTest.php | 29 - .../stripe/tests/Stripe/BankAccountTest.php | 99 --- .../tests/Stripe/BitcoinReceiverTest.php | 62 -- .../includes/stripe/tests/Stripe/CardTest.php | 94 --- .../stripe/tests/Stripe/ChargeTest.php | 140 ---- .../stripe/tests/Stripe/CollectionTest.php | 147 ---- .../stripe/tests/Stripe/CountrySpecTest.php | 29 - .../stripe/tests/Stripe/CouponTest.php | 79 --- .../stripe/tests/Stripe/CustomerTest.php | 269 -------- .../stripe/tests/Stripe/DisputeTest.php | 65 -- .../stripe/tests/Stripe/EphemeralKeyTest.php | 43 -- .../stripe/tests/Stripe/Error/BaseTest.php | 36 - .../Error/SignatureVerificationTest.php | 12 - .../stripe/tests/Stripe/EventTest.php | 29 - .../stripe/tests/Stripe/ExchangeRateTest.php | 54 -- .../stripe/tests/Stripe/FileUploadTest.php | 104 --- .../Stripe/HttpClient/CurlClientTest.php | 228 ------- .../stripe/tests/Stripe/InvoiceItemTest.php | 78 --- .../stripe/tests/Stripe/InvoiceTest.php | 87 --- .../stripe/tests/Stripe/OAuthTest.php | 97 --- .../stripe/tests/Stripe/OrderReturnTest.php | 29 - .../stripe/tests/Stripe/OrderTest.php | 87 --- .../stripe/tests/Stripe/PayoutTest.php | 77 --- .../includes/stripe/tests/Stripe/PlanTest.php | 80 --- .../stripe/tests/Stripe/ProductTest.php | 77 --- .../stripe/tests/Stripe/RecipientTest.php | 90 --- .../stripe/tests/Stripe/RefundTest.php | 65 -- .../includes/stripe/tests/Stripe/SKUTest.php | 82 --- .../stripe/tests/Stripe/SourceTest.php | 134 ---- .../stripe/tests/Stripe/StripeObjectTest.php | 453 ------------ .../stripe/tests/Stripe/StripeTest.php | 30 - .../tests/Stripe/SubscriptionItemTest.php | 77 --- .../stripe/tests/Stripe/SubscriptionTest.php | 115 ---- .../stripe/tests/Stripe/ThreeDSecureTest.php | 32 - .../stripe/tests/Stripe/TokenTest.php | 28 - .../stripe/tests/Stripe/TopupTest.php | 69 -- .../tests/Stripe/TransferReversalTest.php | 21 - .../stripe/tests/Stripe/TransferTest.php | 140 ---- .../tests/Stripe/Util/DefaultLoggerTest.php | 28 - .../tests/Stripe/Util/RequestOptionsTest.php | 81 --- .../stripe/tests/Stripe/Util/UtilTest.php | 90 --- .../stripe/tests/Stripe/WebhookTest.php | 110 --- htdocs/includes/stripe/tests/TestCase.php | 177 ----- .../stripe/tests/bootstrap.no_autoload.php | 5 - htdocs/includes/stripe/tests/bootstrap.php | 43 -- htdocs/includes/stripe/tests/data/test.png | Bin 95 -> 0 bytes htdocs/langs/en_US/paypal.lang | 2 +- htdocs/paypal/lib/paypal.lib.php | 2 +- htdocs/public/payment/newpayment.php | 642 ++++++++++-------- htdocs/public/payment/paymentok.php | 10 +- htdocs/stripe/class/stripe.class.php | 27 +- htdocs/stripe/lib/stripe.lib.php | 4 +- htdocs/theme/eldy/global.inc.php | 21 +- htdocs/theme/md/style.css.php | 14 +- 166 files changed, 3851 insertions(+), 5981 deletions(-) delete mode 100644 htdocs/includes/stripe/.coveralls.yml delete mode 100644 htdocs/includes/stripe/.travis.yml create mode 100644 htdocs/includes/stripe/lib/AccountLink.php create mode 100644 htdocs/includes/stripe/lib/Checkout/Session.php create mode 100644 htdocs/includes/stripe/lib/CreditNote.php create mode 100644 htdocs/includes/stripe/lib/Discount.php create mode 100644 htdocs/includes/stripe/lib/File.php create mode 100644 htdocs/includes/stripe/lib/FileLink.php create mode 100644 htdocs/includes/stripe/lib/InvoiceLineItem.php create mode 100644 htdocs/includes/stripe/lib/IssuerFraudRecord.php create mode 100644 htdocs/includes/stripe/lib/Issuing/Authorization.php create mode 100644 htdocs/includes/stripe/lib/Issuing/Card.php create mode 100644 htdocs/includes/stripe/lib/Issuing/CardDetails.php create mode 100644 htdocs/includes/stripe/lib/Issuing/Cardholder.php create mode 100644 htdocs/includes/stripe/lib/Issuing/Dispute.php create mode 100644 htdocs/includes/stripe/lib/Issuing/Transaction.php create mode 100644 htdocs/includes/stripe/lib/OrderItem.php create mode 100644 htdocs/includes/stripe/lib/PaymentIntent.php create mode 100644 htdocs/includes/stripe/lib/PaymentMethod.php create mode 100644 htdocs/includes/stripe/lib/Person.php create mode 100644 htdocs/includes/stripe/lib/Radar/ValueList.php create mode 100644 htdocs/includes/stripe/lib/Radar/ValueListItem.php create mode 100644 htdocs/includes/stripe/lib/Reporting/ReportRun.php create mode 100644 htdocs/includes/stripe/lib/Reporting/ReportType.php create mode 100644 htdocs/includes/stripe/lib/RequestTelemetry.php create mode 100644 htdocs/includes/stripe/lib/Review.php create mode 100644 htdocs/includes/stripe/lib/Sigma/ScheduledQueryRun.php create mode 100644 htdocs/includes/stripe/lib/SubscriptionSchedule.php create mode 100644 htdocs/includes/stripe/lib/SubscriptionScheduleRevision.php create mode 100644 htdocs/includes/stripe/lib/TaxId.php create mode 100644 htdocs/includes/stripe/lib/TaxRate.php create mode 100644 htdocs/includes/stripe/lib/Terminal/ConnectionToken.php create mode 100644 htdocs/includes/stripe/lib/Terminal/Location.php create mode 100644 htdocs/includes/stripe/lib/Terminal/Reader.php create mode 100644 htdocs/includes/stripe/lib/UsageRecord.php create mode 100644 htdocs/includes/stripe/lib/UsageRecordSummary.php create mode 100644 htdocs/includes/stripe/lib/Util/CaseInsensitiveArray.php create mode 100644 htdocs/includes/stripe/lib/WebhookEndpoint.php delete mode 100644 htdocs/includes/stripe/phpunit.no_autoload.xml delete mode 100644 htdocs/includes/stripe/phpunit.xml delete mode 100644 htdocs/includes/stripe/tests/Stripe/AccountTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/AlipayAccountTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ApiRequestorTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ApplePayDomainTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ApplicationFeeRefundTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ApplicationFeeTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/BalanceTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/BalanceTransactionTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/BankAccountTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/BitcoinReceiverTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/CardTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ChargeTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/CollectionTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/CountrySpecTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/CouponTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/CustomerTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/DisputeTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/EphemeralKeyTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/Error/BaseTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/Error/SignatureVerificationTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/EventTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ExchangeRateTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/FileUploadTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/HttpClient/CurlClientTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/InvoiceItemTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/InvoiceTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/OAuthTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/OrderReturnTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/OrderTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/PayoutTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/PlanTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ProductTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/RecipientTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/RefundTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/SKUTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/SourceTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/StripeObjectTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/StripeTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/SubscriptionItemTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/SubscriptionTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/ThreeDSecureTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/TokenTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/TopupTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/TransferReversalTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/TransferTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/Util/DefaultLoggerTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/Util/RequestOptionsTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/Util/UtilTest.php delete mode 100644 htdocs/includes/stripe/tests/Stripe/WebhookTest.php delete mode 100644 htdocs/includes/stripe/tests/TestCase.php delete mode 100644 htdocs/includes/stripe/tests/bootstrap.no_autoload.php delete mode 100644 htdocs/includes/stripe/tests/bootstrap.php delete mode 100644 htdocs/includes/stripe/tests/data/test.png diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php index 5d88f3e26ea..db5740d277b 100644 --- a/htdocs/core/lib/payments.lib.php +++ b/htdocs/core/lib/payments.lib.php @@ -150,7 +150,7 @@ function showOnlinePaymentUrl($type, $ref) * @param string $localorexternal 0=Url for browser, 1=Url for external access * @return string Url string */ -function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_free_tag', $localorexternal = 0) +function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_tag', $localorexternal = 0) { global $conf, $dolibarr_main_url_root; diff --git a/htdocs/includes/stripe/.coveralls.yml b/htdocs/includes/stripe/.coveralls.yml deleted file mode 100644 index a343c9a7466..00000000000 --- a/htdocs/includes/stripe/.coveralls.yml +++ /dev/null @@ -1,4 +0,0 @@ -service_name: travis-ci -src_dir: . -coverage_clover: clover.xml -json_path: coveralls-upload.json diff --git a/htdocs/includes/stripe/.travis.yml b/htdocs/includes/stripe/.travis.yml deleted file mode 100644 index d575ed51a7d..00000000000 --- a/htdocs/includes/stripe/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -sudo: false - -language: php - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - hhvm - -env: - global: - - STRIPE_MOCK_VERSION=0.8.0 - matrix: - - AUTOLOAD=1 - - AUTOLOAD=0 - -cache: - directories: - - $HOME/.composer/cache/files - - stripe-mock - -before_install: - # Unpack and start stripe-mock so that the test suite can talk to it - - | - if [ ! -d "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}" ]; then - mkdir -p stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/ - curl -L "https://github.com/stripe/stripe-mock/releases/download/v${STRIPE_MOCK_VERSION}/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" -o "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" - tar -zxf "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" -C "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/" - fi - - | - stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/stripe-mock > /dev/null & - STRIPE_MOCK_PID=$! - -script: ./build.php ${AUTOLOAD} - -after_script: ./vendor/bin/coveralls -v diff --git a/htdocs/includes/stripe/CHANGELOG.md b/htdocs/includes/stripe/CHANGELOG.md index 3f0fdfce153..727ac3d1b43 100644 --- a/htdocs/includes/stripe/CHANGELOG.md +++ b/htdocs/includes/stripe/CHANGELOG.md @@ -1,5 +1,221 @@ # Changelog +## 6.34.3 - 2019-05-01 +* [#644](https://github.com/stripe/stripe-php/pull/644) Update return type to `static` to improve static analysis +* [#645](https://github.com/stripe/stripe-php/pull/645) Fix constant for `payment_intent.payment_failed` + +## 6.34.2 - 2019-04-26 +* [#642](https://github.com/stripe/stripe-php/pull/642) Fix an issue where existing idempotency keys would be overwritten when using automatic retries + +## 6.34.1 - 2019-04-25 +* [#640](https://github.com/stripe/stripe-php/pull/640) Add missing phpdocs + +## 6.34.0 - 2019-04-24 +* [#626](https://github.com/stripe/stripe-php/pull/626) Add support for the `TaxRate` resource and APIs +* [#639](https://github.com/stripe/stripe-php/pull/639) Fix multiple phpdoc issues + +## 6.33.0 - 2019-04-22 +* [#630](https://github.com/stripe/stripe-php/pull/630) Add support for the `TaxId` resource and APIs + +## 6.32.1 - 2019-04-19 +* [#636](https://github.com/stripe/stripe-php/pull/636) Correct type of `$personId` in PHPDoc + +## 6.32.0 - 2019-04-18 +* [#621](https://github.com/stripe/stripe-php/pull/621) Add support for `CreditNote` + +## 6.31.5 - 2019-04-12 +* [#628](https://github.com/stripe/stripe-php/pull/628) Add constants for `person.*` event types +* [#628](https://github.com/stripe/stripe-php/pull/628) Add missing constants for `Account` and `Person` + +## 6.31.4 - 2019-04-05 +* [#624](https://github.com/stripe/stripe-php/pull/624) Fix encoding of nested parameters in multipart requests + +## 6.31.3 - 2019-04-02 +* [#623](https://github.com/stripe/stripe-php/pull/623) Only use HTTP/2 with curl >= 7.60.0 + +## 6.31.2 - 2019-03-25 +* [#619](https://github.com/stripe/stripe-php/pull/619) Fix PHPDoc return types for list methods for nested resources + +## 6.31.1 - 2019-03-22 +* [#612](https://github.com/stripe/stripe-php/pull/612) Add a lot of constants +* [#614](https://github.com/stripe/stripe-php/pull/614) Add missing subscription status constants + +## 6.31.0 - 2019-03-18 +* [#600](https://github.com/stripe/stripe-php/pull/600) Add support for the `PaymentMethod` resource and APIs +* [#606](https://github.com/stripe/stripe-php/pull/606) Add support for retrieving a Checkout `Session` +* [#611](https://github.com/stripe/stripe-php/pull/611) Add support for deleting a Terminal `Location` and `Reader` + +## 6.30.5 - 2019-03-11 +* [#607](https://github.com/stripe/stripe-php/pull/607) Correctly handle case where a metadata key is called `metadata` + +## 6.30.4 - 2019-02-27 +* [#602](https://github.com/stripe/stripe-php/pull/602) Add `subscription_schedule` to `Subscription` for PHPDoc. + +## 6.30.3 - 2019-02-26 +* [#603](https://github.com/stripe/stripe-php/pull/603) Improve PHPDoc on the `Source` object to cover all types of Sources currently supported. + +## 6.30.2 - 2019-02-25 +* [#601](https://github.com/stripe/stripe-php/pull/601) Fix PHPDoc across multiple resources and add support for new events. + +## 6.30.1 - 2019-02-16 +* [#599](https://github.com/stripe/stripe-php/pull/599) Fix PHPDoc for `SubscriptionSchedule` and `SubscriptionScheduleRevision` + +## 6.30.0 - 2019-02-12 +* [#590](https://github.com/stripe/stripe-php/pull/590) Add support for `SubscriptionSchedule` and `SubscriptionScheduleRevision` + +## 6.29.3 - 2019-01-31 +* [#592](https://github.com/stripe/stripe-php/pull/592) Some more PHPDoc fixes + +## 6.29.2 - 2019-01-31 +* [#591](https://github.com/stripe/stripe-php/pull/591) Fix PHPDoc for nested resources + +## 6.29.1 - 2019-01-25 +* [#566](https://github.com/stripe/stripe-php/pull/566) Fix dangling message contents +* [#586](https://github.com/stripe/stripe-php/pull/586) Don't overwrite `CURLOPT_HTTP_VERSION` option + +## 6.29.0 - 2019-01-23 +* [#579](https://github.com/stripe/stripe-php/pull/579) Rename `CheckoutSession` to `Session` and move it under the `Checkout` namespace. This is a breaking change, but we've reached out to affected merchants and all new merchants would use the new approach. + +## 6.28.1 - 2019-01-21 +* [#580](https://github.com/stripe/stripe-php/pull/580) Properly serialize `individual` on `Account` objects + +## 6.28.0 - 2019-01-03 +* [#576](https://github.com/stripe/stripe-php/pull/576) Add support for iterating directly over `Collection` instances + +## 6.27.0 - 2018-12-21 +* [#571](https://github.com/stripe/stripe-php/pull/571) Add support for the `CheckoutSession` resource + +## 6.26.0 - 2018-12-11 +* [#568](https://github.com/stripe/stripe-php/pull/568) Enable persistent connections + +## 6.25.0 - 2018-12-10 +* [#567](https://github.com/stripe/stripe-php/pull/567) Add support for account links + +## 6.24.0 - 2018-11-28 +* [#562](https://github.com/stripe/stripe-php/pull/562) Add support for the Review resource +* [#564](https://github.com/stripe/stripe-php/pull/564) Add event name constants for subscription schedule aborted/expiring + +## 6.23.0 - 2018-11-27 +* [#542](https://github.com/stripe/stripe-php/pull/542) Add support for `ValueList` and `ValueListItem` for Radar + +## 6.22.1 - 2018-11-20 +* [#561](https://github.com/stripe/stripe-php/pull/561) Add cast and some docs to telemetry introduced in 6.22.0/#549 + +## 6.22.0 - 2018-11-15 +* [#549](https://github.com/stripe/stripe-php/pull/549) Add support for client telemetry + +## 6.21.1 - 2018-11-12 +* [#548](https://github.com/stripe/stripe-php/pull/548) Don't mutate `Exception` class properties from `OAuthBase` error + +## 6.21.0 - 2018-11-08 +* [#537](https://github.com/stripe/stripe-php/pull/537) Add new API endpoints for the `Invoice` resource. + +## 6.20.1 - 2018-11-07 +* [#546](https://github.com/stripe/stripe-php/pull/546) Drop files from the Composer package that aren't needed in the release + +## 6.20.0 - 2018-10-30 +* [#536](https://github.com/stripe/stripe-php/pull/536) Add support for the `Person` resource +* [#541](https://github.com/stripe/stripe-php/pull/541) Add support for the `WebhookEndpoint` resource + +## 6.19.5 - 2018-10-17 +* [#539](https://github.com/stripe/stripe-php/pull/539) Fix methods on `\Stripe\PaymentIntent` to properly pass arguments to the API. + +## 6.19.4 - 2018-10-11 +* [#534](https://github.com/stripe/stripe-php/pull/534) Fix PSR-4 autoloading for `\Stripe\FileUpload` class alias + +## 6.19.3 - 2018-10-09 +* [#530](https://github.com/stripe/stripe-php/pull/530) Add constants for `flow` (`FLOW_*`), `status` (`STATUS_*`) and `usage` (`USAGE_*`) on `\Stripe\Source` + +## 6.19.2 - 2018-10-08 +* [#531](https://github.com/stripe/stripe-php/pull/531) Store HTTP response headers in case-insensitive array + +## 6.19.1 - 2018-09-25 +* [#526](https://github.com/stripe/stripe-php/pull/526) Ignore null values in request parameters + +## 6.19.0 - 2018-09-24 +* [#523](https://github.com/stripe/stripe-php/pull/523) Add support for Stripe Terminal + +## 6.18.0 - 2018-09-24 +* [#520](https://github.com/stripe/stripe-php/pull/520) Rename `\Stripe\FileUpload` to `\Stripe\File` + +## 6.17.2 - 2018-09-18 +* [#522](https://github.com/stripe/stripe-php/pull/522) Fix warning when adding a new additional owner to an existing array + +## 6.17.1 - 2018-09-14 +* [#517](https://github.com/stripe/stripe-php/pull/517) Integer-index encode all sequential arrays + +## 6.17.0 - 2018-09-05 +* [#514](https://github.com/stripe/stripe-php/pull/514) Add support for reporting resources + +## 6.16.0 - 2018-08-23 +* [#509](https://github.com/stripe/stripe-php/pull/509) Add support for usage record summaries + +## 6.15.0 - 2018-08-03 +* [#504](https://github.com/stripe/stripe-php/pull/504) Add cancel support for topups + +## 6.14.0 - 2018-08-02 +* [#505](https://github.com/stripe/stripe-php/pull/505) Add support for file links + +## 6.13.0 - 2018-07-31 +* [#502](https://github.com/stripe/stripe-php/pull/502) Add `isDeleted()` method to `\Stripe\StripeObject` + +## 6.12.0 - 2018-07-28 +* [#501](https://github.com/stripe/stripe-php/pull/501) Add support for scheduled query runs (`\Stripe\Sigma\ScheduledQueryRun`) for Sigma + +## 6.11.0 - 2018-07-26 +* [#500](https://github.com/stripe/stripe-php/pull/500) Add support for Stripe Issuing + +## 6.10.4 - 2018-07-19 +* [#498](https://github.com/stripe/stripe-php/pull/498) Internal improvements to the `\Stripe\ApiResource.classUrl()` method + +## 6.10.3 - 2018-07-16 +* [#497](https://github.com/stripe/stripe-php/pull/497) Use HTTP/2 only for HTTPS requests + +## 6.10.2 - 2018-07-11 +* [#494](https://github.com/stripe/stripe-php/pull/494) Enable HTTP/2 support + +## 6.10.1 - 2018-07-10 +* [#493](https://github.com/stripe/stripe-php/pull/493) Add PHPDoc for `auto_advance` on `\Stripe\Invoice` + +## 6.10.0 - 2018-06-28 +* [#488](https://github.com/stripe/stripe-php/pull/488) Add support for `$appPartnerId` to `Stripe::setAppInfo()` + +## 6.9.0 - 2018-06-28 +* [#487](https://github.com/stripe/stripe-php/pull/487) Add support for payment intents + +## 6.8.2 - 2018-06-24 +* [#486](https://github.com/stripe/stripe-php/pull/486) Make `Account.deauthorize()` return the `StripeObject` from the API + +## 6.8.1 - 2018-06-13 +* [#472](https://github.com/stripe/stripe-php/pull/472) Added phpDoc for `ApiRequestor` and others, especially regarding thrown errors + +## 6.8.0 - 2018-06-13 +* [#481](https://github.com/stripe/stripe-php/pull/481) Add new `\Stripe\Discount` and `\Stripe\OrderItem` classes, add more PHPDoc describing object attributes + +## 6.7.4 - 2018-05-29 +* [#480](https://github.com/stripe/stripe-php/pull/480) PHPDoc changes for API version 2018-05-21 and the addition of the new `CHARGE_EXPIRED` event type + +## 6.7.3 - 2018-05-28 +* [#479](https://github.com/stripe/stripe-php/pull/479) Fix unnecessary traits on `\Stripe\InvoiceLineItem` + +## 6.7.2 - 2018-05-28 +* [#471](https://github.com/stripe/stripe-php/pull/471) Add `OBJECT_NAME` constant to all API resource classes, add `\Stripe\InvoiceLineItem` class + +## 6.7.1 - 2018-05-13 +* [#468](https://github.com/stripe/stripe-php/pull/468) Update fields in PHP docs for accuracy + +## 6.7.0 - 2018-05-09 +* [#466](https://github.com/stripe/stripe-php/pull/466) Add support for issuer fraud records + +## 6.6.0 - 2018-04-11 +* [#460](https://github.com/stripe/stripe-php/pull/460) Add support for flexible billing primitives + +## 6.5.0 - 2018-04-05 +* [#461](https://github.com/stripe/stripe-php/pull/461) Don't zero keys on non-`metadata` subobjects + +## 6.4.2 - 2018-03-17 +* [#458](https://github.com/stripe/stripe-php/pull/458) Add PHPDoc for `account` on `\Stripe\Event` + ## 6.4.1 - 2018-03-02 * [#455](https://github.com/stripe/stripe-php/pull/455) Fix namespaces in PHPDoc * [#456](https://github.com/stripe/stripe-php/pull/456) Fix namespaces for some exceptions diff --git a/htdocs/includes/stripe/LICENSE b/htdocs/includes/stripe/LICENSE index a21757e4fcd..847c705ad35 100644 --- a/htdocs/includes/stripe/LICENSE +++ b/htdocs/includes/stripe/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2010-2015 Stripe +Copyright (c) 2010-2019 Stripe, Inc. (https://stripe.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/htdocs/includes/stripe/README.md b/htdocs/includes/stripe/README.md index fa492c45cc4..8dca764d7d1 100644 --- a/htdocs/includes/stripe/README.md +++ b/htdocs/includes/stripe/README.md @@ -62,7 +62,7 @@ Please see https://stripe.com/docs/api for up-to-date documentation. ### PHP 5.3 -If you are using PHP 5.3, you can download v5.8.0 ([zip](https://github.com/stripe/stripe-php/archive/v5.8.0.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.8.0.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses. +If you are using PHP 5.3, you can download v5.9.2 ([zip](https://github.com/stripe/stripe-php/archive/v5.9.2.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.9.2.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses. ### PHP 5.2 @@ -181,9 +181,15 @@ retries are safe. ## Development +Get [Composer][composer]. For example, on Mac OS: + +```bash +brew install composer +``` + Install dependencies: -``` bash +```bash composer install ``` @@ -191,8 +197,10 @@ The test suite depends on [stripe-mock], so make sure to fetch and run it from a background terminal ([stripe-mock's README][stripe-mock] also contains instructions for installing via Homebrew and other methods): - go get -u github.com/stripe/stripe-mock - stripe-mock +```bash +go get -u github.com/stripe/stripe-mock +stripe-mock +``` Install dependencies as mentioned above (which will resolve [PHPUnit](http://packagist.org/packages/phpunit/phpunit)), then you can run the test suite: @@ -226,6 +234,7 @@ The method should be called once, before any request is sent to the API. The sec See the "SSL / TLS compatibility issues" paragraph above for full context. If you want to ensure that your plugin can be used on all systems, you should add a configuration option to let your users choose between different values for `CURLOPT_SSLVERSION`: none (default), `CURL_SSLVERSION_TLSv1` and `CURL_SSLVERSION_TLSv1_2`. +[composer]: https://getcomposer.org/ [connect]: https://stripe.com/connect [curl]: http://curl.haxx.se/docs/caextract.html [psr3]: http://www.php-fig.org/psr/psr-3/ diff --git a/htdocs/includes/stripe/VERSION b/htdocs/includes/stripe/VERSION index 4c77920fd2c..a547a9b46f8 100644 --- a/htdocs/includes/stripe/VERSION +++ b/htdocs/includes/stripe/VERSION @@ -1 +1 @@ -6.4.1 +6.34.3 diff --git a/htdocs/includes/stripe/build.php b/htdocs/includes/stripe/build.php index cd053e2baea..6ce0ca38d11 100644 --- a/htdocs/includes/stripe/build.php +++ b/htdocs/includes/stripe/build.php @@ -13,7 +13,7 @@ if (!$autoload) { file_put_contents('composer.json', json_encode($composer, JSON_PRETTY_PRINT)); } -passthru('composer install', $returnStatus); +passthru('composer update', $returnStatus); if ($returnStatus !== 0) { exit(1); } diff --git a/htdocs/includes/stripe/composer.json b/htdocs/includes/stripe/composer.json index 67473fca421..eb92b76fb31 100644 --- a/htdocs/includes/stripe/composer.json +++ b/htdocs/includes/stripe/composer.json @@ -22,8 +22,9 @@ }, "require-dev": { "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "~0.6.1", - "squizlabs/php_codesniffer": "~2.0" + "php-coveralls/php-coveralls": "1.*", + "squizlabs/php_codesniffer": "~2.0", + "symfony/process": "~2.8" }, "autoload": { "psr-4": { "Stripe\\" : "lib/" } diff --git a/htdocs/includes/stripe/init.php b/htdocs/includes/stripe/init.php index 79cf657a7eb..5ccf3327c0b 100644 --- a/htdocs/includes/stripe/init.php +++ b/htdocs/includes/stripe/init.php @@ -5,6 +5,7 @@ require(dirname(__FILE__) . '/lib/Stripe.php'); // Utilities require(dirname(__FILE__) . '/lib/Util/AutoPagingIterator.php'); +require(dirname(__FILE__) . '/lib/Util/CaseInsensitiveArray.php'); require(dirname(__FILE__) . '/lib/Util/LoggerInterface.php'); require(dirname(__FILE__) . '/lib/Util/DefaultLogger.php'); require(dirname(__FILE__) . '/lib/Util/RandomGenerator.php'); @@ -48,6 +49,7 @@ require(dirname(__FILE__) . '/lib/ApiOperations/Update.php'); // Plumbing require(dirname(__FILE__) . '/lib/ApiResponse.php'); +require(dirname(__FILE__) . '/lib/RequestTelemetry.php'); require(dirname(__FILE__) . '/lib/StripeObject.php'); require(dirname(__FILE__) . '/lib/ApiRequestor.php'); require(dirname(__FILE__) . '/lib/ApiResource.php'); @@ -55,6 +57,7 @@ require(dirname(__FILE__) . '/lib/SingletonApiResource.php'); // Stripe API Resources require(dirname(__FILE__) . '/lib/Account.php'); +require(dirname(__FILE__) . '/lib/AccountLink.php'); require(dirname(__FILE__) . '/lib/AlipayAccount.php'); require(dirname(__FILE__) . '/lib/ApplePayDomain.php'); require(dirname(__FILE__) . '/lib/ApplicationFee.php'); @@ -66,40 +69,73 @@ require(dirname(__FILE__) . '/lib/BitcoinReceiver.php'); require(dirname(__FILE__) . '/lib/BitcoinTransaction.php'); require(dirname(__FILE__) . '/lib/Card.php'); require(dirname(__FILE__) . '/lib/Charge.php'); +require(dirname(__FILE__) . '/lib/Checkout/Session.php'); require(dirname(__FILE__) . '/lib/Collection.php'); require(dirname(__FILE__) . '/lib/CountrySpec.php'); require(dirname(__FILE__) . '/lib/Coupon.php'); +require(dirname(__FILE__) . '/lib/CreditNote.php'); require(dirname(__FILE__) . '/lib/Customer.php'); +require(dirname(__FILE__) . '/lib/Discount.php'); require(dirname(__FILE__) . '/lib/Dispute.php'); require(dirname(__FILE__) . '/lib/EphemeralKey.php'); require(dirname(__FILE__) . '/lib/Event.php'); require(dirname(__FILE__) . '/lib/ExchangeRate.php'); +require(dirname(__FILE__) . '/lib/File.php'); +require(dirname(__FILE__) . '/lib/FileLink.php'); require(dirname(__FILE__) . '/lib/FileUpload.php'); require(dirname(__FILE__) . '/lib/Invoice.php'); require(dirname(__FILE__) . '/lib/InvoiceItem.php'); +require(dirname(__FILE__) . '/lib/InvoiceLineItem.php'); +require(dirname(__FILE__) . '/lib/IssuerFraudRecord.php'); +require(dirname(__FILE__) . '/lib/Issuing/Authorization.php'); +require(dirname(__FILE__) . '/lib/Issuing/Card.php'); +require(dirname(__FILE__) . '/lib/Issuing/CardDetails.php'); +require(dirname(__FILE__) . '/lib/Issuing/Cardholder.php'); +require(dirname(__FILE__) . '/lib/Issuing/Dispute.php'); +require(dirname(__FILE__) . '/lib/Issuing/Transaction.php'); require(dirname(__FILE__) . '/lib/LoginLink.php'); require(dirname(__FILE__) . '/lib/Order.php'); +require(dirname(__FILE__) . '/lib/OrderItem.php'); require(dirname(__FILE__) . '/lib/OrderReturn.php'); +require(dirname(__FILE__) . '/lib/PaymentIntent.php'); +require(dirname(__FILE__) . '/lib/PaymentMethod.php'); require(dirname(__FILE__) . '/lib/Payout.php'); +require(dirname(__FILE__) . '/lib/Person.php'); require(dirname(__FILE__) . '/lib/Plan.php'); require(dirname(__FILE__) . '/lib/Product.php'); +require(dirname(__FILE__) . '/lib/Radar/ValueList.php'); +require(dirname(__FILE__) . '/lib/Radar/ValueListItem.php'); require(dirname(__FILE__) . '/lib/Recipient.php'); require(dirname(__FILE__) . '/lib/RecipientTransfer.php'); require(dirname(__FILE__) . '/lib/Refund.php'); +require(dirname(__FILE__) . '/lib/Reporting/ReportRun.php'); +require(dirname(__FILE__) . '/lib/Reporting/ReportType.php'); +require(dirname(__FILE__) . '/lib/Review.php'); require(dirname(__FILE__) . '/lib/SKU.php'); +require(dirname(__FILE__) . '/lib/Sigma/ScheduledQueryRun.php'); require(dirname(__FILE__) . '/lib/Source.php'); require(dirname(__FILE__) . '/lib/SourceTransaction.php'); require(dirname(__FILE__) . '/lib/Subscription.php'); require(dirname(__FILE__) . '/lib/SubscriptionItem.php'); +require(dirname(__FILE__) . '/lib/SubscriptionSchedule.php'); +require(dirname(__FILE__) . '/lib/SubscriptionScheduleRevision.php'); +require(dirname(__FILE__) . '/lib/TaxId.php'); +require(dirname(__FILE__) . '/lib/TaxRate.php'); +require(dirname(__FILE__) . '/lib/Terminal/ConnectionToken.php'); +require(dirname(__FILE__) . '/lib/Terminal/Location.php'); +require(dirname(__FILE__) . '/lib/Terminal/Reader.php'); require(dirname(__FILE__) . '/lib/ThreeDSecure.php'); require(dirname(__FILE__) . '/lib/Token.php'); require(dirname(__FILE__) . '/lib/Topup.php'); require(dirname(__FILE__) . '/lib/Transfer.php'); require(dirname(__FILE__) . '/lib/TransferReversal.php'); +require(dirname(__FILE__) . '/lib/UsageRecord.php'); +require(dirname(__FILE__) . '/lib/UsageRecordSummary.php'); // OAuth require(dirname(__FILE__) . '/lib/OAuth.php'); // Webhooks require(dirname(__FILE__) . '/lib/Webhook.php'); +require(dirname(__FILE__) . '/lib/WebhookEndpoint.php'); require(dirname(__FILE__) . '/lib/WebhookSignature.php'); diff --git a/htdocs/includes/stripe/lib/Account.php b/htdocs/includes/stripe/lib/Account.php index d77d60dedbc..1c10fa2f3a1 100644 --- a/htdocs/includes/stripe/lib/Account.php +++ b/htdocs/includes/stripe/lib/Account.php @@ -7,37 +7,32 @@ namespace Stripe; * * @property string $id * @property string $object - * @property string $business_logo - * @property string $business_name - * @property string $business_primary_color - * @property string $business_url + * @property mixed $business_profile + * @property string $business_type + * @property mixed $capabilities * @property bool $charges_enabled + * @property mixed $company * @property string $country * @property int $created - * @property bool $debit_negative_balances - * @property mixed $decline_charge_on * @property string $default_currency * @property bool $details_submitted - * @property string $display_name * @property string $email - * @property mixed $external_accounts - * @property mixed $legal_entity + * @property Collection $external_accounts + * @property mixed $individual * @property StripeObject $metadata - * @property mixed $payout_schedule - * @property string $payout_statement_descriptor * @property bool $payouts_enabled - * @property string $product_description - * @property string $statement_descriptor - * @property string $support_email - * @property string $support_phone - * @property string $timezone + * @property mixed $requirements + * @property mixed $settings * @property mixed $tos_acceptance - * @property mixed $verification + * @property string $type * * @package Stripe */ class Account extends ApiResource { + + const OBJECT_NAME = "account"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; @@ -47,6 +42,37 @@ class Account extends ApiResource } use ApiOperations\Update; + /** + * Possible string representations of an account's business type. + * @link https://stripe.com/docs/api/accounts/object#account_object-business_type + */ + const BUSINESS_TYPE_COMPANY = 'company'; + const BUSINESS_TYPE_INDIVIDUAL = 'individual'; + + /** + * Possible string representations of an account's capabilities. + * @link https://stripe.com/docs/api/accounts/object#account_object-capabilities + */ + const CAPABILITY_CARD_PAYMENTS = 'card_payments'; + const CAPABILITY_LEGACY_PAYMENTS = 'legacy_payments'; + const CAPABILITY_PLATFORM_PAYMENTS = 'platform_payments'; + + /** + * Possible string representations of an account's capability status. + * @link https://stripe.com/docs/api/accounts/object#account_object-capabilities + */ + const CAPABILITY_STATUS_ACTIVE = 'active'; + const CAPABILITY_STATUS_INACTIVE = 'inactive'; + const CAPABILITY_STATUS_PENDING = 'pending'; + + /** + * Possible string representations of an account's type. + * @link https://stripe.com/docs/api/accounts/object#account_object-type + */ + const TYPE_CUSTOM = 'custom'; + const TYPE_EXPRESS = 'express'; + const TYPE_STANDARD = 'standard'; + public static function getSavedNestedResources() { static $savedNestedResources = null; @@ -61,6 +87,7 @@ class Account extends ApiResource const PATH_EXTERNAL_ACCOUNTS = '/external_accounts'; const PATH_LOGIN_LINKS = '/login_links'; + const PATH_PERSONS = '/persons'; public function instanceUrl() { @@ -101,6 +128,21 @@ class Account extends ApiResource return $this; } + /** + * @param array|null $params + * @param array|string|null $options + * + * @return Collection The list of persons. + */ + public function persons($params = null, $options = null) + { + $url = $this->instanceUrl() . '/persons'; + list($response, $opts) = $this->_request('get', $url, $params, $options); + $obj = Util\Util::convertToStripeObject($response, $opts); + $obj->setLastResponse($response); + return $obj; + } + /** * @param array|null $clientId * @param array|string|null $opts @@ -113,11 +155,11 @@ class Account extends ApiResource 'client_id' => $clientId, 'stripe_user_id' => $this->id, ]; - OAuth::deauthorize($params, $opts); + return OAuth::deauthorize($params, $opts); } /** - * @param array|null $id The ID of the account on which to create the external account. + * @param string|null $id The ID of the account on which to create the external account. * @param array|null $params * @param array|string|null $opts * @@ -129,7 +171,7 @@ class Account extends ApiResource } /** - * @param array|null $id The ID of the account to which the external account belongs. + * @param string|null $id The ID of the account to which the external account belongs. * @param array|null $externalAccountId The ID of the external account to retrieve. * @param array|null $params * @param array|string|null $opts @@ -142,7 +184,7 @@ class Account extends ApiResource } /** - * @param array|null $id The ID of the account to which the external account belongs. + * @param string|null $id The ID of the account to which the external account belongs. * @param array|null $externalAccountId The ID of the external account to update. * @param array|null $params * @param array|string|null $opts @@ -155,7 +197,7 @@ class Account extends ApiResource } /** - * @param array|null $id The ID of the account to which the external account belongs. + * @param string|null $id The ID of the account to which the external account belongs. * @param array|null $externalAccountId The ID of the external account to delete. * @param array|null $params * @param array|string|null $opts @@ -168,11 +210,11 @@ class Account extends ApiResource } /** - * @param array|null $id The ID of the account on which to retrieve the external accounts. + * @param string|null $id The ID of the account on which to retrieve the external accounts. * @param array|null $params * @param array|string|null $opts * - * @return BankAccount|Card + * @return Collection The list of external accounts (BankAccount or Card). */ public static function allExternalAccounts($id, $params = null, $opts = null) { @@ -180,7 +222,7 @@ class Account extends ApiResource } /** - * @param array|null $id The ID of the account on which to create the login link. + * @param string|null $id The ID of the account on which to create the login link. * @param array|null $params * @param array|string|null $opts * @@ -191,6 +233,69 @@ class Account extends ApiResource return self::_createNestedResource($id, static::PATH_LOGIN_LINKS, $params, $opts); } + /** + * @param string|null $id The ID of the account on which to create the person. + * @param array|null $params + * @param array|string|null $opts + * + * @return Person + */ + public static function createPerson($id, $params = null, $opts = null) + { + return self::_createNestedResource($id, static::PATH_PERSONS, $params, $opts); + } + + /** + * @param string|null $id The ID of the account to which the person belongs. + * @param string|null $personId The ID of the person to retrieve. + * @param array|null $params + * @param array|string|null $opts + * + * @return Person + */ + public static function retrievePerson($id, $personId, $params = null, $opts = null) + { + return self::_retrieveNestedResource($id, static::PATH_PERSONS, $personId, $params, $opts); + } + + /** + * @param string|null $id The ID of the account to which the person belongs. + * @param string|null $personId The ID of the person to update. + * @param array|null $params + * @param array|string|null $opts + * + * @return Person + */ + public static function updatePerson($id, $personId, $params = null, $opts = null) + { + return self::_updateNestedResource($id, static::PATH_PERSONS, $personId, $params, $opts); + } + + /** + * @param string|null $id The ID of the account to which the person belongs. + * @param string|null $personId The ID of the person to delete. + * @param array|null $params + * @param array|string|null $opts + * + * @return Person + */ + public static function deletePerson($id, $personId, $params = null, $opts = null) + { + return self::_deleteNestedResource($id, static::PATH_PERSONS, $personId, $params, $opts); + } + + /** + * @param string|null $id The ID of the account on which to retrieve the persons. + * @param array|null $params + * @param array|string|null $opts + * + * @return Collection The list of persons. + */ + public static function allPersons($id, $params = null, $opts = null) + { + return self::_allNestedResources($id, static::PATH_PERSONS, $params, $opts); + } + public function serializeParameters($force = false) { $update = parent::serializeParameters($force); @@ -203,6 +308,12 @@ class Account extends ApiResource $update['legal_entity'] = $entityUpdate; } } + if (isset($this->_values['individual'])) { + $individual = $this['individual']; + if (($individual instanceof Person) && !isset($update['individual'])) { + $update['individual'] = $individual->serializeParameters($force); + } + } return $update; } @@ -224,7 +335,9 @@ class Account extends ApiResource $update = ($v instanceof StripeObject) ? $v->serializeParameters() : $v; if ($update !== []) { - if (!$originalValue || ($update != $legalEntity->serializeParamsValue($originalValue[$i], null, false, true))) { + if (!$originalValue || + !array_key_exists($i, $originalValue) || + ($update != $legalEntity->serializeParamsValue($originalValue[$i], null, false, true))) { $updateArr[$i] = $update; } } diff --git a/htdocs/includes/stripe/lib/AccountLink.php b/htdocs/includes/stripe/lib/AccountLink.php new file mode 100644 index 00000000000..f2975ae3834 --- /dev/null +++ b/htdocs/includes/stripe/lib/AccountLink.php @@ -0,0 +1,21 @@ +setLastResponse($response); $obj->setRequestParams($params); diff --git a/htdocs/includes/stripe/lib/ApiOperations/NestedResource.php b/htdocs/includes/stripe/lib/ApiOperations/NestedResource.php index 1c3a73f45de..2122354362f 100644 --- a/htdocs/includes/stripe/lib/ApiOperations/NestedResource.php +++ b/htdocs/includes/stripe/lib/ApiOperations/NestedResource.php @@ -60,6 +60,7 @@ trait NestedResource /** * @param string $id * @param string $nestedPath + * @param string|null $nestedId * @param array|null $params * @param array|string|null $options * @@ -74,6 +75,7 @@ trait NestedResource /** * @param string $id * @param string $nestedPath + * @param string|null $nestedId * @param array|null $params * @param array|string|null $options * @@ -88,6 +90,7 @@ trait NestedResource /** * @param string $id * @param string $nestedPath + * @param string|null $nestedId * @param array|null $params * @param array|string|null $options * diff --git a/htdocs/includes/stripe/lib/ApiOperations/Request.php b/htdocs/includes/stripe/lib/ApiOperations/Request.php index c6b06585ad2..dd048dc5f5c 100644 --- a/htdocs/includes/stripe/lib/ApiOperations/Request.php +++ b/htdocs/includes/stripe/lib/ApiOperations/Request.php @@ -52,7 +52,8 @@ trait Request protected static function _staticRequest($method, $url, $params, $options) { $opts = \Stripe\Util\RequestOptions::parse($options); - $requestor = new \Stripe\ApiRequestor($opts->apiKey, static::baseUrl()); + $baseUrl = isset($opts->apiBase) ? $opts->apiBase : static::baseUrl(); + $requestor = new \Stripe\ApiRequestor($opts->apiKey, $baseUrl); list($response, $opts->apiKey) = $requestor->request($method, $url, $params, $opts->headers); $opts->discardNonPersistentHeaders(); return [$response, $opts]; diff --git a/htdocs/includes/stripe/lib/ApiOperations/Retrieve.php b/htdocs/includes/stripe/lib/ApiOperations/Retrieve.php index a037326b3e8..ed52296b75b 100644 --- a/htdocs/includes/stripe/lib/ApiOperations/Retrieve.php +++ b/htdocs/includes/stripe/lib/ApiOperations/Retrieve.php @@ -15,7 +15,7 @@ trait Retrieve * or an options array containing an `id` key. * @param array|string|null $opts * - * @return \Stripe\StripeObject + * @return static */ public static function retrieve($id, $opts = null) { diff --git a/htdocs/includes/stripe/lib/ApiRequestor.php b/htdocs/includes/stripe/lib/ApiRequestor.php index 334d84425b3..7cf851877de 100644 --- a/htdocs/includes/stripe/lib/ApiRequestor.php +++ b/htdocs/includes/stripe/lib/ApiRequestor.php @@ -9,12 +9,32 @@ namespace Stripe; */ class ApiRequestor { + /** + * @var string|null + */ private $_apiKey; + /** + * @var string + */ private $_apiBase; + /** + * @var HttpClient\ClientInterface + */ private static $_httpClient; + /** + * @var RequestTelemetry + */ + private static $requestTelemetry; + + /** + * ApiRequestor constructor. + * + * @param string|null $apiKey + * @param string|null $apiBase + */ public function __construct($apiKey = null, $apiBase = null) { $this->_apiKey = $apiKey; @@ -24,6 +44,37 @@ class ApiRequestor $this->_apiBase = $apiBase; } + /** + * Creates a telemetry json blob for use in 'X-Stripe-Client-Telemetry' headers + * @static + * + * @param RequestTelemetry $requestTelemetry + * @return string + */ + private static function _telemetryJson($requestTelemetry) + { + $payload = array( + 'last_request_metrics' => array( + 'request_id' => $requestTelemetry->requestId, + 'request_duration_ms' => $requestTelemetry->requestDuration, + )); + + $result = json_encode($payload); + if ($result != false) { + return $result; + } else { + Stripe::getLogger()->error("Serializing telemetry payload failed!"); + return "{}"; + } + } + + /** + * @static + * + * @param ApiResource|bool|array|mixed $d + * + * @return ApiResource|array|string|mixed + */ private static function _encodeObjects($d) { if ($d instanceof ApiResource) { @@ -44,13 +95,27 @@ class ApiRequestor } /** - * @param string $method - * @param string $url + * @param string $method + * @param string $url * @param array|null $params * @param array|null $headers * * @return array An array whose first element is an API response and second * element is the API key used to make the request. + * @throws Error\Api + * @throws Error\Authentication + * @throws Error\Card + * @throws Error\InvalidRequest + * @throws Error\OAuth\InvalidClient + * @throws Error\OAuth\InvalidGrant + * @throws Error\OAuth\InvalidRequest + * @throws Error\OAuth\InvalidScope + * @throws Error\OAuth\UnsupportedGrantType + * @throws Error\OAuth\UnsupportedResponseType + * @throws Error\Permission + * @throws Error\RateLimit + * @throws Error\Idempotency + * @throws Error\ApiConnection */ public function request($method, $url, $params = null, $headers = null) { @@ -70,13 +135,22 @@ class ApiRequestor * @param array $resp * * @throws Error\InvalidRequest if the error is caused by the user. - * @throws Error\Idempotency if the error is caused by an idempotency key. * @throws Error\Authentication if the error is caused by a lack of * permissions. * @throws Error\Permission if the error is caused by insufficient * permissions. * @throws Error\Card if the error is the error code is 402 (payment * required) + * @throws Error\InvalidRequest if the error is caused by the user. + * @throws Error\Idempotency if the error is caused by an idempotency key. + * @throws Error\OAuth\InvalidClient + * @throws Error\OAuth\InvalidGrant + * @throws Error\OAuth\InvalidRequest + * @throws Error\OAuth\InvalidScope + * @throws Error\OAuth\UnsupportedGrantType + * @throws Error\OAuth\UnsupportedResponseType + * @throws Error\Permission if the error is caused by insufficient + * permissions. * @throws Error\RateLimit if the error is caused by too many requests * hitting the API. * @throws Error\Api otherwise. @@ -102,6 +176,17 @@ class ApiRequestor throw $error; } + /** + * @static + * + * @param string $rbody + * @param int $rcode + * @param array $rheaders + * @param array $resp + * @param array $errorData + * + * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api + */ private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData) { $msg = isset($errorData['message']) ? $errorData['message'] : null; @@ -136,6 +221,17 @@ class ApiRequestor } } + /** + * @static + * + * @param string|bool $rbody + * @param int $rcode + * @param array $rheaders + * @param array $resp + * @param string $errorCode + * + * @return null|Error\OAuth\InvalidClient|Error\OAuth\InvalidGrant|Error\OAuth\InvalidRequest|Error\OAuth\InvalidScope|Error\OAuth\UnsupportedGrantType|Error\OAuth\UnsupportedResponseType + */ private static function _specificOAuthError($rbody, $rcode, $rheaders, $resp, $errorCode) { $description = isset($resp['error_description']) ? $resp['error_description'] : $errorCode; @@ -158,6 +254,13 @@ class ApiRequestor return null; } + /** + * @static + * + * @param null|array $appInfo + * + * @return null|string + */ private static function _formatAppInfo($appInfo) { if ($appInfo !== null) { @@ -174,6 +277,14 @@ class ApiRequestor } } + /** + * @static + * + * @param string $apiKey + * @param null $clientInfo + * + * @return array + */ private static function _defaultHeaders($apiKey, $clientInfo = null) { $uaString = 'Stripe/v1 PhpBindings/' . Stripe::VERSION; @@ -205,6 +316,17 @@ class ApiRequestor return $defaultHeaders; } + /** + * @param string $method + * @param string $url + * @param array $params + * @param array $headers + * + * @return array + * @throws Error\Api + * @throws Error\ApiConnection + * @throws Error\Authentication + */ private function _requestRaw($method, $url, $params, $headers) { $myApiKey = $this->_apiKey; @@ -239,6 +361,10 @@ class ApiRequestor $defaultHeaders['Stripe-Account'] = Stripe::$accountId; } + if (Stripe::$enableTelemetry && self::$requestTelemetry != null) { + $defaultHeaders["X-Stripe-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry); + } + $hasFile = false; $hasCurlFile = class_exists('\CURLFile', false); foreach ($params as $k => $v) { @@ -263,6 +389,8 @@ class ApiRequestor $rawHeaders[] = $header . ': ' . $value; } + $requestStartMs = Util\Util::currentTimeMillis(); + list($rbody, $rcode, $rheaders) = $this->httpClient()->request( $method, $absUrl, @@ -270,9 +398,24 @@ class ApiRequestor $params, $hasFile ); + + if (array_key_exists('request-id', $rheaders)) { + self::$requestTelemetry = new RequestTelemetry( + $rheaders['request-id'], + Util\Util::currentTimeMillis() - $requestStartMs + ); + } + return [$rbody, $rcode, $rheaders, $myApiKey]; } + /** + * @param resource $resource + * @param bool $hasCurlFile + * + * @return \CURLFile|string + * @throws Error\Api + */ private function _processResourceParam($resource, $hasCurlFile) { if (get_resource_type($resource) !== 'stream') { @@ -296,6 +439,26 @@ class ApiRequestor } } + /** + * @param string $rbody + * @param int $rcode + * @param array $rheaders + * + * @return mixed + * @throws Error\Api + * @throws Error\Authentication + * @throws Error\Card + * @throws Error\InvalidRequest + * @throws Error\OAuth\InvalidClient + * @throws Error\OAuth\InvalidGrant + * @throws Error\OAuth\InvalidRequest + * @throws Error\OAuth\InvalidScope + * @throws Error\OAuth\UnsupportedGrantType + * @throws Error\OAuth\UnsupportedResponseType + * @throws Error\Permission + * @throws Error\RateLimit + * @throws Error\Idempotency + */ private function _interpretResponse($rbody, $rcode, $rheaders) { $resp = json_decode($rbody, true); @@ -312,11 +475,29 @@ class ApiRequestor return $resp; } + /** + * @static + * + * @param HttpClient\ClientInterface $client + */ public static function setHttpClient($client) { self::$_httpClient = $client; } + /** + * @static + * + * Resets any stateful telemetry data + */ + public static function resetTelemetry() + { + self::$requestTelemetry = null; + } + + /** + * @return HttpClient\ClientInterface + */ private function httpClient() { if (!self::$_httpClient) { diff --git a/htdocs/includes/stripe/lib/ApiResource.php b/htdocs/includes/stripe/lib/ApiResource.php index f73b22c9663..fe594321687 100644 --- a/htdocs/includes/stripe/lib/ApiResource.php +++ b/htdocs/includes/stripe/lib/ApiResource.php @@ -66,30 +66,6 @@ abstract class ApiResource extends StripeObject return $this; } - /** - * @return string The name of the class, with namespacing and underscores - * stripped. - */ - public static function className() - { - $class = get_called_class(); - // Useful for namespaces: Foo\Charge - if ($postfixNamespaces = strrchr($class, '\\')) { - $class = substr($postfixNamespaces, 1); - } - // Useful for underscored 'namespaces': Foo_Charge - if ($postfixFakeNamespaces = strrchr($class, '')) { - $class = $postfixFakeNamespaces; - } - if (substr($class, 0, strlen('Stripe')) == 'Stripe') { - $class = substr($class, strlen('Stripe')); - } - $class = str_replace('_', '', $class); - $name = urlencode($class); - $name = strtolower($name); - return $name; - } - /** * @return string The base URL for the given class. */ @@ -103,7 +79,9 @@ abstract class ApiResource extends StripeObject */ public static function classUrl() { - $base = static::className(); + // Replace dots with slashes for namespaced resources, e.g. if the object's name is + // "foo.bar", then its URL will be "/v1/foo/bars". + $base = str_replace('.', '/', static::OBJECT_NAME); return "/v1/${base}s"; } diff --git a/htdocs/includes/stripe/lib/ApplePayDomain.php b/htdocs/includes/stripe/lib/ApplePayDomain.php index 124c5dc0632..ea84220a7a9 100644 --- a/htdocs/includes/stripe/lib/ApplePayDomain.php +++ b/htdocs/includes/stripe/lib/ApplePayDomain.php @@ -9,6 +9,9 @@ namespace Stripe; */ class ApplePayDomain extends ApiResource { + + const OBJECT_NAME = "apple_pay_domain"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; diff --git a/htdocs/includes/stripe/lib/ApplicationFee.php b/htdocs/includes/stripe/lib/ApplicationFee.php index 05b94ea9235..0d9fde4c521 100644 --- a/htdocs/includes/stripe/lib/ApplicationFee.php +++ b/htdocs/includes/stripe/lib/ApplicationFee.php @@ -24,23 +24,15 @@ namespace Stripe; */ class ApplicationFee extends ApiResource { + + const OBJECT_NAME = "application_fee"; + use ApiOperations\All; use ApiOperations\NestedResource; use ApiOperations\Retrieve; const PATH_REFUNDS = '/refunds'; - /** - * This is a special case because the application fee endpoint has an - * underscore in it. The parent `className` function strips underscores. - * - * @return string The name of the class. - */ - public static function className() - { - return 'application_fee'; - } - /** * @param array|null $params * @param array|string|null $opts @@ -55,7 +47,7 @@ class ApplicationFee extends ApiResource } /** - * @param array|null $id The ID of the application fee on which to create the refund. + * @param string|null $id The ID of the application fee on which to create the refund. * @param array|null $params * @param array|string|null $opts * @@ -67,7 +59,7 @@ class ApplicationFee extends ApiResource } /** - * @param array|null $id The ID of the application fee to which the refund belongs. + * @param string|null $id The ID of the application fee to which the refund belongs. * @param array|null $refundId The ID of the refund to retrieve. * @param array|null $params * @param array|string|null $opts @@ -80,7 +72,7 @@ class ApplicationFee extends ApiResource } /** - * @param array|null $id The ID of the application fee to which the refund belongs. + * @param string|null $id The ID of the application fee to which the refund belongs. * @param array|null $refundId The ID of the refund to update. * @param array|null $params * @param array|string|null $opts @@ -93,11 +85,11 @@ class ApplicationFee extends ApiResource } /** - * @param array|null $id The ID of the application fee on which to retrieve the refunds. + * @param string|null $id The ID of the application fee on which to retrieve the refunds. * @param array|null $params * @param array|string|null $opts * - * @return ApplicationFeeRefund + * @return Collection The list of refunds. */ public static function allRefunds($id, $params = null, $opts = null) { diff --git a/htdocs/includes/stripe/lib/ApplicationFeeRefund.php b/htdocs/includes/stripe/lib/ApplicationFeeRefund.php index 4b1c425a8ee..91d7e9d2bc6 100644 --- a/htdocs/includes/stripe/lib/ApplicationFeeRefund.php +++ b/htdocs/includes/stripe/lib/ApplicationFeeRefund.php @@ -18,6 +18,9 @@ namespace Stripe; */ class ApplicationFeeRefund extends ApiResource { + + const OBJECT_NAME = "fee_refund"; + use ApiOperations\Update { save as protected _save; } diff --git a/htdocs/includes/stripe/lib/Balance.php b/htdocs/includes/stripe/lib/Balance.php index 115307f843b..25f88ae74c7 100644 --- a/htdocs/includes/stripe/lib/Balance.php +++ b/htdocs/includes/stripe/lib/Balance.php @@ -7,6 +7,7 @@ namespace Stripe; * * @property string $object * @property array $available + * @property array $connect_reserved * @property bool $livemode * @property array $pending * @@ -14,6 +15,9 @@ namespace Stripe; */ class Balance extends SingletonApiResource { + + const OBJECT_NAME = "balance"; + /** * @param array|string|null $opts * diff --git a/htdocs/includes/stripe/lib/BalanceTransaction.php b/htdocs/includes/stripe/lib/BalanceTransaction.php index f82888ab1dd..cd9b79ae675 100644 --- a/htdocs/includes/stripe/lib/BalanceTransaction.php +++ b/htdocs/includes/stripe/lib/BalanceTransaction.php @@ -24,6 +24,9 @@ namespace Stripe; */ class BalanceTransaction extends ApiResource { + + const OBJECT_NAME = "balance_transaction"; + use ApiOperations\All; use ApiOperations\Retrieve; diff --git a/htdocs/includes/stripe/lib/BankAccount.php b/htdocs/includes/stripe/lib/BankAccount.php index 2afc312d003..019a4d87cbd 100644 --- a/htdocs/includes/stripe/lib/BankAccount.php +++ b/htdocs/includes/stripe/lib/BankAccount.php @@ -25,6 +25,9 @@ namespace Stripe; */ class BankAccount extends ApiResource { + + const OBJECT_NAME = "bank_account"; + use ApiOperations\Delete; use ApiOperations\Update; diff --git a/htdocs/includes/stripe/lib/BitcoinReceiver.php b/htdocs/includes/stripe/lib/BitcoinReceiver.php index 8d04256b5db..b4cc5291b56 100644 --- a/htdocs/includes/stripe/lib/BitcoinReceiver.php +++ b/htdocs/includes/stripe/lib/BitcoinReceiver.php @@ -12,6 +12,9 @@ namespace Stripe; */ class BitcoinReceiver extends ApiResource { + + const OBJECT_NAME = "bitcoin_receiver"; + use ApiOperations\All; use ApiOperations\Retrieve; diff --git a/htdocs/includes/stripe/lib/BitcoinTransaction.php b/htdocs/includes/stripe/lib/BitcoinTransaction.php index 6b8e5421124..8269fd216eb 100644 --- a/htdocs/includes/stripe/lib/BitcoinTransaction.php +++ b/htdocs/includes/stripe/lib/BitcoinTransaction.php @@ -10,4 +10,5 @@ namespace Stripe; class BitcoinTransaction extends ApiResource { + const OBJECT_NAME = "bitcoin_transaction"; } diff --git a/htdocs/includes/stripe/lib/Card.php b/htdocs/includes/stripe/lib/Card.php index 7e57423601a..40de733e780 100644 --- a/htdocs/includes/stripe/lib/Card.php +++ b/htdocs/includes/stripe/lib/Card.php @@ -7,6 +7,7 @@ namespace Stripe; * * @property string $id * @property string $object + * @property string $account * @property string $address_city * @property string $address_country * @property string $address_line1 @@ -15,10 +16,13 @@ namespace Stripe; * @property string $address_state * @property string $address_zip * @property string $address_zip_check + * @property string[] $available_payout_methods * @property string $brand * @property string $country + * @property string $currency * @property string $customer * @property string $cvc_check + * @property bool $default_for_currency * @property string $dynamic_last4 * @property int $exp_month * @property int $exp_year @@ -27,15 +31,44 @@ namespace Stripe; * @property string $last4 * @property StripeObject $metadata * @property string $name + * @property string $recipient * @property string $tokenization_method * * @package Stripe */ class Card extends ApiResource { + + const OBJECT_NAME = "card"; + use ApiOperations\Delete; use ApiOperations\Update; + /** + * Possible string representations of the CVC check status. + * @link https://stripe.com/docs/api/cards/object#card_object-cvc_check + */ + const CVC_CHECK_FAIL = 'fail'; + const CVC_CHECK_PASS = 'pass'; + const CVC_CHECK_UNAVAILABLE = 'unavailable'; + const CVC_CHECK_UNCHECKED = 'unchecked'; + + /** + * Possible string representations of the funding of the card. + * @link https://stripe.com/docs/api/cards/object#card_object-funding + */ + const FUNDING_CREDIT = 'credit'; + const FUNDING_DEBIT = 'debit'; + const FUNDING_PREPAID = 'prepaid'; + const FUNDING_UNKNOWN = 'unknown'; + + /** + * Possible string representations of the tokenization method when using Apple Pay or Google Pay. + * @link https://stripe.com/docs/api/cards/object#card_object-tokenization_method + */ + const TOKENIZATION_METHOD_APPLE_PAY = 'apple_pay'; + const TOKENIZATION_METHOD_GOOGLE_PAY = 'google_pay'; + /** * @return string The instance URL for this resource. It needs to be special * cased because cards are nested resources that may belong to different @@ -74,7 +107,7 @@ class Card extends ApiResource { $msg = "Cards cannot be accessed without a customer, recipient or account ID. " . "Retrieve a card using \$customer->sources->retrieve('card_id'), " . - "\$recipient->cards->retrieve('card_id'), or"; + "\$recipient->cards->retrieve('card_id'), or " . "\$account->external_accounts->retrieve('card_id') instead."; throw new Error\InvalidRequest($msg, null); } @@ -90,7 +123,7 @@ class Card extends ApiResource { $msg = "Cards cannot be accessed without a customer, recipient or account ID. " . "Call save() on \$customer->sources->retrieve('card_id'), " . - "\$recipient->cards->retrieve('card_id'), or"; + "\$recipient->cards->retrieve('card_id'), or " . "\$account->external_accounts->retrieve('card_id') instead."; throw new Error\InvalidRequest($msg, null); } diff --git a/htdocs/includes/stripe/lib/Charge.php b/htdocs/includes/stripe/lib/Charge.php index 6d448022877..832a07c7c04 100644 --- a/htdocs/includes/stripe/lib/Charge.php +++ b/htdocs/includes/stripe/lib/Charge.php @@ -29,8 +29,10 @@ namespace Stripe; * @property string $order * @property mixed $outcome * @property bool $paid + * @property string $payment_intent * @property string $receipt_email * @property string $receipt_number + * @property string $receipt_url * @property bool $refunded * @property Collection $refunds * @property string $review @@ -40,17 +42,77 @@ namespace Stripe; * @property string $statement_descriptor * @property string $status * @property string $transfer + * @property mixed $transfer_data * @property string $transfer_group * * @package Stripe */ class Charge extends ApiResource { + + const OBJECT_NAME = "charge"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Retrieve; use ApiOperations\Update; + /** + * Possible string representations of decline codes. + * These strings are applicable to the decline_code property of the \Stripe\Error\Card exception. + * @link https://stripe.com/docs/declines/codes + */ + const DECLINED_APPROVE_WITH_ID = 'approve_with_id'; + const DECLINED_CALL_ISSUER = 'call_issuer'; + const DECLINED_CARD_NOT_SUPPORTED = 'card_not_supported'; + const DECLINED_CARD_VELOCITY_EXCEEDED = 'card_velocity_exceeded'; + const DECLINED_CURRENCY_NOT_SUPPORTED = 'currency_not_supported'; + const DECLINED_DO_NOT_HONOR = 'do_not_honor'; + const DECLINED_DO_NOT_TRY_AGAIN = 'do_not_try_again'; + const DECLINED_DUPLICATED_TRANSACTION = 'duplicate_transaction'; + const DECLINED_EXPIRED_CARD = 'expired_card'; + const DECLINED_FRAUDULENT = 'fraudulent'; + const DECLINED_GENERIC_DECLINE = 'generic_decline'; + const DECLINED_INCORRECT_NUMBER = 'incorrect_number'; + const DECLINED_INCORRECT_CVC = 'incorrect_cvc'; + const DECLINED_INCORRECT_PIN = 'incorrect_pin'; + const DECLINED_INCORRECT_ZIP = 'incorrect_zip'; + const DECLINED_INSUFFICIENT_FUNDS = 'insufficient_funds'; + const DECLINED_INVALID_ACCOUNT = 'invalid_account'; + const DECLINED_INVALID_AMOUNT = 'invalid_amount'; + const DECLINED_INVALID_CVC = 'invalid_cvc'; + const DECLINED_INVALID_EXPIRY_YEAR = 'invalid_expiry_year'; + const DECLINED_INVALID_NUMBER = 'invalid_number'; + const DECLINED_INVALID_PIN = 'invalid_pin'; + const DECLINED_ISSUER_NOT_AVAILABLE = 'issuer_not_available'; + const DECLINED_LOST_CARD = 'lost_card'; + const DECLINED_NEW_ACCOUNT_INFORMATION_AVAILABLE = 'new_account_information_available'; + const DECLINED_NO_ACTION_TAKEN = 'no_action_taken'; + const DECLINED_NOT_PERMITTED = 'not_permitted'; + const DECLINED_PICKUP_CARD = 'pickup_card'; + const DECLINED_PIN_TRY_EXCEEDED = 'pin_try_exceeded'; + const DECLINED_PROCESSING_ERROR = 'processing_error'; + const DECLINED_REENTER_TRANSACTION = 'reenter_transaction'; + const DECLINED_RESTRICTED_CARD = 'restricted_card'; + const DECLINED_REVOCATION_OF_ALL_AUTHORIZATIONS = 'revocation_of_all_authorizations'; + const DECLINED_REVOCATION_OF_AUTHORIZATION = 'revocation_of_authorization'; + const DECLINED_SECURITY_VIOLATION = 'security_violation'; + const DECLINED_SERVICE_NOT_ALLOWED = 'service_not_allowed'; + const DECLINED_STOLEN_CARD = 'stolen_card'; + const DECLINED_STOP_PAYMENT_ORDER = 'stop_payment_order'; + const DECLINED_TESTMODE_DECLINE = 'testmode_decline'; + const DECLINED_TRANSACTION_NOT_ALLOWED = 'transaction_not_allowed'; + const DECLINED_TRY_AGAIN_LATER = 'try_again_later'; + const DECLINED_WITHDRAWAL_COUNT_LIMIT_EXCEEDED = 'withdrawal_count_limit_exceeded'; + + /** + * Possible string representations of the status of the charge. + * @link https://stripe.com/docs/api/charges/object#charge_object-status + */ + const STATUS_FAILED = 'failed'; + const STATUS_PENDING = 'pending'; + const STATUS_SUCCEEDED = 'succeeded'; + /** * @param array|null $params * @param array|string|null $options diff --git a/htdocs/includes/stripe/lib/Checkout/Session.php b/htdocs/includes/stripe/lib/Checkout/Session.php new file mode 100644 index 00000000000..968d58cf632 --- /dev/null +++ b/htdocs/includes/stripe/lib/Checkout/Session.php @@ -0,0 +1,30 @@ +data); + } + /** * @return Util\AutoPagingIterator An iterator that can be used to iterate * across all objects across all pages. As page boundaries are diff --git a/htdocs/includes/stripe/lib/CountrySpec.php b/htdocs/includes/stripe/lib/CountrySpec.php index cdaa4e84d89..668bfe62ed9 100644 --- a/htdocs/includes/stripe/lib/CountrySpec.php +++ b/htdocs/includes/stripe/lib/CountrySpec.php @@ -11,23 +11,16 @@ namespace Stripe; * @property mixed $supported_bank_account_currencies * @property string[] $supported_payment_currencies * @property string[] $supported_payment_methods + * @property string[] $supported_transfer_countries * @property mixed $verification_fields * * @package Stripe */ class CountrySpec extends ApiResource { + + const OBJECT_NAME = "country_spec"; + use ApiOperations\All; use ApiOperations\Retrieve; - - /** - * This is a special case because the country specs endpoint has an - * underscore in it. The parent `className` function strips underscores. - * - * @return string The name of the class. - */ - public static function className() - { - return 'country_spec'; - } } diff --git a/htdocs/includes/stripe/lib/Coupon.php b/htdocs/includes/stripe/lib/Coupon.php index a2d44443ce5..51d4fd86593 100644 --- a/htdocs/includes/stripe/lib/Coupon.php +++ b/htdocs/includes/stripe/lib/Coupon.php @@ -15,7 +15,8 @@ namespace Stripe; * @property bool $livemode * @property int $max_redemptions * @property StripeObject $metadata - * @property int $percent_off + * @property string $name + * @property float $percent_off * @property int $redeem_by * @property int $times_redeemed * @property bool $valid @@ -24,6 +25,9 @@ namespace Stripe; */ class Coupon extends ApiResource { + + const OBJECT_NAME = "coupon"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; diff --git a/htdocs/includes/stripe/lib/CreditNote.php b/htdocs/includes/stripe/lib/CreditNote.php new file mode 100644 index 00000000000..169ed0815c3 --- /dev/null +++ b/htdocs/includes/stripe/lib/CreditNote.php @@ -0,0 +1,73 @@ +instanceUrl() . '/void'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } +} diff --git a/htdocs/includes/stripe/lib/Customer.php b/htdocs/includes/stripe/lib/Customer.php index 8d31b5ac0aa..44f5e6e2f09 100644 --- a/htdocs/includes/stripe/lib/Customer.php +++ b/htdocs/includes/stripe/lib/Customer.php @@ -8,24 +8,33 @@ namespace Stripe; * @property string $id * @property string $object * @property int $account_balance - * @property string $business_vat_id + * @property mixed $address * @property string $created * @property string $currency * @property string $default_source * @property bool $delinquent * @property string $description - * @property mixed $discount + * @property Discount $discount * @property string $email + * @property string $invoice_prefix + * @property mixed $invoice_settings * @property bool $livemode * @property StripeObject $metadata + * @property string $name + * @property string $phone + * @property string[] preferred_locales * @property mixed $shipping * @property Collection $sources * @property Collection $subscriptions + * @property Collection $tax_ids * * @package Stripe */ class Customer extends ApiResource { + + const OBJECT_NAME = "customer"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; @@ -33,6 +42,14 @@ class Customer extends ApiResource use ApiOperations\Retrieve; use ApiOperations\Update; + /** + * Possible string representations of the customer's type of tax exemption. + * @link https://stripe.com/docs/api/customers/object#customer_object-tax_exempt + */ + const TAX_EXEMPT_NONE = 'none'; + const TAX_EXEMPT_EXEMPT = 'exempt'; + const TAX_EXEMPT_REVERSE = 'reverse'; + public static function getSavedNestedResources() { static $savedNestedResources = null; @@ -45,6 +62,7 @@ class Customer extends ApiResource } const PATH_SOURCES = '/sources'; + const PATH_TAX_IDS = '/tax_ids'; /** * @param array|null $params @@ -135,7 +153,7 @@ class Customer extends ApiResource } /** - * @param array|null $id The ID of the customer on which to create the source. + * @param string|null $id The ID of the customer on which to create the source. * @param array|null $params * @param array|string|null $opts * @@ -147,8 +165,8 @@ class Customer extends ApiResource } /** - * @param array|null $id The ID of the customer to which the source belongs. - * @param array|null $sourceId The ID of the source to retrieve. + * @param string|null $id The ID of the customer to which the source belongs. + * @param string|null $sourceId The ID of the source to retrieve. * @param array|null $params * @param array|string|null $opts * @@ -160,8 +178,8 @@ class Customer extends ApiResource } /** - * @param array|null $id The ID of the customer to which the source belongs. - * @param array|null $sourceId The ID of the source to update. + * @param string|null $id The ID of the customer to which the source belongs. + * @param string|null $sourceId The ID of the source to update. * @param array|null $params * @param array|string|null $opts * @@ -173,8 +191,8 @@ class Customer extends ApiResource } /** - * @param array|null $id The ID of the customer to which the source belongs. - * @param array|null $sourceId The ID of the source to delete. + * @param string|null $id The ID of the customer to which the source belongs. + * @param string|null $sourceId The ID of the source to delete. * @param array|null $params * @param array|string|null $opts * @@ -186,14 +204,64 @@ class Customer extends ApiResource } /** - * @param array|null $id The ID of the customer on which to retrieve the sources. + * @param string|null $id The ID of the customer on which to retrieve the sources. * @param array|null $params * @param array|string|null $opts * - * @return ApiResource + * @return Collection The list of sources. */ public static function allSources($id, $params = null, $opts = null) { return self::_allNestedResources($id, static::PATH_SOURCES, $params, $opts); } + + /** + * @param string|null $id The ID of the customer on which to create the tax id. + * @param array|null $params + * @param array|string|null $opts + * + * @return ApiResource + */ + public static function createTaxId($id, $params = null, $opts = null) + { + return self::_createNestedResource($id, static::PATH_TAX_IDS, $params, $opts); + } + + /** + * @param string|null $id The ID of the customer to which the tax id belongs. + * @param string|null $taxIdId The ID of the tax id to retrieve. + * @param array|null $params + * @param array|string|null $opts + * + * @return ApiResource + */ + public static function retrieveTaxId($id, $taxIdId, $params = null, $opts = null) + { + return self::_retrieveNestedResource($id, static::PATH_TAX_IDS, $taxIdId, $params, $opts); + } + + /** + * @param string|null $id The ID of the customer to which the tax id belongs. + * @param string|null $taxIdId The ID of the tax id to delete. + * @param array|null $params + * @param array|string|null $opts + * + * @return ApiResource + */ + public static function deleteTaxId($id, $taxIdId, $params = null, $opts = null) + { + return self::_deleteNestedResource($id, static::PATH_TAX_IDS, $taxIdId, $params, $opts); + } + + /** + * @param string|null $id The ID of the customer on which to retrieve the tax ids. + * @param array|null $params + * @param array|string|null $opts + * + * @return Collection The list of tax ids. + */ + public static function allTaxIds($id, $params = null, $opts = null) + { + return self::_allNestedResources($id, static::PATH_TAX_IDS, $params, $opts); + } } diff --git a/htdocs/includes/stripe/lib/Discount.php b/htdocs/includes/stripe/lib/Discount.php new file mode 100644 index 00000000000..a72d12bc6e3 --- /dev/null +++ b/htdocs/includes/stripe/lib/Discount.php @@ -0,0 +1,21 @@ +code = $code; + $this->errorCode = $code; } public function getErrorCode() { - return $this->code; + return $this->errorCode; } } diff --git a/htdocs/includes/stripe/lib/Event.php b/htdocs/includes/stripe/lib/Event.php index 2add5ce11be..90b55c75151 100644 --- a/htdocs/includes/stripe/lib/Event.php +++ b/htdocs/includes/stripe/lib/Event.php @@ -7,107 +7,152 @@ namespace Stripe; * * @property string $id * @property string $object + * @property string $account * @property string $api_version - * @property int $created - * @property mixed $data - * @property bool $livemode - * @property int $pending_webhooks - * @property mixed $request + * @property int $created + * @property mixed $data + * @property bool $livemode + * @property int $pending_webhooks + * @property mixed $request * @property string $type * * @package Stripe */ class Event extends ApiResource { - /** + + const OBJECT_NAME = "event"; + + /** * Possible string representations of event types. * @link https://stripe.com/docs/api#event_types */ - const ACCOUNT_UPDATED = 'account.updated'; - const ACCOUNT_APPLICATION_DEAUTHORIZED = 'account.application.deauthorized'; - const ACCOUNT_EXTERNAL_ACCOUNT_CREATED = 'account.external_account.created'; - const ACCOUNT_EXTERNAL_ACCOUNT_DELETED = 'account.external_account.deleted'; - const ACCOUNT_EXTERNAL_ACCOUNT_UPDATED = 'account.external_account.updated'; - const APPLICATION_FEE_CREATED = 'application_fee.created'; - const APPLICATION_FEE_REFUNDED = 'application_fee.refunded'; - const APPLICATION_FEE_REFUND_UPDATED = 'application_fee.refund.updated'; - const BALANCE_AVAILABLE = 'balance.available'; - const CHARGE_CAPTURED = 'charge.captured'; - const CHARGE_FAILED = 'charge.failed'; - const CHARGE_PENDING = 'charge.pending'; - const CHARGE_REFUNDED = 'charge.refunded'; - const CHARGE_SUCCEEDED = 'charge.succeeded'; - const CHARGE_UPDATED = 'charge.updated'; - const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed'; - const CHARGE_DISPUTE_CREATED = 'charge.dispute.created'; - const CHARGE_DISPUTE_FUNDS_REINSTATED = 'charge.dispute.funds_reinstated'; - const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn'; - const CHARGE_DISPUTE_UPDATED = 'charge.dispute.updated'; - const CHARGE_REFUND_UPDATED = 'charge.refund.updated'; - const COUPON_CREATED = 'coupon.created'; - const COUPON_DELETED = 'coupon.deleted'; - const COUPON_UPDATED = 'coupon.updated'; - const CUSTOMER_CREATED = 'customer.created'; - const CUSTOMER_DELETED = 'customer.deleted'; - const CUSTOMER_UPDATED = 'customer.updated'; - const CUSTOMER_DISCOUNT_CREATED = 'customer.discount.created'; - const CUSTOMER_DISCOUNT_DELETED = 'customer.discount.deleted'; - const CUSTOMER_DISCOUNT_UPDATED = 'customer.discount.updated'; - const CUSTOMER_SOURCE_CREATED = 'customer.source.created'; - const CUSTOMER_SOURCE_DELETED = 'customer.source.deleted'; - const CUSTOMER_SOURCE_EXPIRING = 'customer.source.expiring'; - const CUSTOMER_SOURCE_UPDATED = 'customer.source.updated'; - const CUSTOMER_SUBSCRIPTION_CREATED = 'customer.subscription.created'; - const CUSTOMER_SUBSCRIPTION_DELETED = 'customer.subscription.deleted'; - const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'customer.subscription.trial_will_end'; - const CUSTOMER_SUBSCRIPTION_UPDATED = 'customer.subscription.updated'; - const FILE_CREATED = 'file.created'; - const INVOICE_CREATED = 'invoice.created'; - const INVOICE_PAYMENT_FAILED = 'invoice.payment_failed'; - const INVOICE_PAYMENT_SUCCEEDED = 'invoice.payment_succeeded'; - const INVOICE_SENT = 'invoice.sent'; - const INVOICE_UPCOMING = 'invoice.upcoming'; - const INVOICE_UPDATED = 'invoice.updated'; - const INVOICEITEM_CREATED = 'invoiceitem.created'; - const INVOICEITEM_DELETED = 'invoiceitem.deleted'; - const INVOICEITEM_UPDATED = 'invoiceitem.updated'; - const ORDER_CREATED = 'order.created'; - const ORDER_PAYMENT_FAILED = 'order.payment_failed'; - const ORDER_PAYMENT_SUCCEEDED = 'order.payment_succeeded'; - const ORDER_UPDATED = 'order.updated'; - const ORDER_RETURN_CREATED = 'order_return.created'; - const PAYOUT_CANCELED = 'payout.canceled'; - const PAYOUT_CREATED = 'payout.created'; - const PAYOUT_FAILED = 'payout.failed'; - const PAYOUT_PAID = 'payout.paid'; - const PAYOUT_UPDATED = 'payout.updated'; - const PING = 'ping'; - const PLAN_CREATED = 'plan.created'; - const PLAN_DELETED = 'plan.deleted'; - const PLAN_UPDATED = 'plan.updated'; - const PRODUCT_CREATED = 'product.created'; - const PRODUCT_DELETED = 'product.deleted'; - const PRODUCT_UPDATED = 'product.updated'; - const RECIPIENT_CREATED = 'recipient.created'; - const RECIPIENT_DELETED = 'recipient.deleted'; - const RECIPIENT_UPDATED = 'recipient.updated'; - const REVIEW_CLOSED = 'review.closed'; - const REVIEW_OPENED = 'review.opened'; - const SIGMA_SCHEDULED_QUERY_RUN_CREATED = 'sigma.scheduled_query_run.created'; - const SKU_CREATED = 'sku.created'; - const SKU_DELETED = 'sku.deleted'; - const SKU_UPDATED = 'sku.updated'; - const SOURCE_CANCELED = 'source.canceled'; - const SOURCE_CHARGEABLE = 'source.chargeable'; - const SOURCE_FAILED = 'source.failed'; - const SOURCE_MANDATE_NOTIFICATION = 'source.mandate_notification'; - const SOURCE_TRANSACTION_CREATED = 'source.transaction.created'; - const TOPUP_CREATED = 'topup.created'; - const TOPUP_FAILED = 'topup.failed'; - const TOPUP_SUCCEEDED = 'topup.succeeded'; - const TRANSFER_CREATED = 'transfer.created'; - const TRANSFER_REVERSED = 'transfer.reversed'; - const TRANSFER_UPDATED = 'transfer.updated'; + const ACCOUNT_UPDATED = 'account.updated'; + const ACCOUNT_APPLICATION_AUTHORIZED = 'account.application.authorized'; + const ACCOUNT_APPLICATION_DEAUTHORIZED = 'account.application.deauthorized'; + const ACCOUNT_EXTERNAL_ACCOUNT_CREATED = 'account.external_account.created'; + const ACCOUNT_EXTERNAL_ACCOUNT_DELETED = 'account.external_account.deleted'; + const ACCOUNT_EXTERNAL_ACCOUNT_UPDATED = 'account.external_account.updated'; + const APPLICATION_FEE_CREATED = 'application_fee.created'; + const APPLICATION_FEE_REFUNDED = 'application_fee.refunded'; + const APPLICATION_FEE_REFUND_UPDATED = 'application_fee.refund.updated'; + const BALANCE_AVAILABLE = 'balance.available'; + const CHARGE_CAPTURED = 'charge.captured'; + const CHARGE_EXPIRED = 'charge.expired'; + const CHARGE_FAILED = 'charge.failed'; + const CHARGE_PENDING = 'charge.pending'; + const CHARGE_REFUNDED = 'charge.refunded'; + const CHARGE_SUCCEEDED = 'charge.succeeded'; + const CHARGE_UPDATED = 'charge.updated'; + const CHARGE_DISPUTE_CLOSED = 'charge.dispute.closed'; + const CHARGE_DISPUTE_CREATED = 'charge.dispute.created'; + const CHARGE_DISPUTE_FUNDS_REINSTATED = 'charge.dispute.funds_reinstated'; + const CHARGE_DISPUTE_FUNDS_WITHDRAWN = 'charge.dispute.funds_withdrawn'; + const CHARGE_DISPUTE_UPDATED = 'charge.dispute.updated'; + const CHARGE_REFUND_UPDATED = 'charge.refund.updated'; + const COUPON_CREATED = 'coupon.created'; + const COUPON_DELETED = 'coupon.deleted'; + const COUPON_UPDATED = 'coupon.updated'; + const CREDIT_NOTE_CREATED = 'credit_note.created'; + const CREDIT_NOTE_UPDATED = 'credit_note.updated'; + const CREDIT_NOTE_VOIDED = 'credit_note.voided'; + const CUSTOMER_CREATED = 'customer.created'; + const CUSTOMER_DELETED = 'customer.deleted'; + const CUSTOMER_UPDATED = 'customer.updated'; + const CUSTOMER_DISCOUNT_CREATED = 'customer.discount.created'; + const CUSTOMER_DISCOUNT_DELETED = 'customer.discount.deleted'; + const CUSTOMER_DISCOUNT_UPDATED = 'customer.discount.updated'; + const CUSTOMER_SOURCE_CREATED = 'customer.source.created'; + const CUSTOMER_SOURCE_DELETED = 'customer.source.deleted'; + const CUSTOMER_SOURCE_EXPIRING = 'customer.source.expiring'; + const CUSTOMER_SOURCE_UPDATED = 'customer.source.updated'; + const CUSTOMER_SUBSCRIPTION_CREATED = 'customer.subscription.created'; + const CUSTOMER_SUBSCRIPTION_DELETED = 'customer.subscription.deleted'; + const CUSTOMER_SUBSCRIPTION_TRIAL_WILL_END = 'customer.subscription.trial_will_end'; + const CUSTOMER_SUBSCRIPTION_UPDATED = 'customer.subscription.updated'; + const FILE_CREATED = 'file.created'; + const INVOICE_CREATED = 'invoice.created'; + const INVOICE_DELETED = 'invoice.deleted'; + const INVOICE_FINALIZED = 'invoice.finalized'; + const INVOICE_MARKED_UNCOLLECTIBLE = 'invoice.marked_uncollectible'; + const INVOICE_PAYMENT_FAILED = 'invoice.payment_failed'; + const INVOICE_PAYMENT_SUCCEEDED = 'invoice.payment_succeeded'; + const INVOICE_SENT = 'invoice.sent'; + const INVOICE_UPCOMING = 'invoice.upcoming'; + const INVOICE_UPDATED = 'invoice.updated'; + const INVOICE_VOIDED = 'invoice.voided'; + const INVOICEITEM_CREATED = 'invoiceitem.created'; + const INVOICEITEM_DELETED = 'invoiceitem.deleted'; + const INVOICEITEM_UPDATED = 'invoiceitem.updated'; + const ISSUER_FRAUD_RECORD_CREATED = 'issuer_fraud_record.created'; + const ISSUING_AUTHORIZATION_CREATED = 'issuing_authorization.created'; + const ISSUING_AUTHORIZATION_UPDATED = 'issuing_authorization.updated'; + const ISSUING_CARD_CREATED = 'issuing_card.created'; + const ISSUING_CARD_UPDATED = 'issuing_card.updated'; + const ISSUING_CARDHOLDER_CREATED = 'issuing_cardholder.created'; + const ISSUING_CARDHOLDER_UPDATED = 'issuing_cardholder.updated'; + const ISSUING_TRANSACTION_CREATED = 'issuing_transaction.created'; + const ISSUING_TRANSACTION_UPDATED = 'issuing_transaction.updated'; + const ORDER_CREATED = 'order.created'; + const ORDER_PAYMENT_FAILED = 'order.payment_failed'; + const ORDER_PAYMENT_SUCCEEDED = 'order.payment_succeeded'; + const ORDER_UPDATED = 'order.updated'; + const ORDER_RETURN_CREATED = 'order_return.created'; + const PAYMENT_INTENT_AMOUNT_CAPTURABLE_UPDATED = 'payment_intent.amount_capturable_updated'; + const PAYMENT_INTENT_CREATED = 'payment_intent.created'; + const PAYMENT_INTENT_PAYMENT_FAILED = 'payment_intent.payment_failed'; + const PAYMENT_INTENT_SUCCEEDED = 'payment_intent.succeeded'; + const PAYOUT_CANCELED = 'payout.canceled'; + const PAYOUT_CREATED = 'payout.created'; + const PAYOUT_FAILED = 'payout.failed'; + const PAYOUT_PAID = 'payout.paid'; + const PAYOUT_UPDATED = 'payout.updated'; + const PERSON_CREATED = 'person.created'; + const PERSON_DELETED = 'person.deleted'; + const PERSON_UPDATED = 'person.updated'; + const PING = 'ping'; + const PLAN_CREATED = 'plan.created'; + const PLAN_DELETED = 'plan.deleted'; + const PLAN_UPDATED = 'plan.updated'; + const PRODUCT_CREATED = 'product.created'; + const PRODUCT_DELETED = 'product.deleted'; + const PRODUCT_UPDATED = 'product.updated'; + const RECIPIENT_CREATED = 'recipient.created'; + const RECIPIENT_DELETED = 'recipient.deleted'; + const RECIPIENT_UPDATED = 'recipient.updated'; + const REPORTING_REPORT_RUN_FAILED = 'reporting.report_run.failed'; + const REPORTING_REPORT_RUN_SUCCEEDED = 'reporting.report_run.succeeded'; + const REPORTING_REPORT_TYPE_UPDATED = 'reporting.report_type.updated'; + const REVIEW_CLOSED = 'review.closed'; + const REVIEW_OPENED = 'review.opened'; + const SIGMA_SCHEDULED_QUERY_RUN_CREATED = 'sigma.scheduled_query_run.created'; + const SKU_CREATED = 'sku.created'; + const SKU_DELETED = 'sku.deleted'; + const SKU_UPDATED = 'sku.updated'; + const SOURCE_CANCELED = 'source.canceled'; + const SOURCE_CHARGEABLE = 'source.chargeable'; + const SOURCE_FAILED = 'source.failed'; + const SOURCE_MANDATE_NOTIFICATION = 'source.mandate_notification'; + const SOURCE_REFUND_ATTRIBUTES_REQUIRED = 'source.refund_attributes_required'; + const SOURCE_TRANSACTION_CREATED = 'source.transaction.created'; + const SOURCE_TRANSACTION_UPDATED = 'source.transaction.updated'; + const SUBSCRIPTION_SCHEDULE_ABORTED = 'subscription_schedule.aborted'; + const SUBSCRIPTION_SCHEDULE_CANCELED = 'subscription_schedule.canceled'; + const SUBSCRIPTION_SCHEDULE_COMPLETED = 'subscription_schedule.completed'; + const SUBSCRIPTION_SCHEDULE_CREATED = 'subscription_schedule.created'; + const SUBSCRIPTION_SCHEDULE_EXPIRING = 'subscription_schedule.expiring'; + const SUBSCRIPTION_SCHEDULE_RELEASED = 'subscription_schedule.released'; + const SUBSCRIPTION_SCHEDULE_UPDATED = 'subscription_schedule.updated'; + const TAX_RATE_CREATED = 'tax_rate.created'; + const TAX_RATE_UPDATED = 'tax_rate.updated'; + const TOPUP_CANCELED = 'topup.canceled'; + const TOPUP_CREATED = 'topup.created'; + const TOPUP_FAILED = 'topup.failed'; + const TOPUP_REVERSED = 'topup.reversed'; + const TOPUP_SUCCEEDED = 'topup.succeeded'; + const TRANSFER_CREATED = 'transfer.created'; + const TRANSFER_REVERSED = 'transfer.reversed'; + const TRANSFER_UPDATED = 'transfer.updated'; use ApiOperations\All; use ApiOperations\Retrieve; diff --git a/htdocs/includes/stripe/lib/ExchangeRate.php b/htdocs/includes/stripe/lib/ExchangeRate.php index 40763261834..803a5f87700 100644 --- a/htdocs/includes/stripe/lib/ExchangeRate.php +++ b/htdocs/includes/stripe/lib/ExchangeRate.php @@ -9,17 +9,9 @@ namespace Stripe; */ class ExchangeRate extends ApiResource { + + const OBJECT_NAME = "exchange_rate"; + use ApiOperations\All; use ApiOperations\Retrieve; - - /** - * This is a special case because the exchange rates endpoint has an - * underscore in it. The parent `className` function strips underscores. - * - * @return string The name of the class. - */ - public static function className() - { - return 'exchange_rate'; - } } diff --git a/htdocs/includes/stripe/lib/File.php b/htdocs/includes/stripe/lib/File.php new file mode 100644 index 00000000000..76109ad38cf --- /dev/null +++ b/htdocs/includes/stripe/lib/File.php @@ -0,0 +1,62 @@ +apiBase)) { + $opts->apiBase = Stripe::$apiUploadBase; + } + // Manually flatten params, otherwise curl's multipart encoder will + // choke on nested arrays. + // TODO: use array_column() once we drop support for PHP 5.4 + $flatParams = []; + foreach (\Stripe\Util\Util::flattenParams($params) as $pair) { + $flatParams[$pair[0]] = $pair[1]; + } + return static::_create($flatParams, $opts); + } +} diff --git a/htdocs/includes/stripe/lib/FileLink.php b/htdocs/includes/stripe/lib/FileLink.php new file mode 100644 index 00000000000..2a012b36105 --- /dev/null +++ b/htdocs/includes/stripe/lib/FileLink.php @@ -0,0 +1,29 @@ +defaultOptions = $defaultOptions; $this->randomGenerator = $randomGenerator ?: new Util\RandomGenerator(); $this->initUserAgentInfo(); + + // TODO: curl_reset requires PHP >= 5.5.0. Once we drop support for PHP 5.4, we can simply + // initialize this to true. + $this->enablePersistentConnections = function_exists('curl_reset'); + + $this->enableHttp2 = $this->canSafelyUseHttp2(); + } + + public function __destruct() + { + $this->closeCurlHandle(); } public function initUserAgentInfo() @@ -77,6 +98,38 @@ class CurlClient implements ClientInterface return $this->userAgentInfo; } + /** + * @return boolean + */ + public function getEnablePersistentConnections() + { + return $this->enablePersistentConnections; + } + + /** + * @param boolean $enable + */ + public function setEnablePersistentConnections($enable) + { + $this->enablePersistentConnections = $enable; + } + + /** + * @return boolean + */ + public function getEnableHttp2() + { + return $this->enableHttp2; + } + + /** + * @param boolean $enable + */ + public function setEnableHttp2($enable) + { + $this->enableHttp2 = $enable; + } + // USER DEFINED TIMEOUTS const DEFAULT_TIMEOUT = 80; @@ -123,6 +176,8 @@ class CurlClient implements ClientInterface $opts = $this->defaultOptions; } + $params = Util\Util::objectsToIds($params); + if ($method == 'get') { if ($hasFile) { throw new Error\Api( @@ -131,16 +186,16 @@ class CurlClient implements ClientInterface } $opts[CURLOPT_HTTPGET] = 1; if (count($params) > 0) { - $encoded = Util\Util::urlEncode($params); + $encoded = Util\Util::encodeParameters($params); $absUrl = "$absUrl?$encoded"; } } elseif ($method == 'post') { $opts[CURLOPT_POST] = 1; - $opts[CURLOPT_POSTFIELDS] = $hasFile ? $params : Util\Util::urlEncode($params); + $opts[CURLOPT_POSTFIELDS] = $hasFile ? $params : Util\Util::encodeParameters($params); } elseif ($method == 'delete') { $opts[CURLOPT_CUSTOMREQUEST] = 'DELETE'; if (count($params) > 0) { - $encoded = Util\Util::urlEncode($params); + $encoded = Util\Util::encodeParameters($params); $absUrl = "$absUrl?$encoded"; } } else { @@ -150,13 +205,13 @@ class CurlClient implements ClientInterface // It is only safe to retry network failures on POST requests if we // add an Idempotency-Key header if (($method == 'post') && (Stripe::$maxNetworkRetries > 0)) { - if (!isset($headers['Idempotency-Key'])) { + if (!$this->hasHeader($headers, "Idempotency-Key")) { array_push($headers, 'Idempotency-Key: ' . $this->randomGenerator->uuid()); } } // Create a callback to capture HTTP headers for the response - $rheaders = []; + $rheaders = new Util\CaseInsensitiveArray(); $headerCallback = function ($curl, $header_line) use (&$rheaders) { // Ignore the HTTP request line (HTTP/1.1 200 OK) if (strpos($header_line, ":") === false) { @@ -193,6 +248,11 @@ class CurlClient implements ClientInterface $opts[CURLOPT_SSL_VERIFYPEER] = false; } + if (!isset($opts[CURLOPT_HTTP_VERSION]) && $this->getEnableHttp2()) { + // For HTTPS requests, enable HTTP/2, if supported + $opts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2TLS; + } + list($rbody, $rcode) = $this->executeRequestWithRetries($opts, $absUrl); return [$rbody, $rcode, $rheaders]; @@ -209,17 +269,19 @@ class CurlClient implements ClientInterface $rcode = 0; $errno = 0; - $curl = curl_init(); - curl_setopt_array($curl, $opts); - $rbody = curl_exec($curl); + $this->resetCurlHandle(); + curl_setopt_array($this->curlHandle, $opts); + $rbody = curl_exec($this->curlHandle); if ($rbody === false) { - $errno = curl_errno($curl); - $message = curl_error($curl); + $errno = curl_errno($this->curlHandle); + $message = curl_error($this->curlHandle); } else { - $rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $rcode = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE); + } + if (!$this->getEnablePersistentConnections()) { + $this->closeCurlHandle(); } - curl_close($curl); if ($this->shouldRetry($errno, $rcode, $numRetries)) { $numRetries += 1; @@ -331,4 +393,68 @@ class CurlClient implements ClientInterface return $sleepSeconds; } + + /** + * Initializes the curl handle. If already initialized, the handle is closed first. + */ + private function initCurlHandle() + { + $this->closeCurlHandle(); + $this->curlHandle = curl_init(); + } + + /** + * Closes the curl handle if initialized. Do nothing if already closed. + */ + private function closeCurlHandle() + { + if (!is_null($this->curlHandle)) { + curl_close($this->curlHandle); + $this->curlHandle = null; + } + } + + /** + * Resets the curl handle. If the handle is not already initialized, or if persistent + * connections are disabled, the handle is reinitialized instead. + */ + private function resetCurlHandle() + { + if (!is_null($this->curlHandle) && $this->getEnablePersistentConnections()) { + curl_reset($this->curlHandle); + } else { + $this->initCurlHandle(); + } + } + + /** + * Indicates whether it is safe to use HTTP/2 or not. + * + * @return boolean + */ + private function canSafelyUseHttp2() + { + // Versions of curl older than 7.60.0 don't respect GOAWAY frames + // (cf. https://github.com/curl/curl/issues/2416), which Stripe use. + $curlVersion = curl_version()['version']; + return (version_compare($curlVersion, '7.60.0') >= 0); + } + + /** + * Checks if a list of headers contains a specific header name. + * + * @param string[] $headers + * @param string $name + * @return boolean + */ + private function hasHeader($headers, $name) + { + foreach ($headers as $header) { + if (strncasecmp($header, "{$name}: ", strlen($name) + 2) === 0) { + return true; + } + } + + return false; + } } diff --git a/htdocs/includes/stripe/lib/Invoice.php b/htdocs/includes/stripe/lib/Invoice.php index 07d67f74a8a..6e0ec9d6b6c 100644 --- a/htdocs/includes/stripe/lib/Invoice.php +++ b/htdocs/includes/stripe/lib/Invoice.php @@ -7,51 +7,161 @@ namespace Stripe; * * @property string $id * @property string $object + * @property string $account_country + * @property string $account_name * @property int $amount_due * @property int $amount_paid * @property int $amount_remaining - * @property int $application_fee + * @property int $application_fee_amount * @property int $attempt_count * @property bool $attempted + * @property bool $auto_advance * @property string $billing + * @property string $billing_reason * @property string $charge - * @property bool $closed + * @property int $created * @property string $currency + * @property array $custom_fields * @property string $customer - * @property int $date + * @property mixed $customer_address + * @property string $customer_email + * @property string $customer_name + * @property string $customer_phone + * @property mixed $customer_shipping + * @property array $customer_tax_ids + * @property string $default_payment_method + * @property string $default_source + * @property array $default_tax_rates * @property string $description - * @property mixed $discount + * @property Discount $discount * @property int $due_date * @property int $ending_balance - * @property bool $forgiven + * @property string $footer + * @property string $hosted_invoice_url + * @property string $invoice_pdf * @property Collection $lines * @property bool $livemode * @property StripeObject $metadata * @property int $next_payment_attempt * @property string $number * @property bool $paid + * @property string $payment_intent * @property int $period_end * @property int $period_start + * @property int $post_payment_credit_notes_amount + * @property int $pre_payment_credit_notes_amount * @property string $receipt_number * @property int $starting_balance * @property string $statement_descriptor + * @property string $status + * @property mixed $status_transitions * @property string $subscription * @property int $subscription_proration_date * @property int $subtotal * @property int $tax - * @property float $tax_percent + * @property mixed $threshold_reason * @property int $total + * @property array $total_tax_amounts * @property int $webhooks_delivered_at * * @package Stripe */ class Invoice extends ApiResource { + + const OBJECT_NAME = "invoice"; + use ApiOperations\All; use ApiOperations\Create; + use ApiOperations\Delete; use ApiOperations\Retrieve; use ApiOperations\Update; + /** + * Possible string representations of the invoice status. + * @link https://stripe.com/docs/api/invoices/object#invoice_object-status + */ + const STATUS_DRAFT = 'draft'; + const STATUS_OPEN = 'open'; + const STATUS_PAID = 'paid'; + const STATUS_UNCOLLECTIBLE = 'uncollectible'; + const STATUS_VOID = 'void'; + + /** + * Possible string representations of the billing. + * @link https://stripe.com/docs/api/invoices/object#invoice_object-billing + */ + const BILLING_SEND_INVOICE = 'send_invoice'; + const BILLING_CHARGE_AUTOMATICALLY = 'charge_automatically'; + + /** + * Possible string representations of the billing reason. + * @link https://stripe.com/docs/api/invoices/object#invoice_object-billing_reason + */ + const BILLING_REASON_SUBSCRIPTION = 'subscription'; + const BILLING_REASON_SUBSCRIPTION_CREATE = 'subscription_create'; + const BILLING_REASON_SUBSCRIPTION_CYCLE = 'subscription_cycle'; + const BILLING_REASON_SUBSCRIPTION_UPDATE = 'subscription_update'; + const BILLING_REASON_SUBSCRIPTION_THRESHOLD = 'subscription_threshold'; + const BILLING_REASON_MANUAL = 'manual'; + const BILLING_REASON_UPCOMING = 'upcoming'; + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return Invoice The finalized invoice. + */ + public function finalizeInvoice($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/finalize'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return Invoice The uncollectible invoice. + */ + public function markUncollectible($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/mark_uncollectible'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return Invoice The paid invoice. + */ + public function pay($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/pay'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return Invoice The sent invoice. + */ + public function sendInvoice($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/send'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + /** * @param array|null $params * @param array|string|null $opts @@ -68,11 +178,14 @@ class Invoice extends ApiResource } /** - * @return Invoice The paid invoice. + * @param array|null $params + * @param array|string|null $opts + * + * @return Invoice The voided invoice. */ - public function pay($params = null, $opts = null) + public function voidInvoice($params = null, $opts = null) { - $url = $this->instanceUrl() . '/pay'; + $url = $this->instanceUrl() . '/void'; list($response, $opts) = $this->_request('post', $url, $params, $opts); $this->refreshFrom($response, $opts); return $this; diff --git a/htdocs/includes/stripe/lib/InvoiceItem.php b/htdocs/includes/stripe/lib/InvoiceItem.php index 37e39f3e105..02ca0f2d7ee 100644 --- a/htdocs/includes/stripe/lib/InvoiceItem.php +++ b/htdocs/includes/stripe/lib/InvoiceItem.php @@ -22,11 +22,16 @@ namespace Stripe; * @property int $quantity * @property string $subscription * @property string $subscription_item + * @property array $tax_rates + * @property int $unit_amount * * @package Stripe */ class InvoiceItem extends ApiResource { + + const OBJECT_NAME = "invoiceitem"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; diff --git a/htdocs/includes/stripe/lib/InvoiceLineItem.php b/htdocs/includes/stripe/lib/InvoiceLineItem.php new file mode 100644 index 00000000000..e8e8c881d5a --- /dev/null +++ b/htdocs/includes/stripe/lib/InvoiceLineItem.php @@ -0,0 +1,32 @@ +instanceUrl() . '/approve'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $options + * + * @return Authorization The declined authorization. + */ + public function decline($params = null, $options = null) + { + $url = $this->instanceUrl() . '/decline'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } +} diff --git a/htdocs/includes/stripe/lib/Issuing/Card.php b/htdocs/includes/stripe/lib/Issuing/Card.php new file mode 100644 index 00000000000..60cc5b4e1bf --- /dev/null +++ b/htdocs/includes/stripe/lib/Issuing/Card.php @@ -0,0 +1,51 @@ +instanceUrl() . '/details'; + list($response, $opts) = $this->_request('get', $url, $params, $options); + $obj = \Stripe\Util\Util::convertToStripeObject($response, $opts); + $obj->setLastResponse($response); + return $obj; + } +} diff --git a/htdocs/includes/stripe/lib/Issuing/CardDetails.php b/htdocs/includes/stripe/lib/Issuing/CardDetails.php new file mode 100644 index 00000000000..65d3919caa4 --- /dev/null +++ b/htdocs/includes/stripe/lib/Issuing/CardDetails.php @@ -0,0 +1,21 @@ +instanceUrl() . '/cancel'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $options + * + * @return PaymentIntent The captured payment intent. + */ + public function capture($params = null, $options = null) + { + $url = $this->instanceUrl() . '/capture'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $options + * + * @return PaymentIntent The confirmed payment intent. + */ + public function confirm($params = null, $options = null) + { + $url = $this->instanceUrl() . '/confirm'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } +} diff --git a/htdocs/includes/stripe/lib/PaymentMethod.php b/htdocs/includes/stripe/lib/PaymentMethod.php new file mode 100644 index 00000000000..1a0bc371d5d --- /dev/null +++ b/htdocs/includes/stripe/lib/PaymentMethod.php @@ -0,0 +1,60 @@ +instanceUrl() . '/attach'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return PaymentMethod The detached payment method. + */ + public function detach($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/detach'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } +} diff --git a/htdocs/includes/stripe/lib/Payout.php b/htdocs/includes/stripe/lib/Payout.php index 0849cae3f61..365d7e47ee9 100644 --- a/htdocs/includes/stripe/lib/Payout.php +++ b/htdocs/includes/stripe/lib/Payout.php @@ -8,18 +8,19 @@ namespace Stripe; * @property string $id * @property string $object * @property int $amount + * @property int $arrival_date + * @property bool $automatic * @property string $balance_transaction - * @property string $cancellation_balance_transaction * @property int $created * @property string $currency - * @property int $arrival_date + * @property string $description * @property string $destination + * @property string $failure_balance_transaction * @property string $failure_code * @property string $failure_message * @property bool $livemode * @property StripeObject $metadata * @property string $method - * @property string $recipient * @property string $source_type * @property string $statement_descriptor * @property string $status @@ -29,11 +30,56 @@ namespace Stripe; */ class Payout extends ApiResource { + + const OBJECT_NAME = "payout"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Retrieve; use ApiOperations\Update; + /** + * Types of payout failure codes. + * @link https://stripe.com/docs/api#payout_failures + */ + const FAILURE_ACCOUNT_CLOSED = 'account_closed'; + const FAILURE_ACCOUNT_FROZEN = 'account_frozen'; + const FAILURE_BANK_ACCOUNT_RESTRICTED = 'bank_account_restricted'; + const FAILURE_BANK_OWNERSHIP_CHANGED = 'bank_ownership_changed'; + const FAILURE_COULD_NOT_PROCESS = 'could_not_process'; + const FAILURE_DEBIT_NOT_AUTHORIZED = 'debit_not_authorized'; + const FAILURE_DECLINED = 'declined'; + const FAILURE_INCORRECT_ACCOUNT_HOLDER_NAME = 'incorrect_account_holder_name'; + const FAILURE_INSUFFICIENT_FUNDS = 'insufficient_funds'; + const FAILURE_INVALID_ACCOUNT_NUMBER = 'invalid_account_number'; + const FAILURE_INVALID_CURRENCY = 'invalid_currency'; + const FAILURE_NO_ACCOUNT = 'no_account'; + const FAILURE_UNSUPPORTED_CARD = 'unsupported_card'; + + /** + * Possible string representations of the payout methods. + * @link https://stripe.com/docs/api/payouts/object#payout_object-method + */ + const METHOD_STANDARD = 'standard'; + const METHOD_INSTANT = 'instant'; + + /** + * Possible string representations of the status of the payout. + * @link https://stripe.com/docs/api/payouts/object#payout_object-status + */ + const STATUS_CANCELED = 'canceled'; + const STATUS_IN_TRANSIT = 'in_transit'; + const STATUS_FAILED = 'failed'; + const STATUS_PAID = 'paid'; + const STATUS_PENDING = 'pending'; + + /** + * Possible string representations of the type of payout. + * @link https://stripe.com/docs/api/payouts/object#payout_object-type + */ + const TYPE_BANK_ACCOUNT = 'bank_account'; + const TYPE_CARD = 'card'; + /** * @return Payout The canceled payout. */ diff --git a/htdocs/includes/stripe/lib/Person.php b/htdocs/includes/stripe/lib/Person.php new file mode 100644 index 00000000000..56241c4c426 --- /dev/null +++ b/htdocs/includes/stripe/lib/Person.php @@ -0,0 +1,108 @@ +retrievePerson('person_id') instead."; + throw new Error\InvalidRequest($msg, null); + } + + /** + * @param string $_id + * @param array|null $_params + * @param array|string|null $_options + * + * @throws \Stripe\Error\InvalidRequest + */ + public static function update($_id, $_params = null, $_options = null) + { + $msg = "Persons cannot be accessed without an account ID. " . + "Retrieve a Person using \$account->retrievePerson('person_id') instead."; + throw new Error\InvalidRequest($msg, null); + } +} diff --git a/htdocs/includes/stripe/lib/Plan.php b/htdocs/includes/stripe/lib/Plan.php index 8b0126b6f2d..54a2b58eb35 100644 --- a/htdocs/includes/stripe/lib/Plan.php +++ b/htdocs/includes/stripe/lib/Plan.php @@ -9,7 +9,10 @@ namespace Stripe; * * @property string $id * @property string $object + * @property bool $active + * @property string $aggregate_usage * @property int $amount + * @property string $billing_scheme * @property int $created * @property string $currency * @property string $interval @@ -18,10 +21,17 @@ namespace Stripe; * @property StripeObject $metadata * @property string $nickname * @property string $product + * @property mixed $tiers + * @property string $tiers_mode + * @property mixed $transform_usage * @property int $trial_period_days + * @property string $usage_type */ class Plan extends ApiResource { + + const OBJECT_NAME = "plan"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; diff --git a/htdocs/includes/stripe/lib/Product.php b/htdocs/includes/stripe/lib/Product.php index 20bd4e1ae44..cb27ef42d8c 100644 --- a/htdocs/includes/stripe/lib/Product.php +++ b/htdocs/includes/stripe/lib/Product.php @@ -13,15 +13,15 @@ namespace Stripe; * @property int $created * @property string[] $deactivate_on * @property string $description - * @property array $images + * @property string[] $images * @property bool $livemode * @property StripeObject $metadata * @property string $name * @property mixed $package_dimensions * @property bool $shippable - * @property Collection $skus * @property string $statement_descriptor * @property string $type + * @property string $unit_label * @property int $updated * @property string $url * @@ -29,9 +29,19 @@ namespace Stripe; */ class Product extends ApiResource { + + const OBJECT_NAME = "product"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; use ApiOperations\Retrieve; use ApiOperations\Update; + + /** + * Possible string representations of the type of product. + * @link https://stripe.com/docs/api/service_products/object#service_product_object-type + */ + const TYPE_GOOD = 'good'; + const TYPE_SERVICE = 'service'; } diff --git a/htdocs/includes/stripe/lib/Radar/ValueList.php b/htdocs/includes/stripe/lib/Radar/ValueList.php new file mode 100644 index 00000000000..d267429b272 --- /dev/null +++ b/htdocs/includes/stripe/lib/Radar/ValueList.php @@ -0,0 +1,32 @@ +requestId = $requestId; + $this->requestDuration = $requestDuration; + } +} diff --git a/htdocs/includes/stripe/lib/Review.php b/htdocs/includes/stripe/lib/Review.php new file mode 100644 index 00000000000..a2fd5d06db3 --- /dev/null +++ b/htdocs/includes/stripe/lib/Review.php @@ -0,0 +1,57 @@ +instanceUrl() . '/approve'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } +} diff --git a/htdocs/includes/stripe/lib/SKU.php b/htdocs/includes/stripe/lib/SKU.php index 1f35da4c759..5b50df8a847 100644 --- a/htdocs/includes/stripe/lib/SKU.php +++ b/htdocs/includes/stripe/lib/SKU.php @@ -24,6 +24,9 @@ namespace Stripe; */ class SKU extends ApiResource { + + const OBJECT_NAME = "sku"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; diff --git a/htdocs/includes/stripe/lib/Sigma/ScheduledQueryRun.php b/htdocs/includes/stripe/lib/Sigma/ScheduledQueryRun.php new file mode 100644 index 00000000000..4d97bf7ce28 --- /dev/null +++ b/htdocs/includes/stripe/lib/Sigma/ScheduledQueryRun.php @@ -0,0 +1,33 @@ + "old_value"] + * + * If we update the object with `metadata[new]=new_value`, the server side + * object now has *both* fields: + * + * metadata = ["old" => "old_value", "new" => "new_value"] + * + * This is okay in itself because usually users will want to treat it as + * additive: + * + * $obj->metadata["new"] = "new_value"; + * $obj->save(); + * + * However, in other cases, they may want to replace the entire existing + * contents: + * + * $obj->metadata = ["new" => "new_value"]; + * $obj->save(); + * + * This is where things get a little bit tricky because in order to clear + * any old keys that may have existed, we actually have to send an explicit + * empty string to the server. So the operation above would have to send + * this form to get the intended behavior: + * + * metadata[old]=&metadata[new]=new_value + * + * This method allows us to track which parameters are considered additive, + * and lets us behave correctly where appropriate when serializing + * parameters to be sent. + * + * @return Util\Set Set of additive parameters + */ + public static function getAdditiveParams() + { + static $additiveParams = null; + if ($additiveParams === null) { + // Set `metadata` as additive so that when it's set directly we remember + // to clear keys that may have been previously set by sending empty + // values for them. + // + // It's possible that not every object has `metadata`, but having this + // option set when there is no `metadata` field is not harmful. + $additiveParams = new Util\Set([ + 'metadata', + ]); + } + return $additiveParams; + } + public function __construct($id = null, $opts = null) { list($id, $this->_retrieveOptions) = Util\Util::normalizeId($id); @@ -153,7 +220,7 @@ class StripeObject implements \ArrayAccess, \Countable, \JsonSerializable * @param array $values * @param null|string|array|Util\RequestOptions $opts * - * @return StripeObject The object constructed from the given values. + * @return static The object constructed from the given values. */ public static function constructFrom($values, $opts = null) { @@ -213,7 +280,7 @@ class StripeObject implements \ArrayAccess, \Countable, \JsonSerializable // This is necessary in case metadata is empty, as PHP arrays do // not differentiate between lists and hashes, and we consider // empty arrays to be lists. - if ($k === "metadata") { + if (($k === "metadata") && (is_array($v))) { $this->_values[$k] = StripeObject::constructFrom($v, $opts); } else { $this->_values[$k] = Util\Util::convertToStripeObject($v, $opts); @@ -323,7 +390,7 @@ class StripeObject implements \ArrayAccess, \Countable, \JsonSerializable } } elseif ($value instanceof StripeObject) { $update = $value->serializeParameters($force); - if ($original && $unsaved) { + if ($original && $unsaved && $key && static::getAdditiveParams()->includes($key)) { $update = array_merge(self::emptyValues($original), $update); } return $update; @@ -432,12 +499,25 @@ class StripeObject implements \ArrayAccess, \Countable, \JsonSerializable } /** - * @param ApiResponse + * Sets the last response from the Stripe API * - * @return void Set the last response from the Stripe API + * @param ApiResponse $resp + * @return void */ public function setLastResponse($resp) { $this->_lastResponse = $resp; } + + /** + * Indicates whether or not the resource has been deleted on the server. + * Note that some, but not all, resources can indicate whether they have + * been deleted. + * + * @return bool Whether the resource is deleted. + */ + public function isDeleted() + { + return isset($this->_values['deleted']) ? $this->_values['deleted'] : false; + } } diff --git a/htdocs/includes/stripe/lib/Subscription.php b/htdocs/includes/stripe/lib/Subscription.php index a5a8da1beb5..8b57d46b625 100644 --- a/htdocs/includes/stripe/lib/Subscription.php +++ b/htdocs/includes/stripe/lib/Subscription.php @@ -9,20 +9,27 @@ namespace Stripe; * @property string $object * @property float $application_fee_percent * @property string $billing + * @property int $billing_cycle_anchor + * @property mixed $billing_thresholds * @property bool $cancel_at_period_end * @property int $canceled_at * @property int $created - * @property int current_period_end - * @property int current_period_start + * @property int $current_period_end + * @property int $current_period_start * @property string $customer * @property int $days_until_due - * @property mixed $discount + * @property string $default_payment_method + * @property string $default_source + * @property array $default_tax_rates + * @property Discount $discount * @property int $ended_at * @property Collection $items + * @property string $latest_invoice * @property boolean $livemode * @property StripeObject $metadata * @property Plan $plan * @property int $quantity + * @property SubscriptionSchedule $schedule * @property int $start * @property string $status * @property float $tax_percent @@ -33,6 +40,9 @@ namespace Stripe; */ class Subscription extends ApiResource { + + const OBJECT_NAME = "subscription"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete { @@ -46,11 +56,13 @@ class Subscription extends ApiResource * * @link https://stripe.com/docs/api#subscription_object-status */ - const STATUS_ACTIVE = 'active'; - const STATUS_CANCELED = 'canceled'; - const STATUS_PAST_DUE = 'past_due'; - const STATUS_TRIALING = 'trialing'; - const STATUS_UNPAID = 'unpaid'; + const STATUS_ACTIVE = 'active'; + const STATUS_CANCELED = 'canceled'; + const STATUS_PAST_DUE = 'past_due'; + const STATUS_TRIALING = 'trialing'; + const STATUS_UNPAID = 'unpaid'; + const STATUS_INCOMPLETE = 'incomplete'; + const STATUS_INCOMPLETE_EXPIRED = 'incomplete_expired'; public static function getSavedNestedResources() { @@ -82,13 +94,4 @@ class Subscription extends ApiResource list($response, $opts) = $this->_request('delete', $url); $this->refreshFrom(['discount' => null], $opts, true); } - - public function serializeParameters($force = false) - { - $update = parent::serializeParameters($force); - if ($this->_unsavedValues->includes('items')) { - $update['items'] = $this->serializeParamsValue($this->items, null, true, $force, 'items'); - } - return $update; - } } diff --git a/htdocs/includes/stripe/lib/SubscriptionItem.php b/htdocs/includes/stripe/lib/SubscriptionItem.php index 9efc726aa66..5baa540fe98 100644 --- a/htdocs/includes/stripe/lib/SubscriptionItem.php +++ b/htdocs/includes/stripe/lib/SubscriptionItem.php @@ -7,16 +7,21 @@ namespace Stripe; * * @property string $id * @property string $object + * @property mixed $billing_thresholds * @property int $created * @property StripeObject $metadata * @property Plan $plan * @property int $quantity * @property string $subscription + * @property array $tax_rates * * @package Stripe */ class SubscriptionItem extends ApiResource { + + const OBJECT_NAME = "subscription_item"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\Delete; @@ -24,13 +29,17 @@ class SubscriptionItem extends ApiResource use ApiOperations\Update; /** - * This is a special case because the subscription items endpoint has an - * underscore in it. The parent `className` function strips underscores. + * @param array|null $params + * @param array|string|null $options * - * @return string The name of the class. + * @return Collection The list of source transactions. */ - public static function className() + public function usageRecordSummaries($params = null, $options = null) { - return 'subscription_item'; + $url = $this->instanceUrl() . '/usage_record_summaries'; + list($response, $opts) = $this->_request('get', $url, $params, $options); + $obj = Util\Util::convertToStripeObject($response, $opts); + $obj->setLastResponse($response); + return $obj; } } diff --git a/htdocs/includes/stripe/lib/SubscriptionSchedule.php b/htdocs/includes/stripe/lib/SubscriptionSchedule.php new file mode 100644 index 00000000000..ac3686f1db8 --- /dev/null +++ b/htdocs/includes/stripe/lib/SubscriptionSchedule.php @@ -0,0 +1,111 @@ +instanceUrl() . '/cancel'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $opts + * + * @return SubscriptionSchedule The released subscription schedule. + */ + public function release($params = null, $opts = null) + { + $url = $this->instanceUrl() . '/release'; + list($response, $opts) = $this->_request('post', $url, $params, $opts); + $this->refreshFrom($response, $opts); + return $this; + } + + /** + * @param array|null $params + * @param array|string|null $options + * + * @return Collection The list of subscription schedule revisions. + */ + public function revisions($params = null, $options = null) + { + $url = $this->instanceUrl() . '/revisions'; + list($response, $opts) = $this->_request('get', $url, $params, $options); + $obj = Util\Util::convertToStripeObject($response, $opts); + $obj->setLastResponse($response); + return $obj; + } + + /** + * @param array|null $id The ID of the subscription schedule to which the person belongs. + * @param array|null $personId The ID of the person to retrieve. + * @param array|null $params + * @param array|string|null $opts + * + * @return Revision + */ + public static function retrieveRevision($id, $personId, $params = null, $opts = null) + { + return self::_retrieveNestedResource($id, static::PATH_REVISIONS, $personId, $params, $opts); + } + + /** + * @param array|null $id The ID of the subscription schedule on which to retrieve the persons. + * @param array|null $params + * @param array|string|null $opts + * + * @return Collection The list of revisions. + */ + public static function allRevisions($id, $params = null, $opts = null) + { + return self::_allNestedResources($id, static::PATH_REVISIONS, $params, $opts); + } +} diff --git a/htdocs/includes/stripe/lib/SubscriptionScheduleRevision.php b/htdocs/includes/stripe/lib/SubscriptionScheduleRevision.php new file mode 100644 index 00000000000..12177236530 --- /dev/null +++ b/htdocs/includes/stripe/lib/SubscriptionScheduleRevision.php @@ -0,0 +1,77 @@ +retrieveRevision('revision_id') instead."; + throw new Error\InvalidRequest($msg, null); + } + + /** + * @param array|string $_id + * @param array|string|null $_opts + * + * @throws \Stripe\Error\InvalidRequest + */ + public static function all($params = null, $opts = null) + { + $msg = "Subscription Schedule Revisions cannot be listed without a Subscription Schedule ID. " . + "List those using \$schedule->allRevisions('revision_id') instead."; + throw new Error\InvalidRequest($msg, null); + } +} diff --git a/htdocs/includes/stripe/lib/TaxId.php b/htdocs/includes/stripe/lib/TaxId.php new file mode 100644 index 00000000000..2993e2d1375 --- /dev/null +++ b/htdocs/includes/stripe/lib/TaxId.php @@ -0,0 +1,80 @@ +instanceUrl() . '/cancel'; + list($response, $opts) = $this->_request('post', $url, $params, $options); + $this->refreshFrom($response, $opts); + return $this; + } } diff --git a/htdocs/includes/stripe/lib/Transfer.php b/htdocs/includes/stripe/lib/Transfer.php index 87d8b79cbf3..dff2faa3329 100644 --- a/htdocs/includes/stripe/lib/Transfer.php +++ b/htdocs/includes/stripe/lib/Transfer.php @@ -12,6 +12,7 @@ namespace Stripe; * @property string $balance_transaction * @property int $created * @property string $currency + * @property string $description * @property string $destination * @property string $destination_payment * @property bool $livemode @@ -26,6 +27,9 @@ namespace Stripe; */ class Transfer extends ApiResource { + + const OBJECT_NAME = "transfer"; + use ApiOperations\All; use ApiOperations\Create; use ApiOperations\NestedResource; @@ -34,6 +38,15 @@ class Transfer extends ApiResource const PATH_REVERSALS = '/reversals'; + /** + * Possible string representations of the source type of the transfer. + * @link https://stripe.com/docs/api/transfers/object#transfer_object-source_type + */ + const SOURCE_TYPE_ALIPAY_ACCOUNT = 'alipay_account'; + const SOURCE_TYPE_BANK_ACCOUNT = 'bank_account'; + const SOURCE_TYPE_CARD = 'card'; + const SOURCE_TYPE_FINANCING = 'financing'; + /** * @return TransferReversal The created transfer reversal. */ @@ -57,7 +70,7 @@ class Transfer extends ApiResource } /** - * @param array|null $id The ID of the transfer on which to create the reversal. + * @param string|null $id The ID of the transfer on which to create the reversal. * @param array|null $params * @param array|string|null $opts * @@ -69,7 +82,7 @@ class Transfer extends ApiResource } /** - * @param array|null $id The ID of the transfer to which the reversal belongs. + * @param string|null $id The ID of the transfer to which the reversal belongs. * @param array|null $reversalId The ID of the reversal to retrieve. * @param array|null $params * @param array|string|null $opts @@ -82,7 +95,7 @@ class Transfer extends ApiResource } /** - * @param array|null $id The ID of the transfer to which the reversal belongs. + * @param string|null $id The ID of the transfer to which the reversal belongs. * @param array|null $reversalId The ID of the reversal to update. * @param array|null $params * @param array|string|null $opts @@ -95,11 +108,11 @@ class Transfer extends ApiResource } /** - * @param array|null $id The ID of the transfer on which to retrieve the reversals. + * @param string|null $id The ID of the transfer on which to retrieve the reversals. * @param array|null $params * @param array|string|null $opts * - * @return TransferReversal + * @return Collection The list of reversals. */ public static function allReversals($id, $params = null, $opts = null) { diff --git a/htdocs/includes/stripe/lib/TransferReversal.php b/htdocs/includes/stripe/lib/TransferReversal.php index cf2a3946d85..c945e5a9360 100644 --- a/htdocs/includes/stripe/lib/TransferReversal.php +++ b/htdocs/includes/stripe/lib/TransferReversal.php @@ -11,13 +11,18 @@ namespace Stripe; * @property string $balance_transaction * @property int $created * @property string $currency + * @property string $destination_payment_refund * @property StripeObject $metadata + * @property string $source_refund * @property string $transfer * * @package Stripe */ class TransferReversal extends ApiResource { + + const OBJECT_NAME = "transfer_reversal"; + use ApiOperations\Update { save as protected _save; } diff --git a/htdocs/includes/stripe/lib/UsageRecord.php b/htdocs/includes/stripe/lib/UsageRecord.php new file mode 100644 index 00000000000..a9e3a25e3e9 --- /dev/null +++ b/htdocs/includes/stripe/lib/UsageRecord.php @@ -0,0 +1,44 @@ +json, $opts); + $obj->setLastResponse($response); + return $obj; + } +} diff --git a/htdocs/includes/stripe/lib/UsageRecordSummary.php b/htdocs/includes/stripe/lib/UsageRecordSummary.php new file mode 100644 index 00000000000..b8f4aebe974 --- /dev/null +++ b/htdocs/includes/stripe/lib/UsageRecordSummary.php @@ -0,0 +1,22 @@ +container = array_map("strtolower", $initial_array); + } + + public function offsetSet($offset, $value) + { + $offset = static::maybeLowercase($offset); + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + public function offsetExists($offset) + { + $offset = static::maybeLowercase($offset); + return isset($this->container[$offset]); + } + + public function offsetUnset($offset) + { + $offset = static::maybeLowercase($offset); + unset($this->container[$offset]); + } + + public function offsetGet($offset) + { + $offset = static::maybeLowercase($offset); + return isset($this->container[$offset]) ? $this->container[$offset] : null; + } + + private static function maybeLowercase($v) + { + if (is_string($v)) { + return strtolower($v); + } else { + return $v; + } + } +} diff --git a/htdocs/includes/stripe/lib/Util/RequestOptions.php b/htdocs/includes/stripe/lib/Util/RequestOptions.php index a31f4d322d9..495236224d8 100644 --- a/htdocs/includes/stripe/lib/Util/RequestOptions.php +++ b/htdocs/includes/stripe/lib/Util/RequestOptions.php @@ -16,11 +16,13 @@ class RequestOptions public $headers; public $apiKey; + public $apiBase; - public function __construct($key = null, $headers = []) + public function __construct($key = null, $headers = [], $base = null) { $this->apiKey = $key; $this->headers = $headers; + $this->apiBase = $base; } /** @@ -36,6 +38,9 @@ class RequestOptions if ($other_options->apiKey === null) { $other_options->apiKey = $this->apiKey; } + if ($other_options->apiBase === null) { + $other_options->apiBase = $this->apiBase; + } $other_options->headers = array_merge($this->headers, $other_options->headers); return $other_options; } @@ -65,16 +70,17 @@ class RequestOptions } if (is_null($options)) { - return new RequestOptions(null, []); + return new RequestOptions(null, [], null); } if (is_string($options)) { - return new RequestOptions($options, []); + return new RequestOptions($options, [], null); } if (is_array($options)) { $headers = []; $key = null; + $base = null; if (array_key_exists('api_key', $options)) { $key = $options['api_key']; } @@ -87,7 +93,10 @@ class RequestOptions if (array_key_exists('stripe_version', $options)) { $headers['Stripe-Version'] = $options['stripe_version']; } - return new RequestOptions($key, $headers); + if (array_key_exists('api_base', $options)) { + $base = $options['api_base']; + } + return new RequestOptions($key, $headers, $base); } $message = 'The second argument to Stripe API method calls is an ' diff --git a/htdocs/includes/stripe/lib/Util/Util.php b/htdocs/includes/stripe/lib/Util/Util.php index 82fd337dd34..c9cfa9fcbd2 100644 --- a/htdocs/includes/stripe/lib/Util/Util.php +++ b/htdocs/includes/stripe/lib/Util/Util.php @@ -67,50 +67,84 @@ abstract class Util { $types = [ // data structures - 'list' => 'Stripe\\Collection', + \Stripe\Collection::OBJECT_NAME => 'Stripe\\Collection', // business objects - 'account' => 'Stripe\\Account', - 'alipay_account' => 'Stripe\\AlipayAccount', - 'apple_pay_domain' => 'Stripe\\ApplePayDomain', - 'application_fee' => 'Stripe\\ApplicationFee', - 'balance' => 'Stripe\\Balance', - 'balance_transaction' => 'Stripe\\BalanceTransaction', - 'bank_account' => 'Stripe\\BankAccount', - 'bitcoin_receiver' => 'Stripe\\BitcoinReceiver', - 'bitcoin_transaction' => 'Stripe\\BitcoinTransaction', - 'card' => 'Stripe\\Card', - 'charge' => 'Stripe\\Charge', - 'country_spec' => 'Stripe\\CountrySpec', - 'coupon' => 'Stripe\\Coupon', - 'customer' => 'Stripe\\Customer', - 'dispute' => 'Stripe\\Dispute', - 'ephemeral_key' => 'Stripe\\EphemeralKey', - 'event' => 'Stripe\\Event', - 'exchange_rate' => 'Stripe\\ExchangeRate', - 'fee_refund' => 'Stripe\\ApplicationFeeRefund', - 'file_upload' => 'Stripe\\FileUpload', - 'invoice' => 'Stripe\\Invoice', - 'invoiceitem' => 'Stripe\\InvoiceItem', - 'login_link' => 'Stripe\\LoginLink', - 'order' => 'Stripe\\Order', - 'order_return' => 'Stripe\\OrderReturn', - 'payout' => 'Stripe\\Payout', - 'plan' => 'Stripe\\Plan', - 'product' => 'Stripe\\Product', - 'recipient' => 'Stripe\\Recipient', - 'recipient_transfer' => 'Stripe\\RecipientTransfer', - 'refund' => 'Stripe\\Refund', - 'sku' => 'Stripe\\SKU', - 'source' => 'Stripe\\Source', - 'source_transaction' => 'Stripe\\SourceTransaction', - 'subscription' => 'Stripe\\Subscription', - 'subscription_item' => 'Stripe\\SubscriptionItem', - 'three_d_secure' => 'Stripe\\ThreeDSecure', - 'token' => 'Stripe\\Token', - 'topup' => 'Stripe\\Topup', - 'transfer' => 'Stripe\\Transfer', - 'transfer_reversal' => 'Stripe\\TransferReversal', + \Stripe\Account::OBJECT_NAME => 'Stripe\\Account', + \Stripe\AccountLink::OBJECT_NAME => 'Stripe\\AccountLink', + \Stripe\AlipayAccount::OBJECT_NAME => 'Stripe\\AlipayAccount', + \Stripe\ApplePayDomain::OBJECT_NAME => 'Stripe\\ApplePayDomain', + \Stripe\ApplicationFee::OBJECT_NAME => 'Stripe\\ApplicationFee', + \Stripe\Balance::OBJECT_NAME => 'Stripe\\Balance', + \Stripe\BalanceTransaction::OBJECT_NAME => 'Stripe\\BalanceTransaction', + \Stripe\BankAccount::OBJECT_NAME => 'Stripe\\BankAccount', + \Stripe\BitcoinReceiver::OBJECT_NAME => 'Stripe\\BitcoinReceiver', + \Stripe\BitcoinTransaction::OBJECT_NAME => 'Stripe\\BitcoinTransaction', + \Stripe\Card::OBJECT_NAME => 'Stripe\\Card', + \Stripe\Charge::OBJECT_NAME => 'Stripe\\Charge', + \Stripe\Checkout\Session::OBJECT_NAME => 'Stripe\\Checkout\\Session', + \Stripe\CountrySpec::OBJECT_NAME => 'Stripe\\CountrySpec', + \Stripe\Coupon::OBJECT_NAME => 'Stripe\\Coupon', + \Stripe\CreditNote::OBJECT_NAME => 'Stripe\\CreditNote', + \Stripe\Customer::OBJECT_NAME => 'Stripe\\Customer', + \Stripe\Discount::OBJECT_NAME => 'Stripe\\Discount', + \Stripe\Dispute::OBJECT_NAME => 'Stripe\\Dispute', + \Stripe\EphemeralKey::OBJECT_NAME => 'Stripe\\EphemeralKey', + \Stripe\Event::OBJECT_NAME => 'Stripe\\Event', + \Stripe\ExchangeRate::OBJECT_NAME => 'Stripe\\ExchangeRate', + \Stripe\ApplicationFeeRefund::OBJECT_NAME => 'Stripe\\ApplicationFeeRefund', + \Stripe\File::OBJECT_NAME => 'Stripe\\File', + \Stripe\File::OBJECT_NAME_ALT => 'Stripe\\File', + \Stripe\FileLink::OBJECT_NAME => 'Stripe\\FileLink', + \Stripe\Invoice::OBJECT_NAME => 'Stripe\\Invoice', + \Stripe\InvoiceItem::OBJECT_NAME => 'Stripe\\InvoiceItem', + \Stripe\InvoiceLineItem::OBJECT_NAME => 'Stripe\\InvoiceLineItem', + \Stripe\IssuerFraudRecord::OBJECT_NAME => 'Stripe\\IssuerFraudRecord', + \Stripe\Issuing\Authorization::OBJECT_NAME => 'Stripe\\Issuing\\Authorization', + \Stripe\Issuing\Card::OBJECT_NAME => 'Stripe\\Issuing\\Card', + \Stripe\Issuing\CardDetails::OBJECT_NAME => 'Stripe\\Issuing\\CardDetails', + \Stripe\Issuing\Cardholder::OBJECT_NAME => 'Stripe\\Issuing\\Cardholder', + \Stripe\Issuing\Dispute::OBJECT_NAME => 'Stripe\\Issuing\\Dispute', + \Stripe\Issuing\Transaction::OBJECT_NAME => 'Stripe\\Issuing\\Transaction', + \Stripe\LoginLink::OBJECT_NAME => 'Stripe\\LoginLink', + \Stripe\Order::OBJECT_NAME => 'Stripe\\Order', + \Stripe\OrderItem::OBJECT_NAME => 'Stripe\\OrderItem', + \Stripe\OrderReturn::OBJECT_NAME => 'Stripe\\OrderReturn', + \Stripe\PaymentIntent::OBJECT_NAME => 'Stripe\\PaymentIntent', + \Stripe\PaymentMethod::OBJECT_NAME => 'Stripe\\PaymentMethod', + \Stripe\Payout::OBJECT_NAME => 'Stripe\\Payout', + \Stripe\Person::OBJECT_NAME => 'Stripe\\Person', + \Stripe\Plan::OBJECT_NAME => 'Stripe\\Plan', + \Stripe\Product::OBJECT_NAME => 'Stripe\\Product', + \Stripe\Radar\ValueList::OBJECT_NAME => 'Stripe\\Radar\\ValueList', + \Stripe\Radar\ValueListItem::OBJECT_NAME => 'Stripe\\Radar\\ValueListItem', + \Stripe\Recipient::OBJECT_NAME => 'Stripe\\Recipient', + \Stripe\RecipientTransfer::OBJECT_NAME => 'Stripe\\RecipientTransfer', + \Stripe\Refund::OBJECT_NAME => 'Stripe\\Refund', + \Stripe\Reporting\ReportRun::OBJECT_NAME => 'Stripe\\Reporting\\ReportRun', + \Stripe\Reporting\ReportType::OBJECT_NAME => 'Stripe\\Reporting\\ReportType', + \Stripe\Review::OBJECT_NAME => 'Stripe\\Review', + \Stripe\SKU::OBJECT_NAME => 'Stripe\\SKU', + \Stripe\Sigma\ScheduledQueryRun::OBJECT_NAME => 'Stripe\\Sigma\\ScheduledQueryRun', + \Stripe\Source::OBJECT_NAME => 'Stripe\\Source', + \Stripe\SourceTransaction::OBJECT_NAME => 'Stripe\\SourceTransaction', + \Stripe\Subscription::OBJECT_NAME => 'Stripe\\Subscription', + \Stripe\SubscriptionItem::OBJECT_NAME => 'Stripe\\SubscriptionItem', + \Stripe\SubscriptionSchedule::OBJECT_NAME => 'Stripe\\SubscriptionSchedule', + \Stripe\SubscriptionScheduleRevision::OBJECT_NAME => 'Stripe\\SubscriptionScheduleRevision', + \Stripe\TaxId::OBJECT_NAME => 'Stripe\\TaxId', + \Stripe\TaxRate::OBJECT_NAME => 'Stripe\\TaxRate', + \Stripe\ThreeDSecure::OBJECT_NAME => 'Stripe\\ThreeDSecure', + \Stripe\Terminal\ConnectionToken::OBJECT_NAME => 'Stripe\\Terminal\\ConnectionToken', + \Stripe\Terminal\Location::OBJECT_NAME => 'Stripe\\Terminal\\Location', + \Stripe\Terminal\Reader::OBJECT_NAME => 'Stripe\\Terminal\\Reader', + \Stripe\Token::OBJECT_NAME => 'Stripe\\Token', + \Stripe\Topup::OBJECT_NAME => 'Stripe\\Topup', + \Stripe\Transfer::OBJECT_NAME => 'Stripe\\Transfer', + \Stripe\TransferReversal::OBJECT_NAME => 'Stripe\\TransferReversal', + \Stripe\UsageRecord::OBJECT_NAME => 'Stripe\\UsageRecord', + \Stripe\UsageRecordSummary::OBJECT_NAME => 'Stripe\\UsageRecordSummary', + \Stripe\WebhookEndpoint::OBJECT_NAME => 'Stripe\\WebhookEndpoint', ]; if (self::isList($resp)) { $mapped = []; @@ -186,42 +220,117 @@ abstract class Util } /** - * @param array $arr A map of param keys to values. - * @param string|null $prefix + * Recursively goes through an array of parameters. If a parameter is an instance of + * ApiResource, then it is replaced by the resource's ID. + * Also clears out null values. * - * @return string A querystring, essentially. + * @param mixed $h + * @return mixed */ - public static function urlEncode($arr, $prefix = null) + public static function objectsToIds($h) { - if (!is_array($arr)) { - return $arr; + if ($h instanceof \Stripe\ApiResource) { + return $h->id; + } elseif (static::isList($h)) { + $results = []; + foreach ($h as $v) { + array_push($results, static::objectsToIds($v)); + } + return $results; + } elseif (is_array($h)) { + $results = []; + foreach ($h as $k => $v) { + if (is_null($v)) { + continue; + } + $results[$k] = static::objectsToIds($v); + } + return $results; + } else { + return $h; } + } - $r = []; - foreach ($arr as $k => $v) { - if (is_null($v)) { - continue; - } + /** + * @param array $params + * + * @return string + */ + public static function encodeParameters($params) + { + $flattenedParams = self::flattenParams($params); + $pieces = []; + foreach ($flattenedParams as $param) { + list($k, $v) = $param; + array_push($pieces, self::urlEncode($k) . '=' . self::urlEncode($v)); + } + return implode('&', $pieces); + } - if ($prefix) { - if ($k !== null && (!is_int($k) || is_array($v))) { - $k = $prefix."[".$k."]"; - } else { - $k = $prefix."[]"; - } - } + /** + * @param array $params + * @param string|null $parentKey + * + * @return array + */ + public static function flattenParams($params, $parentKey = null) + { + $result = []; - if (is_array($v)) { - $enc = self::urlEncode($v, $k); - if ($enc) { - $r[] = $enc; - } + foreach ($params as $key => $value) { + $calculatedKey = $parentKey ? "{$parentKey}[{$key}]" : $key; + + if (self::isList($value)) { + $result = array_merge($result, self::flattenParamsList($value, $calculatedKey)); + } elseif (is_array($value)) { + $result = array_merge($result, self::flattenParams($value, $calculatedKey)); } else { - $r[] = urlencode($k)."=".urlencode($v); + array_push($result, [$calculatedKey, $value]); } } - return implode("&", $r); + return $result; + } + + /** + * @param array $value + * @param string $calculatedKey + * + * @return array + */ + public static function flattenParamsList($value, $calculatedKey) + { + $result = []; + + foreach ($value as $i => $elem) { + if (self::isList($elem)) { + $result = array_merge($result, self::flattenParamsList($elem, $calculatedKey)); + } elseif (is_array($elem)) { + $result = array_merge($result, self::flattenParams($elem, "{$calculatedKey}[{$i}]")); + } else { + array_push($result, ["{$calculatedKey}[{$i}]", $elem]); + } + } + + return $result; + } + + /** + * @param string $key A string to URL-encode. + * + * @return string The URL-encoded string. + */ + public static function urlEncode($key) + { + $s = urlencode($key); + + // Don't use strict form encoding by changing the square bracket control + // characters back to their literals. This is fine by the server, and + // makes these parameter strings easier to read. + $s = str_replace('%5B', '[', $s); + $s = str_replace('%5D', ']', $s); + + return $s; } public static function normalizeId($id) @@ -235,4 +344,14 @@ abstract class Util } return [$id, $params]; } + + /** + * Returns UNIX timestamp in milliseconds + * + * @return integer current time in millis + */ + public static function currentTimeMillis() + { + return (int) round(microtime(true) * 1000); + } } diff --git a/htdocs/includes/stripe/lib/WebhookEndpoint.php b/htdocs/includes/stripe/lib/WebhookEndpoint.php new file mode 100644 index 00000000000..27ecacf690c --- /dev/null +++ b/htdocs/includes/stripe/lib/WebhookEndpoint.php @@ -0,0 +1,29 @@ + - - - tests - - - - - lib - - - - - - diff --git a/htdocs/includes/stripe/phpunit.xml b/htdocs/includes/stripe/phpunit.xml deleted file mode 100644 index 7a73276d0b1..00000000000 --- a/htdocs/includes/stripe/phpunit.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - tests - - - - - lib - - - - - - diff --git a/htdocs/includes/stripe/tests/Stripe/AccountTest.php b/htdocs/includes/stripe/tests/Stripe/AccountTest.php deleted file mode 100644 index 4c621690dcf..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/AccountTest.php +++ /dev/null @@ -1,365 +0,0 @@ -expectsRequest( - 'get', - '/v1/accounts' - ); - $resources = Account::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Account", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/accounts/' . self::TEST_RESOURCE_ID - ); - $resource = Account::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsRetrievableWithoutId() - { - $this->expectsRequest( - 'get', - '/v1/account' - ); - $resource = Account::retrieve(); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/accounts' - ); - $resource = Account::create(["type" => "custom"]); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsSaveable() - { - $resource = Account::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/accounts/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/accounts/' . self::TEST_RESOURCE_ID - ); - $resource = Account::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsDeletable() - { - $resource = Account::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/accounts/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Account", $resource); - } - - public function testIsRejectable() - { - $account = Account::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/accounts/' . $account->id . '/reject' - ); - $resource = $account->reject(["reason" => "fraud"]); - $this->assertInstanceOf("Stripe\\Account", $resource); - $this->assertSame($resource, $account); - } - - public function testIsDeauthorizable() - { - $resource = Account::retrieve(self::TEST_RESOURCE_ID); - $this->stubRequest( - 'post', - '/oauth/deauthorize', - [ - 'client_id' => Stripe::getClientId(), - 'stripe_user_id' => $resource->id, - ], - null, - false, - [ - 'stripe_user_id' => $resource->id, - ], - 200, - Stripe::$connectBase - ); - $resource->deauthorize(); - } - - public function testCanCreateExternalAccount() - { - $this->expectsRequest( - 'post', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/external_accounts' - ); - $resource = Account::createExternalAccount(self::TEST_RESOURCE_ID, [ - "external_account" => "btok_123", - ]); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanRetrieveExternalAccount() - { - $this->expectsRequest( - 'get', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/external_accounts/' . self::TEST_EXTERNALACCOUNT_ID - ); - $resource = Account::retrieveExternalAccount(self::TEST_RESOURCE_ID, self::TEST_EXTERNALACCOUNT_ID); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanUpdateExternalAccount() - { - $this->expectsRequest( - 'post', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/external_accounts/' . self::TEST_EXTERNALACCOUNT_ID - ); - $resource = Account::updateExternalAccount(self::TEST_RESOURCE_ID, self::TEST_EXTERNALACCOUNT_ID, [ - "name" => "name", - ]); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanDeleteExternalAccount() - { - $this->expectsRequest( - 'delete', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/external_accounts/' . self::TEST_EXTERNALACCOUNT_ID - ); - $resource = Account::deleteExternalAccount(self::TEST_RESOURCE_ID, self::TEST_EXTERNALACCOUNT_ID); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanListExternalAccounts() - { - $this->expectsRequest( - 'get', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/external_accounts' - ); - $resources = Account::allExternalAccounts(self::TEST_RESOURCE_ID); - $this->assertTrue(is_array($resources->data)); - } - - public function testCanCreateLoginLink() - { - $this->expectsRequest( - 'post', - '/v1/accounts/' . self::TEST_RESOURCE_ID . '/login_links' - ); - $resource = Account::createLoginLink(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\LoginLink", $resource); - } - - public function testSerializeNewAdditionalOwners() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - 'legal_entity' => StripeObject::constructFrom([]), - ], null); - $obj->legal_entity->additional_owners = [ - ['first_name' => 'Joe'], - ['first_name' => 'Jane'], - ]; - - $expected = [ - 'legal_entity' => [ - 'additional_owners' => [ - 0 => ['first_name' => 'Joe'], - 1 => ['first_name' => 'Jane'], - ], - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializePartiallyChangedAdditionalOwners() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - 'legal_entity' => [ - 'additional_owners' => [ - StripeObject::constructFrom(['first_name' => 'Joe']), - StripeObject::constructFrom(['first_name' => 'Jane']), - ], - ], - ], null); - $obj->legal_entity->additional_owners[1]->first_name = 'Stripe'; - - $expected = [ - 'legal_entity' => [ - 'additional_owners' => [ - 1 => ['first_name' => 'Stripe'], - ], - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeUnchangedAdditionalOwners() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - 'legal_entity' => [ - 'additional_owners' => [ - StripeObject::constructFrom(['first_name' => 'Joe']), - StripeObject::constructFrom(['first_name' => 'Jane']), - ], - ], - ], null); - - $expected = [ - 'legal_entity' => [ - 'additional_owners' => [], - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeUnsetAdditionalOwners() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - 'legal_entity' => [ - 'additional_owners' => [ - StripeObject::constructFrom(['first_name' => 'Joe']), - StripeObject::constructFrom(['first_name' => 'Jane']), - ], - ], - ], null); - $obj->legal_entity->additional_owners = null; - - // Note that the empty string that we send for this one has a special - // meaning for the server, which interprets it as an array unset. - $expected = [ - 'legal_entity' => [ - 'additional_owners' => '', - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSerializeAdditionalOwnersDeletedItem() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - 'legal_entity' => [ - 'additional_owners' => [ - StripeObject::constructFrom(['first_name' => 'Joe']), - StripeObject::constructFrom(['first_name' => 'Jane']), - ], - ], - ], null); - unset($obj->legal_entity->additional_owners[0]); - - $obj->serializeParameters(); - } - - public function testSerializeExternalAccountString() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - ], null); - $obj->external_account = 'btok_123'; - - $expected = [ - 'external_account' => 'btok_123', - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeExternalAccountHash() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - ], null); - $obj->external_account = [ - 'object' => 'bank_account', - 'routing_number' => '110000000', - 'account_number' => '000123456789', - 'country' => 'US', - 'currency' => 'usd', - ]; - - $expected = [ - 'external_account' => [ - 'object' => 'bank_account', - 'routing_number' => '110000000', - 'account_number' => '000123456789', - 'country' => 'US', - 'currency' => 'usd', - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeBankAccountString() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - ], null); - $obj->bank_account = 'btok_123'; - - $expected = [ - 'bank_account' => 'btok_123', - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeBankAccountHash() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'account', - ], null); - $obj->bank_account = [ - 'object' => 'bank_account', - 'routing_number' => '110000000', - 'account_number' => '000123456789', - 'country' => 'US', - 'currency' => 'usd', - ]; - - $expected = [ - 'bank_account' => [ - 'object' => 'bank_account', - 'routing_number' => '110000000', - 'account_number' => '000123456789', - 'country' => 'US', - 'currency' => 'usd', - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/AlipayAccountTest.php b/htdocs/includes/stripe/tests/Stripe/AlipayAccountTest.php deleted file mode 100644 index 7159f5444df..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/AlipayAccountTest.php +++ /dev/null @@ -1,76 +0,0 @@ - self::TEST_RESOURCE_ID, - 'object' => 'card', - 'metadata' => [], - ]; - return AlipayAccount::constructFrom( - array_merge($params, $base), - new Util\RequestOptions() - ); - } - - public function testHasCorrectUrlForCustomer() - { - $resource = $this->createFixture(['customer' => 'cus_123']); - $this->assertSame( - "/v1/customers/cus_123/sources/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyRetrievable() - { - AlipayAccount::retrieve(self::TEST_RESOURCE_ID); - } - - public function testIsSaveable() - { - $resource = $this->createFixture(); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->save(); - $this->assertSame("Stripe\\AlipayAccount", get_class($resource)); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyUpdatable() - { - AlipayAccount::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - } - - public function testIsDeletable() - { - $resource = $this->createFixture(); - $this->expectsRequest( - 'delete', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->delete(); - $this->assertSame("Stripe\\AlipayAccount", get_class($resource)); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ApiRequestorTest.php b/htdocs/includes/stripe/tests/Stripe/ApiRequestorTest.php deleted file mode 100644 index 6fb8229c57d..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ApiRequestorTest.php +++ /dev/null @@ -1,572 +0,0 @@ -getMethod('_encodeObjects'); - $method->setAccessible(true); - - $a = ['customer' => new Customer('abcd')]; - $enc = $method->invoke(null, $a); - $this->assertSame($enc, ['customer' => 'abcd']); - - // Preserves UTF-8 - $v = ['customer' => "☃"]; - $enc = $method->invoke(null, $v); - $this->assertSame($enc, $v); - - // Encodes latin-1 -> UTF-8 - $v = ['customer' => "\xe9"]; - $enc = $method->invoke(null, $v); - $this->assertSame($enc, ['customer' => "\xc3\xa9"]); - - // Encodes booleans - $v = true; - $enc = $method->invoke(null, $v); - $this->assertSame('true', $enc); - - $v = false; - $enc = $method->invoke(null, $v); - $this->assertSame('false', $enc); - } - - public function testHttpClientInjection() - { - $reflector = new \ReflectionClass('Stripe\\ApiRequestor'); - $method = $reflector->getMethod('httpClient'); - $method->setAccessible(true); - - $curl = new CurlClient(); - $curl->setTimeout(10); - ApiRequestor::setHttpClient($curl); - - $injectedCurl = $method->invoke(new ApiRequestor()); - $this->assertSame($injectedCurl, $curl); - } - - public function testDefaultHeaders() - { - $reflector = new \ReflectionClass('Stripe\\ApiRequestor'); - $method = $reflector->getMethod('_defaultHeaders'); - $method->setAccessible(true); - - // no way to stub static methods with PHPUnit 4.x :( - Stripe::setAppInfo('MyTestApp', '1.2.34', 'https://mytestapp.example'); - $apiKey = 'sk_test_notarealkey'; - $clientInfo = ['httplib' => 'testlib 0.1.2']; - - $headers = $method->invoke(null, $apiKey, $clientInfo); - - $ua = json_decode($headers['X-Stripe-Client-User-Agent']); - $this->assertSame($ua->application->name, 'MyTestApp'); - $this->assertSame($ua->application->version, '1.2.34'); - $this->assertSame($ua->application->url, 'https://mytestapp.example'); - - $this->assertSame($ua->httplib, 'testlib 0.1.2'); - - $this->assertSame( - $headers['User-Agent'], - 'Stripe/v1 PhpBindings/' . Stripe::VERSION . ' MyTestApp/1.2.34 (https://mytestapp.example)' - ); - - $this->assertSame($headers['Authorization'], 'Bearer ' . $apiKey); - } - - /** - * @expectedException \Stripe\Error\Authentication - * @expectedExceptionMessageRegExp #No API key provided# - */ - public function testRaisesAuthenticationErrorWhenNoApiKey() - { - Stripe::setApiKey(null); - Charge::create(); - } - - public function testRaisesInvalidRequestErrorOn400() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - null, - false, - [ - 'error' => [ - 'type' => 'invalid_request_error', - 'message' => 'Missing id', - 'param' => 'id', - ], - ], - 400 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\InvalidRequest $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('Missing id', $e->getMessage()); - $this->assertSame('id', $e->getStripeParam()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesIdempotencyErrorOn400AndTypeIdempotencyError() - { - $this->stubRequest( - 'POST', - '/v1/charges', - array(), - null, - false, - array( - 'error' => array( - 'type' => 'idempotency_error', - 'message' => "Keys for idempotent requests can only be used with the same parameters they were first used with. Try using a key other than 'abc' if you meant to execute a different request.", - ), - ), - 400 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\Idempotency $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame("Keys for idempotent requests can only be used with the same parameters they were first used with. Try using a key other than 'abc' if you meant to execute a different request.", $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesAuthenticationErrorOn401() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - null, - false, - [ - 'error' => [ - 'type' => 'invalid_request_error', - 'message' => 'You did not provide an API key.', - ], - ], - 401 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\Authentication $e) { - $this->assertSame(401, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('You did not provide an API key.', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesCardErrorOn402() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - null, - false, - [ - 'error' => [ - 'type' => 'card_error', - 'message' => 'Your card was declined.', - 'code' => 'card_declined', - 'decline_code' => 'generic_decline', - 'charge' => 'ch_declined_charge', - 'param' => 'exp_month', - ], - ], - 402 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\Card $e) { - $this->assertSame(402, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('Your card was declined.', $e->getMessage()); - $this->assertSame('card_declined', $e->getStripeCode()); - $this->assertSame('generic_decline', $e->getDeclineCode()); - $this->assertSame('exp_month', $e->getStripeParam()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesPermissionErrorOn403() - { - $this->stubRequest( - 'GET', - '/v1/accounts/foo', - [], - null, - false, - [ - 'error' => [ - 'type' => 'invalid_request_error', - 'message' => "The provided key 'sk_test_********************1234' does not have access to account 'foo' (or that account does not exist). Application access may have been revoked.", - ], - ], - 403 - ); - - try { - Account::retrieve('foo'); - $this->fail("Did not raise error"); - } catch (Error\Permission $e) { - $this->assertSame(403, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame("The provided key 'sk_test_********************1234' does not have access to account 'foo' (or that account does not exist). Application access may have been revoked.", $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesInvalidRequestErrorOn404() - { - $this->stubRequest( - 'GET', - '/v1/charges/foo', - [], - null, - false, - [ - 'error' => [ - 'type' => 'invalid_request_error', - 'message' => 'No such charge: foo', - 'param' => 'id', - ], - ], - 404 - ); - - try { - Charge::retrieve('foo'); - $this->fail("Did not raise error"); - } catch (Error\InvalidRequest $e) { - $this->assertSame(404, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('No such charge: foo', $e->getMessage()); - $this->assertSame('id', $e->getStripeParam()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesRateLimitErrorOn429() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - null, - false, - [ - 'error' => [ - 'message' => 'Too many requests', - ], - ], - 429 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\RateLimit $e) { - $this->assertSame(429, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('Too many requests', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesRateLimitErrorOn400AndCodeRateLimit() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - null, - false, - [ - 'error' => [ - 'code' => 'rate_limit', - 'message' => 'Too many requests', - ], - ], - 400 - ); - - try { - Charge::create(); - $this->fail("Did not raise error"); - } catch (Error\RateLimit $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertTrue(is_array($e->getJsonBody())); - $this->assertSame('Too many requests', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthInvalidRequestError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'invalid_request', - 'error_description' => 'No grant type specified', - ], - 400, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\InvalidRequest $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertSame('invalid_request', $e->getErrorCode()); - $this->assertSame('No grant type specified', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthInvalidClientError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'invalid_client', - 'error_description' => 'No authentication was provided. Send your secret API key using the Authorization header, or as a client_secret POST parameter.', - ], - 401, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\InvalidClient $e) { - $this->assertSame(401, $e->getHttpStatus()); - $this->assertSame('invalid_client', $e->getErrorCode()); - $this->assertSame('No authentication was provided. Send your secret API key using the Authorization header, or as a client_secret POST parameter.', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthInvalidGrantError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'invalid_grant', - 'error_description' => 'This authorization code has already been used. All tokens issued with this code have been revoked.', - ], - 400, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\InvalidGrant $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertSame('invalid_grant', $e->getErrorCode()); - $this->assertSame('This authorization code has already been used. All tokens issued with this code have been revoked.', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthInvalidScopeError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'invalid_scope', - 'error_description' => 'Invalid scope provided: invalid_scope.', - ], - 400, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\InvalidScope $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertSame('invalid_scope', $e->getErrorCode()); - $this->assertSame('Invalid scope provided: invalid_scope.', $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthUnsupportedGrantTypeError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'unsupported_grant_type', - ], - 400, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\UnsupportedGrantType $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertSame('unsupported_grant_type', $e->getErrorCode()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testRaisesOAuthUnsupportedResponseTypeError() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [], - null, - false, - [ - 'error' => 'unsupported_response_type', - 'error_description' => "Only 'code' response_type is supported, but 'unsupported_response_type' was provided", - ], - 400, - Stripe::$connectBase - ); - - try { - OAuth::token(); - $this->fail("Did not raise error"); - } catch (Error\OAuth\UnsupportedResponseType $e) { - $this->assertSame(400, $e->getHttpStatus()); - $this->assertSame('unsupported_response_type', $e->getErrorCode()); - $this->assertSame("Only 'code' response_type is supported, but 'unsupported_response_type' was provided", $e->getMessage()); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testHeaderStripeVersionGlobal() - { - Stripe::setApiVersion('2222-22-22'); - $this->stubRequest( - 'POST', - '/v1/charges', - [], - [ - 'Stripe-Version: 2222-22-22', - ], - false, - [ - 'id' => 'ch_123', - 'object' => 'charge', - ] - ); - Charge::create(); - } - - public function testHeaderStripeVersionRequestOptions() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - [ - 'Stripe-Version: 2222-22-22', - ], - false, - [ - 'id' => 'ch_123', - 'object' => 'charge', - ] - ); - Charge::create([], ['stripe_version' => '2222-22-22']); - } - - public function testHeaderStripeAccountGlobal() - { - Stripe::setAccountId('acct_123'); - $this->stubRequest( - 'POST', - '/v1/charges', - [], - [ - 'Stripe-Account: acct_123', - ], - false, - [ - 'id' => 'ch_123', - 'object' => 'charge', - ] - ); - Charge::create(); - } - - public function testHeaderStripeAccountRequestOptions() - { - $this->stubRequest( - 'POST', - '/v1/charges', - [], - [ - 'Stripe-Account: acct_123', - ], - false, - [ - 'id' => 'ch_123', - 'object' => 'charge', - ] - ); - Charge::create([], ['stripe_account' => 'acct_123']); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ApplePayDomainTest.php b/htdocs/includes/stripe/tests/Stripe/ApplePayDomainTest.php deleted file mode 100644 index d033f55cbb0..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ApplePayDomainTest.php +++ /dev/null @@ -1,52 +0,0 @@ -expectsRequest( - 'get', - '/v1/apple_pay/domains' - ); - $resources = ApplePayDomain::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\ApplePayDomain", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/apple_pay/domains/' . self::TEST_RESOURCE_ID - ); - $resource = ApplePayDomain::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\ApplePayDomain", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/apple_pay/domains' - ); - $resource = ApplePayDomain::create([ - "domain_name" => "domain", - ]); - $this->assertInstanceOf("Stripe\\ApplePayDomain", $resource); - } - - public function testIsDeletable() - { - $resource = ApplePayDomain::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/apple_pay/domains/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\ApplePayDomain", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ApplicationFeeRefundTest.php b/htdocs/includes/stripe/tests/Stripe/ApplicationFeeRefundTest.php deleted file mode 100644 index 9af059ff7f3..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ApplicationFeeRefundTest.php +++ /dev/null @@ -1,21 +0,0 @@ -metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/application_fees/' . $resource->fee . '/refunds/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\ApplicationFeeRefund", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ApplicationFeeTest.php b/htdocs/includes/stripe/tests/Stripe/ApplicationFeeTest.php deleted file mode 100644 index 66e007ff3d2..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ApplicationFeeTest.php +++ /dev/null @@ -1,83 +0,0 @@ -expectsRequest( - 'get', - '/v1/application_fees' - ); - $resources = ApplicationFee::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\ApplicationFee", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/application_fees/' . self::TEST_RESOURCE_ID - ); - $resource = ApplicationFee::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\ApplicationFee", $resource); - } - - public function testIsRefundable() - { - $fee = ApplicationFee::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/application_fees/' . $fee->id . '/refunds' - ); - $resource = $fee->refund(); - $this->assertInstanceOf("Stripe\\ApplicationFee", $resource); - $this->assertSame($resource, $fee); - } - - public function testCanCreateRefund() - { - $this->expectsRequest( - 'post', - '/v1/application_fees/' . self::TEST_RESOURCE_ID . '/refunds' - ); - $resource = ApplicationFee::createRefund(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\ApplicationFeeRefund", $resource); - } - - public function testCanRetrieveRefund() - { - $this->expectsRequest( - 'get', - '/v1/application_fees/' . self::TEST_RESOURCE_ID . '/refunds/' . self::TEST_FEEREFUND_ID - ); - $resource = ApplicationFee::retrieveRefund(self::TEST_RESOURCE_ID, self::TEST_FEEREFUND_ID); - $this->assertInstanceOf("Stripe\\ApplicationFeeRefund", $resource); - } - - public function testCanUpdateRefund() - { - $this->expectsRequest( - 'post', - '/v1/application_fees/' . self::TEST_RESOURCE_ID . '/refunds/' . self::TEST_FEEREFUND_ID - ); - $resource = ApplicationFee::updateRefund(self::TEST_RESOURCE_ID, self::TEST_FEEREFUND_ID); - $this->assertInstanceOf("Stripe\\ApplicationFeeRefund", $resource); - } - - public function testCanListRefunds() - { - $this->expectsRequest( - 'get', - '/v1/application_fees/' . self::TEST_RESOURCE_ID . '/refunds' - ); - $resources = ApplicationFee::allRefunds(self::TEST_RESOURCE_ID); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\ApplicationFeeRefund", $resources->data[0]); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/BalanceTest.php b/htdocs/includes/stripe/tests/Stripe/BalanceTest.php deleted file mode 100644 index ccbdbdfb747..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/BalanceTest.php +++ /dev/null @@ -1,16 +0,0 @@ -expectsRequest( - 'get', - '/v1/balance' - ); - $resource = Balance::retrieve(); - $this->assertInstanceOf("Stripe\\Balance", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/BalanceTransactionTest.php b/htdocs/includes/stripe/tests/Stripe/BalanceTransactionTest.php deleted file mode 100644 index 8785e859113..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/BalanceTransactionTest.php +++ /dev/null @@ -1,29 +0,0 @@ -expectsRequest( - 'get', - '/v1/balance/history' - ); - $resources = BalanceTransaction::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\BalanceTransaction", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/balance/history/' . self::TEST_RESOURCE_ID - ); - $resource = BalanceTransaction::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\BalanceTransaction", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/BankAccountTest.php b/htdocs/includes/stripe/tests/Stripe/BankAccountTest.php deleted file mode 100644 index ab1dff9d5a8..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/BankAccountTest.php +++ /dev/null @@ -1,99 +0,0 @@ - self::TEST_RESOURCE_ID, - 'object' => 'bank_account', - 'metadata' => [], - ]; - return BankAccount::constructFrom( - array_merge($params, $base), - new Util\RequestOptions() - ); - } - - public function testHasCorrectUrlForCustomer() - { - $resource = $this->createFixture(['customer' => 'cus_123']); - $this->assertSame( - "/v1/customers/cus_123/sources/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - public function testHasCorrectUrlForAccount() - { - $resource = $this->createFixture(['account' => 'acct_123']); - $this->assertSame( - "/v1/accounts/acct_123/external_accounts/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyRetrievable() - { - BankAccount::retrieve(self::TEST_RESOURCE_ID); - } - - public function testIsSaveable() - { - $resource = $this->createFixture(); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->save(); - $this->assertSame("Stripe\\BankAccount", get_class($resource)); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyUpdatable() - { - BankAccount::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - } - - public function testIsDeletable() - { - $resource = $this->createFixture(); - $this->expectsRequest( - 'delete', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->delete(); - $this->assertSame("Stripe\\BankAccount", get_class($resource)); - } - - public function testIsVerifiable() - { - $resource = $this->createFixture(); - $this->expectsRequest( - 'post', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID . "/verify", - [ - "amounts" => [1, 2] - ] - ); - $resource->verify(["amounts" => [1, 2]]); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/BitcoinReceiverTest.php b/htdocs/includes/stripe/tests/Stripe/BitcoinReceiverTest.php deleted file mode 100644 index cea999fc4f2..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/BitcoinReceiverTest.php +++ /dev/null @@ -1,62 +0,0 @@ - self::TEST_RESOURCE_ID, - 'object' => 'bitcoin_receiver', - 'metadata' => [], - ]; - return BitcoinReceiver::constructFrom( - array_merge($params, $base), - new Util\RequestOptions() - ); - } - - public function testHasCorrectStandaloneUrl() - { - $resource = $this->createFixture(); - $this->assertSame( - "/v1/bitcoin/receivers/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - public function testHasCorrectUrlForCustomer() - { - $resource = $this->createFixture(['customer' => 'cus_123']); - $this->assertSame( - "/v1/customers/cus_123/sources/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - public function testIsListable() - { - $this->expectsRequest( - 'get', - '/v1/bitcoin/receivers' - ); - $resources = BitcoinReceiver::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertSame("Stripe\\BitcoinReceiver", get_class($resources->data[0])); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/bitcoin/receivers/' . self::TEST_RESOURCE_ID - ); - $resource = BitcoinReceiver::retrieve(self::TEST_RESOURCE_ID); - $this->assertSame("Stripe\\BitcoinReceiver", get_class($resource)); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/CardTest.php b/htdocs/includes/stripe/tests/Stripe/CardTest.php deleted file mode 100644 index 8976eff6679..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/CardTest.php +++ /dev/null @@ -1,94 +0,0 @@ - self::TEST_RESOURCE_ID, - 'object' => 'card', - 'metadata' => [], - ]; - return Card::constructFrom( - array_merge($params, $base), - new Util\RequestOptions() - ); - } - - public function testHasCorrectUrlForCustomer() - { - $resource = $this->createFixture(['customer' => 'cus_123']); - $this->assertSame( - "/v1/customers/cus_123/sources/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - public function testHasCorrectUrlForAccount() - { - $resource = $this->createFixture(['account' => 'acct_123']); - $this->assertSame( - "/v1/accounts/acct_123/external_accounts/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - public function testHasCorrectUrlForRecipient() - { - $resource = $this->createFixture(['recipient' => 'rp_123']); - $this->assertSame( - "/v1/recipients/rp_123/cards/" . self::TEST_RESOURCE_ID, - $resource->instanceUrl() - ); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyRetrievable() - { - Card::retrieve(self::TEST_RESOURCE_ID); - } - - public function testIsSaveable() - { - $resource = $this->createFixture(); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->save(); - $this->assertSame("Stripe\\Card", get_class($resource)); - } - - /** - * @expectedException \Stripe\Error\InvalidRequest - */ - public function testIsNotDirectlyUpdatable() - { - Card::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - } - - public function testIsDeletable() - { - $resource = $this->createFixture(); - $this->expectsRequest( - 'delete', - '/v1/customers/cus_123/sources/' . self::TEST_RESOURCE_ID - ); - $resource->delete(); - $this->assertSame("Stripe\\Card", get_class($resource)); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ChargeTest.php b/htdocs/includes/stripe/tests/Stripe/ChargeTest.php deleted file mode 100644 index b8c6cbabf3b..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ChargeTest.php +++ /dev/null @@ -1,140 +0,0 @@ -expectsRequest( - 'get', - '/v1/charges' - ); - $resources = Charge::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Charge", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/charges/' . self::TEST_RESOURCE_ID - ); - $resource = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Charge", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/charges' - ); - $resource = Charge::create([ - "amount" => 100, - "currency" => "usd", - "source" => "tok_123" - ]); - $this->assertInstanceOf("Stripe\\Charge", $resource); - } - - public function testIsSaveable() - { - $resource = Charge::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/charges/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/charges/' . self::TEST_RESOURCE_ID - ); - $resource = Charge::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Charge", $resource); - } - - public function testCanRefund() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id . '/refund' - ); - $resource = $charge->refund(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - $this->assertSame($resource, $charge); - } - - public function testCanCapture() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id . '/capture' - ); - $resource = $charge->capture(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - $this->assertSame($resource, $charge); - } - - public function testCanUpdateDispute() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id . '/dispute' - ); - $resource = $charge->updateDispute(); - $this->assertInstanceOf("Stripe\\Dispute", $resource); - } - - public function testCanCloseDispute() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id . '/dispute/close' - ); - $resource = $charge->closeDispute(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - $this->assertSame($resource, $charge); - } - - public function testCanMarkAsFraudulent() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id, - ['fraud_details' => ['user_report' => 'fraudulent']] - ); - $resource = $charge->markAsFraudulent(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - $this->assertSame($resource, $charge); - } - - public function testCanMarkAsSafe() - { - $charge = Charge::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/charges/' . $charge->id, - ['fraud_details' => ['user_report' => 'safe']] - ); - $resource = $charge->markAsSafe(); - $this->assertInstanceOf("Stripe\\Charge", $resource); - $this->assertSame($resource, $charge); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/CollectionTest.php b/htdocs/includes/stripe/tests/Stripe/CollectionTest.php deleted file mode 100644 index 560085aede2..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/CollectionTest.php +++ /dev/null @@ -1,147 +0,0 @@ -fixture = Collection::constructFrom([ - 'data' => [['id' => 1]], - 'has_more' => true, - 'url' => '/things', - ]); - } - - public function testCanList() - { - $this->stubRequest( - 'GET', - '/things', - [], - null, - false, - [ - 'data' => [['id' => 1]], - 'has_more' => true, - 'url' => '/things', - ] - ); - - $resources = $this->fixture->all(); - $this->assertTrue(is_array($resources->data)); - } - - public function testCanRetrieve() - { - $this->stubRequest( - 'GET', - '/things/1', - [], - null, - false, - [ - 'id' => 1, - ] - ); - - $this->fixture->retrieve(1); - } - - public function testCanCreate() - { - $this->stubRequest( - 'POST', - '/things', - [ - 'foo' => 'bar', - ], - null, - false, - [ - 'id' => 2, - ] - ); - - $this->fixture->create([ - 'foo' => 'bar', - ]); - } - - public function testProvidesAutoPagingIterator() - { - $this->stubRequest( - 'GET', - '/things', - [ - 'starting_after' => 1, - ], - null, - false, - [ - 'data' => [['id' => 2], ['id' => 3]], - 'has_more' => false, - ] - ); - - $seen = []; - foreach ($this->fixture->autoPagingIterator() as $item) { - array_push($seen, $item['id']); - } - - $this->assertSame([1, 2, 3], $seen); - } - - public function testSupportsIteratorToArray() - { - $this->stubRequest( - 'GET', - '/things', - [ - 'starting_after' => 1, - ], - null, - false, - [ - 'data' => [['id' => 2], ['id' => 3]], - 'has_more' => false, - ] - ); - - $seen = []; - foreach (iterator_to_array($this->fixture->autoPagingIterator()) as $item) { - array_push($seen, $item['id']); - } - - $this->assertSame([1, 2, 3], $seen); - } - - public function testHeaders() - { - $this->stubRequest( - 'POST', - '/things', - [ - 'foo' => 'bar', - ], - [ - 'Stripe-Account: acct_foo', - 'Idempotency-Key: qwertyuiop', - ], - false, - [ - 'id' => 2, - ] - ); - - $this->fixture->create([ - 'foo' => 'bar', - ], [ - 'stripe_account' => 'acct_foo', - 'idempotency_key' => 'qwertyuiop', - ]); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/CountrySpecTest.php b/htdocs/includes/stripe/tests/Stripe/CountrySpecTest.php deleted file mode 100644 index cccd4116845..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/CountrySpecTest.php +++ /dev/null @@ -1,29 +0,0 @@ -expectsRequest( - 'get', - '/v1/country_specs' - ); - $resources = CountrySpec::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\CountrySpec", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/country_specs/' . self::TEST_RESOURCE_ID - ); - $resource = CountrySpec::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\CountrySpec", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/CouponTest.php b/htdocs/includes/stripe/tests/Stripe/CouponTest.php deleted file mode 100644 index 8a6fbf630cd..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/CouponTest.php +++ /dev/null @@ -1,79 +0,0 @@ -expectsRequest( - 'get', - '/v1/coupons' - ); - $resources = Coupon::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Coupon", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/coupons/' . self::TEST_RESOURCE_ID - ); - $resource = Coupon::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Coupon", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/coupons' - ); - $resource = Coupon::create([ - "percent_off" => 25, - "duration" => "repeating", - "duration_in_months" => 3, - "id" => self::TEST_RESOURCE_ID, - ]); - $this->assertInstanceOf("Stripe\\Coupon", $resource); - } - - public function testIsSaveable() - { - $resource = Coupon::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/coupons/' . self::TEST_RESOURCE_ID - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Coupon", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/coupons/' . self::TEST_RESOURCE_ID - ); - $resource = Coupon::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Coupon", $resource); - } - - public function testIsDeletable() - { - $resource = Coupon::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/coupons/' . self::TEST_RESOURCE_ID - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Coupon", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/CustomerTest.php b/htdocs/includes/stripe/tests/Stripe/CustomerTest.php deleted file mode 100644 index e279e5489e8..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/CustomerTest.php +++ /dev/null @@ -1,269 +0,0 @@ -expectsRequest( - 'get', - '/v1/customers' - ); - $resources = Customer::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Customer", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/customers/' . self::TEST_RESOURCE_ID - ); - $resource = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Customer", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/customers' - ); - $resource = Customer::create(); - $this->assertInstanceOf("Stripe\\Customer", $resource); - } - - public function testIsSaveable() - { - $resource = Customer::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/customers/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Customer", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/customers/' . self::TEST_RESOURCE_ID - ); - $resource = Customer::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Customer", $resource); - } - - public function testIsDeletable() - { - $resource = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/customers/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Customer", $resource); - } - - public function testCanAddInvoiceItem() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/invoiceitems', - [ - "amount" => 100, - "currency" => "usd", - "customer" => $customer->id - ] - ); - $resource = $customer->addInvoiceItem([ - "amount" => 100, - "currency" => "usd" - ]); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } - - public function testCanListInvoices() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'get', - '/v1/invoices', - ["customer" => $customer->id] - ); - $resources = $customer->invoices(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Invoice", $resources->data[0]); - } - - public function testCanListInvoiceItems() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'get', - '/v1/invoiceitems', - ["customer" => $customer->id] - ); - $resources = $customer->invoiceItems(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resources->data[0]); - } - - public function testCanListCharges() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'get', - '/v1/charges', - ["customer" => $customer->id] - ); - $resources = $customer->charges(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Charge", $resources->data[0]); - } - - public function testCanUpdateSubscription() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->stubRequest( - 'post', - '/v1/customers/' . $customer->id . '/subscription', - ["plan" => "plan"], - null, - false, - [ - "object" => "subscription", - "id" => "sub_foo" - ] - ); - $resource = $customer->updateSubscription(["plan" => "plan"]); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - $this->assertSame("sub_foo", $customer->subscription->id); - } - - public function testCanCancelSubscription() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->stubRequest( - 'delete', - '/v1/customers/' . $customer->id . '/subscription', - [], - null, - false, - [ - "object" => "subscription", - "id" => "sub_foo" - ] - ); - $resource = $customer->cancelSubscription(); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - $this->assertSame("sub_foo", $customer->subscription->id); - } - - public function testCanDeleteDiscount() - { - $customer = Customer::retrieve(self::TEST_RESOURCE_ID); - $this->stubRequest( - 'delete', - '/v1/customers/' . $customer->id . '/discount' - ); - $customer->deleteDiscount(); - $this->assertSame($customer->discount, null); - } - - public function testCanCreateSource() - { - $this->expectsRequest( - 'post', - '/v1/customers/' . self::TEST_RESOURCE_ID . '/sources' - ); - $resource = Customer::createSource(self::TEST_RESOURCE_ID, ["source" => "btok_123"]); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanRetrieveSource() - { - $this->expectsRequest( - 'get', - '/v1/customers/' . self::TEST_RESOURCE_ID . '/sources/' . self::TEST_SOURCE_ID - ); - $resource = Customer::retrieveSource(self::TEST_RESOURCE_ID, self::TEST_SOURCE_ID); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanUpdateSource() - { - $this->expectsRequest( - 'post', - '/v1/customers/' . self::TEST_RESOURCE_ID . '/sources/' . self::TEST_SOURCE_ID - ); - $resource = Customer::updateSource(self::TEST_RESOURCE_ID, self::TEST_SOURCE_ID, ["name" => "name"]); - // stripe-mock returns a Card on this method and not a bank account - $this->assertInstanceOf("Stripe\\Card", $resource); - } - - public function testCanDeleteSource() - { - $this->expectsRequest( - 'delete', - '/v1/customers/' . self::TEST_RESOURCE_ID . '/sources/' . self::TEST_SOURCE_ID - ); - $resource = Customer::deleteSource(self::TEST_RESOURCE_ID, self::TEST_SOURCE_ID); - $this->assertInstanceOf("Stripe\\BankAccount", $resource); - } - - public function testCanListSources() - { - $this->expectsRequest( - 'get', - '/v1/customers/' . self::TEST_RESOURCE_ID . '/sources' - ); - $resources = Customer::allSources(self::TEST_RESOURCE_ID); - $this->assertTrue(is_array($resources->data)); - } - - public function testSerializeSourceString() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'customer', - ], null); - $obj->source = 'tok_visa'; - - $expected = [ - 'source' => 'tok_visa', - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } - - public function testSerializeSourceMap() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'customer', - ], null); - $obj->source = [ - 'object' => 'card', - 'number' => '4242424242424242', - 'exp_month' => 12, - 'exp_year' => 2032, - ]; - - $expected = [ - 'source' => [ - 'object' => 'card', - 'number' => '4242424242424242', - 'exp_month' => 12, - 'exp_year' => 2032, - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/DisputeTest.php b/htdocs/includes/stripe/tests/Stripe/DisputeTest.php deleted file mode 100644 index 81d93da0213..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/DisputeTest.php +++ /dev/null @@ -1,65 +0,0 @@ -expectsRequest( - 'get', - '/v1/disputes' - ); - $resources = Dispute::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Dispute", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/disputes/' . self::TEST_RESOURCE_ID - ); - $resource = Dispute::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Dispute", $resource); - } - - public function testIsSaveable() - { - $resource = Dispute::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/disputes/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Dispute", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/disputes/' . self::TEST_RESOURCE_ID - ); - $resource = Dispute::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Dispute", $resource); - } - - public function testIsClosable() - { - $dispute = Dispute::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/disputes/' . $dispute->id . '/close' - ); - $resource = $dispute->close(); - $this->assertInstanceOf("Stripe\\Dispute", $resource); - $this->assertSame($resource, $dispute); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/EphemeralKeyTest.php b/htdocs/includes/stripe/tests/Stripe/EphemeralKeyTest.php deleted file mode 100644 index e8a1fc0e9ef..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/EphemeralKeyTest.php +++ /dev/null @@ -1,43 +0,0 @@ -expectsRequest( - 'post', - '/v1/ephemeral_keys', - null, - ["Stripe-Version: 2017-05-25"] - ); - $resource = EphemeralKey::create([ - "customer" => "cus_123", - ], ["stripe_version" => "2017-05-25"]); - $this->assertInstanceOf("Stripe\\EphemeralKey", $resource); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testIsNotCreatableWithoutAnExplicitApiVersion() - { - $resource = EphemeralKey::create([ - "customer" => "cus_123", - ]); - } - - public function testIsDeletable() - { - $key = EphemeralKey::create([ - "customer" => "cus_123", - ], ["stripe_version" => "2017-05-25"]); - $this->expectsRequest( - 'delete', - '/v1/ephemeral_keys/' . $key->id - ); - $resource = $key->delete(); - $this->assertInstanceOf("Stripe\\EphemeralKey", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/Error/BaseTest.php b/htdocs/includes/stripe/tests/Stripe/Error/BaseTest.php deleted file mode 100644 index 4c2732ed1d1..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/Error/BaseTest.php +++ /dev/null @@ -1,36 +0,0 @@ -getMockForAbstractClass('Stripe\\Error\\Base', [ - 'message', - 200, - '{"key": "value"}', - ['key' => 'value'], - [ - 'Some-Header' => 'Some Value', - 'Request-Id' => 'req_test', - ], - ]); - } - - public function testGetters() - { - $e = $this->createFixture(); - $this->assertSame(200, $e->getHttpStatus()); - $this->assertSame('{"key": "value"}', $e->getHttpBody()); - $this->assertSame(['key' => 'value'], $e->getJsonBody()); - $this->assertSame('Some Value', $e->getHttpHeaders()['Some-Header']); - $this->assertSame('req_test', $e->getRequestId()); - } - - public function testToString() - { - $e = $this->createFixture(); - $this->assertContains("from API request 'req_test'", (string)$e); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/Error/SignatureVerificationTest.php b/htdocs/includes/stripe/tests/Stripe/Error/SignatureVerificationTest.php deleted file mode 100644 index 020a41f8f76..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/Error/SignatureVerificationTest.php +++ /dev/null @@ -1,12 +0,0 @@ -assertSame('sig_header', $e->getSigHeader()); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/EventTest.php b/htdocs/includes/stripe/tests/Stripe/EventTest.php deleted file mode 100644 index 2e3c92f0e49..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/EventTest.php +++ /dev/null @@ -1,29 +0,0 @@ -expectsRequest( - 'get', - '/v1/events' - ); - $resources = Event::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Event", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/events/' . self::TEST_RESOURCE_ID - ); - $resource = Event::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Event", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ExchangeRateTest.php b/htdocs/includes/stripe/tests/Stripe/ExchangeRateTest.php deleted file mode 100644 index 8b07b5a1358..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ExchangeRateTest.php +++ /dev/null @@ -1,54 +0,0 @@ -stubRequest( - 'get', - '/v1/exchange_rates', - [], - null, - false, - [ - 'object' => 'list', - 'data' => [ - [ - 'id' => 'eur', - 'object' => 'exchange_rate', - 'rates' => ['usd' => 1.18221], - ], - [ - 'id' => 'usd', - 'object' => 'exchange_rate', - 'rates' => ['eur' => 0.845876], - ], - ], - ] - ); - - $listRates = ExchangeRate::all(); - $this->assertTrue(is_array($listRates->data)); - $this->assertEquals('exchange_rate', $listRates->data[0]->object); - } - - public function testIsRetrievable() - { - $this->stubRequest( - 'get', - '/v1/exchange_rates/usd', - [], - null, - false, - [ - 'id' => 'usd', - 'object' => 'exchange_rate', - 'rates' => ['eur' => 0.845876], - ] - ); - $rates = ExchangeRate::retrieve("usd"); - $this->assertEquals('exchange_rate', $rates->object); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/FileUploadTest.php b/htdocs/includes/stripe/tests/Stripe/FileUploadTest.php deleted file mode 100644 index 21bb0b568f6..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/FileUploadTest.php +++ /dev/null @@ -1,104 +0,0 @@ -fixture = [ - 'id' => self::TEST_RESOURCE_ID, - 'object' => 'file_upload', - ]; - } - - public function testIsListable() - { - $this->stubRequest( - 'get', - '/v1/files', - [], - null, - false, - [ - 'object' => 'list', - 'data' => [$this->fixture], - 'resource_url' => '/v1/files', - ], - 200, - Stripe::$apiUploadBase - ); - - $resources = FileUpload::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\FileUpload", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->stubRequest( - 'get', - '/v1/files/' . self::TEST_RESOURCE_ID, - [], - null, - false, - $this->fixture, - 200, - Stripe::$apiUploadBase - ); - $resource = FileUpload::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\FileUpload", $resource); - } - - public function testIsCreatableWithFileHandle() - { - $this->stubRequest( - 'post', - '/v1/files', - null, - ['Content-Type: multipart/form-data'], - true, - $this->fixture, - 200, - Stripe::$apiUploadBase - ); - $fp = fopen(dirname(__FILE__) . '/../data/test.png', 'r'); - $resource = FileUpload::create([ - "purpose" => "dispute_evidence", - "file" => $fp, - ]); - $this->assertInstanceOf("Stripe\\FileUpload", $resource); - } - - public function testIsCreatableWithCurlFile() - { - if (!class_exists('\CurlFile', false)) { - // Older PHP versions don't support this - return; - } - - $this->stubRequest( - 'post', - '/v1/files', - null, - ['Content-Type: multipart/form-data'], - true, - $this->fixture, - 200, - Stripe::$apiUploadBase - ); - $curlFile = new \CurlFile(dirname(__FILE__) . '/../data/test.png'); - $resource = FileUpload::create([ - "purpose" => "dispute_evidence", - "file" => $curlFile, - ]); - $this->assertInstanceOf("Stripe\\FileUpload", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/HttpClient/CurlClientTest.php b/htdocs/includes/stripe/tests/Stripe/HttpClient/CurlClientTest.php deleted file mode 100644 index 086e6d3ee8d..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/HttpClient/CurlClientTest.php +++ /dev/null @@ -1,228 +0,0 @@ -origMaxNetworkRetries = Stripe::getMaxNetworkRetries(); - $this->origMaxNetworkRetryDelay = Stripe::getMaxNetworkRetryDelay(); - $this->origInitialNetworkRetryDelay = Stripe::getInitialNetworkRetryDelay(); - } - - /** - * @before - */ - public function setUpReflectors() - { - $stripeReflector = new \ReflectionClass('\Stripe\Stripe'); - - $this->maxNetworkRetryDelayProperty = $stripeReflector->getProperty('maxNetworkRetryDelay'); - $this->maxNetworkRetryDelayProperty->setAccessible(true); - - $this->initialNetworkRetryDelayProperty = $stripeReflector->getProperty('initialNetworkRetryDelay'); - $this->initialNetworkRetryDelayProperty->setAccessible(true); - - $curlClientReflector = new \ReflectionClass('Stripe\HttpClient\CurlClient'); - - $this->shouldRetryMethod = $curlClientReflector->getMethod('shouldRetry'); - $this->shouldRetryMethod->setAccessible(true); - - $this->sleepTimeMethod = $curlClientReflector->getMethod('sleepTime'); - $this->sleepTimeMethod->setAccessible(true); - } - - /** - * @after - */ - public function restoreOriginalNetworkValues() - { - Stripe::setMaxNetworkRetries($this->origMaxNetworkRetries); - $this->setMaxNetworkRetryDelay($this->origMaxNetworkRetryDelay); - $this->setInitialNetworkRetryDelay($this->origInitialNetworkRetryDelay); - } - - private function setMaxNetworkRetryDelay($maxNetworkRetryDelay) - { - $this->maxNetworkRetryDelayProperty->setValue(null, $maxNetworkRetryDelay); - } - - private function setInitialNetworkRetryDelay($initialNetworkRetryDelay) - { - $this->initialNetworkRetryDelayProperty->setValue(null, $initialNetworkRetryDelay); - } - - private function createFakeRandomGenerator($returnValue = 1.0) - { - $fakeRandomGenerator = $this->getMock('Stripe\Util\RandomGenetator', ['randFloat']); - $fakeRandomGenerator->method('randFloat')->willReturn($returnValue); - return $fakeRandomGenerator; - } - - public function testTimeout() - { - $curl = new CurlClient(); - $this->assertSame(CurlClient::DEFAULT_TIMEOUT, $curl->getTimeout()); - $this->assertSame(CurlClient::DEFAULT_CONNECT_TIMEOUT, $curl->getConnectTimeout()); - - // implicitly tests whether we're returning the CurlClient instance - $curl = $curl->setConnectTimeout(1)->setTimeout(10); - $this->assertSame(1, $curl->getConnectTimeout()); - $this->assertSame(10, $curl->getTimeout()); - - $curl->setTimeout(-1); - $curl->setConnectTimeout(-999); - $this->assertSame(0, $curl->getTimeout()); - $this->assertSame(0, $curl->getConnectTimeout()); - } - - public function testUserAgentInfo() - { - $curl = new CurlClient(); - $uaInfo = $curl->getUserAgentInfo(); - $this->assertNotNull($uaInfo); - $this->assertNotNull($uaInfo['httplib']); - $this->assertNotNull($uaInfo['ssllib']); - } - - public function testDefaultOptions() - { - // make sure options array loads/saves properly - $optionsArray = [CURLOPT_PROXY => 'localhost:80']; - $withOptionsArray = new CurlClient($optionsArray); - $this->assertSame($withOptionsArray->getDefaultOptions(), $optionsArray); - - // make sure closure-based options work properly, including argument passing - $ref = null; - $withClosure = new CurlClient(function ($method, $absUrl, $headers, $params, $hasFile) use (&$ref) { - $ref = func_get_args(); - return []; - }); - - $withClosure->request('get', 'https://httpbin.org/status/200', [], [], false); - $this->assertSame($ref, ['get', 'https://httpbin.org/status/200', [], [], false]); - - // this is the last test case that will run, since it'll throw an exception at the end - $withBadClosure = new CurlClient(function () { - return 'thisShouldNotWork'; - }); - $this->setExpectedException('Stripe\Error\Api', "Non-array value returned by defaultOptions CurlClient callback"); - $withBadClosure->request('get', 'https://httpbin.org/status/200', [], [], false); - } - - public function testSslOption() - { - // make sure options array loads/saves properly - $optionsArray = [CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1]; - $withOptionsArray = new CurlClient($optionsArray); - $this->assertSame($withOptionsArray->getDefaultOptions(), $optionsArray); - } - - public function testShouldRetryOnTimeout() - { - Stripe::setMaxNetworkRetries(2); - - $curlClient = new CurlClient(); - - $this->assertTrue($this->shouldRetryMethod->invoke($curlClient, CURLE_OPERATION_TIMEOUTED, 0, 0)); - } - - public function testShouldRetryOnConnectionFailure() - { - Stripe::setMaxNetworkRetries(2); - - $curlClient = new CurlClient(); - - $this->assertTrue($this->shouldRetryMethod->invoke($curlClient, CURLE_COULDNT_CONNECT, 0, 0)); - } - - public function testShouldRetryOnConflict() - { - Stripe::setMaxNetworkRetries(2); - - $curlClient = new CurlClient(); - - $this->assertTrue($this->shouldRetryMethod->invoke($curlClient, 0, 409, 0)); - } - - public function testShouldNotRetryAtMaximumCount() - { - Stripe::setMaxNetworkRetries(2); - - $curlClient = new CurlClient(); - - $this->assertFalse($this->shouldRetryMethod->invoke($curlClient, 0, 0, Stripe::getMaxNetworkRetries())); - } - - public function testShouldNotRetryOnCertValidationError() - { - Stripe::setMaxNetworkRetries(2); - - $curlClient = new CurlClient(); - - $this->assertFalse($this->shouldRetryMethod->invoke($curlClient, CURLE_SSL_PEER_CERTIFICATE, -1, 0)); - } - - public function testSleepTimeShouldGrowExponentially() - { - $this->setMaxNetworkRetryDelay(999); - - $curlClient = new CurlClient(null, $this->createFakeRandomGenerator()); - - $this->assertEquals( - Stripe::getInitialNetworkRetryDelay() * 1, - $this->sleepTimeMethod->invoke($curlClient, 1) - ); - $this->assertEquals( - Stripe::getInitialNetworkRetryDelay() * 2, - $this->sleepTimeMethod->invoke($curlClient, 2) - ); - $this->assertEquals( - Stripe::getInitialNetworkRetryDelay() * 4, - $this->sleepTimeMethod->invoke($curlClient, 3) - ); - $this->assertEquals( - Stripe::getInitialNetworkRetryDelay() * 8, - $this->sleepTimeMethod->invoke($curlClient, 4) - ); - } - - public function testSleepTimeShouldEnforceMaxNetworkRetryDelay() - { - $this->setInitialNetworkRetryDelay(1); - $this->setMaxNetworkRetryDelay(2); - - $curlClient = new CurlClient(null, $this->createFakeRandomGenerator()); - - $this->assertEquals(1, $this->sleepTimeMethod->invoke($curlClient, 1)); - $this->assertEquals(2, $this->sleepTimeMethod->invoke($curlClient, 2)); - $this->assertEquals(2, $this->sleepTimeMethod->invoke($curlClient, 3)); - $this->assertEquals(2, $this->sleepTimeMethod->invoke($curlClient, 4)); - } - - public function testSleepTimeShouldAddSomeRandomness() - { - $randomValue = 0.8; - $this->setInitialNetworkRetryDelay(1); - $this->setMaxNetworkRetryDelay(8); - - $curlClient = new CurlClient(null, $this->createFakeRandomGenerator($randomValue)); - - $baseValue = Stripe::getInitialNetworkRetryDelay() * (0.5 * (1 + $randomValue)); - - // the initial value cannot be smaller than the base, - // so the randomness is ignored - $this->assertEquals(Stripe::getInitialNetworkRetryDelay(), $this->sleepTimeMethod->invoke($curlClient, 1)); - - // after the first one, the randomness is applied - $this->assertEquals($baseValue * 2, $this->sleepTimeMethod->invoke($curlClient, 2)); - $this->assertEquals($baseValue * 4, $this->sleepTimeMethod->invoke($curlClient, 3)); - $this->assertEquals($baseValue * 8, $this->sleepTimeMethod->invoke($curlClient, 4)); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/InvoiceItemTest.php b/htdocs/includes/stripe/tests/Stripe/InvoiceItemTest.php deleted file mode 100644 index ffe140aa7ca..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/InvoiceItemTest.php +++ /dev/null @@ -1,78 +0,0 @@ -expectsRequest( - 'get', - '/v1/invoiceitems' - ); - $resources = InvoiceItem::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/invoiceitems/' . self::TEST_RESOURCE_ID - ); - $resource = InvoiceItem::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/invoiceitems' - ); - $resource = InvoiceItem::create([ - "amount" => 100, - "currency" => "usd", - "customer" => "cus_123" - ]); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } - - public function testIsSaveable() - { - $resource = InvoiceItem::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/invoiceitems/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/invoiceitems/' . self::TEST_RESOURCE_ID - ); - $resource = InvoiceItem::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } - - public function testIsDeletable() - { - $invoiceItem = InvoiceItem::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/invoiceitems/' . $invoiceItem->id - ); - $resource = $invoiceItem->delete(); - $this->assertInstanceOf("Stripe\\InvoiceItem", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/InvoiceTest.php b/htdocs/includes/stripe/tests/Stripe/InvoiceTest.php deleted file mode 100644 index f1ae9378628..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/InvoiceTest.php +++ /dev/null @@ -1,87 +0,0 @@ -expectsRequest( - 'get', - '/v1/invoices' - ); - $resources = Invoice::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Invoice", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/invoices/' . self::TEST_RESOURCE_ID - ); - $resource = Invoice::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/invoices' - ); - $resource = Invoice::create([ - "customer" => "cus_123" - ]); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - } - - public function testIsSaveable() - { - $resource = Invoice::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/invoices/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/invoices/' . self::TEST_RESOURCE_ID - ); - $resource = Invoice::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - } - - public function testCanRetrieveUpcoming() - { - $this->expectsRequest( - 'get', - '/v1/invoices/upcoming' - ); - $resource = Invoice::upcoming(["customer" => "cus_123"]); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - } - - public function testIsPayable() - { - $invoice = Invoice::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/invoices/' . $invoice->id . '/pay' - ); - $resource = $invoice->pay(); - $this->assertInstanceOf("Stripe\\Invoice", $resource); - $this->assertSame($resource, $invoice); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/OAuthTest.php b/htdocs/includes/stripe/tests/Stripe/OAuthTest.php deleted file mode 100644 index b4e43a88103..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/OAuthTest.php +++ /dev/null @@ -1,97 +0,0 @@ - 'read_write', - 'state' => 'csrf_token', - 'stripe_user' => [ - 'email' => 'test@example.com', - 'url' => 'https://example.com/profile/test', - 'country' => 'US', - ], - ]); - - $uri = parse_url($uriStr); - parse_str($uri['query'], $params); - - $this->assertSame('https', $uri['scheme']); - $this->assertSame('connect.stripe.com', $uri['host']); - $this->assertSame('/oauth/authorize', $uri['path']); - - $this->assertSame('ca_123', $params['client_id']); - $this->assertSame('read_write', $params['scope']); - $this->assertSame('test@example.com', $params['stripe_user']['email']); - $this->assertSame('https://example.com/profile/test', $params['stripe_user']['url']); - $this->assertSame('US', $params['stripe_user']['country']); - } - - /** - * @expectedException \Stripe\Error\Authentication - * @expectedExceptionMessageRegExp #No client_id provided# - */ - public function testRaisesAuthenticationErrorWhenNoClientId() - { - Stripe::setClientId(null); - OAuth::authorizeUrl(); - } - - public function testToken() - { - $this->stubRequest( - 'POST', - '/oauth/token', - [ - 'grant_type' => 'authorization_code', - 'code' => 'this_is_an_authorization_code', - ], - null, - false, - [ - 'access_token' => 'sk_access_token', - 'scope' => 'read_only', - 'livemode' => false, - 'token_type' => 'bearer', - 'refresh_token' => 'sk_refresh_token', - 'stripe_user_id' => 'acct_test', - 'stripe_publishable_key' => 'pk_test', - ], - 200, - Stripe::$connectBase - ); - - $resp = OAuth::token([ - 'grant_type' => 'authorization_code', - 'code' => 'this_is_an_authorization_code', - ]); - $this->assertSame('sk_access_token', $resp->access_token); - } - - public function testDeauthorize() - { - $this->stubRequest( - 'POST', - '/oauth/deauthorize', - [ - 'stripe_user_id' => 'acct_test_deauth', - 'client_id' => 'ca_123', - ], - null, - false, - [ - 'stripe_user_id' => 'acct_test_deauth', - ], - 200, - Stripe::$connectBase - ); - - $resp = OAuth::deauthorize([ - 'stripe_user_id' => 'acct_test_deauth', - ]); - $this->assertSame('acct_test_deauth', $resp->stripe_user_id); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/OrderReturnTest.php b/htdocs/includes/stripe/tests/Stripe/OrderReturnTest.php deleted file mode 100644 index bb2d65c437a..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/OrderReturnTest.php +++ /dev/null @@ -1,29 +0,0 @@ -expectsRequest( - 'get', - '/v1/order_returns' - ); - $resources = OrderReturn::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\OrderReturn", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/order_returns/' . self::TEST_RESOURCE_ID - ); - $resource = OrderReturn::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\OrderReturn", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/OrderTest.php b/htdocs/includes/stripe/tests/Stripe/OrderTest.php deleted file mode 100644 index 51d17e94fc7..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/OrderTest.php +++ /dev/null @@ -1,87 +0,0 @@ -expectsRequest( - 'get', - '/v1/orders' - ); - $resources = Order::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Order", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/orders/' . self::TEST_RESOURCE_ID - ); - $resource = Order::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Order", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/orders' - ); - $resource = Order::create([ - 'currency' => 'usd' - ]); - $this->assertInstanceOf("Stripe\\Order", $resource); - } - - public function testIsSaveable() - { - $resource = Order::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/orders/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Order", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/orders/' . self::TEST_RESOURCE_ID - ); - $resource = Order::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Order", $resource); - } - - public function testIsPayable() - { - $resource = Order::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/orders/' . $resource->id . '/pay' - ); - $resource->pay(); - $this->assertInstanceOf("Stripe\\Order", $resource); - } - - public function testIsReturnable() - { - $order = Order::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/orders/' . $order->id . '/returns' - ); - $resource = $order->returnOrder(); - $this->assertInstanceOf("Stripe\\OrderReturn", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/PayoutTest.php b/htdocs/includes/stripe/tests/Stripe/PayoutTest.php deleted file mode 100644 index 79c7b5fd015..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/PayoutTest.php +++ /dev/null @@ -1,77 +0,0 @@ -expectsRequest( - 'get', - '/v1/payouts' - ); - $resources = Payout::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Payout", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/payouts/' . self::TEST_RESOURCE_ID - ); - $resource = Payout::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Payout", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/payouts' - ); - $resource = Payout::create([ - "amount" => 100, - "currency" => "usd" - ]); - $this->assertInstanceOf("Stripe\\Payout", $resource); - } - - public function testIsSaveable() - { - $resource = Payout::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/payouts/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Payout", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/payouts/' . self::TEST_RESOURCE_ID - ); - $resource = Payout::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Payout", $resource); - } - - public function testIsCancelable() - { - $resource = Payout::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/payouts/' . $resource->id . '/cancel' - ); - $resource->cancel(); - $this->assertInstanceOf("Stripe\\Payout", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/PlanTest.php b/htdocs/includes/stripe/tests/Stripe/PlanTest.php deleted file mode 100644 index 8d71745ed56..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/PlanTest.php +++ /dev/null @@ -1,80 +0,0 @@ -expectsRequest( - 'get', - '/v1/plans' - ); - $resources = Plan::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Plan", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/plans/' . self::TEST_RESOURCE_ID - ); - $resource = Plan::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Plan", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/plans' - ); - $resource = Plan::create([ - 'amount' => 100, - 'interval' => 'month', - 'currency' => 'usd', - 'name' => self::TEST_RESOURCE_ID, - 'id' => self::TEST_RESOURCE_ID - ]); - $this->assertInstanceOf("Stripe\\Plan", $resource); - } - - public function testIsSaveable() - { - $resource = Plan::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/plans/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Plan", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/plans/' . self::TEST_RESOURCE_ID - ); - $resource = Plan::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Plan", $resource); - } - - public function testIsDeletable() - { - $resource = Plan::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/plans/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Plan", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ProductTest.php b/htdocs/includes/stripe/tests/Stripe/ProductTest.php deleted file mode 100644 index c2a3813c870..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ProductTest.php +++ /dev/null @@ -1,77 +0,0 @@ -expectsRequest( - 'get', - '/v1/products' - ); - $resources = Product::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Product", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/products/' . self::TEST_RESOURCE_ID - ); - $resource = Product::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Product", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/products' - ); - $resource = Product::create([ - 'name' => 'name', - 'type' => 'good' - ]); - $this->assertInstanceOf("Stripe\\Product", $resource); - } - - public function testIsSaveable() - { - $resource = Product::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/products/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Product", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/products/' . self::TEST_RESOURCE_ID - ); - $resource = Product::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Product", $resource); - } - - public function testIsDeletable() - { - $resource = Product::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/products/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Product", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/RecipientTest.php b/htdocs/includes/stripe/tests/Stripe/RecipientTest.php deleted file mode 100644 index 43dd6e82a79..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/RecipientTest.php +++ /dev/null @@ -1,90 +0,0 @@ -expectsRequest( - 'get', - '/v1/recipients' - ); - $resources = Recipient::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Recipient", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/recipients/' . self::TEST_RESOURCE_ID - ); - $resource = Recipient::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Recipient", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/recipients' - ); - $resource = Recipient::create([ - "name" => "name", - "type" => "individual" - ]); - $this->assertInstanceOf("Stripe\\Recipient", $resource); - } - - public function testIsSaveable() - { - $resource = Recipient::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/recipients/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Recipient", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/recipients/' . self::TEST_RESOURCE_ID - ); - $resource = Recipient::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Recipient", $resource); - } - - public function testIsDeletable() - { - $resource = Recipient::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/recipients/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Recipient", $resource); - } - - public function testCanListTransfers() - { - $recipient = Recipient::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'get', - '/v1/transfers', - ["recipient" => $recipient->id] - ); - $resources = $recipient->transfers(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Transfer", $resources->data[0]); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/RefundTest.php b/htdocs/includes/stripe/tests/Stripe/RefundTest.php deleted file mode 100644 index 788361d4d9d..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/RefundTest.php +++ /dev/null @@ -1,65 +0,0 @@ -expectsRequest( - 'get', - '/v1/refunds' - ); - $resources = Refund::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Refund", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/refunds/' . self::TEST_RESOURCE_ID - ); - $resource = Refund::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Refund", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/refunds' - ); - $resource = Refund::create([ - "charge" => "ch_123" - ]); - $this->assertInstanceOf("Stripe\\Refund", $resource); - } - - public function testIsSaveable() - { - $resource = Refund::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/refunds/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Refund", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/refunds/' . self::TEST_RESOURCE_ID - ); - $resource = Refund::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Refund", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/SKUTest.php b/htdocs/includes/stripe/tests/Stripe/SKUTest.php deleted file mode 100644 index d4fc2ad408b..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/SKUTest.php +++ /dev/null @@ -1,82 +0,0 @@ -expectsRequest( - 'get', - '/v1/skus' - ); - $resources = SKU::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\SKU", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/skus/' . self::TEST_RESOURCE_ID - ); - $resource = SKU::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\SKU", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/skus' - ); - $resource = SKU::create([ - 'currency' => 'usd', - 'inventory' => [ - 'type' => 'finite', - 'quantity' => 1 - ], - 'price' => 100, - 'product' => "prod_123" - ]); - $this->assertInstanceOf("Stripe\\SKU", $resource); - } - - public function testIsSaveable() - { - $resource = SKU::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/skus/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\SKU", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/skus/' . self::TEST_RESOURCE_ID - ); - $resource = SKU::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\SKU", $resource); - } - - public function testIsDeletable() - { - $resource = SKU::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/skus/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\SKU", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/SourceTest.php b/htdocs/includes/stripe/tests/Stripe/SourceTest.php deleted file mode 100644 index ad11b0d3455..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/SourceTest.php +++ /dev/null @@ -1,134 +0,0 @@ -expectsRequest( - 'get', - '/v1/sources/' . self::TEST_RESOURCE_ID - ); - $resource = Source::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Source", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/sources' - ); - $resource = Source::create([ - "type" => "card" - ]); - $this->assertInstanceOf("Stripe\\Source", $resource); - } - - public function testIsSaveable() - { - $resource = Source::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/sources/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Source", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/sources/' . self::TEST_RESOURCE_ID - ); - $resource = Source::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Source", $resource); - } - - public function testCanSaveCardExpiryDate() - { - $response = [ - 'id' => 'src_foo', - 'object' => 'source', - 'card' => [ - 'exp_month' => 8, - 'exp_year' => 2019, - ], - ]; - $source = Source::constructFrom($response); - - $response['card']['exp_month'] = 12; - $response['card']['exp_year'] = 2022; - $this->stubRequest( - 'POST', - '/v1/sources/src_foo', - [ - 'card' => [ - 'exp_month' => 12, - 'exp_year' => 2022, - ] - ], - null, - false, - $response - ); - - $source->card->exp_month = 12; - $source->card->exp_year = 2022; - $source->save(); - - $this->assertSame(12, $source->card->exp_month); - $this->assertSame(2022, $source->card->exp_year); - } - - public function testIsDetachableWhenAttached() - { - $resource = Source::retrieve(self::TEST_RESOURCE_ID); - $resource->customer = "cus_123"; - $this->expectsRequest( - 'delete', - '/v1/customers/cus_123/sources/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\Source", $resource); - } - - /** - * @expectedException \Stripe\Error\Api - */ - public function testIsNotDetachableWhenUnattached() - { - $resource = Source::retrieve(self::TEST_RESOURCE_ID); - $resource->detach(); - } - - public function testCanListSourceTransactions() - { - $source = Source::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'get', - '/v1/sources/' . $source->id . "/source_transactions" - ); - $resources = $source->sourceTransactions(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\SourceTransaction", $resources->data[0]); - } - - public function testCanVerify() - { - $resource = Source::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/sources/' . $resource->id . "/verify" - ); - $resource->verify(["values" => [32, 45]]); - $this->assertInstanceOf("Stripe\\Source", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/StripeObjectTest.php b/htdocs/includes/stripe/tests/Stripe/StripeObjectTest.php deleted file mode 100644 index af1cd936e1c..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/StripeObjectTest.php +++ /dev/null @@ -1,453 +0,0 @@ -deepCopyReflector = new \ReflectionMethod('Stripe\\StripeObject', 'deepCopy'); - $this->deepCopyReflector->setAccessible(true); - - // This is used to access the `_opts` protected variable - $this->optsReflector = new \ReflectionProperty('Stripe\\StripeObject', '_opts'); - $this->optsReflector->setAccessible(true); - } - - public function testArrayAccessorsSemantics() - { - $s = new StripeObject(); - $s['foo'] = 'a'; - $this->assertSame($s['foo'], 'a'); - $this->assertTrue(isset($s['foo'])); - unset($s['foo']); - $this->assertFalse(isset($s['foo'])); - } - - public function testNormalAccessorsSemantics() - { - $s = new StripeObject(); - $s->foo = 'a'; - $this->assertSame($s->foo, 'a'); - $this->assertTrue(isset($s->foo)); - unset($s->foo); - $this->assertFalse(isset($s->foo)); - } - - public function testArrayAccessorsMatchNormalAccessors() - { - $s = new StripeObject(); - $s->foo = 'a'; - $this->assertSame($s['foo'], 'a'); - - $s['bar'] = 'b'; - $this->assertSame($s->bar, 'b'); - } - - public function testCount() - { - $s = new StripeObject(); - $this->assertSame(0, count($s)); - - $s['key1'] = 'value1'; - $this->assertSame(1, count($s)); - - $s['key2'] = 'value2'; - $this->assertSame(2, count($s)); - - unset($s['key1']); - $this->assertSame(1, count($s)); - } - - public function testKeys() - { - $s = new StripeObject(); - $s->foo = 'bar'; - $this->assertSame($s->keys(), ['foo']); - } - - public function testValues() - { - $s = new StripeObject(); - $s->foo = 'bar'; - $this->assertSame($s->values(), ['bar']); - } - - public function testToArray() - { - $s = new StripeObject(); - $s->foo = 'a'; - - $converted = $s->__toArray(); - - $this->assertInternalType('array', $converted); - $this->assertArrayHasKey('foo', $converted); - $this->assertEquals('a', $converted['foo']); - } - - public function testRecursiveToArray() - { - $s = new StripeObject(); - $z = new StripeObject(); - - $s->child = $z; - $z->foo = 'a'; - - $converted = $s->__toArray(true); - - $this->assertInternalType('array', $converted); - $this->assertArrayHasKey('child', $converted); - $this->assertInternalType('array', $converted['child']); - $this->assertArrayHasKey('foo', $converted['child']); - $this->assertEquals('a', $converted['child']['foo']); - } - - public function testNonexistentProperty() - { - $s = new StripeObject(); - $this->assertNull($s->nonexistent); - } - - public function testPropertyDoesNotExists() - { - $s = new StripeObject(); - $this->assertNull($s['nonexistent']); - } - - public function testJsonEncode() - { - $s = new StripeObject(); - $s->foo = 'a'; - - $this->assertEquals('{"foo":"a"}', json_encode($s)); - } - - public function testToString() - { - $s = new StripeObject(); - $s->foo = 'a'; - - $string = $s->__toString(); - $expected = <<assertEquals($expected, $string); - } - - public function testReplaceNewNestedUpdatable() - { - $s = new StripeObject(); - - $s->metadata = ['bar']; - $this->assertSame($s->metadata, ['bar']); - $s->metadata = ['baz', 'qux']; - $this->assertSame($s->metadata, ['baz', 'qux']); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSetPermanentAttribute() - { - $s = new StripeObject(); - $s->id = 'abc_123'; - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSetEmptyStringValue() - { - $s = new StripeObject(); - $s->foo = ''; - } - - public function testSerializeParametersOnEmptyObject() - { - $obj = StripeObject::constructFrom([]); - $this->assertSame([], $obj->serializeParameters()); - } - - public function testSerializeParametersOnNewObjectWithSubObject() - { - $obj = new StripeObject(); - $obj->metadata = ['foo' => 'bar']; - $this->assertSame(['metadata' => ['foo' => 'bar']], $obj->serializeParameters()); - } - - public function testSerializeParametersOnBasicObject() - { - $obj = StripeObject::constructFrom(['foo' => null]); - $obj->updateAttributes(['foo' => 'bar']); - $this->assertSame(['foo' => 'bar'], $obj->serializeParameters()); - } - - public function testSerializeParametersOnMoreComplexObject() - { - $obj = StripeObject::constructFrom([ - 'foo' => StripeObject::constructFrom([ - 'bar' => null, - 'baz' => null, - ]), - ]); - $obj->foo->bar = 'newbar'; - $this->assertSame(['foo' => ['bar' => 'newbar']], $obj->serializeParameters()); - } - - public function testSerializeParametersOnArray() - { - $obj = StripeObject::constructFrom([ - 'foo' => null, - ]); - $obj->foo = ['new-value']; - $this->assertSame(['foo' => ['new-value']], $obj->serializeParameters()); - } - - public function testSerializeParametersOnArrayThatShortens() - { - $obj = StripeObject::constructFrom([ - 'foo' => ['0-index', '1-index', '2-index'], - ]); - $obj->foo = ['new-value']; - $this->assertSame(['foo' => ['new-value']], $obj->serializeParameters()); - } - - public function testSerializeParametersOnArrayThatLengthens() - { - $obj = StripeObject::constructFrom([ - 'foo' => ['0-index', '1-index', '2-index'], - ]); - $obj->foo = array_fill(0, 4, 'new-value'); - $this->assertSame(['foo' => array_fill(0, 4, 'new-value')], $obj->serializeParameters()); - } - - public function testSerializeParametersOnArrayOfHashes() - { - $obj = StripeObject::constructFrom(['foo' => null]); - $obj->foo = [ - StripeObject::constructFrom(['bar' => null]), - ]; - - $obj->foo[0]->bar = 'baz'; - $this->assertSame(['foo' => [['bar' => 'baz']]], $obj->serializeParameters()); - } - - public function testSerializeParametersDoesNotIncludeUnchangedValues() - { - $obj = StripeObject::constructFrom([ - 'foo' => null, - ]); - $this->assertSame([], $obj->serializeParameters()); - } - - public function testSerializeParametersOnUnchangedArray() - { - $obj = StripeObject::constructFrom([ - 'foo' => ['0-index', '1-index', '2-index'], - ]); - $obj->foo = ['0-index', '1-index', '2-index']; - $this->assertSame([], $obj->serializeParameters()); - } - - public function testSerializeParametersWithStripeObject() - { - $obj = StripeObject::constructFrom([]); - $obj->metadata = StripeObject::constructFrom(['foo' => 'bar']); - - $serialized = $obj->serializeParameters(); - $this->assertSame(['foo' => 'bar'], $serialized['metadata']); - } - - public function testSerializeParametersOnReplacedStripeObject() - { - $obj = StripeObject::constructFrom([ - 'metadata' => StripeObject::constructFrom(['bar' => 'foo']), - ]); - $obj->metadata = StripeObject::constructFrom(['baz' => 'foo']); - - $serialized = $obj->serializeParameters(); - $this->assertSame(['bar' => '', 'baz' => 'foo'], $serialized['metadata']); - } - - public function testSerializeParametersOnArrayOfStripeObjects() - { - $obj = StripeObject::constructFrom([]); - $obj->metadata = [ - StripeObject::constructFrom(['foo' => 'bar']), - ]; - - $serialized = $obj->serializeParameters(); - $this->assertSame([['foo' => 'bar']], $serialized['metadata']); - } - - public function testSerializeParametersOnSetApiResource() - { - $customer = Customer::constructFrom(['id' => 'cus_123']); - $obj = StripeObject::constructFrom([]); - - // the key here is that the property is set explicitly (and therefore - // marked as unsaved), which is why it gets included below - $obj->customer = $customer; - - $serialized = $obj->serializeParameters(); - $this->assertSame(['customer' => $customer], $serialized); - } - - public function testSerializeParametersOnNotSetApiResource() - { - $customer = Customer::constructFrom(['id' => 'cus_123']); - $obj = StripeObject::constructFrom(['customer' => $customer]); - - $serialized = $obj->serializeParameters(); - $this->assertSame([], $serialized); - } - - public function testSerializeParametersOnApiResourceFlaggedWithSaveWithParent() - { - $customer = Customer::constructFrom(['id' => 'cus_123']); - $customer->saveWithParent = true; - - $obj = StripeObject::constructFrom(['customer' => $customer]); - - $serialized = $obj->serializeParameters(); - $this->assertSame(['customer' => []], $serialized); - } - - public function testSerializeParametersRaisesExceotionOnOtherEmbeddedApiResources() - { - // This customer doesn't have an ID and therefore the library doesn't know - // what to do with it and throws an InvalidArgumentException because it's - // probably not what the user expected to happen. - $customer = Customer::constructFrom([]); - - $obj = StripeObject::constructFrom([]); - $obj->customer = $customer; - - try { - $serialized = $obj->serializeParameters(); - $this->fail("Did not raise error"); - } catch (\InvalidArgumentException $e) { - $this->assertSame( - "Cannot save property `customer` containing an API resource of type Stripe\Customer. " . - "It doesn't appear to be persisted and is not marked as `saveWithParent`.", - $e->getMessage() - ); - } catch (\Exception $e) { - $this->fail("Unexpected exception: " . get_class($e)); - } - } - - public function testSerializeParametersForce() - { - $obj = StripeObject::constructFrom([ - 'id' => 'id', - 'metadata' => StripeObject::constructFrom([ - 'bar' => 'foo', - ]), - ]); - - $serialized = $obj->serializeParameters(true); - $this->assertSame(['id' => 'id', 'metadata' => ['bar' => 'foo']], $serialized); - } - - public function testDirty() - { - $obj = StripeObject::constructFrom([ - 'id' => 'id', - 'metadata' => StripeObject::constructFrom([ - 'bar' => 'foo', - ]), - ]); - - // note that `$force` and `dirty()` are for different things, but are - // functionally equivalent - $obj->dirty(); - - $serialized = $obj->serializeParameters(); - $this->assertSame(['id' => 'id', 'metadata' => ['bar' => 'foo']], $serialized); - } - - public function testDeepCopy() - { - $opts = [ - "api_base" => Stripe::$apiBase, - "api_key" => "apikey", - ]; - $values = [ - "id" => 1, - "name" => "Stripe", - "arr" => [ - StripeObject::constructFrom(["id" => "index0"], $opts), - "index1", - 2, - ], - "map" => [ - "0" => StripeObject::constructFrom(["id" => "index0"], $opts), - "1" => "index1", - "2" => 2 - ], - ]; - - $copyValues = $this->deepCopyReflector->invoke(null, $values); - - // we can't compare the hashes directly because they have embedded - // objects which are different from each other - $this->assertEquals($values["id"], $copyValues["id"]); - $this->assertEquals($values["name"], $copyValues["name"]); - $this->assertEquals(count($values["arr"]), count($copyValues["arr"])); - - // internal values of the copied StripeObject should be the same, - // but the object itself should be new (hence the assertNotSame) - $this->assertEquals($values["arr"][0]["id"], $copyValues["arr"][0]["id"]); - $this->assertNotSame($values["arr"][0], $copyValues["arr"][0]); - - // likewise, the Util\RequestOptions instance in _opts should have - // copied values but be a new instance - $this->assertEquals( - $this->optsReflector->getValue($values["arr"][0]), - $this->optsReflector->getValue($copyValues["arr"][0]) - ); - $this->assertNotSame( - $this->optsReflector->getValue($values["arr"][0]), - $this->optsReflector->getValue($copyValues["arr"][0]) - ); - - // scalars however, can be compared - $this->assertEquals($values["arr"][1], $copyValues["arr"][1]); - $this->assertEquals($values["arr"][2], $copyValues["arr"][2]); - - // and a similar story with the hash - $this->assertEquals($values["map"]["0"]["id"], $copyValues["map"]["0"]["id"]); - $this->assertNotSame($values["map"]["0"], $copyValues["map"]["0"]); - $this->assertNotSame( - $this->optsReflector->getValue($values["arr"][0]), - $this->optsReflector->getValue($copyValues["arr"][0]) - ); - $this->assertEquals( - $this->optsReflector->getValue($values["map"]["0"]), - $this->optsReflector->getValue($copyValues["map"]["0"]) - ); - $this->assertNotSame( - $this->optsReflector->getValue($values["map"]["0"]), - $this->optsReflector->getValue($copyValues["map"]["0"]) - ); - $this->assertEquals($values["map"]["1"], $copyValues["map"]["1"]); - $this->assertEquals($values["map"]["2"], $copyValues["map"]["2"]); - } - - public function testDeepCopyMaintainClass() - { - $charge = Charge::constructFrom(["id" => 1], null); - $copyCharge = $this->deepCopyReflector->invoke(null, $charge); - $this->assertEquals(get_class($charge), get_class($copyCharge)); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/StripeTest.php b/htdocs/includes/stripe/tests/Stripe/StripeTest.php deleted file mode 100644 index f594518d13d..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/StripeTest.php +++ /dev/null @@ -1,30 +0,0 @@ -orig = [ - 'caBundlePath' => Stripe::$caBundlePath, - ]; - } - - /** - * @after - */ - public function restoreOriginalValues() - { - Stripe::$caBundlePath = $this->orig['caBundlePath']; - } - - public function testCABundlePathAccessors() - { - Stripe::setCABundlePath('path/to/ca/bundle'); - $this->assertEquals('path/to/ca/bundle', Stripe::getCABundlePath()); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/SubscriptionItemTest.php b/htdocs/includes/stripe/tests/Stripe/SubscriptionItemTest.php deleted file mode 100644 index 09e766c1bec..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/SubscriptionItemTest.php +++ /dev/null @@ -1,77 +0,0 @@ -expectsRequest( - 'get', - '/v1/subscription_items' - ); - $resources = SubscriptionItem::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/subscription_items/' . self::TEST_RESOURCE_ID - ); - $resource = SubscriptionItem::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/subscription_items' - ); - $resource = SubscriptionItem::create([ - "plan" => "plan", - "subscription" => "sub_123" - ]); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resource); - } - - public function testIsSaveable() - { - $resource = SubscriptionItem::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/subscription_items/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/subscription_items/' . self::TEST_RESOURCE_ID - ); - $resource = SubscriptionItem::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resource); - } - - public function testIsDeletable() - { - $resource = SubscriptionItem::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/subscription_items/' . $resource->id - ); - $resource->delete(); - $this->assertInstanceOf("Stripe\\SubscriptionItem", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/SubscriptionTest.php b/htdocs/includes/stripe/tests/Stripe/SubscriptionTest.php deleted file mode 100644 index 4a42e218224..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/SubscriptionTest.php +++ /dev/null @@ -1,115 +0,0 @@ -expectsRequest( - 'get', - '/v1/subscriptions' - ); - $resources = Subscription::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Subscription", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/subscriptions/' . self::TEST_RESOURCE_ID - ); - $resource = Subscription::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/subscriptions' - ); - $resource = Subscription::create([ - "customer" => "cus_123", - "plan" => "plan" - ]); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testIsSaveable() - { - $resource = Subscription::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/subscriptions/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/subscriptions/' . self::TEST_RESOURCE_ID - ); - $resource = Subscription::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testIsCancelable() - { - $resource = Subscription::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/subscriptions/' . $resource->id, - [ - 'at_period_end' => 'true', - ] - ); - $resource->cancel([ - 'at_period_end' => true, - ]); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testCanDeleteDiscount() - { - $resource = Subscription::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'delete', - '/v1/subscriptions/' . $resource->id . '/discount' - ); - $resource->deleteDiscount(); - $this->assertInstanceOf("Stripe\\Subscription", $resource); - } - - public function testSerializeParametersItems() - { - $obj = Util\Util::convertToStripeObject([ - 'object' => 'subscription', - 'items' => Util\Util::convertToStripeObject([ - 'object' => 'list', - 'data' => [], - ], null), - ], null); - $obj->items = [ - ['id' => 'si_foo', 'deleted' => true], - ['plan' => 'plan_bar'], - ]; - $expected = [ - 'items' => [ - 0 => ['id' => 'si_foo', 'deleted' => true], - 1 => ['plan' => 'plan_bar'], - ], - ]; - $this->assertSame($expected, $obj->serializeParameters()); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/ThreeDSecureTest.php b/htdocs/includes/stripe/tests/Stripe/ThreeDSecureTest.php deleted file mode 100644 index f56e649cbc1..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/ThreeDSecureTest.php +++ /dev/null @@ -1,32 +0,0 @@ -expectsRequest( - 'get', - '/v1/3d_secure/' . self::TEST_RESOURCE_ID - ); - $resource = ThreeDSecure::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\ThreeDSecure", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/3d_secure' - ); - $resource = ThreeDSecure::create([ - "amount" => 100, - "currency" => "usd", - "return_url" => "url" - ]); - $this->assertInstanceOf("Stripe\\ThreeDSecure", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/TokenTest.php b/htdocs/includes/stripe/tests/Stripe/TokenTest.php deleted file mode 100644 index 36bb4bc8283..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/TokenTest.php +++ /dev/null @@ -1,28 +0,0 @@ -expectsRequest( - 'get', - '/v1/tokens/' . self::TEST_RESOURCE_ID - ); - $resource = Token::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Token", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/tokens' - ); - $resource = Token::create(["card" => "tok_visa"]); - $this->assertInstanceOf("Stripe\\Token", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/TopupTest.php b/htdocs/includes/stripe/tests/Stripe/TopupTest.php deleted file mode 100644 index 994447636c6..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/TopupTest.php +++ /dev/null @@ -1,69 +0,0 @@ -expectsRequest( - 'get', - '/v1/topups' - ); - $resources = Topup::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Topup", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/topups/' . self::TEST_RESOURCE_ID - ); - $resource = Topup::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Topup", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/topups' - ); - $resource = Topup::create([ - "amount" => 100, - "currency" => "usd", - "source" => "tok_123", - "description" => "description", - "statement_descriptor" => "statement descriptor" - ]); - $this->assertInstanceOf("Stripe\\Topup", $resource); - } - - public function testIsSaveable() - { - $resource = Topup::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/topups/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Topup", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/topups/' . self::TEST_RESOURCE_ID - ); - $resource = Topup::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Topup", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/TransferReversalTest.php b/htdocs/includes/stripe/tests/Stripe/TransferReversalTest.php deleted file mode 100644 index 37101c73208..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/TransferReversalTest.php +++ /dev/null @@ -1,21 +0,0 @@ -metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/transfers/' . $resource->transfer . '/reversals/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\TransferReversal", $resource); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/TransferTest.php b/htdocs/includes/stripe/tests/Stripe/TransferTest.php deleted file mode 100644 index d60d560e7c5..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/TransferTest.php +++ /dev/null @@ -1,140 +0,0 @@ -expectsRequest( - 'get', - '/v1/transfers' - ); - $resources = Transfer::all(); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\Transfer", $resources->data[0]); - } - - public function testIsRetrievable() - { - $this->expectsRequest( - 'get', - '/v1/transfers/' . self::TEST_RESOURCE_ID - ); - $resource = Transfer::retrieve(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - } - - public function testIsCreatable() - { - $this->expectsRequest( - 'post', - '/v1/transfers' - ); - $resource = Transfer::create([ - "amount" => 100, - "currency" => "usd", - "destination" => "acct_123" - ]); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - } - - public function testIsSaveable() - { - $resource = Transfer::retrieve(self::TEST_RESOURCE_ID); - $resource->metadata["key"] = "value"; - $this->expectsRequest( - 'post', - '/v1/transfers/' . $resource->id - ); - $resource->save(); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - } - - public function testIsUpdatable() - { - $this->expectsRequest( - 'post', - '/v1/transfers/' . self::TEST_RESOURCE_ID - ); - $resource = Transfer::update(self::TEST_RESOURCE_ID, [ - "metadata" => ["key" => "value"], - ]); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - } - - public function testIsReversable() - { - $resource = Transfer::retrieve(self::TEST_RESOURCE_ID); - $this->expectsRequest( - 'post', - '/v1/transfers/' . $resource->id . '/reversals' - ); - $resource->reverse(); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - } - - public function testIsCancelable() - { - $transfer = Transfer::retrieve(self::TEST_RESOURCE_ID); - - // stripe-mock does not support this anymore so we stub it - $this->stubRequest( - 'post', - '/v1/transfers/' . $transfer->id . '/cancel' - ); - $resource = $transfer->cancel(); - $this->assertInstanceOf("Stripe\\Transfer", $resource); - $this->assertSame($resource, $transfer); - } - - public function testCanCreateReversal() - { - $this->expectsRequest( - 'post', - '/v1/transfers/' . self::TEST_RESOURCE_ID . '/reversals' - ); - $resource = Transfer::createReversal(self::TEST_RESOURCE_ID); - $this->assertInstanceOf("Stripe\\TransferReversal", $resource); - } - - public function testCanRetrieveReversal() - { - $this->expectsRequest( - 'get', - '/v1/transfers/' . self::TEST_RESOURCE_ID . '/reversals/' . self::TEST_REVERSAL_ID - ); - $resource = Transfer::retrieveReversal(self::TEST_RESOURCE_ID, self::TEST_REVERSAL_ID); - $this->assertInstanceOf("Stripe\\TransferReversal", $resource); - } - - public function testCanUpdateReversal() - { - $this->expectsRequest( - 'post', - '/v1/transfers/' . self::TEST_RESOURCE_ID . '/reversals/' . self::TEST_REVERSAL_ID - ); - $resource = Transfer::updateReversal( - self::TEST_RESOURCE_ID, - self::TEST_REVERSAL_ID, - [ - "metadata" => ["key" => "value"], - ] - ); - $this->assertInstanceOf("Stripe\\TransferReversal", $resource); - } - - public function testCanListReversal() - { - $this->expectsRequest( - 'get', - '/v1/transfers/' . self::TEST_RESOURCE_ID . '/reversals' - ); - $resources = Transfer::allReversals(self::TEST_RESOURCE_ID); - $this->assertTrue(is_array($resources->data)); - $this->assertInstanceOf("Stripe\\TransferReversal", $resources->data[0]); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/Util/DefaultLoggerTest.php b/htdocs/includes/stripe/tests/Stripe/Util/DefaultLoggerTest.php deleted file mode 100644 index 711af03c4a0..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/Util/DefaultLoggerTest.php +++ /dev/null @@ -1,28 +0,0 @@ -error("message"); - - global $lastMessage; - $this->assertSame($lastMessage, "message"); - } -} - -// This is a little terrible, but unfortunately there's no clean way to stub a -// call to `error_log`. Here we overwrite it so that we can get the last arguments -// that went to it. This is obviously bad, but luckily it's constrained to -// being just in \Stripe\Util (i.e. won't interfere with PHPUnit for example) -// and _just_ present when tests are running. -function error_log($message) -{ - global $lastMessage; - $lastMessage = $message; -} diff --git a/htdocs/includes/stripe/tests/Stripe/Util/RequestOptionsTest.php b/htdocs/includes/stripe/tests/Stripe/Util/RequestOptionsTest.php deleted file mode 100644 index 558f73982ea..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/Util/RequestOptionsTest.php +++ /dev/null @@ -1,81 +0,0 @@ -assertSame("foo", $opts->apiKey); - $this->assertSame([], $opts->headers); - } - - public function testNull() - { - $opts = Util\RequestOptions::parse(null); - $this->assertSame(null, $opts->apiKey); - $this->assertSame([], $opts->headers); - } - - public function testEmptyArray() - { - $opts = Util\RequestOptions::parse([]); - $this->assertSame(null, $opts->apiKey); - $this->assertSame([], $opts->headers); - } - - public function testAPIKeyArray() - { - $opts = Util\RequestOptions::parse( - [ - 'api_key' => 'foo', - ] - ); - $this->assertSame('foo', $opts->apiKey); - $this->assertSame([], $opts->headers); - } - - public function testIdempotentKeyArray() - { - $opts = Util\RequestOptions::parse( - [ - 'idempotency_key' => 'foo', - ] - ); - $this->assertSame(null, $opts->apiKey); - $this->assertSame(['Idempotency-Key' => 'foo'], $opts->headers); - } - - public function testKeyArray() - { - $opts = Util\RequestOptions::parse( - [ - 'idempotency_key' => 'foo', - 'api_key' => 'foo' - ] - ); - $this->assertSame('foo', $opts->apiKey); - $this->assertSame(['Idempotency-Key' => 'foo'], $opts->headers); - } - - /** - * @expectedException Stripe\Error\Api - */ - public function testWrongType() - { - $opts = Util\RequestOptions::parse(5); - } - - public function testDiscardNonPersistentHeaders() - { - $opts = Util\RequestOptions::parse( - [ - 'stripe_account' => 'foo', - 'idempotency_key' => 'foo', - ] - ); - $opts->discardNonPersistentHeaders(); - $this->assertSame(['Stripe-Account' => 'foo'], $opts->headers); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/Util/UtilTest.php b/htdocs/includes/stripe/tests/Stripe/Util/UtilTest.php deleted file mode 100644 index cf5130208db..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/Util/UtilTest.php +++ /dev/null @@ -1,90 +0,0 @@ -assertTrue(Util\Util::isList($list)); - - $notlist = [5, 'nstaoush', [], 'bar' => 'baz']; - $this->assertFalse(Util\Util::isList($notlist)); - } - - public function testThatPHPHasValueSemanticsForArrays() - { - $original = ['php-arrays' => 'value-semantics']; - $derived = $original; - $derived['php-arrays'] = 'reference-semantics'; - - $this->assertSame('value-semantics', $original['php-arrays']); - } - - public function testConvertStripeObjectToArrayIncludesId() - { - $customer = Util\Util::convertToStripeObject([ - 'id' => 'cus_123', - 'object' => 'customer', - ], null); - $this->assertTrue(array_key_exists("id", $customer->__toArray(true))); - } - - public function testUtf8() - { - // UTF-8 string - $x = "\xc3\xa9"; - $this->assertSame(Util\Util::utf8($x), $x); - - // Latin-1 string - $x = "\xe9"; - $this->assertSame(Util\Util::utf8($x), "\xc3\xa9"); - - // Not a string - $x = true; - $this->assertSame(Util\Util::utf8($x), $x); - } - - public function testUrlEncode() - { - $a = [ - 'my' => 'value', - 'that' => ['your' => 'example'], - 'bar' => 1, - 'baz' => null - ]; - - $enc = Util\Util::urlEncode($a); - $this->assertSame('my=value&that%5Byour%5D=example&bar=1', $enc); - - $a = ['that' => ['your' => 'example', 'foo' => null]]; - $enc = Util\Util::urlEncode($a); - $this->assertSame('that%5Byour%5D=example', $enc); - - $a = ['that' => 'example', 'foo' => ['bar', 'baz']]; - $enc = Util\Util::urlEncode($a); - $this->assertSame('that=example&foo%5B%5D=bar&foo%5B%5D=baz', $enc); - - $a = [ - 'my' => 'value', - 'that' => ['your' => ['cheese', 'whiz', null]], - 'bar' => 1, - 'baz' => null - ]; - - $enc = Util\Util::urlEncode($a); - $expected = 'my=value&that%5Byour%5D%5B%5D=cheese' - . '&that%5Byour%5D%5B%5D=whiz&bar=1'; - $this->assertSame($expected, $enc); - - // Ignores an empty array - $enc = Util\Util::urlEncode(['foo' => [], 'bar' => 'baz']); - $expected = 'bar=baz'; - $this->assertSame($expected, $enc); - - $a = ['foo' => [['bar' => 'baz'], ['bar' => 'bin']]]; - $enc = Util\Util::urlEncode($a); - $this->assertSame('foo%5B0%5D%5Bbar%5D=baz&foo%5B1%5D%5Bbar%5D=bin', $enc); - } -} diff --git a/htdocs/includes/stripe/tests/Stripe/WebhookTest.php b/htdocs/includes/stripe/tests/Stripe/WebhookTest.php deleted file mode 100644 index dcd82671afc..00000000000 --- a/htdocs/includes/stripe/tests/Stripe/WebhookTest.php +++ /dev/null @@ -1,110 +0,0 @@ -generateHeader(); - $event = Webhook::constructEvent(self::EVENT_PAYLOAD, $sigHeader, self::SECRET); - $this->assertEquals("evt_test_webhook", $event->id); - } - - /** - * @expectedException \UnexpectedValueException - */ - public function testInvalidJson() - { - $payload = "this is not valid JSON"; - $sigHeader = $this->generateHeader(["payload" => $payload]); - Webhook::constructEvent($payload, $sigHeader, self::SECRET); - } - - /** - * @expectedException \Stripe\Error\SignatureVerification - */ - public function testValidJsonAndInvalidHeader() - { - $sigHeader = "bad_header"; - Webhook::constructEvent(self::EVENT_PAYLOAD, $sigHeader, self::SECRET); - } - - /** - * @expectedException \Stripe\Error\SignatureVerification - * @expectedExceptionMessage Unable to extract timestamp and signatures from header - */ - public function testMalformedHeader() - { - $sigHeader = "i'm not even a real signature header"; - WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET); - } - - /** - * @expectedException \Stripe\Error\SignatureVerification - * @expectedExceptionMessage No signatures found with expected scheme - */ - public function testNoSignaturesWithExpectedScheme() - { - $sigHeader = $this->generateHeader(["scheme" => "v0"]); - WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET); - } - - /** - * @expectedException \Stripe\Error\SignatureVerification - * @expectedExceptionMessage No signatures found matching the expected signature for payload - */ - public function testNoValidSignatureForPayload() - { - $sigHeader = $this->generateHeader(["signature" => "bad_signature"]); - WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET); - } - - /** - * @expectedException \Stripe\Error\SignatureVerification - * @expectedExceptionMessage Timestamp outside the tolerance zone - */ - public function testTimestampOutsideTolerance() - { - $sigHeader = $this->generateHeader(["timestamp" => time() - 15]); - WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET, 10); - } - - public function testValidHeaderAndSignature() - { - $sigHeader = $this->generateHeader(); - $this->assertTrue(WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET, 10)); - } - - public function testHeaderContainsValidSignature() - { - $sigHeader = $this->generateHeader() . ",v1=bad_signature"; - $this->assertTrue(WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET, 10)); - } - - public function testTimestampOffButNoTolerance() - { - $sigHeader = $this->generateHeader(["timestamp" => 12345]); - $this->assertTrue(WebhookSignature::verifyHeader(self::EVENT_PAYLOAD, $sigHeader, self::SECRET)); - } -} diff --git a/htdocs/includes/stripe/tests/TestCase.php b/htdocs/includes/stripe/tests/TestCase.php deleted file mode 100644 index 840c0ec58c1..00000000000 --- a/htdocs/includes/stripe/tests/TestCase.php +++ /dev/null @@ -1,177 +0,0 @@ -origApiBase = Stripe::$apiBase; - $this->origApiKey = Stripe::getApiKey(); - $this->origClientId = Stripe::getClientId(); - $this->origApiVersion = Stripe::getApiVersion(); - $this->origAccountId = Stripe::getAccountId(); - - // Set up host and credentials for stripe-mock - Stripe::$apiBase = "http://localhost:" . MOCK_PORT; - Stripe::setApiKey("sk_test_123"); - Stripe::setClientId("ca_123"); - Stripe::setApiVersion(null); - Stripe::setAccountId(null); - - // Set up the HTTP client mocker - $this->clientMock = $this->getMock('\Stripe\HttpClient\ClientInterface'); - - // By default, use the real HTTP client - ApiRequestor::setHttpClient(HttpClient\CurlClient::instance()); - } - - protected function tearDown() - { - // Restore original values - Stripe::$apiBase = $this->origApiBase; - Stripe::setApiKey($this->origApiKey); - Stripe::setClientId($this->origClientId); - Stripe::setApiVersion($this->origApiVersion); - Stripe::setAccountId($this->origAccountId); - } - - /** - * Sets up a request expectation with the provided parameters. The request - * will actually go through and be emitted. - * - * @param string $method HTTP method (e.g. 'post', 'get', etc.) - * @param string $path relative path (e.g. '/v1/charges') - * @param array|null $params array of parameters. If null, parameters will - * not be checked. - * @param string[]|null $headers array of headers. Does not need to be - * exhaustive. If null, headers are not checked. - * @param bool $hasFile Whether the request parameters contains a file. - * Defaults to false. - */ - protected function expectsRequest( - $method, - $path, - $params = null, - $headers = null, - $hasFile = false - ) { - $this->prepareRequestMock($method, $path, $params, $headers, $hasFile) - ->will($this->returnCallback( - function ($method, $absUrl, $headers, $params, $hasFile) { - $curlClient = HttpClient\CurlClient::instance(); - ApiRequestor::setHttpClient($curlClient); - return $curlClient->request($method, $absUrl, $headers, $params, $hasFile); - } - )); - } - - /** - * Sets up a request expectation with the provided parameters. The request - * will not actually be emitted, instead the provided response parameters - * will be returned. - * - * @param string $method HTTP method (e.g. 'post', 'get', etc.) - * @param string $path relative path (e.g. '/v1/charges') - * @param array|null $params array of parameters. If null, parameters will - * not be checked. - * @param string[]|null $headers array of headers. Does not need to be - * exhaustive. If null, headers are not checked. - * @param bool $hasFile Whether the request parameters contains a file. - * Defaults to false. - * @param array $response - * @param integer $rcode - * @param string|null $base - * - * @return array - */ - protected function stubRequest( - $method, - $path, - $params = null, - $headers = null, - $hasFile = false, - $response = [], - $rcode = 200, - $base = null - ) { - $this->prepareRequestMock($method, $path, $params, $headers, $hasFile, $base) - ->willReturn([json_encode($response), $rcode, []]); - } - - /** - * Prepares the client mocker for an invocation of the `request` method. - * This helper method is used by both `expectsRequest` and `stubRequest` to - * prepare the client mocker to expect an invocation of the `request` method - * with the provided arguments. - * - * @param string $method HTTP method (e.g. 'post', 'get', etc.) - * @param string $path relative path (e.g. '/v1/charges') - * @param array|null $params array of parameters. If null, parameters will - * not be checked. - * @param string[]|null $headers array of headers. Does not need to be - * exhaustive. If null, headers are not checked. - * @param bool $hasFile Whether the request parameters contains a file. - * Defaults to false. - * @param string|null $base base URL (e.g. 'https://api.stripe.com') - * - * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker - */ - private function prepareRequestMock( - $method, - $path, - $params = null, - $headers = null, - $hasFile = false, - $base = null - ) { - ApiRequestor::setHttpClient($this->clientMock); - - if ($base === null) { - $base = Stripe::$apiBase; - } - $absUrl = $base . $path; - - return $this->clientMock - ->expects($this->once()) - ->method('request') - ->with( - $this->identicalTo(strtolower($method)), - $this->identicalTo($absUrl), - // for headers, we only check that all of the headers provided in $headers are - // present in the list of headers of the actual request - $headers === null ? $this->anything() : $this->callback(function ($array) use ($headers) { - foreach ($headers as $header) { - if (!in_array($header, $array)) { - return false; - } - } - return true; - }), - $params === null ? $this->anything() : $this->identicalTo($params), - $this->identicalTo($hasFile) - ); - } -} diff --git a/htdocs/includes/stripe/tests/bootstrap.no_autoload.php b/htdocs/includes/stripe/tests/bootstrap.no_autoload.php deleted file mode 100644 index 7011a3f4782..00000000000 --- a/htdocs/includes/stripe/tests/bootstrap.no_autoload.php +++ /dev/null @@ -1,5 +0,0 @@ -s01R$Gz9%CSj!PC{xWt~$(697H@6ZHT9 diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang index 1f8a9c2bd35..de2f0b19958 100644 --- a/htdocs/langs/en_US/paypal.lang +++ b/htdocs/langs/en_US/paypal.lang @@ -33,4 +33,4 @@ PaypalImportPayment=Import PayPal payments PostActionAfterPayment=Post actions after payments ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary. ValidationOfPaymentFailed=Validation of payment has failed -CardOwner=Card owner +CardOwner=Card holder diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php index d3942e560ed..7d5a81dab25 100644 --- a/htdocs/paypal/lib/paypal.lib.php +++ b/htdocs/paypal/lib/paypal.lib.php @@ -88,7 +88,7 @@ function showPaypalPaymentUrl($type, $ref) * @param string $freetag Free tag * @return string Url string */ -function getPaypalPaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_free_tag') +function getPaypalPaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_tag') { global $conf; diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 8489f0ef071..374556c3342 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -188,7 +188,7 @@ if ((empty($paymentmethod) || $paymentmethod == 'paybox') && ! empty($conf->payb { $langs->load("paybox"); - // TODO + // TODO Chek setup is complete $validpaymentmethod['paybox']='valid'; } @@ -425,187 +425,238 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled)) $error = 0; $errormessage = ''; - try { - $metadata = array( - 'dol_version' => DOL_VERSION, - 'dol_entity' => $conf->entity, - 'dol_company' => $mysoc->name, // Usefull when using multicompany - 'ipaddress'=> getUserRemoteIP() - ); + if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + try { + $metadata = array( + 'dol_version' => DOL_VERSION, + 'dol_entity' => $conf->entity, + 'dol_company' => $mysoc->name, // Usefull when using multicompany + 'ipaddress'=> getUserRemoteIP() + ); - if (! empty($thirdparty_id)) $metadata["dol_thirdparty_id"] = $thirdparty_id; + if (! empty($thirdparty_id)) $metadata["dol_thirdparty_id"] = $thirdparty_id; - if ($thirdparty_id > 0) - { - dol_syslog("Search existing Stripe customer profile for thirdparty_id=".$thirdparty_id, LOG_DEBUG, 0, '_stripe'); + if ($thirdparty_id > 0) + { + dol_syslog("Search existing Stripe customer profile for thirdparty_id=".$thirdparty_id, LOG_DEBUG, 0, '_stripe'); - $service = 'StripeTest'; - $servicestatus = 0; - if (! empty($conf->global->STRIPE_LIVE) && ! GETPOST('forcesandbox', 'int')) - { - $service = 'StripeLive'; - $servicestatus = 1; - } + $service = 'StripeTest'; + $servicestatus = 0; + if (! empty($conf->global->STRIPE_LIVE) && ! GETPOST('forcesandbox', 'int')) + { + $service = 'StripeLive'; + $servicestatus = 1; + } - $thirdparty = new Societe($db); - $thirdparty->fetch($thirdparty_id); + $thirdparty = new Societe($db); + $thirdparty->fetch($thirdparty_id); - // Create Stripe customer - include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; - $stripe = new Stripe($db); - $stripeacc = $stripe->getStripeAccount($service); - $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1); + // Create Stripe customer + include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1); - // Create Stripe card from Token - if ($savesource) { - $card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata)); - } else { - $card = $stripeToken; - } + // Create Stripe card from Token + if ($savesource) { + $card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata)); + } else { + $card = $stripeToken; + } - if (empty($card)) - { - $error++; - dol_syslog('Failed to create card record', LOG_WARNING, 0, '_stripe'); - setEventMessages('Failed to create card record', null, 'errors'); - $action=''; - } - else - { - if (! empty($FULLTAG)) $metadata["FULLTAG"] = $FULLTAG; - if (! empty($dol_id)) $metadata["dol_id"] = $dol_id; - if (! empty($dol_type)) $metadata["dol_type"] = $dol_type; + if (empty($card)) + { + $error++; + dol_syslog('Failed to create card record', LOG_WARNING, 0, '_stripe'); + setEventMessages('Failed to create card record', null, 'errors'); + $action=''; + } + else + { + if (! empty($FULLTAG)) $metadata["FULLTAG"] = $FULLTAG; + if (! empty($dol_id)) $metadata["dol_id"] = $dol_id; + if (! empty($dol_type)) $metadata["dol_type"] = $dol_type; - dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_stripe'); - $charge = \Stripe\Charge::create(array( - 'amount' => price2num($amountstripe, 'MU'), - 'currency' => $currency, - 'capture' => true, // Charge immediatly - 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, - 'metadata' => $metadata, - 'customer' => $customer->id, - 'source' => $card, - 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) - ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); - // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) - if (empty($charge)) - { - $error++; - dol_syslog('Failed to charge card', LOG_WARNING, 0, '_stripe'); - setEventMessages('Failed to charge card', null, 'errors'); - $action=''; - } - } - } - else - { - $vatcleaned = $vatnumber ? $vatnumber : null; + dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_stripe'); + $charge = \Stripe\Charge::create(array( + 'amount' => price2num($amountstripe, 'MU'), + 'currency' => $currency, + 'capture' => true, // Charge immediatly + 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, + 'metadata' => $metadata, + 'customer' => $customer->id, + 'source' => $card, + 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) + ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); + // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) + if (empty($charge)) + { + $error++; + dol_syslog('Failed to charge card', LOG_WARNING, 0, '_stripe'); + setEventMessages('Failed to charge card', null, 'errors'); + $action=''; + } + } + } + else + { + $vatcleaned = $vatnumber ? $vatnumber : null; - $taxinfo = array('type'=>'vat'); - if ($vatcleaned) - { - $taxinfo["tax_id"] = $vatcleaned; - } - // We force data to "null" if not defined as expected by Stripe - if (empty($vatcleaned)) $taxinfo=null; + $taxinfo = array('type'=>'vat'); + if ($vatcleaned) + { + $taxinfo["tax_id"] = $vatcleaned; + } + // We force data to "null" if not defined as expected by Stripe + if (empty($vatcleaned)) $taxinfo=null; - dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_stripe'); - $customer = \Stripe\Customer::create(array( - 'email' => $email, - 'description' => ($email?'Anonymous customer for '.$email:'Anonymous customer'), - 'metadata' => $metadata, - 'tax_info' => $taxinfo, - 'source' => $stripeToken // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?) - )); - // Return $customer = array('id'=>'cus_XXXX', ...) + dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_stripe'); + $customer = \Stripe\Customer::create(array( + 'email' => $email, + 'description' => ($email?'Anonymous customer for '.$email:'Anonymous customer'), + 'metadata' => $metadata, + 'tax_info' => $taxinfo, + 'source' => $stripeToken // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?) + )); + // Return $customer = array('id'=>'cus_XXXX', ...) - if (! empty($FULLTAG)) $metadata["FULLTAG"] = $FULLTAG; - if (! empty($dol_id)) $metadata["dol_id"] = $dol_id; - if (! empty($dol_type)) $metadata["dol_type"] = $dol_type; + if (! empty($FULLTAG)) $metadata["FULLTAG"] = $FULLTAG; + if (! empty($dol_id)) $metadata["dol_id"] = $dol_id; + if (! empty($dol_type)) $metadata["dol_type"] = $dol_type; - // The customer was just created with a source, so we can make a charge - // with no card defined, the source just used for customer creation will be used. - dol_syslog("Create charge", LOG_DEBUG, 0, '_stripe'); - $charge = \Stripe\Charge::create(array( - 'customer' => $customer->id, - 'amount' => price2num($amountstripe, 'MU'), - 'currency' => $currency, - 'capture' => true, // Charge immediatly - 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, - 'metadata' => $metadata, - 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) - ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); - // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) - if (empty($charge)) - { - $error++; - dol_syslog('Failed to charge card', LOG_WARNING, 0, '_stripe'); - setEventMessages('Failed to charge card', null, 'errors'); - $action=''; - } - } - } catch(\Stripe\Error\Card $e) { - // Since it's a decline, \Stripe\Error\Card will be caught - $body = $e->getJsonBody(); - $err = $body['error']; + // The customer was just created with a source, so we can make a charge + // with no card defined, the source just used for customer creation will be used. + dol_syslog("Create charge", LOG_DEBUG, 0, '_stripe'); + $charge = \Stripe\Charge::create(array( + 'customer' => $customer->id, + 'amount' => price2num($amountstripe, 'MU'), + 'currency' => $currency, + 'capture' => true, // Charge immediatly + 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, + 'metadata' => $metadata, + 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) + ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); + // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) + if (empty($charge)) + { + $error++; + dol_syslog('Failed to charge card', LOG_WARNING, 0, '_stripe'); + setEventMessages('Failed to charge card', null, 'errors'); + $action=''; + } + } + } catch(\Stripe\Error\Card $e) { + // Since it's a decline, \Stripe\Error\Card will be caught + $body = $e->getJsonBody(); + $err = $body['error']; - print('Status is:' . $e->getHttpStatus() . "\n"); - print('Type is:' . $err['type'] . "\n"); - print('Code is:' . $err['code'] . "\n"); - // param is '' in this case - print('Param is:' . $err['param'] . "\n"); - print('Message is:' . $err['message'] . "\n"); + print('Status is:' . $e->getHttpStatus() . "\n"); + print('Type is:' . $err['type'] . "\n"); + print('Code is:' . $err['code'] . "\n"); + // param is '' in this case + print('Param is:' . $err['param'] . "\n"); + print('Message is:' . $err['message'] . "\n"); + + $error++; + $errormessage="ErrorCard ".$e->getMessage()." err=".var_export($err, true); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (\Stripe\Error\RateLimit $e) { + // Too many requests made to the API too quickly + $error++; + $errormessage="ErrorRateLimit ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (\Stripe\Error\InvalidRequest $e) { + // Invalid parameters were supplied to Stripe's API + $error++; + $errormessage="ErrorInvalidRequest ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (\Stripe\Error\Authentication $e) { + // Authentication with Stripe's API failed + // (maybe you changed API keys recently) + $error++; + $errormessage="ErrorAuthentication ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (\Stripe\Error\ApiConnection $e) { + // Network communication with Stripe failed + $error++; + $errormessage="ErrorApiConnection ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (\Stripe\Error\Base $e) { + // Display a very generic error to the user, and maybe send + // yourself an email + $error++; + $errormessage="ErrorBase ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } catch (Exception $e) { + // Something else happened, completely unrelated to Stripe + $error++; + $errormessage="ErrorException ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } + } + + if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + $service = 'StripeTest'; + $servicestatus = 0; + if (! empty($conf->global->STRIPE_LIVE) && ! GETPOST('forcesandbox', 'int')) + { + $service = 'StripeLive'; + $servicestatus = 1; + } + include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; + $stripe = new Stripe($db); + $stripeacc = $stripe->getStripeAccount($service); + + // We go here if $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is set. + // In such a case, payment is always ok when we call the "charge" action. + $paymentintent_id = GETPOST("paymentintent_id", "alpha"); + + // Force to use the correct API key + global $stripearrayofkeysbyenv; + \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']); + + try { + if (empty($key)) { // If the Stripe connect account not set, we use common API usage + $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id); + } else { + $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id, array("stripe_account" => $stripeacc)); + } + } + catch(Exception $e) + { + $error++; + $errormessage="CantRetreivePaymentIntent ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } + + if ($paymentintent->status != 'succeeded') + { + $error++; + $errormessage="StatusOfRetreivedIntent is not succeeded: ".$e->getMessage(); + dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); + setEventMessages($e->getMessage(), null, 'errors'); + $action=''; + } + } - $error++; - $errormessage="ErrorCard ".$e->getMessage()." err=".var_export($err, true); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (\Stripe\Error\RateLimit $e) { - // Too many requests made to the API too quickly - $error++; - $errormessage="ErrorRateLimit ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (\Stripe\Error\InvalidRequest $e) { - // Invalid parameters were supplied to Stripe's API - $error++; - $errormessage="ErrorInvalidRequest ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (\Stripe\Error\Authentication $e) { - // Authentication with Stripe's API failed - // (maybe you changed API keys recently) - $error++; - $errormessage="ErrorAuthentication ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (\Stripe\Error\ApiConnection $e) { - // Network communication with Stripe failed - $error++; - $errormessage="ErrorApiConnection ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (\Stripe\Error\Base $e) { - // Display a very generic error to the user, and maybe send - // yourself an email - $error++; - $errormessage="ErrorBase ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } catch (Exception $e) { - // Something else happened, completely unrelated to Stripe - $error++; - $errormessage="ErrorException ".$e->getMessage(); - dol_syslog($errormessage, LOG_WARNING, 0, '_stripe'); - setEventMessages($e->getMessage(), null, 'errors'); - $action=''; - } $remoteip = getUserRemoteIP(); @@ -615,7 +666,7 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled)) $_SESSION["paymentType"] = ''; $_SESSION['ipaddress'] = ($remoteip?$remoteip:'unknown'); // Payer ip $_SESSION['payerID'] = is_object($customer)?$customer->id:''; - $_SESSION['TRANSACTIONID'] = is_object($charge)?$charge->id:''; + $_SESSION['TRANSACTIONID'] = (is_object($charge) ? $charge->id : (is_object($paymentintent) ? $paymentintent->id : '')); $_SESSION['errormessage'] = $errormessage; dol_syslog("Action charge stripe ip=".$remoteip, LOG_DEBUG, 0, '_stripe'); @@ -768,8 +819,8 @@ $object = null; if (! $source) { $found=true; - $tag=GETPOST("tag"); - $fulltag=$tag; + $tag=GETPOST("tag", 'alpha'); + $fulltag="TAG=".$tag; // Creditor print ''.$langs->trans("Creditor"); @@ -818,12 +869,9 @@ if (! $source) $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = null; - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum // as they don't exists (buyer is unknown, tag is free). @@ -848,9 +896,8 @@ if ($source == 'order') else { $result=$order->fetch_thirdparty($order->socid); - - $object = $order; } + $object = $order; if ($action != 'dopayment') // Do not change amount if we just click on first dopayment { @@ -860,7 +907,6 @@ if ($source == 'order') } $fulltag='ORD='.$order->id.'.CUS='.$order->thirdparty->id; - //$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); @@ -933,12 +979,9 @@ if ($source == 'order') $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = $stripe->customerStripe($order->thirdparty, $stripeacc, $servicestatus, 1); - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag.' ref='.$object->ref, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // Shipping address @@ -992,9 +1035,8 @@ if ($source == 'invoice') else { $result=$invoice->fetch_thirdparty($invoice->socid); - - $object = $invoice; } + $object = $invoice; if ($action != 'dopayment') // Do not change amount if we just click on first dopayment { @@ -1083,12 +1125,9 @@ if ($source == 'invoice') $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = $stripe->customerStripe($invoice->thirdparty, $stripeacc, $servicestatus, 1); - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag.' ref='.$object->ref, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // Shipping address @@ -1144,8 +1183,6 @@ if ($source == 'contractline') { if ($contractline->fk_contrat > 0) { - $object = $contractline; - $result=$contract->fetch($contractline->fk_contrat); if ($result > 0) { @@ -1163,6 +1200,7 @@ if ($source == 'contractline') $error++; } } + $object = $contractline; if ($action != 'dopayment') // Do not change amount if we just click on first dopayment { @@ -1317,12 +1355,9 @@ if ($source == 'contractline') $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = null; - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag." ref=".$object->ref, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // Shipping address @@ -1376,9 +1411,9 @@ if ($source == 'membersubscription') else { $member->fetch_thirdparty(); - $object = $member; $subscription=new Subscription($db); } + $object = $member; if ($action != 'dopayment') // Do not change amount if we just click on first dopayment { @@ -1506,12 +1541,9 @@ if ($source == 'membersubscription') $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = null; - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag." ref=".$object->ref, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // Shipping address @@ -1564,8 +1596,8 @@ if ($source == 'donation') else { $don->fetch_thirdparty(); - $object = $don; } + $object = $don; if ($action != 'dopayment') // Do not change amount if we just click on first dopayment { @@ -1670,12 +1702,9 @@ if ($source == 'donation') $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = $stripe->customerStripe($don->thirdparty, $stripeacc, $servicestatus, 1); - // for dev only - print ''.$langs->trans("PaymentIntent"); - print ''; - $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus); - print ''.$paymentintent->id.''; - print ''."\n"; + + $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag." ref=".$object->ref, $object, $stripecu, $stripeacc, $servicestatus); + if ($stripe->error) setEventMessages($stripe->error, null, 'errors'); } // Shipping address @@ -1718,6 +1747,7 @@ if ($mesg) print '
'. print ''."\n"; print "\n"; + if ($action != 'dopayment') { if ($found && ! $error) // We are in a management option and no error @@ -1748,13 +1778,13 @@ if ($action != 'dopayment') if ((empty($paymentmethod) || $paymentmethod == 'paybox') && ! empty($conf->paybox->enabled)) { // If STRIPE_PICTO_FOR_PAYMENT is 'cb' we show a picto of a crdit card instead of paybox - print '
'; + print '
'; } if ((empty($paymentmethod) || $paymentmethod == 'stripe') && ! empty($conf->stripe->enabled)) { // If STRIPE_PICTO_FOR_PAYMENT is 'cb' we show a picto of a crdit card instead of stripe - print '
'; + print '
'; } if ((empty($paymentmethod) || $paymentmethod == 'paypal') && ! empty($conf->paypal->enabled)) @@ -1763,11 +1793,11 @@ if ($action != 'dopayment') if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'integral') { - print '
'; + print '
'; } if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'paypalonly') { - print '
'; + print '
'; } } } @@ -1799,17 +1829,6 @@ if (preg_match('/^dopayment/', $action)) // Stripe if (GETPOST('dopayment_stripe', 'alpha')) { - // Simple checkout - /* - print ''; - */ - // Personalized checkout print ''; - print ' + print '
'; -
-
'; + print ''; print ''."\n"; print ''."\n"; @@ -1860,41 +1878,60 @@ if (preg_match('/^dopayment/', $action)) print ''; print ''; - print ' - - -
'; + if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION) || ! empty($paymentintent)) + { + print ' + + +
'; + + if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + print '
'; + } + + print ' +
+ + '; + + if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) + { + print '
'; + } + + print '
+ +
+ + + + +
+ +
'; + + print ''; + print ''; + + print ' +
'; + } if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { - print '
'; + if (empty($paymentintent)) + { + print '
'.$langs->trans("Error").'
'; + } + else + { + print ''; + //$_SESSION["paymentintent_id"] = $paymentintent->id; + } } - print ' -
- - '; - - if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) - { - print '
'; - } - - print '
- -
- - - - -
'; - - print '
- - -
- -
'."\n"; + print ''."\n"; print ''."\n"; @@ -1931,7 +1968,6 @@ if (preg_match('/^dopayment/', $action)) }; var cardElement = elements.create('card', {style: style}); - var cardholderName = document.getElementById('cardholder-name'); // Add an instance of the card Element into the `card-element`
cardElement.mount('#card-element'); @@ -1940,44 +1976,70 @@ if (preg_match('/^dopayment/', $action)) cardElement.addEventListener('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { - console.log("Show event error"); + console.log("Show event error (like 'Incorrect card number', ...)"); displayError.textContent = event.error.message; } else { - console.log("No error"); + console.log("Reset error message"); displayError.textContent = ''; } }); // Handle form submission + var cardholderName = document.getElementById('cardholder-name'); var cardButton = document.getElementById('buttontopay'); var clientSecret = cardButton.dataset.secret; cardButton.addEventListener('click', function(event) { - stripe.handleCardPayment( - clientSecret, cardElement, { - source_data: { - owner: { - name: cardholderName.value, + console.log("We click on buttontopay"); + event.preventDefault(); + + if (cardholderName.value == '') + { + console.log("Field Card holder is empty"); + var displayError = document.getElementById('card-errors'); + displayError.textContent = 'trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CardOwner"))); ?>'; + } + else + { + stripe.handleCardPayment( + clientSecret, cardElement, { + payment_method_data: { + billing_details: { + name: cardholderName.value + , email: '', + thirdparty)) { ?>, phone: thirdparty->phone; ?>', + thirdparty)) { + print ', address: {'."\n"; + print ' city: '.$object->thirdparty->town.','; + print ' country: '.$object->thirdparty->country_code.','; + print ' line1: '.$object->thirdparty->address.','; + print ' postal_code: '.$object->thirdparty->zip; + print '}'."\n"; + } ?> + } /* TODO Add all other known data like emails, ... to be SCA compliant */ + }, + save_payment_method: false } - } + ).then(function(result) { + console.log(result); + if (result.error) { + console.log("Error on result of handleCardPayment"); + jQuery('#buttontopay').show(); + jQuery('#hourglasstopay').hide(); + // Inform the user if there was an error + var errorElement = document.getElementById('card-errors'); + errorElement.textContent = result.error.message; + } else { + // The payment has succeeded. Display a success message. + console.log("No error on result of handleCardPayment, so we submit the form"); + // Submit the form + jQuery('#buttontopay').hide(); + jQuery('#hourglasstopay').show(); + // Send form (action=charge that will do nothing) + jQuery('#payment-form').submit(); + } + }); } - ).then(function(result) { - jQuery('#buttontopay').hide(); - jQuery('#hourglasstopay').show(); - if (result.error) { - console.log("Error on result of handleCardPayment"); - jQuery('#buttontopay').show(); - jQuery('#hourglasstopay').hide(); - // Inform the user if there was an error - var errorElement = document.getElementById('card-errors'); - errorElement.textContent = result.error.message; - } else { - console.log("No error on result of handleCardPayment, so we submit the form"); - // Submit the form - jQuery('#buttontopay').hide(); - jQuery('#hourglasstopay').show(); - } - }); }); diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 62d709fc674..52413921f90 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -280,7 +280,7 @@ $fulltag = $FULLTAG; $tmptag=dolExplodeIntoArray($fulltag, '.', '='); -dol_syslog("ispaymentok=".$ispaymentok, LOG_DEBUG, 0, '_payment'); +dol_syslog("ispaymentok=".$ispaymentok." tmptag=".var_export($tmptag, true), LOG_DEBUG, 0, '_payment'); // Make complementary actions @@ -296,7 +296,7 @@ if ($ispaymentok) $user->rights->facture->creer = 1; $user->rights->adherent->cotisation->creer = 1; - if (in_array('MEM', array_keys($tmptag))) + if (array_key_exists('MEM', $tmptag) && $tmptag['MEM'] > 0) { // Validate member // Create subscription @@ -583,7 +583,7 @@ if ($ispaymentok) $ispostactionok = -1; } } - elseif (in_array('INV', array_keys($tmptag))) + elseif (array_key_exists('INV', $tmptag) && $tmptag['INV'] > 0) { // Record payment include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -769,14 +769,14 @@ if ($ispaymentok) $urlback=$_SERVER["REQUEST_URI"]; $topic='['.$appli.'] '.$companylangs->transnoentitiesnoconv("NewOnlinePaymentReceived"); $content=""; - if (in_array('MEM', array_keys($tmptag))) + if (array_key_exists('MEM', $tmptag)) { $url=$urlwithroot."/adherents/subscription.php?rowid=".$tmptag['MEM']; $content.=''.$companylangs->trans("PaymentSubscription")."

\n"; $content.=$companylangs->trans("MemberId").': '.$tmptag['MEM']."
\n"; $content.=$companylangs->trans("Link").': '.$url.''."
\n"; } - elseif (in_array('INV', array_keys($tmptag))) + elseif (array_key_exists('INV', $tmptag)) { $url=$urlwithroot."/compta/facture/card.php?id=".$tmptag['INV']; $content.=''.$companylangs->trans("Payment")."

\n"; diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 1f2f39719a8..ee1c1a67f0a 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -243,6 +243,7 @@ class Stripe extends CommonObject * @param double $amount Amount * @param string $currency_code Currency code * @param string $tag Tag + * @param string $description Description * @param Societe $object Object to pay with Stripe * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect @@ -252,10 +253,14 @@ class Stripe extends CommonObject * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found */ - public function getPaymentIntent($amount, $currency_code, $tag, $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) + public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) { global $conf, $user, $mysoc; + dol_syslog("getPaymentIntent"); + + $error = 0; + if (empty($status)) $service = 'StripeTest'; else $service = 'StripeLive'; @@ -305,6 +310,7 @@ class Stripe extends CommonObject } catch(Exception $e) { + $error++; $this->error = $e->getMessage(); } } @@ -314,9 +320,6 @@ class Stripe extends CommonObject if (empty($paymentintent)) { $ipaddress=getUserRemoteIP(); - // Not enough space for a ref so we store id. Also with multicompany we can have same ref for 2 different - // object and we need a unique (this is used later as idempotency_key) - $description=$tag; $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress); if (is_object($object)) { @@ -330,12 +333,14 @@ class Stripe extends CommonObject "amount" => $stripeamount, "currency" => $currency_code, "payment_method_types" => ["card"], - "statement_descriptor" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) + "description" => $description, + "statement_descriptor" => dol_trunc($tag, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) "metadata" => $metadata ); if (! is_null($customer)) $dataforintent["customer"]=$customer; // save_payment_method = true, // payment_method = + //var_dump($dataforintent); if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0) { @@ -353,9 +358,12 @@ class Stripe extends CommonObject if (empty($key)) { // If the Stripe connect account not set, we use common API usage $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description")); + //$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array()); } else { $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key)); + //$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("stripe_account" => $key)); } + //var_dump($paymentintent); // Store the payment intent if (is_object($object)) @@ -366,6 +374,7 @@ class Stripe extends CommonObject $resql = $this->db->query($sql); if (! $resql) { + $error++; $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database."); } @@ -377,10 +386,18 @@ class Stripe extends CommonObject } catch(Exception $e) { + /*var_dump($dataforintent); + var_dump($description); + var_dump($key); + var_dump($paymentintent); + var_dump($e->getMessage());*/ + $error++; $this->error = $e->getMessage(); } } + dol_syslog("getPaymentIntent return error=".$error); + return $paymentintent; } diff --git a/htdocs/stripe/lib/stripe.lib.php b/htdocs/stripe/lib/stripe.lib.php index d806d6a39b3..100ce840e24 100644 --- a/htdocs/stripe/lib/stripe.lib.php +++ b/htdocs/stripe/lib/stripe.lib.php @@ -87,12 +87,12 @@ function showStripePaymentUrl($type, $ref) * @param string $freetag Free tag * @return string Url string */ -function getStripePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_free_tag') +function getStripePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag = 'your_tag') { global $conf; $ref=str_replace(' ', '', $ref); - + if ($type == 'free') { $out=DOL_MAIN_URL_ROOT.'/public/stripe/newpayment.php?amount='.($mode?'':'').$amount.($mode?'':'').'&tag='.($mode?'':'').$freetag.($mode?'':''); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index b8ffa08fbaf..7302191fc84 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -132,19 +132,27 @@ input.smallpadd { /* Used for timesheet input */ input.buttongen { vertical-align: middle; } -input.buttonpayment { +input.buttonpayment, button.buttonpayment, div.buttonpayment { min-width: 320px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; background: none; - padding-left: 38px; - text-align: ; - border: 1px solid #ddd; - background-color: #eee; + text-align: center; + border: 0; + background-color: #9999bb; white-space: normal; - box-shadow: 1px 1px 8px #bbb; + box-shadow: 1px 1px 4px #bbb; + color: #fff; + border-radius: 4px; +} +div.buttonpayment input { + background-color: unset; + color: #fff; + border-bottom: unset; + font-weight: bold; + text-transform: uppercase; } input.buttonpaymentcb { background-image: url(); @@ -3569,6 +3577,7 @@ div#card-errors { color: #fa755a; text-align: center; padding-top: 3px; + max-width: 320px; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 755736eb79f..2906da3729c 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -352,18 +352,25 @@ input.smallpadd { /* Used for timesheet input */ input.buttongen { vertical-align: middle; } -input.buttonpayment { +input.buttonpayment, button.buttonpayment, div.buttonpayment { min-width: 320px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; background: none; - padding-left: 30px; - text-align: ; + text-align: center; border: 2px solid #ccc; background-color: #eee; white-space: normal; + color: #888 !important; +} +div.buttonpayment input { + background-color: unset; + border-bottom: unset; + font-weight: bold; + text-transform: uppercase; + color: #333; } input.buttonpaymentcb { background-image: url(); @@ -3660,6 +3667,7 @@ div#card-errors { color: #fa755a; text-align: center; padding-top: 3px; + max-width: 320px; } From ab3ad77704aaea548c00bab00f24c85b87fe8262 Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Fri, 3 May 2019 10:55:51 +0200 Subject: [PATCH 50/75] FIX : Sale representative column didn't increase nbfield variable on proposal list --- htdocs/comm/propal/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index a253b1e2eb1..24c53d26526 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -968,6 +968,7 @@ if ($resql) print ' '; } print ''; + if (! $i) $totalarray['nbfield']++; } // Extra fields From 9115df743944e10464ae61cbdd1b5193c78f7477 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 May 2019 11:25:53 +0200 Subject: [PATCH 51/75] Debug v10 --- htdocs/admin/dict.php | 46 +++++++++++-------------- htdocs/core/modules/modTicket.class.php | 7 ++-- htdocs/fourn/facture/card.php | 2 +- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index ae4fde1876b..ab5803a086a 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -652,6 +652,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder'; if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated'; if ($fieldnamekey == 'revenuestamp_type') $fieldnamekey = 'TypeOfRevenueStamp'; + if ($fieldnamekey == 'use_default') $fieldnamekey = 'UseByDefault'; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); } @@ -1053,11 +1054,12 @@ if ($id) continue; } - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees + // Define field friedly name from its technical name $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut $valuetoshow=$langs->trans($valuetoshow); // try to translate $class=''; + + if ($fieldlist[$field]=='pos') { $valuetoshow=$langs->trans("Position"); $class='width100'; } if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } if ($fieldlist[$field]=='taux') { @@ -1125,6 +1127,7 @@ if ($id) if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } if ($fieldlist[$field]=='fk_c_exp_tax_cat') { $valuetoshow=$langs->trans("CarCategory"); } if ($fieldlist[$field]=='revenuestamp_type') { $valuetoshow=$langs->trans('TypeOfRevenueStamp'); } + if ($fieldlist[$field]=='use_default') { $valuetoshow=$langs->trans('Default'); } if ($id == 2) // Special cas for state page { @@ -1197,8 +1200,10 @@ if ($id) print ''; + print '
'; + print '
'; print ''; print ''; @@ -1221,7 +1226,7 @@ if ($id) print '
'; print ''; - // Title line with search boxes + // Title line with search input fields print ''; $filterfound=0; foreach ($fieldlist as $field => $value) @@ -1276,17 +1281,12 @@ if ($id) // dans les dictionnaires de donnees $showfield=1; // By defaut $align="left"; + $cssprefix=''; $sortable=1; - $valuetoshow=''; - /* - $tmparray=getLabelOfField($fieldlist[$field]); - $showfield=$tmp['showfield']; - $valuetoshow=$tmp['valuetoshow']; - $align=$tmp['align']; - $sortable=$tmp['sortable']; - */ $valuetoshow=ucfirst($fieldlist[$field]); // By defaut $valuetoshow=$langs->trans($valuetoshow); // try to translate + + // Special cases if ($fieldlist[$field]=='source') { $valuetoshow=$langs->trans("Contact"); } if ($fieldlist[$field]=='price') { $valuetoshow=$langs->trans("PriceUHT"); } if ($fieldlist[$field]=='taux') { @@ -1304,10 +1304,7 @@ if ($id) if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } if ($fieldlist[$field]=='position') { $align='right'; } if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } - if ($fieldlist[$field]=='libelle_facture') { - //$valuetoshow=$form->textwithtooltip($langs->trans("LabelOnDocuments"), $langs->trans("LabelUsedByDefault"),2,1,img_help(1,'')); - $valuetoshow=$langs->trans("LabelOnDocuments"); - } + if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments"); } if ($fieldlist[$field]=='country') { $valuetoshow=$langs->trans("Country"); } if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; } if ($fieldlist[$field]=='nbjour') { $valuetoshow=$langs->trans("NbOfDays"); } @@ -1316,7 +1313,6 @@ if ($id) if ($fieldlist[$field]=='width' || $fieldlist[$field]=='nx') { $valuetoshow=$langs->trans("Width"); } if ($fieldlist[$field]=='height' || $fieldlist[$field]=='ny') { $valuetoshow=$langs->trans("Height"); } if ($fieldlist[$field]=='unit' || $fieldlist[$field]=='metric') { $valuetoshow=$langs->trans("MeasuringUnit"); } - if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); } if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); $sortable=0; } if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); $sortable=0; } @@ -1347,11 +1343,14 @@ if ($id) if ($fieldlist[$field]=='range_ik') { $valuetoshow=$langs->trans("RangeIk"); } if ($fieldlist[$field]=='fk_c_exp_tax_cat') { $valuetoshow=$langs->trans("CarCategory"); } if ($fieldlist[$field]=='revenuestamp_type') { $valuetoshow=$langs->trans('TypeOfRevenueStamp'); } + if ($fieldlist[$field]=='use_default') { $valuetoshow=$langs->trans('Default'); } - // Affiche nom du champ + if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } + + // Show field title if ($showfield) { - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder, $cssprefix); } } // Favorite - Only activated on country dictionary @@ -1806,7 +1805,6 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if (in_array('region_id', $fieldlist)) { print ''; continue; } // For state page, we do not show the country input (we link to region, not country) @@ -1912,7 +1910,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) { - print ''; + print ''; } elseif ($fieldlist[$field]=='unit') { print ''; + print ''; } /* From 6797c951644e2cea922d42c2495d5a9295e175de Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 May 2019 12:10:29 +0200 Subject: [PATCH 52/75] Fix syntax error --- .../accountancy/bookkeeping/thirdparty_lettering_supplier.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php index 3795099c78d..fab30066982 100644 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php @@ -197,7 +197,7 @@ if ($resql) { print ''; print ''; - $letteringbutton = '\'; + $letteringbutton = ''; print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); From 61547e3f824c8c68c9a800a8cace7c1857b14cfe Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 3 May 2019 14:08:20 +0200 Subject: [PATCH 53/75] NEW Manage account sell_intra & sell_export in page default product --- htdocs/accountancy/admin/productaccount.php | 141 +++++++++++++++----- htdocs/langs/en_US/accountancy.lang | 4 + 2 files changed, 111 insertions(+), 34 deletions(-) diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 537eddfceb4..bd79791f709 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2016 Alexandre Spangaro + * Copyright (C) 2013-2019 Alexandre Spangaro * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2015 Ari Elbaz (elarifr) @@ -111,6 +111,8 @@ if ($action == 'update') { $accounting_product_modes = array ( 'ACCOUNTANCY_SELL', + 'ACCOUNTANCY_SELL_INTRA', + 'ACCOUNTANCY_SELL_EXPORT', 'ACCOUNTANCY_BUY' ); @@ -158,6 +160,12 @@ if ($action == 'update') { if ($accounting_product_mode == 'ACCOUNTANCY_SELL') { $sql .= " SET accountancy_code_sell = " . $accounting->account_number; } + if ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + $sql .= " SET accountancy_code_sell_intra = " . $accounting->account_number; + } + if ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') { + $sql .= " SET accountancy_code_sell_export = " . $accounting->account_number; + } $sql .= " WHERE rowid = " . $productid; dol_syslog("/accountancy/admin/productaccount.php sql=" . $sql, LOG_DEBUG); @@ -193,15 +201,19 @@ $form = new FormAccounting($db); // so we need to get those default value rowid first $accounting = new AccountingAccount($db); // TODO: we should need to check if result is a really exist accountaccount rowid..... -$aarowid_servbuy = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1); -$aarowid_prodbuy = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1); -$aarowid_servsell = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1); -$aarowid_prodsell = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1); +$aarowid_servbuy = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1); +$aarowid_prodbuy = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1); +$aarowid_servsell = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1); +$aarowid_prodsell = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1); +$aarowid_prodsell_intra = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT, 1); +$aarowid_prodsell_export = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT, 1); -$aacompta_servbuy = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodbuy = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_servbuy = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_prodbuy = (! empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_servsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_prodsell_intra = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_prodsell_export = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); llxHeader('', $langs->trans("ProductsBinding")); @@ -209,27 +221,45 @@ $pcgverid = $conf->global->CHARTOFACCOUNTS; $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version'); if (empty($pcgvercode)) $pcgvercode=$pcgverid; -$sql = "SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.accountancy_code_sell, p.accountancy_code_buy, p.tms, p.fk_product_type as product_type,"; +$sql = "SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.tms, p.fk_product_type as product_type,"; $sql.= " aa.rowid as aaid"; $sql.= " FROM " . MAIN_DB_PREFIX . "product as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON"; if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { $sql.=" p.accountancy_code_buy = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'"; } -else +elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') { $sql.=" p.accountancy_code_sell = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'"; } +elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') +{ + $sql.=" p.accountancy_code_sell_intra = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'"; +} +else +{ + $sql.=" p.accountancy_code_sell_intra = aa.account_number AND aa.fk_pcg_version = '" . $pcgvercode . "'"; +} $sql.= ' WHERE p.entity IN ('.getEntity('product').')'; if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { if (strlen(trim($search_current_account))) { $sql .= natural_search("p.accountancy_code_buy", $search_current_account); } -} else { +} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') { if (strlen(trim($search_current_account))) { $sql .= natural_search("p.accountancy_code_sell", $search_current_account); } } +elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + if (strlen(trim($search_current_account))) { + $sql .= natural_search("p.accountancy_code_sell_intra", $search_current_account); + } +} +else { + if (strlen(trim($search_current_account))) { + $sql .= natural_search("p.accountancy_code_sell_export", $search_current_account); + } +} if ($search_current_account_valid == 'withoutvalidaccount') { $sql .= " AND aa.account_number IS NULL"; @@ -280,7 +310,7 @@ if ($result) if ($search_current_account > 0) $param.="&search_current_account=".urlencode($search_current_account); if ($search_current_account_valid && $search_current_account_valid != '-1') $param.="&search_current_account_valid=".urlencode($search_current_account_valid); if ($accounting_product_mode) $param.='&accounting_product_mode='.urlencode($accounting_product_mode); - + print ''; if ($optioncss != '') print ''; print ''; @@ -301,9 +331,15 @@ if ($result) print ''; print ''; print "\n"; - print ''; + print ''; print '\n"; + print ''; + print '\n"; + print ''; + print '\n"; print ''; print '\n"; print "
'; - //print join(',',$fieldlist); print ''; @@ -1972,12 +1970,8 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $classtd=''; $class=''; if ($fieldlist[$field]=='code') $classtd='width100'; - if ($fieldlist[$field]=='affect') $class='maxwidth50'; - if ($fieldlist[$field]=='delay') $class='maxwidth50'; - if ($fieldlist[$field]=='position') $class='maxwidth50'; - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $class='quatrevingtpercent'; - if ($fieldlist[$field]=='tracking') $class='quatrevingtpercent'; - if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $class='maxwidth50'; + if (in_array($fieldlist[$field], array('pos', 'use_default', 'affect', 'delay', 'position', 'sortorder', 'sens', 'category_type'))) $class='maxwidth50'; + if (in_array($fieldlist[$field], array('libelle', 'label', 'tracking'))) $class='quatrevingtpercent'; print ''; $transfound=0; if (in_array($fieldlist[$field], array('label','libelle'))) diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 5aef264a11e..871bc94670d 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -120,15 +120,16 @@ class modTicket extends DolibarrModules } $this->dictionaries = array( 'langs' => 'ticket', - 'tabname' => array(MAIN_DB_PREFIX . "c_ticket_type", MAIN_DB_PREFIX . "c_ticket_category", MAIN_DB_PREFIX . "c_ticket_severity"), - 'tablib' => array("TicketDictType", "TicketDictCategory", "TicketDictSeverity"), - 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_category as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_severity as f'), + 'tabname' => array(MAIN_DB_PREFIX . "c_ticket_type", MAIN_DB_PREFIX . "c_ticket_severity", MAIN_DB_PREFIX . "c_ticket_category"), + 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory"), + 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_severity as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_category as f'), 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC"), 'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), 'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), 'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), 'tabrowid' => array("rowid", "rowid", "rowid"), 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled), + 'tabhelp' => array(array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"))), ); // Boxes diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 5c47aa41f40..f7a1c800443 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -2789,7 +2789,7 @@ else } else { - print '
'.$langs->trans("None").'
'.$langs->trans("None").'
' . $langs->trans('Options') . '' . $langs->trans('Description') . '
' . $langs->trans('OptionModeProductSell') . '
' . $langs->trans('OptionModeProductSell') . ''.$langs->trans('OptionModeProductSellDesc'); print "
' . $langs->trans('OptionModeProductSellIntra') . ''.$langs->trans('OptionModeProductSellIntraDesc'); + print "
' . $langs->trans('OptionModeProductSellExport') . ''.$langs->trans('OptionModeProductSellExportDesc'); + print "
' . $langs->trans('OptionModeProductBuy') . ''.$langs->trans('OptionModeProductBuyDesc')."
\n"; @@ -318,9 +354,9 @@ if ($result) $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - $buttonsave = ''; - //print '
'.$buttonsave.'
'; - + $buttonsave = ''; + //print '
'.$buttonsave.'
'; + $texte=$langs->trans("ListOfProductsServices"); print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $buttonsave, $num, $nbtotalofrecords, '', 0, '', '', $limit); @@ -332,7 +368,7 @@ if ($result) print ''; if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print ''; // On sell - if ($accounting_product_mode == 'ACCOUNTANCY_SELL') print ''; + if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') print ''; // On buy if ($accounting_product_mode == 'ACCOUNTANCY_BUY') print ''; // Current account @@ -352,10 +388,19 @@ if ($result) print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); if (! empty($conf->global->ACCOUNTANCY_SHOW_PROD_DESC)) print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "p.description", "", $param, '', $sortfield, $sortorder); - if ($accounting_product_mode == 'ACCOUNTANCY_SELL') print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center '); - if ($accounting_product_mode == 'ACCOUNTANCY_BUY') print_liste_field_titre("OnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center '); - if ($accounting_product_mode == 'ACCOUNTANCY_BUY') $fieldtosortaccount="p.accountancy_code_buy"; - else $fieldtosortaccount="p.accountancy_code_sell"; + if ($accounting_product_mode == 'ACCOUNTANCY_SELL') { + print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center '); + $fieldtosortaccount="p.accountancy_code_sell"; + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center '); + $fieldtosortaccount="p.accountancy_code_sell_intra"; + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') { + print_liste_field_titre("OnSell", $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center '); + $fieldtosortaccount="p.accountancy_code_sell_export"; + } else { + if ($accounting_product_mode == 'ACCOUNTANCY_BUY') print_liste_field_titre("OnBuy", $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center '); + $fieldtosortaccount="p.accountancy_code_buy"; + } print_liste_field_titre("CurrentDedicatedAccountingAccount", $_SERVER["PHP_SELF"], $fieldtosortaccount, "", $param, '', $sortfield, $sortorder); print_liste_field_titre("AssignDedicatedAccountingAccount"); $clickpitco=$form->showCheckAddButtons('checkforselect', 1); @@ -378,10 +423,16 @@ if ($result) $product_static->status = $obj->tosell; $product_static->status_buy = $obj->tobuy; - if ($obj->product_type == 0) { + if ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL') { $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); $compta_prodsell_id = $aarowid_prodsell; - } else { + } elseif ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); + $compta_prodsell_id = $aarowid_prodsell_intra; + } elseif ($obj->product_type == 0 && $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') { + $compta_prodsell = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); + $compta_prodsell_id = $aarowid_prodsell_export; + } else { $compta_prodsell = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); $compta_prodsell_id = $aarowid_servsell; } @@ -411,7 +462,7 @@ if ($result) print '' . nl2br(dol_trunc($obj->description, $trunclengh)) . ''; } - if ($accounting_product_mode == 'ACCOUNTANCY_SELL') + if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') print ''.$product_static->getLibStatut(3, 0).''; if ($accounting_product_mode == 'ACCOUNTANCY_BUY') @@ -422,12 +473,16 @@ if ($result) if ($accounting_product_mode == 'ACCOUNTANCY_BUY') { print length_accountg($obj->accountancy_code_buy); if ($obj->accountancy_code_buy && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount")); - } - else - { - print length_accountg($obj->accountancy_code_sell); - if ($obj->accountancy_code_sell && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount")); - } + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') { + print length_accountg($obj->accountancy_code_sell); + if ($obj->accountancy_code_sell && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount")); + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + print length_accountg($obj->accountancy_code_sell_intra); + if ($obj->accountancy_code_sell_intra && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount")); + } else { + print length_accountg($obj->accountancy_code_sell_export); + if ($obj->accountancy_code_sell_export && empty($obj->aaid)) print ' '.img_warning($langs->trans("ValueNotIntoChartOfAccount")); + } print ''; // Dedicated account @@ -441,7 +496,7 @@ if ($result) if (! empty($obj->aaid)) $defaultvalue = ''; // Do not suggest default new value is code is already valid print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1); print ''; - } else { + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') { // Accounting account sell print ''; //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha'); This is id and we need a code @@ -451,7 +506,26 @@ if ($result) if (! empty($obj->aaid)) $defaultvalue = ''; // Do not suggest default new value is code is already valid print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1); print ''; - } + } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { + // Accounting account sell intra (In EEC) + print ''; + //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha'); This is id and we need a code + if (empty($defaultvalue)) $defaultvalue=$compta_prodsell; + $codesell=length_accountg($obj->accountancy_code_sell_intra); + //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell); + if (! empty($obj->aaid)) $defaultvalue = ''; // Do not suggest default new value is code is already valid + print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1); + print ''; + } else { + // Accounting account sell export (Out of EEC) + print ''; + //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha'); This is id and we need a code + if (empty($defaultvalue)) $defaultvalue=$compta_prodsell; + $codesell=length_accountg($obj->accountancy_code_sell_export); + if (! empty($obj->aaid)) $defaultvalue = ''; // Do not suggest default new value is code is already valid + print $form->select_account($defaultvalue, 'codeventil_' . $product_static->id, 1, array(), 1); + print ''; + } // Checkbox select print ''; @@ -462,7 +536,6 @@ if ($result) print ''; print '
'; - // Example : Adding jquery code print '