dolibarr  20.0.0-beta
interface_80_modStripe_Stripe.class.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Copyright (C) 2018 ptibogxiv <support@ptibogxiv.net>
4  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
31 require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
32 
33 
38 {
44  public function __construct($db)
45  {
46  $this->db = $db;
47 
48  $this->name = preg_replace('/^Interface/i', '', get_class($this));
49  $this->family = 'stripe';
50  $this->description = "Triggers of the module Stripe";
51  $this->version = self::VERSIONS['prod'];
52  $this->picto = 'stripe';
53  }
54 
67  public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
68  {
69  // Put here code you want to execute when a Dolibarr business event occurs.
70  // Data and type of action are stored into $object and $action
71  global $langs, $db, $conf;
72 
73  if (empty($conf->stripe) || empty($conf->stripe->enabled)) {
74  return 0;
75  }
76 
77  require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
78  $stripe = new Stripe($db);
79 
80  $ok = 1;
81 
82  $service = 'StripeTest';
83  $servicestatus = 0;
84  if (getDolGlobalString('STRIPE_LIVE') && !GETPOST('forcesandbox', 'alpha')) {
85  $service = 'StripeLive';
86  $servicestatus = 1;
87  }
88 
89  // If customer is linked to Stripe, we update/delete Stripe too
90  if ($action == 'COMPANY_MODIFY' && $object instanceof Societe) {
91  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
92 
93  $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined.
94 
95  if ($object->client != 0) {
96  $customer = $stripe->customerStripe($object, $stripeacc, $servicestatus); // This make a network request
97  if ($customer) {
98  $namecleaned = $object->name ? $object->name : null;
99  $vatcleaned = $object->tva_intra ? $object->tva_intra : null; // Example of valid numbers are 'FR12345678901' or 'FR12345678902'
100  $desccleaned = $object->name_alias ? $object->name_alias : null;
101  $taxexemptcleaned = $object->tva_assuj ? 'none' : 'exempt';
102  $langcleaned = $object->default_lang ? array(substr($object->default_lang, 0, 2)) : null;
103  /*$taxinfo = array('type'=>'vat');
104  if ($vatcleaned)
105  {
106  $taxinfo["tax_id"] = $vatcleaned;
107  }
108  // We force data to "null" if not defined as expected by Stripe
109  if (empty($vatcleaned)) $taxinfo=null;*/
110 
111  // Detect if we change a Stripe info (email, description, vat id)
112  $changerequested = 0;
113  if (!empty($object->email) && $object->email != $customer->email) {
114  $changerequested++;
115  }
116  /* if ($namecleaned != $customer->description) $changerequested++;
117  if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++;
118  elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++;
119  elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned))
120  {
121  if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++;
122  } */
123  if ($namecleaned != $customer->name) {
124  $changerequested++;
125  }
126  if ($desccleaned != $customer->description) {
127  $changerequested++;
128  }
129  if (($customer->tax_exempt == 'exempt' && !$object->tva_assuj) || (!$customer->tax_exempt == 'exempt' && empty($object->tva_assuj))) {
130  $changerequested++;
131  }
132  if (!isset($customer->tax_ids->data) && !is_null($vatcleaned)) {
133  $changerequested++;
134  } elseif (isset($customer->tax_ids->data)) {
135  $taxinfo = reset($customer->tax_ids->data);
136  if (empty($taxinfo) && !empty($vatcleaned)) {
137  $changerequested++;
138  }
139  if (isset($taxinfo->value) && $vatcleaned != $taxinfo->value) {
140  $changerequested++;
141  }
142  }
143 
144  if ($changerequested) {
145  /*if (!empty($object->email)) $customer->email = $object->email;
146  $customer->description = $namecleaned;
147  if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null);
148  else $customer->tax_info = $taxinfo; */
149  $customer->name = $namecleaned;
150  $customer->description = $desccleaned;
151  $customer->preferred_locales = $langcleaned;
152  $customer->tax_exempt = $taxexemptcleaned;
153 
154  try {
155  // Update Tax info on Stripe
156  if (getDolGlobalString('STRIPE_SAVE_TAX_IDS')) { // We setup to save Tax info on Stripe side. Warning: This may result in error when saving customer
157  if (!empty($vatcleaned)) {
158  $isineec = isInEEC($object);
159  if ($object->country_code && $isineec) {
160  //$taxids = $customer->allTaxIds($customer->id);
161  $customer->createTaxId($customer->id, array('type' => 'eu_vat', 'value' => $vatcleaned));
162  }
163  } else {
164  $taxids = $customer->allTaxIds($customer->id);
165  if (is_array($taxids->data)) {
166  foreach ($taxids->data as $taxidobj) {
167  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
168  $customer->deleteTaxId($customer->id, $taxidobj->id);
169  }
170  }
171  }
172  }
173 
174  // Update Customer on Stripe
175  // @phan-suppress-next-line PhanDeprecatedFunction
176  $customer->save();
177  } catch (Exception $e) {
178  //var_dump(\Stripe\Stripe::getApiVersion());
179  $this->errors[] = $e->getMessage();
180  $ok = -1;
181  }
182  }
183  }
184  }
185  }
186  if ($action == 'COMPANY_DELETE' && $object instanceof Societe) {
187  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
188 
189  if (getDolGlobalString('STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRDPARTY')) {
190  // By default, we do not delete the stripe account. We may need to reuse it with its payment_intent, for example if delete is for a merge of thirdparties.
191  $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined.
192 
193  $customer = $stripe->customerStripe($object, $stripeacc, $servicestatus);
194  if ($customer) {
195  try {
196  $customer->delete();
197  } catch (Exception $e) {
198  dol_syslog("Failed to delete Stripe customer ".$e->getMessage(), LOG_WARNING);
199  }
200  }
201  }
202 
203  $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account";
204  $sql .= " WHERE site='stripe' AND fk_soc = ".((int) $object->id);
205  $this->db->query($sql);
206  }
207 
208  // If payment mode is linked to Stripe, we update/delete Stripe too
209  if ($action == 'COMPANYPAYMENTMODE_CREATE' && $object->type == 'card') {
210  // For creation of credit card, we do not create in Stripe automatically
211  }
212  if ($action == 'COMPANYPAYMENTMODE_MODIFY' && $object->type == 'card' && $object instanceof CompanyPaymentMode) {
213  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
214 
215  if (!empty($object->stripe_card_ref)) {
216  $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined.
217  $stripecu = $stripe->getStripeCustomerAccount($object->fk_soc); // No need of network access for this
218 
219  if ($stripecu) {
220  // Get customer (required to get a card)
221  if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
222  $customer = \Stripe\Customer::retrieve($stripecu);
223  } else {
224  $customer = \Stripe\Customer::retrieve($stripecu, array("stripe_account" => $stripeacc));
225  }
226 
227  if ($customer) {
228  dol_syslog("We got the customer, so now we update the credit card", LOG_DEBUG);
229  $card = $stripe->cardStripe($customer, $object, $stripeacc, $servicestatus);
230  if ($card) {
231  // @phpstan-ignore-next-line @phan-suppress-next-line PhanTypeMismatchPropertyProbablyReal
232  $card->metadata = array('dol_id' => $object->id, 'dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'ipaddress' => (empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']));
233  try {
234  // @phan-suppress-next-line PhanDeprecatedFunction
235  $card->save();
236  } catch (Exception $e) {
237  $ok = -1;
238  $this->errors[] = $e->getMessages();
239  }
240  }
241  }
242  }
243  }
244  }
245  if ($action == 'COMPANYPAYMENTMODE_DELETE' && $object->type == 'card' && $object instanceof CompanyPaymentMode) {
246  dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
247 
248  if (!empty($object->stripe_card_ref)) {
249  $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined.
250  $stripecu = $stripe->getStripeCustomerAccount($object->fk_soc); // No need of network access for this
251 
252  if ($stripecu) {
253  // Get customer (required to get a card)
254  if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
255  $customer = \Stripe\Customer::retrieve($stripecu);
256  } else {
257  $customer = \Stripe\Customer::retrieve($stripecu, array("stripe_account" => $stripeacc));
258  }
259 
260  if ($customer) {
261  $card = $stripe->cardStripe($customer, $object, $stripeacc, $servicestatus);
262  if ($card) {
263  if (method_exists($card, 'detach')) {
264  $card->detach();
265  } else {
266  $card->delete();
267  }
268  }
269  }
270  }
271  }
272  }
273 
274  return $ok;
275  }
276 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
Class for CompanyPaymentMode.
Class to stock current configuration.
Definition: conf.class.php:34
Class that all triggers must inherit.
Class of triggers for stripe module.
runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
Function called when a Dolibarr business event is done.
Class to manage third parties objects (customers, suppliers, prospects...)
Stripe class @TODO No reason to extends CommonObject.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:50
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:126