Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload invoice (49022) #380

Merged
merged 9 commits into from
Dec 16, 2024
2 changes: 1 addition & 1 deletion 202/build.xml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
<property name="src-dir" value="${basedir}" />
<property name="TARGETNAME" value="shoppingfeed" />
<property name="TARGETBRANCH" value="${env.GIT_BRANCH}" />
<property name="TARGETVERSION" value="1.12.0" />
<property name="TARGETVERSION" value="2.0.0" />
<target name="build" depends="build-common,package-zip,psvalidator,tot-testing" />

<target name="build-common" depends="lint,prepare" />
7 changes: 7 additions & 0 deletions classes/ShoppingfeedApi.php
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@

use ShoppingFeed\Sdk\Api\Catalog\InventoryUpdate;
use ShoppingFeed\Sdk\Api\Catalog\PricingUpdate;
use ShoppingFeed\Sdk\Api\Order\Document\Invoice;
use ShoppingFeed\Sdk\Api\Order\Identifier\Id;
use ShoppingFeed\Sdk\Api\Order\Operation;
use ShoppingFeed\Sdk\Client\Client;
@@ -314,6 +315,12 @@ public function updateMainStoreOrdersStatus($taskOrders, $shoppingfeed_store_id
new Id((int) $taskOrder['id_internal_shoppingfeed'])
);
continue 2;
case Shoppingfeed::ORDER_OPERATION_UPLOAD_DOCUMENTS:
$operation->uploadDocument(
new Id((int) $taskOrder['id_internal_shoppingfeed']),
new Invoice($taskOrder['payload']['uri'])
);
continue 2;
}
}

8 changes: 7 additions & 1 deletion classes/ShoppingfeedTaskOrder.php
Original file line number Diff line number Diff line change
@@ -27,6 +27,8 @@ class ShoppingfeedTaskOrder extends ObjectModel
{
const ACTION_SYNC_STATUS = 'SYNC_STATUS';

const ACTION_UPLOAD_INVOICE = 'UPLOAD_INVOICE';

// As in, "check the ticket related to the Order Status synchronization"
const ACTION_CHECK_TICKET_SYNC_STATUS = 'CHECK_TICKET_SYNC_STATUS';

@@ -60,7 +62,11 @@ class ShoppingfeedTaskOrder extends ObjectModel
'validate' => 'isGenericName',
'required' => true,
'unique' => true,
'values' => [self::ACTION_SYNC_STATUS, self::ACTION_CHECK_TICKET_SYNC_STATUS],
'values' => [
self::ACTION_SYNC_STATUS,
self::ACTION_CHECK_TICKET_SYNC_STATUS,
self::ACTION_UPLOAD_INVOICE,
],
],
'id_order' => [
'type' => ObjectModel::TYPE_INT,
137 changes: 137 additions & 0 deletions classes/actions/ShoppingfeedOrderSyncActions.php
Original file line number Diff line number Diff line change
@@ -386,6 +386,78 @@ public function prepareTaskOrdersSyncStatus()
return true;
}

public function prepareTaskOrdersSyncInvoice()
{
if (empty($this->conveyor['id_shop'])) {
ProcessLoggerHandler::logError(
$this->l('No ID Shop found.', 'ShoppingfeedOrderSyncActions'),
'Order'
);

return false;
}
if (empty($this->conveyor['taskOrders'])) {
ProcessLoggerHandler::logInfo(
$this->l('No Task Orders to prepare.', 'ShoppingfeedOrderSyncActions'),
'Order'
);

return false;
}

$taskOrders = $this->conveyor['taskOrders'];
$this->conveyor['preparedTaskOrders'] = [];

foreach ($taskOrders as $taskOrder) {
/** @var $taskOrder ShoppingfeedTaskOrder */
$logPrefix = self::getLogPrefix($taskOrder->id_order);
$order = new Order($taskOrder->id_order);
$sfOrder = ShoppingfeedOrder::getByIdOrder($taskOrder->id_order);

if (!Validate::isLoadedObject($order)) {
ProcessLoggerHandler::logError(
$logPrefix . ' ' .
$this->l('Order could not be loaded.', 'ShoppingfeedOrderSyncActions'),
'Order',
$taskOrder->id_order
);
Registry::increment('syncStatusErrors');
continue;
}

if (empty($sfOrder->id_internal_shoppingfeed)) {
ProcessLoggerHandler::logError(
$logPrefix . ' ' .
$this->l('No SF Order id set.', 'ShoppingfeedOrderSyncActions'),
'Order',
$taskOrder->id_order
);
Registry::increment('syncStatusErrors');
continue;
}

foreach ($order->getInvoicesCollection() as $invoice) {
$pdf = new PDF($invoice, PDF::TEMPLATE_INVOICE, Context::getContext()->smarty);
$file = _PS_MODULE_DIR_ . 'shoppingfeed/views/tmp/' . $invoice->id . '.pdf';
$isInvoiceExist = file_put_contents($file, $pdf->render(false));

if ($isInvoiceExist) {
$this->conveyor['preparedTaskOrders'][Shoppingfeed::ORDER_OPERATION_UPLOAD_DOCUMENTS][] = [
'id_internal_shoppingfeed' => $sfOrder->id_internal_shoppingfeed,
'taskOrder' => $taskOrder,
'file' => $file,
'operation' => Shoppingfeed::ORDER_OPERATION_UPLOAD_DOCUMENTS,
'payload' => [
'uri' => $file,
],
];
}
}
}

return true;
}

protected function initCarrierFinder()
{
return new CarrierFinder();
@@ -460,6 +532,71 @@ public function sendTaskOrdersSyncStatus()
return true;
}

public function sendTaskOrdersSyncInvoice()
{
if (empty($this->conveyor['id_shop'])) {
ProcessLoggerHandler::logError(
$this->l('No ID Shop found.', 'ShoppingfeedOrderSyncActions'),
'Order'
);

return false;
}

if (empty($this->conveyor['preparedTaskOrders'])) {
ProcessLoggerHandler::logError(
$this->l('No prepared Task Orders found.', 'ShoppingfeedOrderSyncActions'),
'Order'
);

return false;
}

$shoppingfeedApi = ShoppingfeedApi::getInstanceByToken($this->conveyor['id_token']);
if ($shoppingfeedApi == false) {
ProcessLoggerHandler::logError(
$this->l('Could not retrieve Shopping Feed API.', 'ShoppingfeedOrderSyncActions'),
'Order'
);

return false;
}

foreach ($this->conveyor['preparedTaskOrders'] as $preparedTaskOrders) {
$result = $shoppingfeedApi->updateMainStoreOrdersStatus($preparedTaskOrders, $this->conveyor['shoppingfeed_store_id']);

if (!$result) {
continue;
}

$batchId = current($result->getBatchIds());
if (empty($batchId) === true) {
continue;
}

foreach ($preparedTaskOrders as $preparedTaskOrder) {
$taskOrder = $preparedTaskOrder['taskOrder'];
$taskOrder->batch_id = $batchId;
$taskOrder->action = ShoppingfeedTaskOrder::ACTION_CHECK_TICKET_SYNC_STATUS;
$taskOrder->save();

ProcessLoggerHandler::logSuccess(
static::getLogPrefix($taskOrder->id_order) . ' ' . $this->l('Ticket created to upload an order invoice', 'ShoppingfeedOrderSyncActions'),
'Order',
$taskOrder->id_order
);

$this->conveyor['successfulTaskOrders'][] = $taskOrder;
unlink($preparedTaskOrder['file']);
}
}
if (empty($this->conveyor['successfulTaskOrders'])) {
return false;
}

return true;
}

public function prepareTaskOrdersCheckTicketsSyncStatus()
{
if (empty($this->conveyor['taskOrders'])) {
16 changes: 16 additions & 0 deletions controllers/admin/AdminShoppingfeedOrderImportRules.php
Original file line number Diff line number Diff line change
@@ -194,9 +194,11 @@ public function renderOrderSyncForm($order_sync_available, $order_import_availab
$orderShippedState['selected'] = [];
$orderCancelledState['selected'] = [];
$orderRefundedState['selected'] = [];
$orderDeliveredState['selected'] = [];
$orderShippedState['unselected'] = [];
$orderCancelledState['unselected'] = [];
$orderRefundedState['unselected'] = [];
$orderDeliveredState['unselected'] = [];

foreach ($allState as $state) {
$orderShippedState[in_array($state['id_order_state'], $ids_shipped_status_selected) ? 'selected' : 'unselected'][] = [
@@ -527,6 +529,10 @@ function ($c) {
'name' => 'name',
],
],
[
'type' => 'shoppingfeed_marketplace_switch_list',
'marketplaces' => \ShoppingfeedAddon\OrderInvoiceSync\Hub::getInstance()->getMarketplaces(),
],
[
'type' => 'shoppingfeed_close-section',
],
@@ -646,6 +652,16 @@ public function saveOrdersConfig()
);
}

if (Tools::getValue('order_invoice_sync_marketplace')) {
foreach (Tools::getValue('order_invoice_sync_marketplace') as $id => $isEnabled) {
if ((int) $isEnabled) {
\ShoppingfeedAddon\OrderInvoiceSync\Hub::getInstance()->enable($id);
} else {
\ShoppingfeedAddon\OrderInvoiceSync\Hub::getInstance()->disable($id);
}
}
}

$orderStatusesShipped = Tools::getValue('status_shipped_order');
if (!$orderStatusesShipped) {
$orderStatusesShipped = [];
59 changes: 59 additions & 0 deletions controllers/front/syncOrder.php
Original file line number Diff line number Diff line change
@@ -200,6 +200,65 @@ public function syncOrderStatus()
$this->processMonitor->getProcessObjectModelId()
);
}
// Start upload invoices
ProcessLoggerHandler::logInfo(
$logPrefix . ' ' . $this->module->l('Process start : Order invoice sync', 'syncOrder'),
$this->processMonitor->getProcessObjectModelName(),
$this->processMonitor->getProcessObjectModelId()
);

$failedSyncStatusTaskOrders = [];
$successfulSyncTaskOrders = [];
try {
Registry::set('syncStatusErrors', 0);

/** @var ShoppingfeedHandler $orderStatusHandler */
$orderStatusHandler = new ActionsHandler();
$orderStatusHandler->setConveyor([
'id_shop' => $token['id_shop'],
'id_token' => $token['id_shoppingfeed_token'],
'order_action' => ShoppingfeedTaskOrder::ACTION_UPLOAD_INVOICE,
'shoppingfeed_store_id' => $token['shoppingfeed_store_id'],
]);
$orderStatusHandler->addActions(
'getTaskOrders',
'prepareTaskOrdersSyncInvoice',
'sendTaskOrdersSyncInvoice'
);

if ($orderStatusHandler->process('ShoppingfeedOrderSync')) {
$processData = $orderStatusHandler->getConveyor();
$failedSyncStatusTaskOrders = isset($processData['failedTaskOrders']) ? $processData['failedTaskOrders'] : [];
$successfulSyncTaskOrders = isset($processData['successfulTaskOrders']) ? $processData['successfulTaskOrders'] : [];

ProcessLoggerHandler::logSuccess(
sprintf(
$logPrefix . ' ' . $this->module->l('%d tickets created; %d tickets not created; %d errors', 'syncOrder'),
count($successfulSyncTaskOrders),
count($failedSyncStatusTaskOrders),
Registry::get('syncStatusErrors')
),
$this->processMonitor->getProcessObjectModelName(),
$this->processMonitor->getProcessObjectModelId()
);
}

ProcessLoggerHandler::logInfo(
$logPrefix . ' ' . $this->module->l('Process finished : Order invoice sync', 'syncOrder'),
$this->processMonitor->getProcessObjectModelName(),
$this->processMonitor->getProcessObjectModelId()
);
} catch (Throwable $e) {
ProcessLoggerHandler::logError(
sprintf(
$logPrefix . ' ' . $this->module->l('Error : %s', 'syncOrder'),
$e->getMessage() . ' ' . $e->getFile() . ':' . $e->getLine()
),
$this->processMonitor->getProcessObjectModelName(),
$this->processMonitor->getProcessObjectModelId()
);
}
// End upload invoices

// Send mail
try {
Loading