diff --git a/.gitignore b/.gitignore
index 0beed12..04ae816 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
/.settings/
/.project
/.idea/
+/.vscode
/vendor/
diff --git a/class/business/eCommerceSynchro.class.php b/class/business/eCommerceSynchro.class.php
index da3944b..a92290c 100755
--- a/class/business/eCommerceSynchro.class.php
+++ b/class/business/eCommerceSynchro.class.php
@@ -4317,7 +4317,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4320");
// Set the order
//---------------------------
if (!$error) {
@@ -4340,6 +4340,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
// Update order
if ($order->id > 0) {
+ dol_syslog("!! ecommerceng #4343");
$new_order = false;
if (!empty($conf->global->ECOMMERCENG_ENABLE_LOG_IN_NOTE)) {
$order->note_private = dol_concatdesc($order->note_private, $this->langs->trans('ECommerceUpdateOrderFromSiteNote', dol_print_date(dol_now(), 'dayhour'), $this->eCommerceSite->name, $order_data['remote_id']));
@@ -4356,6 +4357,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
} // Create order
else {
+ dol_syslog("!! ecommerceng #4360");
$new_order = true;
$order->statut = Commande::STATUS_DRAFT; // STATUS_DRAFT by default at creation
$order->cond_reglement_id = isset($this->eCommerceSite->parameters['payment_cond']) ? $this->eCommerceSite->parameters['payment_cond'] : null;
@@ -4378,7 +4380,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
if (empty($order->error) && empty($order->errors)) $this->errors[] = $this->db->lasterror();
$error++;
}
-
+ dol_syslog("!! ecommerceng #4383");
// Add / update contacts
if (!$error) {
// Search or create the third party for customer contact
@@ -4558,23 +4560,23 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4563");
// Add product line if new created
if (!$error && $new_order && count($order_data['items'])) {
if (empty($conf->global->ECOMMERCENG_DISABLED_PRODUCT_SYNCHRO_STOD)) {
// Get products to synchronize
$remote_id_to_synchronize = array();
foreach ($order_data['items'] as $item) {
-// $this->initECommerceProduct();
-// $result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
-// if ($result < 0 && !empty($this->eCommerceProduct->error)) {
-// $this->error = $this->eCommerceProduct->error;
-// $this->errors = array_merge($this->errors, $this->eCommerceProduct->errors);
-// $error++;
-// } elseif ($result <= 0) {
+ //$this->initECommerceProduct();
+ //$result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
+ //if ($result < 0 && !empty($this->eCommerceProduct->error)) {
+ //$this->error = $this->eCommerceProduct->error;
+ //$this->errors = array_merge($this->errors, $this->eCommerceProduct->errors);
+ //$error++;
+ //} elseif ($result <= 0) {
if (!empty($item['id_remote_product']))
$remote_id_to_synchronize[] = str_replace('|%', '', $item['id_remote_product']);
-// }
+ //}
}
// Synchronize the product to synchronize
@@ -4689,7 +4691,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4694");
// Set amount paid warning
if (!$error && price2num($order_data['payment_amount_ttc']) != price2num($order->total_ttc)) {
$result = $order->update_note(dol_concatdesc($this->langs->trans('ECommerceWarningWrongAmountTTCWithPaid', $order_data['payment_amount_ttc']), $order->note_private), '_private');
@@ -4700,7 +4702,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$error++;
}
}
-
+ dol_syslog("!! ecommerceng #4705");
// Get payment gateways
if (!$error && !empty($order_data['payment_method_id'])) {
$result = $this->loadPaymentGateways();
@@ -4715,7 +4717,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4720");
// Search payment mode by ID if payment gateways found
if (!$error && isset($selected_payment_gateways)) {
if ($selected_payment_gateways['payment_mode_id'] > 0) {
@@ -4725,7 +4727,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$error++;
}
}
-
+ dol_syslog("!! ecommerceng #4730");
// Search payment mode by label
if (!$error && !($payment_method_id > 0) && !empty($order_data['payment_method'])) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
@@ -4738,7 +4740,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$payment_method_id = $result;
}
}
-
+ dol_syslog("!! ecommerceng #4743");
// Set payment mode
$payment_methods_already_set = false;
if (!$error && $payment_method_id > 0 && $order->statut >= 0) {
@@ -4752,7 +4754,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$payment_methods_already_set = true;
}
}
-
+ dol_syslog("!! ecommerceng #4757");
// Update the order status
if (!$error && ($new_order || ($order->statut != $order_data['status']))) { // Always when creating
// Todo We don't change stock here, even if dolibarr option is on because, this should be already done by product sync ?
@@ -4820,7 +4822,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4825");
// Set payment mode
if (!$error && !$payment_methods_already_set && $payment_method_id > 0 && $order->statut >= 0) {
$result = $order->setPaymentMethods($payment_method_id);
@@ -4838,7 +4840,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
}
}
}
-
+ dol_syslog("!! ecommerceng #4843 $bypass");
// Update the link of the synchronization
//--------------------------------------------
if (!$error && !$bypass) {
@@ -4865,7 +4867,7 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$error++;
}
}
-
+ dol_syslog("!! ecommerceng #4870");
$last_sync_date = 'ECOMMERCE_LAST_SYNC_DATE_ORDER_' . $this->eCommerceSite->id;
if (!$error && (!is_numeric($conf->global->$last_sync_date) || $conf->global->$last_sync_date < $order_data['create_date'])) {
$result = dolibarr_set_const($this->db, $last_sync_date, $order_data['create_date'], 'chaine', 0, '', $conf->entity);
@@ -4880,11 +4882,20 @@ public function synchronizeOrder($order_data, $dont_synchronize_products = false
$this->errors[] = $e->getMessage();
$error++;
}
-
+ dol_syslog("!! ecommerceng #4885 $error $bypass");
if (!$error && !$bypass) {
- $result = $this->synchronizeInvoiceFromOrder($order_data, $dont_synchronize_products);
- if ($result < 0) {
+ $invoice_id = $this->synchronizeInvoiceFromOrder($order_data, $dont_synchronize_products);
+ if ($invoice_id < 0) {
$error++;
+ }else{
+ if(!is_empty($order_data->refunds)){
+ foreach($order_data->refunds as $i=>$refund){
+ $result = $this->synchronizeCreditNoteFromOrder($order_data, $dont_synchronize_products, $invoice_id, $i);
+ if ($result < 0) {
+ $error++;
+ }
+ }
+ }
}
}
@@ -4946,6 +4957,10 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
try {
// Fetch invoice by ref_ext
$result = $invoice->fetch(0, '', $invoice_ref_ext);
+ dol_syslog("!! ecommerceng #4949 $result");
+ dol_syslog("!! ecommerceng #4949 ". $this->eCommerceSite->parameters['order_actions']['create_invoice']);
+ dol_syslog("!! ecommerceng #4949 ". $order_data['billed']);
+ dol_syslog(var_export($order_data, true));
if ($result < 0) {
$this->error = $invoice->error;
$this->errors = array_merge($this->errors, $invoice->errors);
@@ -4954,6 +4969,7 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
// Check if order / invoice already synchronized
$this->initECommerceCommande();
$result = $this->eCommerceCommande->fetchByRemoteId($order_data['remote_id'], $this->eCommerceSite->id);
+ dol_syslog("!! ecommerceng #4957 $result");
if ($result < 0 && !empty($this->eCommerceCommande->error)) {
$this->errors[] = $this->langs->trans('ECommerceErrorFetchOrderLinkByRemoteId', $order_data['remote_id'], $this->eCommerceSite->id);
$this->errors[] = $this->eCommerceCommande->error;
@@ -4963,7 +4979,8 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
$order_id = $this->eCommerceCommande->fk_commande;
}
}
-
+
+ dol_syslog("!! ecommerceng #4968 $error");
// Fetch order
if (!$error) {
if (!($order_id > 0)) {
@@ -4985,7 +5002,7 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
}
}
}
-
+ dol_syslog("!! ecommerceng #4996");
if (!$error) {
// Recreate the link to the order if not exist
if ($invoice->id > 0) {
@@ -4994,7 +5011,7 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
else {
// Need to synchronize ?
$bypass = $order_data['create_date'] < $this->eCommerceSite->parameters['order_first_date_etod'];
-
+ dol_syslog("!! ecommerceng #5005 $bypass");
if (!$bypass) {
if ($order->id > 0) {
$third_party_id = $order->socid;
@@ -5391,16 +5408,1352 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
// Get products to synchronize
$remote_id_to_synchronize = array();
foreach ($order_data['items'] as $item) {
-// $this->initECommerceProduct();
-// $result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
-// if ($result < 0 && !empty($this->eCommerceProduct->error)) {
-// $this->error = $this->eCommerceProduct->error;
-// $this->errors = array_merge($this->errors, $this->eCommerceProduct->errors);
-// $error++;
-// } elseif ($result <= 0) {
+ //$this->initECommerceProduct();
+ //$result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
+ //if ($result < 0 && !empty($this->eCommerceProduct->error)) {
+ // $this->error = $this->eCommerceProduct->error;
+ // $this->errors = array_merge($this->errors, $this->eCommerceProduct->errors);
+ // $error++;
+ //} elseif ($result <= 0) {
+ if (!empty($item['id_remote_product']))
+ $remote_id_to_synchronize[] = str_replace('|%', '', $item['id_remote_product']);
+ //}
+ }
+
+ // Synchronize the product to synchronize
+ if (!empty($remote_id_to_synchronize) && !$dont_synchronize_products) {
+ // Todo We don't change stock here, even if dolibarr option is on because, this should be already done by product sync ?
+ $result = $this->synchronizeProducts(null, null, $remote_id_to_synchronize, count($remote_id_to_synchronize), false, $invoice);
+ if ($result < 0) {
+ $error++;
+ }
+ }
+ }
+
+ // Add product lines
+ if (!$error) {
+ // If we create a deposit with all lines and a percent, we change amount
+ if ($isDepositType && $typeAmount == 'variablealllines') {
+ foreach ($order_data['items'] as $k => $item) {
+ // We keep 'price', but we change the 'qty'
+ $order_data['items'][$k]['qty'] = price2num($item['qty'] * $valueDeposit / 100, 'MS');
+ }
+ }
+
+ $parent_match = array();
+ foreach ($order_data['items'] as $item) {
+ // Get product ID
+ $fk_product = 0;
+ if (!empty($item['id_remote_product'])) {
+ if (empty($conf->global->ECOMMERCENG_DISABLED_PRODUCT_SYNCHRO_STOD)) {
+ $this->initECommerceProduct();
+ $result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
+ if ($result < 0 && !empty($this->eCommerceProduct->error)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchProductLinkByRemoteId', $item['id_remote_product'], $this->eCommerceSite->id);
+ $this->errors[] = $this->eCommerceProduct->error;
+ $error++;
+ break; // break on items
+ } elseif ($result > 0) {
+ $fk_product = $this->eCommerceProduct->fk_product;
+ }
+ } else {
+ $product_ref = trim($item['ref']);
+ if (!empty($product_ref)) {
+ $product = new Product($this->db);
+ $result = $product->fetch(0, $product_ref);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchProductByRef', $product_ref);
+ $this->errors[] = $product->errorsToString();
+ $error++;
+ break; // break on items
+ } elseif ($result == 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorProductNotFoundByRef', $product_ref);
+ $error++;
+ break; // break on items
+ }
+ $fk_product = $product->id;
+ } elseif (!empty($conf->global->ECOMMERCENG_PRODUCT_REF_MANDATORY)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorProductRefMandatory2', $item['label']);
+ $error++;
+ break; // break on items
+ }
+ }
+ } elseif (!empty($item['id_product'])) {
+ $fk_product = $item['id_product'];
+ }
+
+ if (!$error) {
+ $price = $item['price'];
+ $total_ht = $item['total_ht'];
+ $total_tva = $item['total_tva'];
+ $total_ttc = $item['total_ttc'];
+ $description = $item['description'];
+ if (empty($description) && $fk_product > 0) {
+ $product = new Product($this->db);
+ $product->fetch($fk_product);
+ $description = $product->description;
+ }
+ $description = dol_concatdesc($description, $item['additional_description']);
+
+ if ($price < 0 && empty($conf->global->ECOMMERCE_KEEP_NEGATIVE_PRICE_LINES_WHEN_CREATE_INVOICE)) {
+ // Negative line, we create a discount line
+ $discount = new DiscountAbsolute($this->db);
+ $discount->fk_soc = $invoice->socid;
+ $discount->amount_ht = abs($total_ht);
+ $discount->amount_tva = abs($total_tva);
+ $discount->amount_ttc = abs($total_ttc);
+ $discount->tva_tx = $item['tva_tx'];
+ $discount->fk_user = $this->user->id;
+ $discount->description = $description;
+ $discount_id = $discount->create($this->user);
+ if ($discount_id > 0) {
+ $result = $invoice->insert_discount($discount_id); // This include link_to_invoice
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceInsertDiscount');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ break; // break on items
+ }
+ } else {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceDiscountCreate');
+ if (!empty($discount->error)) $this->errors[] = $discount->error;
+ $this->errors = array_merge($this->errors, $discount->errors);
+ $error++;
+ break;
+ }
+ } else {
+ // Define the buy price for margin calculation
+ if (isset($item['buy_price'])) {
+ $buy_price = $item['buy_price'];
+ } else {
+ $buy_price = $item['price'];
+ if ($fk_product > 0) {
+ $result = $order->defineBuyPrice($buy_price, 0, $fk_product);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorOrderDefineBuyPrice', $fk_product, $buy_price);
+ if (!empty($order->error)) $this->errors[] = $order->error;
+ $this->errors = array_merge($this->errors, $order->errors);
+ $error++;
+ break; // break on items
+ } else {
+ $buy_price = $result;
+ }
+ }
+ }
+
+ $label = !empty($item['label']) ? $item['label'] : '';
+ $discount = $item['discount'];
+ $product_type = $item['product_type'] != "simple" ? 1 : 0;
+
+ $array_options = array();
+ if (is_array($item['extrafields'])) {
+ foreach ($item['extrafields'] as $extrafield => $extrafield_value) {
+ $array_options['options_' . $extrafield] = $extrafield_value;
+ }
+ }
+
+ $fk_parent_line = isset($parent_match[$item['parent_item_id']]) ? $parent_match[$item['parent_item_id']] : 0;
+ $result = $invoice->addline($description, $price, $item['qty'], $item['tva_tx'], $item['local_tax1_tx'], $item['local_tax2_tx'],
+ $fk_product, $discount, '', '', 0, 0, 0, 'HT',
+ 0, $product_type, -1, 0, '', 0, 0, 0, $buy_price,
+ $label, $array_options, 100, 0, 0, 0);
+ if ($result <= 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceAddLine');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ break; // break on items
+ }
+ $parent_match[$item['item_id']] = $result;
+ }
+ }
+
+ unset($this->eCommerceProduct);
+ }
+ }
+ }
+ }
+
+ // Set amount paid warning
+ if (!$error && price2num($order_data['payment_amount_ttc']) != price2num($invoice->total_ttc)) {
+ $result = $invoice->update_note(dol_concatdesc($this->langs->trans('ECommerceWarningWrongAmountTTCWithPaid', $order_data['payment_amount_ttc']), $invoice->note_private), '_private');
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorUpdatePrivateNote');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+
+ // Add contacts
+ if (!$error) {
+ // Search or create the third party for customer contact
+ $contact_data = $order_data['socpeopleCommande'];
+ $result = $this->getContactInfosFromData($contact_data, $invoice->socid);
+ if (!is_array($result) || empty($result) || !($result['company_id'] > 0)) $result = $this->getContactInfosFromData($contact_data);
+ if (!is_array($result)) {
+ $error++;
+ } elseif (!empty($result) && $result['company_id'] > 0) {
+ $order_data['socpeopleCommande']['fk_soc'] = $result['company_id'];
+ } else {
+ if (empty($contact_data['company'])) {
+ if (!empty($contact_data['firstname']) && !empty($contact_data['lastname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $contact_data['lastname']);
+ } elseif (!empty($contact_data['firstname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $this->langs->transnoentitiesnoconv("ECommerceLastNameNotInformed"));
+ } else {
+ $third_party_name = $this->langs->transnoentitiesnoconv('ECommerceFirstNameLastNameNotInformed');
+ }
+ } else {
+ $third_party_name = $contact_data['company'];
+ }
+ $result = $this->getThirdPartyByEmailOrName($contact_data['email'], $third_party_name);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleCommande']['fk_soc'] = $result;
+ } else {
+ $result = $this->createThirdParty($order_data['ref_client'],
+ $contact_data['company'], $contact_data['firstname'], $contact_data['lastname'],
+ $contact_data['address'], $contact_data['zip'], $contact_data['town'], $contact_data['country_id'], $contact_data['email'], $contact_data['phone'], $contact_data['fax']);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleCommande']['fk_soc'] = $result;
+ }
+ }
+ }
+
+ // Add customer contact
+ if (!$error) {
+ $result = $this->synchSocpeople($order_data['socpeopleCommande']);
+ if ($result > 0) {
+ $result = $this->addUpdateContact($invoice, true, $result, 'CUSTOMER');
+ if ($result < 0) {
+ $error++;
+ } else {
+ // Update thirdparty of the order
+ if ($order_data['socpeopleCommande']['fk_soc'] > 0 && $third_party_id != $order_data['socpeopleCommande']['fk_soc']) {
+ $invoice->socid = $order_data['socpeopleCommande']['fk_soc'];
+ $result = $invoice->update($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceUpdate');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+ }
+ } else {
+ $this->errors = array_merge(array($this->langs->trans('ECommerceErrorWhenSynchronizeContact')), $this->errors);
+ $error++;
+ }
+ }
+
+ // Search or create the third party for billing contact
+ if (!$error) {
+ $contact_data = $order_data['socpeopleFacture'];
+ $result = $this->getContactInfosFromData($contact_data, $invoice->socid);
+ if (!is_array($result) || empty($result) || !($result['company_id'] > 0)) $result = $this->getContactInfosFromData($contact_data);
+ if (!is_array($result)) {
+ $error++;
+ } elseif (!empty($result) && $result['company_id'] > 0) {
+ $order_data['socpeopleCommande']['fk_soc'] = $result['company_id'];
+ } else {
+ if (empty($contact_data['company'])) {
+ if (!empty($contact_data['firstname']) && !empty($contact_data['lastname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $contact_data['lastname']);
+ } elseif (!empty($contact_data['firstname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $this->langs->transnoentitiesnoconv("ECommerceLastNameNotInformed"));
+ } else {
+ $third_party_name = $this->langs->transnoentitiesnoconv('ECommerceFirstNameLastNameNotInformed');
+ }
+ } else {
+ $third_party_name = $contact_data['company'];
+ }
+ $result = $this->getThirdPartyByEmailOrName($contact_data['email'], $third_party_name);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleFacture']['fk_soc'] = $result;
+ } else {
+ $result = $this->createThirdParty($order_data['ref_client'],
+ $contact_data['company'], $contact_data['firstname'], $contact_data['lastname'],
+ $contact_data['address'], $contact_data['zip'], $contact_data['town'], $contact_data['country_id'], $contact_data['email'], $contact_data['phone'], $contact_data['fax']);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleFacture']['fk_soc'] = $result;
+ }
+ }
+ }
+ }
+
+ // Add billing contact
+ if (!$error) {
+ $result = $this->synchSocpeople($order_data['socpeopleFacture']);
+ if ($result > 0) {
+ $result = $this->addUpdateContact($invoice, true, $result, 'BILLING');
+ if ($result < 0) {
+ $error++;
+ }
+ } else {
+ $this->errors = array_merge(array($this->langs->trans('ECommerceErrorWhenSynchronizeContact')), $this->errors);
+ $error++;
+ }
+ }
+
+ // Search or create the third party for shipping contact
+ if (!$error) {
+ $contact_data = $order_data['socpeopleLivraison'];
+ $result = $this->getContactInfosFromData($contact_data, $invoice->socid);
+ if (!is_array($result) || empty($result) || !($result['company_id'] > 0)) $result = $this->getContactInfosFromData($contact_data);
+ if (!is_array($result)) {
+ $error++;
+ } elseif (!empty($result) && $result['company_id'] > 0) {
+ $order_data['socpeopleCommande']['fk_soc'] = $result['company_id'];
+ } else {
+ if (empty($contact_data['company'])) {
+ if (!empty($contact_data['firstname']) && !empty($contact_data['lastname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $contact_data['lastname']);
+ } elseif (!empty($contact_data['firstname'])) {
+ $third_party_name = dolGetFirstLastname($contact_data['firstname'], $this->langs->transnoentitiesnoconv("ECommerceLastNameNotInformed"));
+ } else {
+ $third_party_name = $this->langs->transnoentitiesnoconv('ECommerceFirstNameLastNameNotInformed');
+ }
+ } else {
+ $third_party_name = $contact_data['company'];
+ }
+ $result = $this->getThirdPartyByEmailOrName($contact_data['email'], $third_party_name);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleLivraison']['fk_soc'] = $result;
+ } else {
+ $result = $this->createThirdParty($order_data['ref_client'],
+ $contact_data['company'], $contact_data['firstname'], $contact_data['lastname'],
+ $contact_data['address'], $contact_data['zip'], $contact_data['town'], $contact_data['country_id'], $contact_data['email'], $contact_data['phone'], $contact_data['fax']);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $order_data['socpeopleLivraison']['fk_soc'] = $result;
+ }
+ }
+ }
+ }
+
+ // Add shipping contact
+ if (!$error) {
+ $result = $this->synchSocpeople($order_data['socpeopleLivraison']);
+ if ($result > 0) {
+ $result = $this->addUpdateContact($invoice, true, $result, 'SHIPPING');
+ if ($result < 0) {
+ $error++;
+ }
+ } else {
+ $this->errors = array_merge(array($this->langs->trans('ECommerceErrorWhenSynchronizeContact')), $this->errors);
+ $error++;
+ }
+ }
+
+ // Add contact
+ if (!$error && $this->eCommerceSite->parameters['default_sales_representative_follow'] > 0) {
+ $result = $this->addUpdateContact($invoice, true, $this->eCommerceSite->parameters['default_sales_representative_follow'], 'SALESREPFOLL', 'internal');
+ if ($result < 0) {
+ $error++;
+ }
+ }
+ }
+ }
+ }
+
+ // Get payment gateways
+ if (!$error && !empty($order_data['payment_method_id'])) {
+ $result = $this->loadPaymentGateways();
+ if ($result < 0) {
+ $error++;
+ } else {
+ if (isset($this->payment_gateways_cached[$order_data['payment_method_id']])) {
+ $selected_payment_gateways = $this->payment_gateways_cached[$order_data['payment_method_id']];
+ } else {
+ $this->errors[] = $this->langs->trans('ECommerceErrorPaymentGatewaysNotFound', $order_data['payment_method_id'], $order_data['payment_method']);
+ $error++;
+ }
+ }
+ }
+
+ // Search payment mode by ID if payment gateways found
+ if (!$error && isset($selected_payment_gateways)) {
+ if ($selected_payment_gateways['payment_mode_id'] > 0) {
+ $payment_method_id = $selected_payment_gateways['payment_mode_id'];
+ } else {
+ $this->errors[] = $this->langs->trans('ECommerceErrorPaymentGatewaysPaymentMethodNotConfigured', $order_data['payment_method_id'], $order_data['payment_method']);
+ $error++;
+ }
+ }
+
+ // Search payment mode by label
+ if (!$error && !($payment_method_id > 0) && !empty($order_data['payment_method'])) {
+ require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
+ $result = dol_getIdFromCode($this->db, $order_data['payment_method'], 'c_paiement', 'libelle', 'id');
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorWhenFetchPaymentMethodByLabel', $order_data['payment_method']);
+ $this->errors[] = $this->db->lasterror();
+ $error++;
+ } elseif ($result != '' && $result > 0) {
+ $payment_method_id = $result;
+ }
+ }
+
+ // Set payment mode
+ if (!$error && $payment_method_id > 0) {
+ $result = $invoice->setPaymentMethods($payment_method_id);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceSetPaymentMethods');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+
+ dol_syslog(var_export($selected_payment_gateways,true));
+ // Set bank account
+ if (!$error && isset($selected_payment_gateways)) {
+ $bank_account_id = $selected_payment_gateways['bank_account_id'] > 0 ? $selected_payment_gateways['bank_account_id'] : 0;
+ if ($bank_account_id == 0 && $conf->banque->enabled && (!empty($selected_payment_gateways['create_invoice_payment']) || !empty($selected_payment_gateways['create_supplier_invoice_payment']))) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorPaymentGatewaysBankAccountNotConfigured', $order_data['payment_method_id'], $order_data['payment_method']);
+ $error++;
+ } elseif ($bank_account_id > 0) {
+ $result = $invoice->setBankAccount($bank_account_id);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceSetBankAccount');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+ }
+
+ // Get warehouse ID
+ $warehouse_id = 0;
+ // Todo We don't change stock here, even if dolibarr option is on because, this should be already done by product sync ?
+ //if (!$error && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $this->eCommerceSite->stock_sync_direction == 'ecommerce2dolibarr') {
+ //$warehouse_id = $this->eCommerceSite->fk_warehouse > 0 ? $this->eCommerceSite->fk_warehouse : 0;
+ //if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
+ // $qualified_for_stock_change = $invoice->hasProductsOrServices(2);
+ //} else {
+ // $qualified_for_stock_change = $invoice->hasProductsOrServices(1);
+ //}
+ //
+ //if ($qualified_for_stock_change && $warehouse_id == 0) {
+ // $this->errors[] = $this->langs->trans('ECommerceErrorWarehouseNotConfigured');
+ // $error++;
+ //}
+ //}
+
+ if ($isDepositType) {
+ $save_WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER = $conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER;
+ $save_WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL = $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL;
+ $save_WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER = $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER;
+ $conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER = 0;
+ $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL = 0;
+ $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER = 0;
+ }
+
+ // Validate invoice
+ if (!$error) {
+ $result = $invoice->validate($this->user, '', $warehouse_id);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceValidate');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+
+ // Creation of payment line
+ dol_syslog("!!Ecommerceng - #5863");
+ if (!$error) {
+ dol_syslog("!!Ecommerceng - #5865");
+ if ($invoice->total_ttc != 0) {
+ dol_syslog("!!Ecommerceng - #5867");
+ dol_syslog($conf->banque->enabled);
+ if ($conf->banque->enabled && !empty($selected_payment_gateways['create_invoice_payment'])) {
+ dol_syslog("!!Ecommerceng - #5873");
+ $payment = new Paiement($this->db);
+ $payment->datepaye = $invoice->date;
+ $payment->amounts = array($invoice->id => $invoice->total_ttc); // Array with all payments dispatching with invoice id
+ $payment->multicurrency_amounts = array(); // Array with all payments dispatching
+ $payment->paiementid = $invoice->mode_reglement_id;
+ $payment->num_paiement = '';
+ $payment->note = 'Created by WooSync';
+
+ $payment_id = $payment->create($this->user, 1);
+ if ($payment_id < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceCreatePayment');
+ if (!empty($payment->error)) $this->errors[] = $payment->error;
+ $this->errors = array_merge($this->errors, $payment->errors);
+ $error++;
+ } else {
+ $result = $payment->addPaymentToBank($this->user, 'payment', '(CustomerInvoicePayment)', $bank_account_id, '', '');
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceAddPaymentToBank');
+ if (!empty($payment->error)) $this->errors[] = $payment->error;
+ $this->errors = array_merge($this->errors, $payment->errors);
+ $error++;
+ }
+ }
+ }
+ } else {
+ $result = $invoice->set_paid($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceSetPaid');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+ }
+
+ if ($isDepositType) {
+ $conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER = $save_WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER;
+ $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL = $save_WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL;
+ $conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER = $save_WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER;
+ }
+
+ // Generate document
+ if (!$error && !empty($invoice->modelpdf) && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+ // Define output language
+ $outputlangs = $this->langs;
+ $newlang = '';
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $invoice->thirdparty->default_lang;
+ if (!empty($newlang)) {
+ $outputlangs = new Translate("", $conf);
+ $outputlangs->setDefaultLang($newlang);
+ $outputlangs->load('products');
+ }
+ $invoice->fetch($invoice->id); // Reload to get new records
+
+ $hidedetails = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0;
+ $hidedesc = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0;
+ $hideref = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0;
+ $result = $invoice->generateDocument($invoice->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceGenerateDocument');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ }
+
+ // Create supplier invoice
+ if (!$error && !empty($this->eCommerceSite->parameters['order_actions']['create_supplier_invoice']) && is_array($order_data['fee_lines']) && count($order_data['fee_lines']) > 0) {
+ // Check if supplier third party configured
+ $supplier_id = $selected_payment_gateways['supplier_id'] > 0 ? $selected_payment_gateways['supplier_id'] : 0;
+ if ($supplier_id == 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorPaymentGatewaysSupplierNotConfigured', $order_data['payment_method_id'], $order_data['payment_method']);
+ $error++;
+ } else {
+ // Set the supplier invoice
+ $supplier_invoice = new FactureFournisseur($this->db);
+ $supplier_invoice->type = FactureFournisseur::TYPE_STANDARD;
+ $supplier_invoice->ref = '';
+ $supplier_invoice->ref_supplier = $invoice_ref_ext;
+ $supplier_invoice->socid = $supplier_id;
+ $supplier_invoice->libelle = '';
+ $supplier_invoice->date = $invoice->date;
+ $supplier_invoice->date_echeance = '';
+ $supplier_invoice->cond_reglement_id = 0;
+ $supplier_invoice->mode_reglement_id = $invoice->mode_reglement_id;
+ $supplier_invoice->fk_account = $bank_account_id;
+
+ if (!empty($conf->global->ECOMMERCENG_ENABLE_LOG_IN_NOTE)) {
+ $supplier_invoice->note_private = dol_concatdesc($supplier_invoice->note_private, $this->langs->trans('ECommerceCreateSupplierInvoiceFromSiteNote', $this->eCommerceSite->name) . " :\n" . json_encode($order_data['remote_order']));
+ }
+
+ $supplier_invoice->linkedObjectsIds[$invoice->element] = $invoice->id;
+ if ($order->id > 0) {
+ $supplier_invoice->linkedObjectsIds[$order->element] = $order->id;
+ }
+
+ // Create supplier invoice
+ $id = $supplier_invoice->create($this->user);
+ if ($id < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceCreate');
+ if (!empty($supplier_invoice->error)) $this->errors[] = $supplier_invoice->error;
+ $this->errors = array_merge($this->errors, $supplier_invoice->errors);
+ $error++;
+ }
+
+ // Add lines
+ if (!$error) {
+ $product_id = $selected_payment_gateways['product_id_for_fee'] > 0 ? $selected_payment_gateways['product_id_for_fee'] : 0;
+ foreach ($order_data['fee_lines'] as $fee_line) {
+ if (floatval(DOL_VERSION) < 8) $this->db->begin(); // Not exist in addline function but commit and rollback exist
+ $result = $supplier_invoice->addline(
+ $fee_line['label'],
+ $fee_line['price'],
+ $fee_line['tax'],
+ $fee_line['local_tax1_tx'],
+ $fee_line['local_tax2_tx'],
+ $fee_line['qty'],
+ $product_id);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceAddLine');
+ if (!empty($supplier_invoice->error)) $this->errors[] = $supplier_invoice->error;
+ $this->errors = array_merge($this->errors, $supplier_invoice->errors);
+ $error++;
+ break;
+ }
+ }
+ }
+
+ // Validate invoice
+ if (!$error) {
+ $result = $supplier_invoice->validate($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceValidate');
+ if (!empty($supplier_invoice->error)) $this->errors[] = $supplier_invoice->error;
+ $this->errors = array_merge($this->errors, $supplier_invoice->errors);
+ $error++;
+ }
+ }
+
+ // Creation of payment line
+ if (!$error && $conf->banque->enabled && !empty($selected_payment_gateways['create_supplier_invoice_payment'])) {
+ $payment = new PaiementFourn($this->db);
+ $payment->datepaye = $supplier_invoice->date;
+ $payment->amounts = array($supplier_invoice->id => $supplier_invoice->total_ttc); // Array of amounts
+ $payment->multicurrency_amounts = array();
+ $payment->paiementid = $supplier_invoice->mode_reglement_id;
+ $payment->num_paiement = '';
+ $payment->note = 'Created by WooSync';
+
+ $payment_id = $payment->create($this->user, 1);
+ if ($payment_id < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceCreatePayment');
+ if (!empty($payment->error)) $this->errors[] = $payment->error;
+ $this->errors = array_merge($this->errors, $payment->errors);
+ $error++;
+ } else {
+ $result = $payment->addPaymentToBank($this->user, 'payment_supplier', '(SupplierInvoicePayment)', $bank_account_id, '', '');
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceAddPaymentToBank');
+ if (!empty($payment->error)) $this->errors[] = $payment->error;
+ $this->errors = array_merge($this->errors, $payment->errors);
+ $error++;
+ }
+ }
+ }
+
+ // Generate document
+ if (!$error && !empty($conf->global->INVOICE_SUPPLIER_ADDON_PDF) && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+ // Define output language
+ $outputlangs = $this->langs;
+ $newlang = '';
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $supplier_invoice->thirdparty->default_lang;
+ if (!empty($newlang)) {
+ $outputlangs = new Translate("", $conf);
+ $outputlangs->setDefaultLang($newlang);
+ $outputlangs->load('products');
+ }
+ $supplier_invoice->fetch($supplier_invoice->id); // Reload to get new records
+
+ $hidedetails = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0;
+ $hidedesc = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0;
+ $hideref = !empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0;
+ $result = $supplier_invoice->generateDocument($conf->global->INVOICE_SUPPLIER_ADDON_PDF, $outputlangs, $hidedetails, $hidedesc, $hideref);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSupplierInvoiceGenerateDocument');
+ if (!empty($supplier_invoice->error)) $this->errors[] = $supplier_invoice->error;
+ $this->errors = array_merge($this->errors, $supplier_invoice->errors);
+ $error++;
+ }
+ }
+ }
+ }
+
+ // Auto send invoice by mail
+ if (!$error && !empty($this->eCommerceSite->parameters['order_actions']['send_invoice_by_mail'])) {
+ $send_to = trim($order_data['socpeopleCommande']['email']);
+ if (empty($send_to)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorCustomerEmailEmptyForSendInvoiceByEmail');
+ $error++;
+ } elseif (!($selected_payment_gateways['mail_model_for_send_invoice'] > 0)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorPaymentGatewaysMailModelNotConfigured', $order_data['payment_method_id'], $order_data['payment_method']);
+ $error++;
+ }
+
+ if (!$error) {
+ $ret = $invoice->fetch($invoice->id);
+ $ret = $invoice->fetch_thirdparty();
+
+ require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
+ $formmail = new FormMail($this->db);
+
+ $this->langs->load('mails');
+ $this->langs->load("commercial");
+ if (!empty($conf->dolimail->enabled)) $this->langs->load("dolimail@dolimail");
+
+ $trackid = 'inv' . $invoice->id;
+ $deliveryreceipt = 0;
+
+ // from / send to / ...
+ $from = $conf->global->MAIN_INFO_SOCIETE_NOM . ' <' . $conf->global->MAIN_INFO_SOCIETE_MAIL . '>';
+ $sendtocc = '';
+ $sendtobcc = !empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) ? $conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO : '';
+
+ // Define output language
+ $outputlangs = $this->langs;
+ $newlang = $conf->global->MAIN_MULTILANGS ? $invoice->thirdparty->default_lang : '';
+ if (!empty($newlang)) {
+ $outputlangs = new Translate('', $conf);
+ $outputlangs->setDefaultLang($newlang);
+ $outputlangs->loadLangs(array('commercial', 'bills', 'orders', 'contracts', 'members', 'propal', 'products', 'supplier_proposal', 'interventions'));
+ }
+
+ // Make substitution in email content
+ $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $invoice);
+ $substitutionarray['__CHECK_READ__'] = (is_object($invoice) && is_object($invoice->thirdparty)) ? '' : '';
+ $substitutionarray['__PERSONALIZED__'] = ''; // deprecated
+ $substitutionarray['__CONTACTCIVNAME__'] = '';
+ $parameters = array('mode' => 'formemail');
+ complete_substitutions_array($substitutionarray, $outputlangs, $invoice, $parameters);
+
+ // Get email template
+ $type_template = 'facture_send';
+ $arraydefaultmessage = $formmail->getEMailTemplate($this->db, $type_template, $this->user, $outputlangs, $selected_payment_gateways['mail_model_for_send_invoice']);
+ if (is_numeric($arraydefaultmessage) && $arraydefaultmessage < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorGetEMailTemplate');
+ if (!empty($formmail->error)) $this->errors[] = $formmail->error;
+ else $this->errors[] = $this->db->lasterror();
+ $error++;
+ }
+
+ if (!$error) {
+ // Complete substitution array
+ if (empty($substitutionarray['__REF__'])) {
+ $paymenturl = '';
+ } else {
+ // Set the online payment url link into __ONLINE_PAYMENT_URL__ key
+ require_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php';
+ $outputlangs->load('paypal');
+ $paymenturl = getOnlinePaymentUrl(0, 'invoice', $substitutionarray['__REF__']);
+ }
+ $substitutionarray['__ONLINE_PAYMENT_URL__'] = $paymenturl;
+
+ // Define subject / message
+ $message = str_replace('\n', "\n", is_array($arraydefaultmessage) ? $arraydefaultmessage['content'] : $arraydefaultmessage->content);
+ // Deal with format differences between message and signature (text / HTML)
+ if (dol_textishtml($message) && !dol_textishtml($substitutionarray['__USER_SIGNATURE__'])) {
+ $substitutionarray['__USER_SIGNATURE__'] = dol_nl2br($substitutionarray['__USER_SIGNATURE__']);
+ } else if (!dol_textishtml($message) && dol_textishtml($substitutionarray['__USER_SIGNATURE__'])) {
+ $message = dol_nl2br($message);
+ }
+
+ $subject = make_substitutions(is_array($arraydefaultmessage) ? $arraydefaultmessage['topic'] : $arraydefaultmessage->topic, $substitutionarray);
+ $message = make_substitutions($message, $substitutionarray);
+ if (method_exists($invoice, 'makeSubstitution')) {
+ $subject = $invoice->makeSubstitution($subject);
+ $message = $invoice->makeSubstitution($message);
+ }
+
+ // Clean first \n and br (to avoid empty line when CONTACTCIVNAME is empty)
+ $message = preg_replace("/^(
)+/", "", $message);
+ $message = preg_replace("/^\n+/", "", $message);
+
+ // Define $urlwithroot
+ global $dolibarr_main_url_root;
+ $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
+ $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT; // This is to use external domain name found into config file
+ //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
+ // Make a change into HTML code to allow to include images from medias directory with an external reabable URL.
+ //
+ // become
+ //
+ $message = preg_replace('/()/', '\1' . $urlwithroot . '/viewimage.php\2modulepart=medias\3file=\4\5', $message);
+
+ // Attach invoice file
+ $formmail->trackid = $trackid; // $trackid must be defined
+ $formmail->clear_attached_files();
+ if (!empty(is_array($arraydefaultmessage) ? $arraydefaultmessage['joinfiles'] : $arraydefaultmessage->joinfiles)) {
+ $ref = dol_sanitizeFileName($invoice->ref);
+ $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/') . '[^\-]+');
+ $file = $fileparams['fullname'];
+ $formmail->add_attached_files($file, basename($file), dol_mimetype($file));
+ }
+ $attachedfiles = $formmail->get_attached_files();
+ $filepath = $attachedfiles['paths'];
+ $filename = $attachedfiles['names'];
+ $mimetype = $attachedfiles['mimes'];
+
+ // Send mail (substitutionarray must be done just before this)
+ require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
+ $sendcontext = 'standard';
+ $mailfile = new CMailFile($subject, $send_to, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', $trackid, '', $sendcontext);
+ if ($mailfile->error) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceCreateMail');
+ if (!empty($mailfile->error)) $this->errors[] = $mailfile->error;
+ $this->errors = array_merge($this->errors, $mailfile->errors);
+ $error++;
+ } else {
+ $result = $mailfile->sendfile();
+ if ($result) {
+ // Get order contacts
+ $contact_list = $invoice->liste_contact(-1, 'external');
+ if (!is_array($contact_list)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceGetExternalContacts', $invoice->id);
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ } else {
+ // Event send email
+ $sendtoid = array();
+ foreach ($contact_list as $contact_infos) {
+ $sendtoid[$contact_infos['id']] = $contact_infos['id'];
+ }
+ $sendtoid = array_values($sendtoid);
+
+ $actionmsg = '';
+ $actionmsg2 = $this->langs->transnoentities('MailSentBy') . ' ' . CMailFile::getValidAddress($from, 4, 0, 1) . ' ' . $this->langs->transnoentities('To') . ' ' . CMailFile::getValidAddress($send_to, 4, 0, 1);
+ if ($message) {
+ $actionmsg = $this->langs->transnoentities('MailFrom') . ': ' . dol_escape_htmltag($from);
+ $actionmsg = dol_concatdesc($actionmsg, $this->langs->transnoentities('MailTo') . ': ' . dol_escape_htmltag($send_to));
+ $actionmsg = dol_concatdesc($actionmsg, $this->langs->transnoentities('MailTopic') . ": " . $subject);
+ $actionmsg = dol_concatdesc($actionmsg, $this->langs->transnoentities('TextUsedInTheMessageBody') . ":");
+ $actionmsg = dol_concatdesc($actionmsg, $message);
+ }
+
+ $invoice->sendtoid = $sendtoid; // To link to contacts/addresses. This is an array.
+ $invoice->actiontypecode = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
+ $invoice->actionmsg = $actionmsg; // Long text
+ $invoice->actionmsg2 = $actionmsg2; // Short text
+ $invoice->trackid = $trackid;
+ $invoice->fk_element = $invoice->id;
+ $invoice->elementtype = $invoice->element;
+ if (is_array($attachedfiles) && count($attachedfiles) > 0) {
+ $invoice->attachedfiles = $attachedfiles;
+ }
+
+ include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+ $interface = new Interfaces($this->db);
+ $result = $interface->run_triggers('BILL_SENTBYMAIL', $invoice, $this->user, $this->langs, $conf);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceCreateSendMailEvent');
+ if (!empty($interface->error)) $this->errors[] = $interface->error;
+ $this->errors = array_merge($this->errors, $interface->errors);
+ $error++;
+ }
+ }
+ } else {
+ $this->langs->load("other");
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceSendByMail');
+ if ($mailfile->error) {
+ $this->errors[] = $this->langs->trans('ErrorFailedToSendMail', $from, $send_to);
+ $this->errors[] = $mailfile->error;
+ } else {
+ $this->errors[] = ' No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS';
+ }
+ $error++;
+ }
+ }
+ }
+ }
+ }
+ } elseif (empty($this->eCommerceSite->parameters['order_actions']['create_order'])) {
+ $this->warnings[] = $this->langs->trans('ECommerceWarningOrderThirdPartyNotSupported', $order_data['remote_id'], $order_data['remote_id_societe']);
+ $bypass = true;
+ }
+ }
+ }
+
+ // Update the link of the synchronization
+ //--------------------------------------------
+ if (!$error && !$bypass) {
+ $this->eCommerceCommande->last_update = $order_data['last_update'];
+ $this->eCommerceCommande->fk_commande = $order->id > 0 ? $order->id : ($invoice->id > 0 ? -$invoice->id : 0);
+
+ // Update link
+ if ($this->eCommerceCommande->id > 0) {
+ $result = $this->eCommerceCommande->update($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorUpdateOrderLink');
+ }
+ } // Create link
+ else {
+ $this->eCommerceCommande->fk_site = $this->eCommerceSite->id;
+ $this->eCommerceCommande->remote_id = $order_data['remote_id'];
+ $result = $this->eCommerceCommande->create($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorCreateOrderLink');
+ }
+ }
+ if ($result < 0) {
+ $this->errors = array_merge($this->errors, $this->eCommerceCommande->errors);
+ $error++;
+ }
+ }
+
+ $last_sync_date = 'ECOMMERCE_LAST_SYNC_DATE_ORDER_' . $this->eCommerceSite->id;
+ if (!$error && (!is_numeric($conf->global->$last_sync_date) || $conf->global->$last_sync_date < $order_data['create_date'])) {
+ $result = dolibarr_set_const($this->db, $last_sync_date, $order_data['create_date'], 'chaine', 0, '', $conf->entity);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorSetLastSyncDateOrder');
+ $this->errors[] = $this->db->lasterror();
+ $error++;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception $e) {
+ $this->errors[] = $e->getMessage();
+ $error++;
+ }
+
+ // Commit / rollback actions
+ if ($error) {
+ $this->db->rollback();
+ } else {
+ $this->db->commit();
+ }
+ }
+
+ if ($error) {
+ $this->errors = array_merge(array($this->langs->trans('ECommerceErrorWhenSynchronizeOrderToInvoice', $order_data['remote_id'])), $this->errors);
+ dol_syslog(__METHOD__ . ' Error=' . $this->errorsToString(), LOG_ERR);
+ return -1;
+ } else {
+ return $invoice->id > 0 ? $invoice->id : 0;
+ }
+ }
+
+ /**
+ * Synchronize a order data in the credit note in Dolibarr database
+ *
+ * @param array $order_data Order data to synchronize
+ * @param bool $dont_synchronize_products Bypass the synchronization of the product of the order
+ * @param int $invoice_id Source invoice id
+ * @param int $refund_key Key of order refunds array
+ * @return int <0 if KO, =0 if bypassed, Id of the invoice in Dolibarr if OK
+ */
+ public function synchronizeCreditNoteFromOrder($order_data, $dont_synchronize_products = false, $invoice_id, $refund_key)
+ {
+ dol_syslog(__METHOD__ . ' order_data=' . json_encode($order_data), LOG_DEBUG);
+ global $conf;
+
+ $this->error = '';
+ $this->errors = array();
+ $error = 0;
+
+ require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
+ require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
+ $order = new Commande($this->db);
+ $source_invoice = new Facture($this->db);
+ $invoice = new Facture($this->db);
+
+ if (!is_array($order_data)) {
+ $this->langs->load('errors');
+ $this->errors[] = $this->langs->trans('ErrorBadParameters') . '; order_data=' . json_encode($order_data);
+ $error++;
+ }
+
+ if (!$error && !empty($order_data)) {
+ $order_ref_ext = $this->eCommerceSite->name . '-' . $order_data['remote_id'];
+ $source_invoice_ref_ext = 'eCommerce-' . $this->eCommerceSite->id . '-' . $order_data['remote_id'];
+ $invoice_ref_ext = 'eCommerce-' . $this->eCommerceSite->id . '-' . $order_data['refunds'][$refund_key]["id"];
+ $order_id = 0;
+ $third_party_id = 0;
+ $selected_payment_gateways = null;
+ $payment_method_id = 0;
+ $bank_account_id = 0;
+
+ $this->db->begin();
+
+ try {
+ // Fetch source invoice by ref_ext
+ $result = $source_invoice->fetch(0, '', $source_invoice_ref_ext);
+ if ($result < 0) {
+ $this->error = $source_invoice->error;
+ $this->errors = array_merge($this->errors, $source_invoice->errors);
+ $error++;
+ } elseif ($result > 0) {
+ $result = $invoice->fetch(0, '', $invoice_ref_ext);
+ if ($result < 0) {
+ $this->error = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ // Check if order / invoice already synchronized
+ $this->initECommerceCommande();
+ $result = $this->eCommerceCommande->fetchByRemoteId($order_data['remote_id'], $this->eCommerceSite->id);
+ if ($result < 0 && !empty($this->eCommerceCommande->error)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchOrderLinkByRemoteId', $order_data['remote_id'], $this->eCommerceSite->id);
+ $this->errors[] = $this->eCommerceCommande->error;
+ $error++;
+ } else {
+ if ($this->eCommerceCommande->fk_commande > 0) {
+ $order_id = $this->eCommerceCommande->fk_commande;
+ }
+ }
+
+ // Fetch order
+ if (!$error) {
+ if ($order_id <= 0) {
+ // Fetch order by ref_ext if already created but the link is deleted
+ $result = $order->fetch(0, '', $order_ref_ext);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchOrderByRefExt', $order_ref_ext);
+ if (!empty($order->error)) $this->errors[] = $order->error;
+ $this->errors = array_merge($this->errors, $order->errors);
+ $error++;
+ }
+ } else {
+ $result = $order->fetch($order_id);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchOrder', $order_id);
+ if (!empty($order->error)) $this->errors[] = $order->error;
+ $this->errors = array_merge($this->errors, $order->errors);
+ $error++;
+ }
+ }
+ }
+ if (!$error) {
+ // Recreate the link to the order if not exist
+ if ($invoice->id > 0) {
+ if ($order->id > 0) $invoice->add_object_linked($order->element, $order->id);
+ } // Create the invoice only the first time
+ else {
+ // Need to synchronize ?
+ $bypass = $order_data['create_date'] < $this->eCommerceSite->parameters['order_first_date_etod'];
+ dol_syslog("!! ecommerceng #5005 $bypass");
+ if (!$bypass) {
+ if ($order->id > 0) {
+ $third_party_id = $order->socid;
+ } else {
+ // Check if third party already synchronized
+ if ($order_data['remote_id_societe'] > 0) {
+ $this->initECommerceSociete();
+ $result = $this->eCommerceSociete->fetchByRemoteId($order_data['remote_id_societe'], $this->eCommerceSite->id);
+ if ($result < 0 && !empty($this->eCommerceSociete->error)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchThirdPartyLinkByRemoteId', $order_data['remote_id_societe'], $this->eCommerceSite->id);
+ $this->errors[] = $this->eCommerceSociete->error;
+ $error++;
+ } elseif ($result > 0) {
+ $third_party_id = $this->eCommerceSociete->fk_societe;
+ } else {
+ // Synchronize the new customer
+ $result = $this->synchronizeCustomers(null, null, array($order_data['remote_id_societe']), 1, true, false);
+ if ($result < 0) {
+ $error++;
+ } elseif ($result > 0) {
+ $result = $this->eCommerceSociete->fetchByRemoteId($order_data['remote_id_societe'], $this->eCommerceSite->id);
+ if ($result < 0 && !empty($this->eCommerceSociete->error)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorFetchThirdPartyLinkByRemoteId', $order_data['remote_id_societe'], $this->eCommerceSite->id);
+ $this->errors[] = $this->eCommerceSociete->error;
+ $error++;
+ } elseif ($result > 0) {
+ $third_party_id = $this->eCommerceSociete->fk_societe;
+ } else {
+ // Customer not supported (eg. order created by admin so we don't need it)
+ $third_party_id = null;
+ }
+ }
+ }
+ } else {
+ // This is an guest customer.
+ if ($this->eCommerceSite->fk_anonymous_thirdparty > 0) {
+ $third_party_id = $this->eCommerceSite->fk_anonymous_thirdparty;
+ } else {
+ $this->errors[] = $this->langs->trans('ECommerceErrorAnonymousThirdPartyNotConfigured', $this->eCommerceSite->id);
+ $error++;
+ }
+ }
+ }
+
+ // Create the invoice only if the third party ID is found (otherwise it's bypassed)
+ if (!$error) {
+ if (isset($third_party_id)) {
+
+ // Set the invoice
+ $invoice->socid = $third_party_id;
+ $invoice->type = Facture::TYPE_CREDIT_NOTE;
+ $invoice->date = $order->id > 0 ? $order->date : strtotime($order_data['date_commande']);
+ $invoice->ref_client = $order->id > 0 ? $order->ref_client : $order_data['ref_client'];
+ $invoice->ref_ext = $invoice_ref_ext;
+ $invoice->modelpdf = $conf->global->FACTURE_ADDON_PDF;
+ $invoice->cond_reglement_id = $order->id > 0 ? $order->cond_reglement_id : (isset($this->eCommerceSite->parameters['payment_cond']) ? $this->eCommerceSite->parameters['payment_cond'] : null);
+ $invoice->multicurrency_code = $order->id > 0 ? $order->multicurrency_code : null;
+ $invoice->multicurrency_tx = $order->id > 0 ? $order->multicurrency_tx : null;
+ $invoice->entity = $conf->entity;
+ $invoice->statut = Facture::STATUS_DRAFT;
+
+ $invoice->note_private = isset($order_data['note']) ? $order_data['note'] : "";
+ if (!empty($conf->global->ECOMMERCENG_ENABLE_LOG_IN_NOTE)) {
+ $invoice->note_private = dol_concatdesc($invoice->note_private, $this->langs->trans('ECommerceCreateInvoiceFromSiteNote', $this->eCommerceSite->name) . " :\n" . json_encode($order_data['remote_order']));
+ }
+
+ if ($order->id > 0) {
+ $invoice->linkedObjectsIds[$order->element] = $order->id;
+ }
+
+ if ($order->id > 0) {
+ $invoice->array_options = $order->array_options;
+ } elseif (is_array($order_data['extrafields'])) {
+ foreach ($order_data['extrafields'] as $key => $value) {
+ $invoice->array_options['options_' . $key] = $value;
+ }
+ }
+
+ $invoice->context['fromsyncofecommerceid'] = $this->eCommerceSite->id;
+
+ // Create invoice
+ $result = $invoice->create($this->user);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceCreate');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+
+ // Add product lines and contacts
+ if (!$error) {
+ if ($order->id > 0) {
+ if (empty($order->lines)) {
+ if (method_exists($order, 'fetch_lines')) $order->fetch_lines();
+ elseif (method_exists($order, 'getLinesArray')) $order->getLinesArray();
+ }
+
+ // Add product lines
+ $fk_parent_line = 0;
+ $lines = $order->lines;
+ if (is_array($lines) && count($lines) > 0) {
+ // If we create a deposit with all lines and a percent, we change amount
+ if ($isDepositType && $typeAmount == 'variablealllines') {
+ foreach ($lines as $k => $line) {
+ // We keep ->subprice and ->pa_ht, but we change the qty
+ $lines[$k]->qty = price2num($line->qty * $valueDeposit / 100, 'MS');
+ }
+ }
+
+ $parent_line_match = array();
+ $fk_parent_line = 0;
+
+ foreach ($lines as $line) {
+ $label = (!empty($line->label) ? $line->label : '');
+ $desc = (!empty($line->desc) ? $line->desc : $line->libelle);
+
+ if ($line->subprice < 0 && empty($conf->global->ECOMMERCE_KEEP_NEGATIVE_PRICE_LINES_WHEN_CREATE_INVOICE)) {
+ // Negative line, we create a discount line
+ $discount = new DiscountAbsolute($this->db);
+ $discount->fk_soc = $invoice->socid;
+ $discount->amount_ht = abs($line->total_ht);
+ $discount->amount_tva = abs($line->total_tva);
+ $discount->amount_ttc = abs($line->total_ttc);
+ $discount->tva_tx = $line->tva_tx;
+ $discount->fk_user = $this->user->id;
+ $discount->description = $desc;
+ $discount_id = $discount->create($this->user);
+ if ($discount_id > 0) {
+ $result = $invoice->insert_discount($discount_id); // This include link_to_invoice
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceInsertDiscount');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ }
+ } else {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceDiscountCreate');
+ if (!empty($discount->error)) $this->errors[] = $discount->error;
+ $this->errors = array_merge($this->errors, $discount->errors);
+ $error++;
+ break;
+ }
+ } else {
+ // Positive line
+ $product_type = ($line->product_type ? $line->product_type : 0);
+
+ // Date start
+ $date_start = false;
+ if ($line->date_debut_prevue)
+ $date_start = $line->date_debut_prevue;
+ if ($line->date_debut_reel)
+ $date_start = $line->date_debut_reel;
+ if ($line->date_start)
+ $date_start = $line->date_start;
+
+ // Date end
+ $date_end = false;
+ if ($line->date_fin_prevue)
+ $date_end = $line->date_fin_prevue;
+ if ($line->date_fin_reel)
+ $date_end = $line->date_fin_reel;
+ if ($line->date_end)
+ $date_end = $line->date_end;
+
+ // Reset fk_parent_line for no child products and special product
+ if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
+ $fk_parent_line = 0;
+ } else {
+ $fk_parent_line = isset($parent_line_match[$line->fk_parent_line]) ? $parent_line_match[$line->fk_parent_line] : $fk_parent_line;
+ }
+
+ // Extrafields
+ $array_options = array();
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+ $array_options = $line->array_options;
+ }
+
+ $tva_tx = $line->tva_tx;
+ if (!empty($line->vat_src_code) && !preg_match('/\(/', $tva_tx)) $tva_tx .= ' (' . $line->vat_src_code . ')';
+
+ $result = $invoice->addline($desc, $line->subprice, $line->qty, $tva_tx, $line->localtax1_tx, $line->localtax2_tx,
+ $line->fk_product, $line->remise_percent, $date_start, $date_end, 0, $line->info_bits, $line->fk_remise_except, 'HT',
+ 0, $product_type, $line->rang, $line->special_code, $order->element, $line->id, $fk_parent_line, $line->fk_fournprice, $line->pa_ht,
+ $label, $array_options, 100, 0, $line->fk_unit, $line->multicurrency_subprice);
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceAddLine');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ break;
+ } elseif ($result > 0) {
+ $parent_line_match[$line->id] = $result;
+ // Defined the new fk_parent_line
+ if ($line->product_type == 9) {
+ $fk_parent_line = $result;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Get order internal contacts
+ $internal_contact_list = $order->liste_contact(-1, 'internal');
+ if (!is_array($internal_contact_list)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceGetOrderInternalContacts', $order->id);
+ if (!empty($order->error)) $this->errors[] = $order->error;
+ $this->errors = array_merge($this->errors, $order->errors);
+ $error++;
+ }
+
+ // Get order external contacts
+ $external_contact_list = $order->liste_contact(-1, 'external');
+ if (!is_array($external_contact_list)) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceGetOrderExternalContacts', $order->id);
+ if (!empty($order->error)) $this->errors[] = $order->error;
+ $this->errors = array_merge($this->errors, $order->errors);
+ $error++;
+ }
+
+ $contact_list = array_merge($internal_contact_list, $external_contact_list);
+ foreach ($contact_list as $contact_infos) {
+ $result = $invoice->add_contact($contact_infos['id'], $contact_infos['code'], $contact_infos['source']); // May failed because of duplicate key or because code of contact type does not exists for new object
+ if ($result < 0 && $this->db->errno() != 'DB_ERROR_RECORD_ALREADY_EXISTS' && $invoice->error != 'CODE_NOT_VALID_FOR_THIS_ELEMENT') {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceAddContact', $contact_infos['id'], $contact_infos['code'], $contact_infos['source']);
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ break;
+ }
+ }
+ } else {
+ // Add deposit lines
+ if ($isDepositType && in_array($typeAmount, array('amount', 'variable'))) {
+ $amount_ttc_diff = 0;
+ $amountdeposit = array();
+
+ $order_total_ttc = price2num($order_data['payment_amount_ttc'], 'MT');
+ if ($typeAmount == 'amount') $valueDeposit = $order_total_ttc;
+
+ if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) {
+ if ($typeAmount == 'amount') $amount = $valueDeposit;
+ else $amount = $order_total_ttc * ($valueDeposit / 100);
+
+ $TTotalByTva = array();
+ foreach ($order_data['items'] as $item) {
+ $TTotalByTva[$item['tva_tx']] += $item['total_ttc'];
+ }
+
+ foreach ($TTotalByTva as $tva => &$total) {
+ $coef = $total / $order_total_ttc; // Calc coef
+ $am = $amount * $coef;
+ $amount_ttc_diff += $am;
+ $amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline
+ }
+ } else {
+ if ($typeAmount == 'amount') {
+ $amountdeposit[0] = $valueDeposit;
+ } elseif ($typeAmount == 'variable') {
+ $totalamount = 0;
+ foreach ($order_data['items'] as $item) {
+ $qualified = 1;
+ if (empty($item['qty'])) $qualified = 0; // We discard qty=0, it is an option
+ if ($qualified) {
+ $totalamount += $item['total_ht']; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
+ $tva_tx = $item['tva_tx'];
+ $amountdeposit[$tva_tx] += ($item['total_ht'] * $valueDeposit) / 100;
+ }
+ }
+
+ if ($totalamount == 0) {
+ $amountdeposit[0] = 0;
+ }
+ }
+
+ $amount_ttc_diff = $amountdeposit[0];
+ }
+
+ foreach ($amountdeposit as $tva => $amount) {
+ if (empty($amount)) continue;
+
+ $descline = '(DEPOSIT)';
+ if ($typeAmount == 'amount') {
+ $descline .= ' (' . price($valueDeposit, '', $this->langs, 0, -1, -1, (!empty($invoice->multicurrency_code) ? $invoice->multicurrency_code : $conf->currency)) . ')';
+ } elseif ($typeAmount == 'variable') {
+ $descline .= ' (' . $valueDeposit . '%)';
+ }
+ $descline .= ' - ' . $order_data['ref_client'];
+
+ // Add deposit line
+ $result = $invoice->addline($descline, $amount, 1, $tva, 0, 0, (empty($conf->global->INVOICE_PRODUCTID_DEPOSIT) ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT));
+ if ($result < 0) {
+ $this->errors[] = $this->langs->trans('ECommerceErrorInvoiceAddLine');
+ if (!empty($invoice->error)) $this->errors[] = $invoice->error;
+ $this->errors = array_merge($this->errors, $invoice->errors);
+ $error++;
+ break;
+ }
+ }
+
+ if (!$error) {
+ $diff = $invoice->total_ttc - $amount_ttc_diff;
+ if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0) {
+ $invoice->fetch_lines();
+ $subprice_diff = $invoice->lines[0]->subprice - $diff / (1 + $invoice->lines[0]->tva_tx / 100);
+ $invoice->updateline($invoice->lines[0]->id, $invoice->lines[0]->desc, $subprice_diff, $invoice->lines[0]->qty, $invoice->lines[0]->remise_percent, $invoice->lines[0]->date_start, $invoice->lines[0]->date_end, $invoice->lines[0]->tva_tx, 0, 0, 'HT', $invoice->lines[0]->info_bits, $invoice->lines[0]->product_type, 0, 0, 0, $invoice->lines[0]->pa_ht, $invoice->lines[0]->label, 0, array(), 100);
+ }
+ }
+ } else {
+ // Add product lines
+ if (!$error && is_array($order_data['items']) && count($order_data['items']) > 0) {
+ if (empty($conf->global->ECOMMERCENG_DISABLED_PRODUCT_SYNCHRO_STOD)) {
+ // Get products to synchronize
+ $remote_id_to_synchronize = array();
+ foreach ($order_data['items'] as $item) {
+ //$this->initECommerceProduct();
+ //$result = $this->eCommerceProduct->fetchByRemoteId($item['id_remote_product'], $this->eCommerceSite->id); // load info of table ecommerce_product
+ //if ($result < 0 && !empty($this->eCommerceProduct->error)) {
+ // $this->error = $this->eCommerceProduct->error;
+ // $this->errors = array_merge($this->errors, $this->eCommerceProduct->errors);
+ // $error++;
+ //} elseif ($result <= 0) {
if (!empty($item['id_remote_product']))
$remote_id_to_synchronize[] = str_replace('|%', '', $item['id_remote_product']);
-// }
+ //}
}
// Synchronize the product to synchronize
@@ -5800,6 +7153,7 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
}
}
+ dol_syslog(var_export($selected_payment_gateways,true));
// Set bank account
if (!$error && isset($selected_payment_gateways)) {
$bank_account_id = $selected_payment_gateways['bank_account_id'] > 0 ? $selected_payment_gateways['bank_account_id'] : 0;
@@ -5820,19 +7174,19 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
// Get warehouse ID
$warehouse_id = 0;
// Todo We don't change stock here, even if dolibarr option is on because, this should be already done by product sync ?
-// if (!$error && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $this->eCommerceSite->stock_sync_direction == 'ecommerce2dolibarr') {
-// $warehouse_id = $this->eCommerceSite->fk_warehouse > 0 ? $this->eCommerceSite->fk_warehouse : 0;
-// if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
-// $qualified_for_stock_change = $invoice->hasProductsOrServices(2);
-// } else {
-// $qualified_for_stock_change = $invoice->hasProductsOrServices(1);
-// }
-//
-// if ($qualified_for_stock_change && $warehouse_id == 0) {
-// $this->errors[] = $this->langs->trans('ECommerceErrorWarehouseNotConfigured');
-// $error++;
-// }
-// }
+ //if (!$error && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $this->eCommerceSite->stock_sync_direction == 'ecommerce2dolibarr') {
+ //$warehouse_id = $this->eCommerceSite->fk_warehouse > 0 ? $this->eCommerceSite->fk_warehouse : 0;
+ //if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
+ // $qualified_for_stock_change = $invoice->hasProductsOrServices(2);
+ //} else {
+ // $qualified_for_stock_change = $invoice->hasProductsOrServices(1);
+ //}
+ //
+ //if ($qualified_for_stock_change && $warehouse_id == 0) {
+ // $this->errors[] = $this->langs->trans('ECommerceErrorWarehouseNotConfigured');
+ // $error++;
+ //}
+ //}
if ($isDepositType) {
$save_WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER = $conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER;
@@ -5855,9 +7209,14 @@ public function synchronizeInvoiceFromOrder($order_data, $dont_synchronize_produ
}
// Creation of payment line
+ dol_syslog("!!Ecommerceng - #5863");
if (!$error) {
+ dol_syslog("!!Ecommerceng - #5865");
if ($invoice->total_ttc != 0) {
+ dol_syslog("!!Ecommerceng - #5867");
+ dol_syslog($conf->banque->enabled);
if ($conf->banque->enabled && !empty($selected_payment_gateways['create_invoice_payment'])) {
+ dol_syslog("!!Ecommerceng - #5873");
$payment = new Paiement($this->db);
$payment->datepaye = $invoice->date;
$payment->amounts = array($invoice->id => $invoice->total_ttc); // Array with all payments dispatching with invoice id
diff --git a/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php b/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php
index 71f5e2d..eb71fa6 100755
--- a/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php
+++ b/class/data/woocommerce/eCommerceRemoteAccessWoocommerce.class.php
@@ -1600,6 +1600,33 @@ public function convertOrderDataIntoProcessedData($remote_data)
}
}
+ // Set refund lines
+ $refund_lines = [];
+ if (!empty($remote_data->refunds)) {
+ $parameters['consumer_key'] = "ck_9736ffcbb8aeac4da9d24dfd80102530d4bd8a9d";
+ $parameters['consumer_secret'] = "cs_a348ae93292dad7b5b2cf95e2cc724360341c185";
+ $verifySsl = true;
+ $timeout = 30;
+ $followRedirects = false;
+ $rawHeaders=['Content-Type: application/json'];
+ $url = "https://staging.tokay-ultimate.com/";
+
+ $url .= "wp-json/wc/v3/orders/16180/refunds/";
+ $url .= '?' . http_build_query($parameters);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verifySsl);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $rawHeaders);
+ curl_setopt($ch, CURLOPT_URL, $url);
+
+ $body = curl_exec($ch);
+
+ $refund_lines = $remote_data->refunds;
+ }
+
$create_date = $this->getDateTimeFromGMTDateTime($remote_data->date_created_gmt);
$last_update = $this->getDateTimeFromGMTDateTime(!empty($remote_data->date_modified_gmt) ? $remote_data->date_modified_gmt : $remote_data->date_created_gmt);
@@ -1765,6 +1792,7 @@ public function convertOrderDataIntoProcessedData($remote_data)
'payment_method_id' => $remote_data->payment_method,
'payment_amount_ttc' => $remote_data->total,
'fee_lines' => $fee_lines,
+ 'refunds' => $refund_lines,
'extrafields' => [
"ecommerceng_online_payment_{$conf->entity}" => empty($remote_data->date_paid) ? 0 : 1,
"ecommerceng_wc_status_{$this->site->id}_{$conf->entity}" => $orderStatus,
@@ -4228,7 +4256,7 @@ private function getTaxesInfoFromRemoteData($taxes_data, $tax_list = array())
$this->loadTaxes();
foreach ($taxes_data as $data) {
- if (empty($data->total)) continue;
+ if (empty($data->subtotal)) continue;
$count++;
if ($count > 1) break;