From eee89a9fc5582708cc51da6b08f277ee63aa6d68 Mon Sep 17 00:00:00 2001 From: Damien <damien.burel@maarch.org> Date: Fri, 22 Mar 2019 17:39:10 +0100 Subject: [PATCH] FEAT #9107 Sending mechanic --- .gitignore | 1 + .../xml/mailevaConfig.xml.default | 6 + .../controllers/ActionMethodController.php | 107 +-------- src/app/action/controllers/ShippingTrait.php | 212 ++++++++++++++++++ src/core/models/CoreConfigModel.php | 16 +- src/core/models/CurlModel.php | 54 +++-- .../shipping-administration.component.ts | 4 +- src/frontend/lang/lang-en.ts | 4 +- src/frontend/lang/lang-fr.ts | 4 +- src/frontend/lang/lang-nl.ts | 4 +- .../app/shipping/ShippingControllerTest.php | 8 +- 11 files changed, 283 insertions(+), 137 deletions(-) create mode 100644 apps/maarch_entreprise/xml/mailevaConfig.xml.default create mode 100644 src/app/action/controllers/ShippingTrait.php diff --git a/.gitignore b/.gitignore index 4db3d8f926c..d547762df19 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ composer.lock installed.lck apps/maarch_entreprise/xml/config.xml +apps/maarch_entreprise/xml/mailevaConfig.xml apps/maarch_entreprise/xml/log4php.xml .vscode/ .phplint-cache diff --git a/apps/maarch_entreprise/xml/mailevaConfig.xml.default b/apps/maarch_entreprise/xml/mailevaConfig.xml.default new file mode 100644 index 00000000000..f90ae64b328 --- /dev/null +++ b/apps/maarch_entreprise/xml/mailevaConfig.xml.default @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<ROOT> + <URI></URI> + <CLIENT_ID></CLIENT_ID> + <CLIENT_SECRET></CLIENT_SECRET> +</ROOT> diff --git a/src/app/action/controllers/ActionMethodController.php b/src/app/action/controllers/ActionMethodController.php index 8b58a3a1f95..8b306372f0a 100644 --- a/src/app/action/controllers/ActionMethodController.php +++ b/src/app/action/controllers/ActionMethodController.php @@ -12,9 +12,6 @@ namespace Action\controllers; -use Attachment\models\AttachmentModel; -use Convert\controllers\ConvertPdfController; -use Docserver\models\DocserverModel; use Entity\controllers\ListInstanceController; use Entity\models\ListInstanceModel; use History\controllers\HistoryController; @@ -23,7 +20,6 @@ use Resource\models\ResModel; use Action\models\ResMarkAsReadModel; use Action\models\BasketPersistenceModel; use Action\models\ActionModel; -use SrcCore\models\CoreConfigModel; use SrcCore\models\ValidatorModel; use SrcCore\models\CurlModel; use AcknowledgementReceipt\models\AcknowledgementReceiptModel; @@ -33,6 +29,7 @@ use User\models\UserModel; class ActionMethodController { use AcknowledgementReceiptTrait; + use ShippingTrait; const COMPONENTS_ACTIONS = [ 'confirmAction' => null, @@ -254,108 +251,6 @@ class ActionMethodController return ['errors' => [$controller['errors']]]; } - return true; - } - - public static function maileva(array $args) - { - ValidatorModel::notEmpty($args, ['resId']); - ValidatorModel::intVal($args, ['resId']); - - $curlAuth = CurlModel::execSimple([ - 'url' => 'https://api.sandbox.aws.maileva.net/authentication/oauth2/token', - 'basicAuth' => ['user' => 'd80cafd2bf3b42c79dc84f4dc8e6acea', 'password' => 'aaa7833f3e9e48e68bbe3e727b5b5360'], - 'headers' => ['Content-Type: application/x-www-form-urlencoded'], - 'method' => 'POST', - 'queryParams' => ['grant_type' => 'password', 'username' => 'sandbox.562', 'password' => 'lgileb'] - ]); - - $token = $curlAuth['access_token']; - $sendingName = CoreConfigModel::uniqueId(); - - $curl = CurlModel::execSimple([ - 'url' => 'https://api.sandbox.aws.maileva.net/mail/v1/sendings', - 'bearerAuth' => ['token' => $token], - 'headers' => ['Content-Type: application/json'], - 'method' => 'POST', - 'body' => ['name' => $sendingName] - ]); - $curl = CurlModel::execSimple([ - 'url' => 'https://api.sandbox.aws.maileva.net/mail/v1/sendings', - 'bearerAuth' => ['token' => $token], - 'method' => 'GET' - ]); - - foreach ($curl['sendings'] as $sending) { - if ($sending['name'] == $sendingName) { - $sendingId = $sending['id']; - } - } - - $attachments = AttachmentModel::getOnView(['select' => ['res_id', 'res_id_version'], 'where' => ['res_id_master = ?'], 'data' => [$args['resId']]]); - $convertedDocument = ConvertPdfController::getConvertedPdfById(['resId' => $attachments[0]['res_id'], 'collId' => 'attachment_coll', 'isVersion' => false]); - - $docserver = DocserverModel::getByDocserverId(['docserverId' => $convertedDocument['docserver_id'], 'select' => ['path_template']]); - if (empty($docserver['path_template']) || !file_exists($docserver['path_template'])) { - //TODO - return ['errors' => 'Docserver does not exist']; - } - - $pathToDocument = $docserver['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $convertedDocument['path']) . $convertedDocument['filename']; - if (!file_exists($pathToDocument)) { - //TODO - return ['errors' => 'Document not found on docserver']; - } - - $curl = CurlModel::execSimple([ - 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/documents", - 'bearerAuth' => ['token' => $token], - 'headers' => ['Content-Type: multipart/form-data'], - 'method' => 'POST', - 'body' => ['document' => CurlModel::makeCurlFile(['path' => $pathToDocument]), 'metadata' => ['priority' => 0, 'name' => 'tata']], - 'toto' => 1 - ]); - $curl = CurlModel::execSimple([ - 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/documents", - 'bearerAuth' => ['token' => $token], - 'method' => 'GET' - ]); - - $curl = CurlModel::execSimple([ - 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/recipients", - 'bearerAuth' => ['token' => $token], - 'headers' => ['Content-Type: application/json'], - 'method' => 'POST', - 'body' => [ - "address_line_1" => "La Poste", - "address_line_2" => "Me Eva DUPONT", - "address_line_3" => "Résidence des Peupliers", - "address_line_4" => "33 avenue de Paris", - "address_line_5" => "BP 356", - "address_line_6" => "75000 Paris", - "country_code" => "FR" - ], - ]); - $curl = CurlModel::execSimple([ - 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/options", - 'bearerAuth' => ['token' => $token], - 'headers' => ['Content-Type: application/json'], - 'method' => 'PATCH', - 'body' => [ - 'postage_type' => "FAST", //ECONOMIC - 'color_printing' => true, - 'duplex_printing' => true, - 'optional_address_sheet' => false - ], - ]); - $curl = CurlModel::execSimple([ - 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/submit", - 'bearerAuth' => ['token' => $token], - 'headers' => ['Content-Type: application/json'], - 'method' => 'POST' - ]); - - return true; } } diff --git a/src/app/action/controllers/ShippingTrait.php b/src/app/action/controllers/ShippingTrait.php new file mode 100644 index 00000000000..7786a434405 --- /dev/null +++ b/src/app/action/controllers/ShippingTrait.php @@ -0,0 +1,212 @@ +<?php + +/** +* Copyright Maarch since 2008 under licence GPLv3. +* See LICENCE.txt file at the root folder for more details. +* This file is part of Maarch software. + +* @brief AcknowledgementReceiptTrait +* @author dev <dev@maarch.org> +* @ingroup core +*/ + +namespace Action\controllers; + +use Attachment\models\AttachmentModel; +use Convert\controllers\ConvertPdfController; +use Docserver\models\DocserverModel; +use Shipping\models\ShippingTemplateModel; +use SrcCore\models\CoreConfigModel; +use SrcCore\models\CurlModel; +use SrcCore\models\PasswordModel; +use SrcCore\models\ValidatorModel; + + +trait ShippingTrait +{ + public static function createMailevaShippings(array $args) + { + ValidatorModel::notEmpty($args, ['resId']); + ValidatorModel::intVal($args, ['resId']); + ValidatorModel::arrayType($args, ['data']); + + //TODO remove after test + $args['data']['shippingTemplateId'] = 1; + + $mailevaConfig = CoreConfigModel::getMailevaConfiguration(); + if (empty($mailevaConfig)) { + //TODO + return ['errors' => 'Maileva configuration does not exist']; + } + $shippingTemplate = ShippingTemplateModel::getById(['id' => $args['data']['shippingTemplateId']]); + if (empty($shippingTemplate)) { + //TODO + return ['errors' => 'Shipping template does not exist']; + } + $shippingTemplate['options'] = json_decode($shippingTemplate['options'], true); + $shippingTemplate['account'] = json_decode($shippingTemplate['account'], true); + + //TODO recup les bon attachments + $attachments = AttachmentModel::getOnView(['select' => ['res_id', 'res_id_version', 'title'], 'where' => ['res_id_master = ?'], 'data' => [$args['resId']]]); + if (empty($attachments)) { + return true; + } + $attachments = [$attachments[0]]; //TODO Remove for test + + $curlAuth = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . '/authentication/oauth2/token', + 'basicAuth' => ['user' => $mailevaConfig['clientId'], 'password' => $mailevaConfig['clientSecret']], + 'headers' => ['Content-Type: application/x-www-form-urlencoded'], + 'method' => 'POST', + 'queryParams' => [ + 'grant_type' => 'password', + 'username' => $shippingTemplate['account']['id'], + 'password' => PasswordModel::decrypt(['cryptedPassword' => $shippingTemplate['account']['password']]) + ] + ]); + + if ($curlAuth['code'] != 200) { + //TODO + return ['errors' => 'Maileva authentication failed']; + } + $token = $curlAuth['response']['access_token']; + + $errors = []; + foreach ($attachments as $attachment) { + $sendingName = CoreConfigModel::uniqueId(); + if (!empty($attachment['res_id'])) { + $isVersion = false; + $attachmentId = $attachment['res_id']; + } else { + $isVersion = true; + $attachmentId = $attachment['res_id_version']; + } + + $createSending = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . '/mail/v1/sendings', + 'bearerAuth' => ['token' => $token], + 'headers' => ['Content-Type: application/json'], + 'method' => 'POST', + 'body' => ['name' => $sendingName] + ]); + if ($createSending['code'] != 201) { + //TODO AttachmentId ?? + $errors[] = 'Maileva sending creation failed'; + continue; + } + + $sendings = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . '/mail/v1/sendings', + 'bearerAuth' => ['token' => $token], + 'method' => 'GET' + ]); + if ($sendings['code'] != 200) { + //TODO AttachmentId ?? + $errors[] = 'Maileva get sendings failed'; + continue; + } + + foreach ($sendings['response']['sendings'] as $sending) { + if ($sending['name'] == $sendingName) { + $sendingId = $sending['id']; + } + } + if (empty($sendingId)) { + //TODO AttachmentId ?? + $errors[] = 'Maileva sending id not found'; + continue; + } + + $convertedDocument = ConvertPdfController::getConvertedPdfById(['resId' => $attachmentId, 'collId' => 'attachment_coll', 'isVersion' => $isVersion]); + $docserver = DocserverModel::getByDocserverId(['docserverId' => $convertedDocument['docserver_id'], 'select' => ['path_template']]); + if (empty($docserver['path_template']) || !file_exists($docserver['path_template'])) { + //TODO AttachmentId + $errors[] = 'Docserver does not exist'; + continue; + } + $pathToDocument = $docserver['path_template'] . str_replace('#', DIRECTORY_SEPARATOR, $convertedDocument['path']) . $convertedDocument['filename']; + if (!file_exists($pathToDocument) || !is_file($pathToDocument)) { + //TODO AttachmentId + $errors[] = 'Document not found on docserver'; + continue; + } + + $createDocument = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . "/mail/v1/sendings/{$sendingId}/documents", + 'bearerAuth' => ['token' => $token], + 'method' => 'POST', + 'multipartBody' => ['document' => file_get_contents($pathToDocument), 'metadata' => json_encode(['priority' => 0, 'name' => $attachment['title']])] + ]); + if ($createDocument['code'] != 201) { + //TODO AttachmentId ?? + $errors[] = 'Maileva document creation failed'; + continue; + } + + //TODO remove after test + $curl = CurlModel::execSimple([ + 'url' => "https://api.sandbox.aws.maileva.net/mail/v1/sendings/{$sendingId}/documents", + 'bearerAuth' => ['token' => $token], + 'method' => 'GET' + ]); + + //TODO Aller chercher le contact de l'attachment + $createRecipient = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . "/mail/v1/sendings/{$sendingId}/recipients", + 'bearerAuth' => ['token' => $token], + 'headers' => ['Content-Type: application/json'], + 'method' => 'POST', + 'body' => [ + "address_line_1" => "La Poste", + "address_line_2" => "Me Eva DUPONT", + "address_line_3" => "Résidence des Peupliers", + "address_line_4" => "33 avenue de Paris", + "address_line_5" => "BP 356", + "address_line_6" => "75000 Paris", + "country_code" => "FR" + ], + ]); + if ($createRecipient['code'] != 201) { + //TODO AttachmentId ?? + $errors[] = 'Maileva recipient creation failed'; + continue; + } + + $setOptions = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . "/mail/v1/sendings/{$sendingId}/options", + 'bearerAuth' => ['token' => $token], + 'headers' => ['Content-Type: application/json'], + 'method' => 'PATCH', + 'body' => [ + 'postage_type' => strtoupper($shippingTemplate['options']['sendMode']), + 'color_printing' => in_array('color', $shippingTemplate['options']['shapingOptions']), + 'duplex_printing' => in_array('duplexPrinting', $shippingTemplate['options']['shapingOptions']), + 'optional_address_sheet' => in_array('addressPage', $shippingTemplate['options']['shapingOptions']) + ], + ]); + if ($setOptions['code'] != 200) { + //TODO AttachmentId ?? + $errors[] = 'Maileva options modification failed'; + continue; + } + + $submit = CurlModel::execSimple([ + 'url' => $mailevaConfig['uri'] . "/mail/v1/sendings/{$sendingId}/submit", + 'bearerAuth' => ['token' => $token], + 'headers' => ['Content-Type: application/json'], + 'method' => 'POST' + ]); + if ($submit['code'] != 200) { + //TODO AttachmentId ?? + $errors[] = 'Maileva submit failed'; + continue; + } + } + + if (!empty($errors)) { + return ['errors' => $errors]; + } + + return true; + } +} diff --git a/src/core/models/CoreConfigModel.php b/src/core/models/CoreConfigModel.php index a7801fa9675..08301dff8f4 100755 --- a/src/core/models/CoreConfigModel.php +++ b/src/core/models/CoreConfigModel.php @@ -187,12 +187,26 @@ class CoreConfigModel return $loggingMethod; } + public static function getMailevaConfiguration() + { + $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'apps/maarch_entreprise/xml/mailevaConfig.xml']); + + $mailevaConfig = []; + if ($loadedXml) { + $mailevaConfig['uri'] = (string)$loadedXml->URI; + $mailevaConfig['clientId'] = (string)$loadedXml->CLIENT_ID; + $mailevaConfig['clientSecret'] = (string)$loadedXml->CLIENT_SECRET; + } + + return $mailevaConfig; + } + public static function getOzwilloConfiguration(array $aArgs = []) { ValidatorModel::stringType($aArgs, ['customId']); - if (empty($aArgs['customId'])) { $customId = CoreConfigModel::getCustomId(); + if (empty($aArgs['customId'])) { } else { $customId = $aArgs['customId']; } diff --git a/src/core/models/CurlModel.php b/src/core/models/CurlModel.php index 8c7fced6fe6..51a00284367 100644 --- a/src/core/models/CurlModel.php +++ b/src/core/models/CurlModel.php @@ -275,6 +275,7 @@ class CurlModel $opts[CURLOPT_HTTPHEADER][] = 'Authorization: Bearer ' . $args['bearerAuth']['token']; } + //QueryParams if (!empty($args['queryParams'])) { $args['url'] .= '?'; $i = 0; @@ -286,50 +287,67 @@ class CurlModel ++$i; } } - $opts[CURLOPT_URL] = $args['url']; - + //Body if (!empty($args['body'])) { $opts[CURLOPT_POSTFIELDS] = json_encode($args['body']); } + //MultipartBody + if (!empty($args['multipartBody'])) { + $boundary = uniqid(); + $postData = CurlModel::createMultipartFormData(['boundary' => $boundary, 'body' => $args['multipartBody']]); + $opts[CURLOPT_HTTPHEADER][] = "Content-Type: multipart/form-data; boundary=-------------{$boundary}"; + $opts[CURLOPT_POSTFIELDS] = $postData; + } + //Method if ($args['method'] == 'POST') { $opts[CURLOPT_POST] = true; } elseif ($args['method'] == 'PUT' || $args['method'] == 'PATCH' || $args['method'] == 'DELETE') { $opts[CURLOPT_CUSTOMREQUEST] = $args['method']; } + //Url + $opts[CURLOPT_URL] = $args['url']; + $curl = curl_init(); curl_setopt_array($curl, $opts); $rawResponse = curl_exec($curl); + $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); - $error = curl_error($curl); + $errors = curl_error($curl); curl_close($curl); LogsController::add([ 'isTech' => true, 'moduleId' => 'curl', 'level' => 'DEBUG', - 'tableName' => '', + 'tableName' => 'curl', 'recordId' => 'execSimple', - 'eventType' => 'Exec Curl : ' . $args['url'], - 'eventId' => $rawResponse + 'eventType' => "Url : {$args['url']} HttpCode : {$code} Errors : {$errors}", + 'eventId' => "Response : {$rawResponse}" ]); - if (!empty($error)) { - LogsController::add([ - 'isTech' => true, - 'moduleId' => 'curl', - 'level' => 'ERROR', - 'tableName' => '', - 'recordId' => '', - 'eventType' => 'Error Exec Curl : ' . $error, - 'eventId' => $rawResponse - ]); + return ['code' => $code, 'response' => json_decode($rawResponse, true), 'errors' => $errors]; + } - return ['errors' => $error]; + private static function createMultipartFormData(array $args) + { + ValidatorModel::notEmpty($args, ['boundary', 'body']); + ValidatorModel::stringType($args, ['boundary']); + ValidatorModel::arrayType($args, ['body']); + + $delimiter = "-------------{$args['boundary']}"; + + $postData = ''; + foreach ($args['body'] as $key => $value) { + $postData .= "--{$delimiter}\r\n"; + $postData .= "Content-Disposition: form-data; name=\"{$key}\"\r\n"; + $postData .= "\r\n"; + $postData .= "{$value}\r\n"; } + $postData .= "--{$delimiter}--\r\n"; - return json_decode($rawResponse, true); + return $postData; } public static function isEnabled(array $aArgs) diff --git a/src/frontend/app/administration/shipping/shipping-administration.component.ts b/src/frontend/app/administration/shipping/shipping-administration.component.ts index 5368f909a9f..e8607f0d0b2 100644 --- a/src/frontend/app/administration/shipping/shipping-administration.component.ts +++ b/src/frontend/app/administration/shipping/shipping-administration.component.ts @@ -52,8 +52,8 @@ export class ShippingAdministrationComponent implements OnInit { shapingOptions: string[] = [ 'color', - 'both_sides', - 'address_page', + 'duplexPrinting', + 'addressPage', ]; sendModes: string[] = [ diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index ab696c70dd8..720c3430aa2 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -884,8 +884,8 @@ export const LANG_EN = { "willBeAutomaticallyInCopy" : "will be automatically <b>in copy</b>", "confirm" : "Confirm", "shipping_color" : "Color", - "shipping_both_sides" : "Both sides", - "shipping_address_page" : "Address page", + "shipping_duplexPrinting" : "Both sides", + "shipping_addressPage" : "Address page", "shipping_fast" : "Fast (J+2)", "shipping_economic" : "Economic (J+4)", "shipping_registered_mail" : "Registered mail", diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index 1888944be2e..8a86069b30e 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -910,8 +910,8 @@ export const LANG_FR = { "willBeAutomaticallyInCopy" : "sera automatiquement mise <b>en copie</b>", "confirm" : "Confirmer", "shipping_color" : "Couleur", - "shipping_both_sides" : "Recto verso", - "shipping_address_page" : "Page porte adresse", + "shipping_duplexPrinting" : "Recto verso", + "shipping_addressPage" : "Page porte adresse", "shipping_fast" : "Rapide (J+2)", "shipping_economic" : "Economique (J+4)", "shipping_registered_mail" : "Recommandé", diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index 9279c70b6f3..442a6113f8c 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -912,8 +912,8 @@ export const LANG_NL = { "willBeAutomaticallyInCopy" : "wordt automatisch <b>gekopieerd</b>", //_TO_TRANSLATE "confirm" : "Bevestigen", //_TO_TRANSLATE "shipping_color" : "Color", //_TO_TRANSLATE - "shipping_both_sides" : "Both sides", //_TO_TRANSLATE - "shipping_address_page" : "Address page", //_TO_TRANSLATE + "shipping_duplexPrinting" : "Both sides", //_TO_TRANSLATE + "shipping_addressPage" : "Address page", //_TO_TRANSLATE "shipping_fast" : "Fast (J+2)", //_TO_TRANSLATE "shipping_economic" : "Economic (J+4)", //_TO_TRANSLATE "shipping_registered_mail" : "Registered mail", //_TO_TRANSLATE diff --git a/test/unitTests/app/shipping/ShippingControllerTest.php b/test/unitTests/app/shipping/ShippingControllerTest.php index 8a5fe740b13..b6632e895c6 100755 --- a/test/unitTests/app/shipping/ShippingControllerTest.php +++ b/test/unitTests/app/shipping/ShippingControllerTest.php @@ -23,7 +23,7 @@ class ShippingTemplateControllerTest extends TestCase 'label' => 'TEST', 'description' => 'description du TEST', 'options' => [ - 'shaping' => ['color', 'both_sides', 'address_page'], + 'shaping' => ['color', 'duplexPrinting', 'addressPage'], 'sendMode' => 'fast' ], 'fee' => ['first_page' => 1, 'next_page' => 2, 'postage_price' => 12], @@ -42,7 +42,7 @@ class ShippingTemplateControllerTest extends TestCase $aArgs = [ 'description' => 'description du TEST', 'options' => [ - 'shaping' => ['color', 'both_sides', 'address_page'], + 'shaping' => ['color', 'duplexPrinting', 'addressPage'], 'sendMode' => 'fast' ], 'fee' => ['first_page' => 1, 'next_page' => 2, 'postage_price' => 12], @@ -70,8 +70,8 @@ class ShippingTemplateControllerTest extends TestCase $this->assertSame('TEST', $responseBody->shipping->label); $this->assertSame('description du TEST', $responseBody->shipping->description); $this->assertSame('color', $responseBody->shipping->options->shaping[0]); - $this->assertSame('both_sides', $responseBody->shipping->options->shaping[1]); - $this->assertSame('address_page', $responseBody->shipping->options->shaping[2]); + $this->assertSame('duplexPrinting', $responseBody->shipping->options->shaping[1]); + $this->assertSame('addressPage', $responseBody->shipping->options->shaping[2]); $this->assertSame('fast', $responseBody->shipping->options->sendMode); $this->assertSame(1, $responseBody->shipping->fee->first_page); $this->assertSame(2, $responseBody->shipping->fee->next_page); -- GitLab