| 1 |
<?php |
| 2 |
/** |
| 3 |
* Class CustomsDeclarationMetabox. |
| 4 |
* |
| 5 |
* @package Packetery |
| 6 |
*/ |
| 7 |
|
| 8 |
declare(strict_types=1); |
| 9 |
|
| 10 |
namespace Packetery\Module\Order; |
| 11 |
|
| 12 |
use Packetery\Core\CoreHelper; |
| 13 |
use Packetery\Core\Entity; |
| 14 |
use Packetery\Core\Entity\Order; |
| 15 |
use Packetery\Latte\Engine; |
| 16 |
use Packetery\Module\CustomsDeclaration; |
| 17 |
use Packetery\Module\EntityFactory; |
| 18 |
use Packetery\Module\Exception\DeleteErrorException; |
| 19 |
use Packetery\Module\FormFactory; |
| 20 |
use Packetery\Module\FormRules; |
| 21 |
use Packetery\Module\Framework\WpAdapter; |
| 22 |
use Packetery\Module\Message; |
| 23 |
use Packetery\Module\MessageManager; |
| 24 |
use Packetery\Module\ModuleHelper; |
| 25 |
use Packetery\Nette\Forms\Container; |
| 26 |
use Packetery\Nette\Forms\Controls\BaseControl; |
| 27 |
use Packetery\Nette\Forms\Controls\Checkbox; |
| 28 |
use Packetery\Nette\Forms\Controls\UploadControl; |
| 29 |
use Packetery\Nette\Forms\Form; |
| 30 |
use Packetery\Nette\Http\FileUpload; |
| 31 |
use Packetery\Nette\Http\Request; |
| 32 |
|
| 33 |
/** |
| 34 |
* Class CustomsDeclarationMetabox. |
| 35 |
*/ |
| 36 |
class CustomsDeclarationMetabox { |
| 37 |
|
| 38 |
private const MAX_UPLOAD_FILE_MEGABYTES = 16; |
| 39 |
|
| 40 |
private const EAD_OWN = 'own'; |
| 41 |
private const EAD_CREATE = 'create'; |
| 42 |
private const EAD_CARRIER = 'carrier'; |
| 43 |
|
| 44 |
public const FORM_ID = 'packetery-customs-declaration-metabox-form'; |
| 45 |
public const FORM_CONTAINER_NAME = 'packetery_customs_declaration'; |
| 46 |
public const FORM_ACTIVATOR_NAME = 'fill_customs_declaration'; |
| 47 |
|
| 48 |
/** |
| 49 |
* Latte engine. |
| 50 |
* |
| 51 |
* @var Engine |
| 52 |
*/ |
| 53 |
private $latteEngine; |
| 54 |
|
| 55 |
/** |
| 56 |
* Form factory. |
| 57 |
* |
| 58 |
* @var FormFactory |
| 59 |
*/ |
| 60 |
private $formFactory; |
| 61 |
|
| 62 |
/** |
| 63 |
* Customs declaration repository. |
| 64 |
* |
| 65 |
* @var CustomsDeclaration\Repository |
| 66 |
*/ |
| 67 |
private $customsDeclarationRepository; |
| 68 |
|
| 69 |
/** |
| 70 |
* Customs declaration entity factory. |
| 71 |
* |
| 72 |
* @var EntityFactory\CustomsDeclaration |
| 73 |
*/ |
| 74 |
private $customsDeclarationEntityFactory; |
| 75 |
|
| 76 |
/** |
| 77 |
* HTTP Request. |
| 78 |
* |
| 79 |
* @var Request |
| 80 |
*/ |
| 81 |
private $request; |
| 82 |
|
| 83 |
/** |
| 84 |
* Message manager. |
| 85 |
* |
| 86 |
* @var MessageManager |
| 87 |
*/ |
| 88 |
private $messageManager; |
| 89 |
|
| 90 |
/** |
| 91 |
* Order detail comon logic. |
| 92 |
* |
| 93 |
* @var DetailCommonLogic |
| 94 |
*/ |
| 95 |
private $detailCommonLogic; |
| 96 |
|
| 97 |
/** |
| 98 |
* @var WpAdapter |
| 99 |
*/ |
| 100 |
private $wpAdapter; |
| 101 |
|
| 102 |
/** |
| 103 |
* Constructor. |
| 104 |
* |
| 105 |
* @param Engine $latteEngine Latte engine. |
| 106 |
* @param FormFactory $formFactory Form factory. |
| 107 |
* @param CustomsDeclaration\Repository $customsDeclarationRepository Customs declaration repository. |
| 108 |
* @param EntityFactory\CustomsDeclaration $customsDeclarationEntityFactory Customs declaration entity factory. |
| 109 |
* @param Request $request Request. |
| 110 |
* @param MessageManager $messageManager Message manager. |
| 111 |
* @param DetailCommonLogic $detailCommonLogic Detail common logic. |
| 112 |
*/ |
| 113 |
public function __construct( |
| 114 |
Engine $latteEngine, |
| 115 |
FormFactory $formFactory, |
| 116 |
CustomsDeclaration\Repository $customsDeclarationRepository, |
| 117 |
EntityFactory\CustomsDeclaration $customsDeclarationEntityFactory, |
| 118 |
Request $request, |
| 119 |
MessageManager $messageManager, |
| 120 |
DetailCommonLogic $detailCommonLogic, |
| 121 |
WpAdapter $wpAdapter |
| 122 |
) { |
| 123 |
$this->latteEngine = $latteEngine; |
| 124 |
$this->formFactory = $formFactory; |
| 125 |
$this->customsDeclarationRepository = $customsDeclarationRepository; |
| 126 |
$this->customsDeclarationEntityFactory = $customsDeclarationEntityFactory; |
| 127 |
$this->request = $request; |
| 128 |
$this->messageManager = $messageManager; |
| 129 |
$this->detailCommonLogic = $detailCommonLogic; |
| 130 |
$this->wpAdapter = $wpAdapter; |
| 131 |
} |
| 132 |
|
| 133 |
/** |
| 134 |
* Registers related hooks. |
| 135 |
* |
| 136 |
* @return void |
| 137 |
*/ |
| 138 |
public function register(): void { |
| 139 |
add_action( 'add_meta_boxes', [ $this, 'addMetaBoxes' ] ); |
| 140 |
add_action( 'admin_head', [ $this, 'renderTemplate' ] ); |
| 141 |
} |
| 142 |
|
| 143 |
/** |
| 144 |
* Adds meta boxes. |
| 145 |
* |
| 146 |
* @return void |
| 147 |
*/ |
| 148 |
public function addMetaBoxes(): void { |
| 149 |
$order = $this->detailCommonLogic->getOrder(); |
| 150 |
|
| 151 |
if ( |
| 152 |
$order === null || |
| 153 |
$order->getCarrier()->requiresCustomsDeclarations() === false |
| 154 |
) { |
| 155 |
return; |
| 156 |
} |
| 157 |
|
| 158 |
add_meta_box( |
| 159 |
'packetery_customs_declaration_metabox', |
| 160 |
__( 'Customs declaration', 'packeta' ), |
| 161 |
[ $this, 'render' ], |
| 162 |
ModuleHelper::isHposEnabled() ? wc_get_page_screen_id( 'shop-order' ) : 'shop_order', |
| 163 |
'advanced', |
| 164 |
'high' |
| 165 |
); |
| 166 |
} |
| 167 |
|
| 168 |
/** |
| 169 |
* Renders template. |
| 170 |
* |
| 171 |
* @return void |
| 172 |
*/ |
| 173 |
public function renderTemplate(): void { |
| 174 |
$formTemplate = $this->formFactory->create(); |
| 175 |
$prefixContainer = $formTemplate->addContainer( self::FORM_CONTAINER_NAME ); |
| 176 |
$items = $prefixContainer->addContainer( 'items' ); |
| 177 |
$this->addCustomsDeclarationItem( $formTemplate->addCheckbox( self::FORM_ACTIVATOR_NAME ), $items, '0' ); |
| 178 |
|
| 179 |
$this->latteEngine->render( |
| 180 |
PACKETERY_PLUGIN_DIR . '/template/order/customs-declaration-form-template.latte', |
| 181 |
[ |
| 182 |
'formTemplate' => $formTemplate, |
| 183 |
'translations' => [ |
| 184 |
'delete' => __( 'Delete', 'packeta' ), |
| 185 |
], |
| 186 |
] |
| 187 |
); |
| 188 |
} |
| 189 |
|
| 190 |
/** |
| 191 |
* Saves submitted form fields data. |
| 192 |
* |
| 193 |
* @param Order $order Order ID. |
| 194 |
* @return void |
| 195 |
*/ |
| 196 |
public function saveFields( Order $order ): void { |
| 197 |
if ( |
| 198 |
( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || |
| 199 |
$this->request->getPost( self::FORM_CONTAINER_NAME ) === null |
| 200 |
) { |
| 201 |
return; |
| 202 |
} |
| 203 |
|
| 204 |
$form = $this->createForm( |
| 205 |
$this->request->getPost(), |
| 206 |
$this->customsDeclarationRepository->getByOrderNumber( $order->getNumber() ) |
| 207 |
); |
| 208 |
|
| 209 |
if ( $form->isSubmitted() ) { |
| 210 |
$form->fireEvents(); |
| 211 |
} |
| 212 |
} |
| 213 |
|
| 214 |
/** |
| 215 |
* Renders meta box. |
| 216 |
* |
| 217 |
* @return void |
| 218 |
*/ |
| 219 |
public function render(): void { |
| 220 |
$order = $this->detailCommonLogic->getOrder(); |
| 221 |
if ( $order === null ) { |
| 222 |
return; |
| 223 |
} |
| 224 |
|
| 225 |
$customsDeclaration = $this->customsDeclarationRepository->getByOrderNumber( $order->getNumber() ); |
| 226 |
|
| 227 |
$formData = []; |
| 228 |
if ( $customsDeclaration !== null ) { |
| 229 |
$formData = [ |
| 230 |
self::FORM_CONTAINER_NAME => $this->customsDeclarationRepository->declarationToDbArray( |
| 231 |
$customsDeclaration, |
| 232 |
[ 'invoice_file', 'ead_file', 'order_id' ] |
| 233 |
), |
| 234 |
]; |
| 235 |
$formData[ self::FORM_CONTAINER_NAME ]['items'] = []; |
| 236 |
|
| 237 |
$customsDeclarationItems = $this->customsDeclarationRepository->getItemsByCustomsDeclarationId( $customsDeclaration->getId() ); |
| 238 |
foreach ( $customsDeclarationItems as $customsDeclarationItem ) { |
| 239 |
$formData[ self::FORM_CONTAINER_NAME ]['items'][ $customsDeclarationItem->getId() ] = $this->customsDeclarationRepository->declarationItemToDbArray( $customsDeclarationItem ); |
| 240 |
} |
| 241 |
} |
| 242 |
|
| 243 |
$form = $this->createForm( $formData, $customsDeclaration ); |
| 244 |
$form->setDefaults( $formData ); |
| 245 |
|
| 246 |
$hasInvoiceFile = $customsDeclaration !== null && $customsDeclaration->hasInvoiceFileContent(); |
| 247 |
$hasEadFile = $customsDeclaration !== null && $customsDeclaration->hasEadFileContent(); |
| 248 |
$runWizardUrl = $this->wpAdapter->adminUrl( "admin.php?page=wc-orders&action=edit&id={$order->getNumber()}&wizard-enabled=true&wizard-order-detail-custom-declaration-enabled=true#packetery_customs_declaration_metabox" ); |
| 249 |
|
| 250 |
$this->latteEngine->render( |
| 251 |
PACKETERY_PLUGIN_DIR . '/template/order/customs-declaration-metabox.latte', |
| 252 |
[ |
| 253 |
'form' => $form, |
| 254 |
'hasInvoiceFile' => $hasInvoiceFile, |
| 255 |
'hasEadFile' => $hasEadFile, |
| 256 |
'runWizardUrl' => $runWizardUrl, |
| 257 |
'translations' => [ |
| 258 |
'addCustomsDeclarationItem' => $this->wpAdapter->__( 'Add item', 'packeta' ), |
| 259 |
'delete' => $this->wpAdapter->__( 'Delete', 'packeta' ), |
| 260 |
'itemsLabel' => $this->wpAdapter->__( 'Items', 'packeta' ), |
| 261 |
'fileUploaded' => $this->wpAdapter->__( 'File uploaded.', 'packeta' ), |
| 262 |
'runWizard' => $this->wpAdapter->__( 'Run customs declaration wizard', 'packeta' ), |
| 263 |
], |
| 264 |
] |
| 265 |
); |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Creates form. |
| 270 |
* |
| 271 |
* @param array $structureData Data specifying how form will be constructed. |
| 272 |
* When user browser sends added customs declaration items, the form factory has to reflect that. |
| 273 |
* @param Entity\CustomsDeclaration|null $customsDeclaration Related customs declaration. |
| 274 |
* |
| 275 |
* @return Form |
| 276 |
*/ |
| 277 |
private function createForm( array $structureData, ?Entity\CustomsDeclaration $customsDeclaration ): Form { |
| 278 |
$form = $this->formFactory->create(); |
| 279 |
|
| 280 |
$activator = $form->addCheckbox( self::FORM_ACTIVATOR_NAME, __( 'View/hide customs declaration form', 'packeta' ) ); |
| 281 |
if ( $this->request->getQuery( 'wizard-order-detail-custom-declaration-enabled' ) === 'true' ) { |
| 282 |
$activator->setValue( true ); |
| 283 |
} |
| 284 |
$activator |
| 285 |
->addCondition( Form::FILLED ) |
| 286 |
->toggle( 'customs-declaration-container' ); |
| 287 |
|
| 288 |
$prefixContainer = $form->addContainer( self::FORM_CONTAINER_NAME ); |
| 289 |
|
| 290 |
$ead = $prefixContainer->addSelect( |
| 291 |
'ead', |
| 292 |
__( 'EAD', 'packeta' ), |
| 293 |
[ |
| 294 |
self::EAD_OWN => __( 'Self-declaration (I have a EAD)', 'packeta' ), |
| 295 |
self::EAD_CREATE => __( 'Issuing a EAD via Packeta', 'packeta' ), |
| 296 |
self::EAD_CARRIER => __( 'Postal clearance (no EAD and no fees)', 'packeta' ), |
| 297 |
] |
| 298 |
); |
| 299 |
$ead |
| 300 |
->addConditionOn( $activator, Form::FILLED ) |
| 301 |
->setRequired(); |
| 302 |
|
| 303 |
$prefixContainer->addText( 'delivery_cost', __( 'Delivery cost', 'packeta' ) ) |
| 304 |
->addConditionOn( $activator, Form::FILLED ) |
| 305 |
->setRequired() |
| 306 |
->addRule( Form::FLOAT ) |
| 307 |
->addRule( ...FormRules::getGreaterThanParameters( 0 ) ); |
| 308 |
|
| 309 |
$prefixContainer->addText( 'invoice_number', __( 'Invoice number', 'packeta' ) ) |
| 310 |
->addConditionOn( $activator, Form::FILLED ) |
| 311 |
->setRequired(); |
| 312 |
|
| 313 |
$prefixContainer->addText( 'invoice_issue_date', __( 'Invoice issue date', 'packeta' ) ) |
| 314 |
->addConditionOn( $activator, Form::FILLED ) |
| 315 |
->setRequired() |
| 316 |
->addRule( ...FormRules::getDateParameters() ); |
| 317 |
|
| 318 |
$invoiceFile = $prefixContainer->addUpload( 'invoice_file', __( 'Invoice PDF file', 'packeta' ) ) |
| 319 |
->setRequired( false ); |
| 320 |
|
| 321 |
if ( $customsDeclaration === null || $customsDeclaration->hasInvoiceFileContent() === false ) { |
| 322 |
$invoiceFile |
| 323 |
->addConditionOn( $activator, Form::FILLED ) |
| 324 |
->addConditionOn( $ead, Form::EQUAL, self::EAD_OWN ) |
| 325 |
->setRequired() |
| 326 |
->endCondition() |
| 327 |
->addConditionOn( $ead, Form::EQUAL, self::EAD_CREATE ) |
| 328 |
->setRequired(); |
| 329 |
} |
| 330 |
|
| 331 |
$prefixContainer->addText( 'mrn', __( 'MRN', 'packeta' ) ) |
| 332 |
->setRequired( false ) |
| 333 |
->addConditionOn( $activator, Form::FILLED ) |
| 334 |
->addRule( Form::MAX_LENGTH, null, 32 ) |
| 335 |
->addConditionOn( $ead, Form::EQUAL, self::EAD_OWN ) |
| 336 |
->toggle( 'customs-declaration-own-field-mrn' ) |
| 337 |
->setRequired(); |
| 338 |
|
| 339 |
$eadFile = $prefixContainer->addUpload( 'ead_file', __( 'EAD PDF file', 'packeta' ) ) |
| 340 |
->setRequired( false ) |
| 341 |
->addConditionOn( $ead, Form::EQUAL, self::EAD_OWN ) |
| 342 |
->toggle( 'customs-declaration-own-field-ead_file' ); |
| 343 |
|
| 344 |
if ( $customsDeclaration === null || $customsDeclaration->hasEadFileContent() === false ) { |
| 345 |
$eadFile |
| 346 |
->addConditionOn( $activator, Form::FILLED ) |
| 347 |
->addConditionOn( $ead, Form::EQUAL, self::EAD_OWN ) |
| 348 |
->setRequired(); |
| 349 |
} |
| 350 |
|
| 351 |
$form->addSubmit( 'save' ); |
| 352 |
|
| 353 |
$items = $prefixContainer->addContainer( 'items' ); |
| 354 |
|
| 355 |
$itemsData = $structureData[ self::FORM_CONTAINER_NAME ]['items'] ?? null; |
| 356 |
|
| 357 |
if ( $itemsData === null ) { |
| 358 |
$this->addCustomsDeclarationItem( $activator, $items, 'new_0' ); |
| 359 |
} else { |
| 360 |
foreach ( $itemsData as $itemId => $itemDefaults ) { |
| 361 |
$this->addCustomsDeclarationItem( $activator, $items, (string) $itemId ); |
| 362 |
} |
| 363 |
} |
| 364 |
|
| 365 |
$form->onSuccess[] = [ $this, 'onFormSuccess' ]; |
| 366 |
$form->onError[] = [ $this, 'onFormError' ]; |
| 367 |
|
| 368 |
return $form; |
| 369 |
} |
| 370 |
|
| 371 |
/** |
| 372 |
* On form error. |
| 373 |
* |
| 374 |
* @param Form $form Form. |
| 375 |
* @return void |
| 376 |
*/ |
| 377 |
public function onFormError( Form $form ): void { |
| 378 |
/** Form input control. @var BaseControl[] $controls */ |
| 379 |
$controls = $form->getComponents( true, BaseControl::class ); |
| 380 |
foreach ( $controls as $control ) { |
| 381 |
if ( $control instanceof BaseControl ) { |
| 382 |
foreach ( $control->getErrors() as $error ) { |
| 383 |
$this->messageManager->flashMessageObject( |
| 384 |
Message::create() |
| 385 |
->setText( sprintf( '%s: %s', $control->getCaption(), $error ) ) |
| 386 |
->setType( MessageManager::TYPE_ERROR ) |
| 387 |
); |
| 388 |
} |
| 389 |
} |
| 390 |
} |
| 391 |
} |
| 392 |
|
| 393 |
/** |
| 394 |
* On form success callback. |
| 395 |
* |
| 396 |
* @param Form $form Form. |
| 397 |
* @return void |
| 398 |
*/ |
| 399 |
public function onFormSuccess( Form $form ): void { |
| 400 |
$order = $this->detailCommonLogic->getOrder(); |
| 401 |
if ( $order === null ) { |
| 402 |
return; |
| 403 |
} |
| 404 |
|
| 405 |
$fieldsToOmit = []; |
| 406 |
/** @var Container $customsDeclarationContainer */ |
| 407 |
$customsDeclarationContainer = $form[ self::FORM_CONTAINER_NAME ]; |
| 408 |
$prefixedValues = $form->getValues( 'array' ); |
| 409 |
$containerValues = $prefixedValues[ self::FORM_CONTAINER_NAME ]; |
| 410 |
$items = $containerValues['items']; |
| 411 |
unset( $containerValues['items'] ); |
| 412 |
|
| 413 |
if ( $prefixedValues[ self::FORM_ACTIVATOR_NAME ] === false ) { |
| 414 |
return; |
| 415 |
} |
| 416 |
|
| 417 |
$this->processUploadedFile( |
| 418 |
'invoice_file', |
| 419 |
'invoice_file_id', |
| 420 |
$containerValues, |
| 421 |
$customsDeclarationContainer, |
| 422 |
$fieldsToOmit |
| 423 |
); |
| 424 |
|
| 425 |
$this->processUploadedFile( |
| 426 |
'ead_file', |
| 427 |
'ead_file_id', |
| 428 |
$containerValues, |
| 429 |
$customsDeclarationContainer, |
| 430 |
$fieldsToOmit |
| 431 |
); |
| 432 |
|
| 433 |
if ( $containerValues['mrn'] === '' ) { |
| 434 |
$containerValues['mrn'] = null; |
| 435 |
} |
| 436 |
|
| 437 |
$containerValues['id'] = null; |
| 438 |
$oldCustomsDeclaration = $this->customsDeclarationRepository->getByOrderNumber( $order->getNumber() ); |
| 439 |
if ( $oldCustomsDeclaration !== null ) { |
| 440 |
$containerValues['id'] = $oldCustomsDeclaration->getId(); |
| 441 |
} |
| 442 |
|
| 443 |
$customsDeclaration = $this->customsDeclarationEntityFactory->fromStandardizedStructure( $containerValues, $order->getNumber() ); |
| 444 |
$customsDeclaration->setInvoiceFile( $containerValues['invoice_file'], (bool) $containerValues['invoice_file'] ); |
| 445 |
$customsDeclaration->setEadFile( $containerValues['ead_file'], (bool) $containerValues['ead_file'] ); |
| 446 |
$updatedRowCount = $this->customsDeclarationRepository->save( $customsDeclaration, $fieldsToOmit ); |
| 447 |
if ( $updatedRowCount === false ) { |
| 448 |
$this->messageManager->flash_message( |
| 449 |
(string) $this->wpAdapter->__( 'An error occurred while saving the customs declaration. More details in WC log.', 'packeta' ), |
| 450 |
MessageManager::TYPE_ERROR |
| 451 |
); |
| 452 |
} |
| 453 |
|
| 454 |
$customsDeclarationItems = $this->customsDeclarationRepository->getItemsByCustomsDeclarationId( $customsDeclaration->getId() ); |
| 455 |
$customsDeclaration->setItems( $customsDeclarationItems ); |
| 456 |
foreach ( $customsDeclarationItems as $customsDeclarationItem ) { |
| 457 |
$itemId = $customsDeclarationItem->getId(); |
| 458 |
if ( ! isset( $items[ $itemId ] ) ) { |
| 459 |
try { |
| 460 |
$this->customsDeclarationRepository->deleteItem( (int) $itemId ); |
| 461 |
} catch ( DeleteErrorException $e ) { |
| 462 |
// No user message needed. |
| 463 |
} |
| 464 |
} |
| 465 |
} |
| 466 |
|
| 467 |
$itemSavingError = false; |
| 468 |
foreach ( $items as $itemId => $item ) { |
| 469 |
if ( strpos( (string) $itemId, 'new_' ) === 0 ) { |
| 470 |
$itemId = null; |
| 471 |
} else { |
| 472 |
$itemId = (string) $itemId; |
| 473 |
} |
| 474 |
|
| 475 |
$item['id'] = $itemId; |
| 476 |
$item['customs_declaration_id'] = $customsDeclaration->getId(); |
| 477 |
$updatedRowCount = $this->customsDeclarationRepository->saveItem( |
| 478 |
$this->customsDeclarationEntityFactory->createItemFromStandardizedStructure( $item ) |
| 479 |
); |
| 480 |
if ( $updatedRowCount === false ) { |
| 481 |
$itemSavingError = true; |
| 482 |
} |
| 483 |
} |
| 484 |
|
| 485 |
if ( $itemSavingError === true ) { |
| 486 |
$this->messageManager->flash_message( |
| 487 |
(string) $this->wpAdapter->__( 'An error occurred while saving the customs declaration items. More details in WC log.', 'packeta' ), |
| 488 |
MessageManager::TYPE_ERROR |
| 489 |
); |
| 490 |
} |
| 491 |
} |
| 492 |
|
| 493 |
/** |
| 494 |
* Adds customs declaration item. |
| 495 |
* |
| 496 |
* @param Checkbox $activator Activating checkbox. |
| 497 |
* @param Container $container Container. |
| 498 |
* @param string $index Item index. |
| 499 |
* |
| 500 |
* @return void |
| 501 |
*/ |
| 502 |
public function addCustomsDeclarationItem( Checkbox $activator, Container $container, string $index ): void { |
| 503 |
$item = $container->addContainer( $index ); |
| 504 |
$item->addText( 'customs_code', __( 'Customs code', 'packeta' ) ) |
| 505 |
->addConditionOn( $activator, Form::FILLED ) |
| 506 |
->setRequired() |
| 507 |
->addRule( Form::MAX_LENGTH, null, 8 ); |
| 508 |
|
| 509 |
$item->addText( 'value', __( 'Value', 'packeta' ) ) |
| 510 |
->addConditionOn( $activator, Form::FILLED ) |
| 511 |
->setRequired() |
| 512 |
->addRule( Form::FLOAT ) |
| 513 |
->addRule( ...FormRules::getGreaterThanParameters( 0 ) ); |
| 514 |
|
| 515 |
$item->addText( 'product_name_en', __( 'Product name (EN)', 'packeta' ) ) |
| 516 |
->addConditionOn( $activator, Form::FILLED ) |
| 517 |
->setRequired(); |
| 518 |
$item->addText( 'product_name', __( 'Product name', 'packeta' ) ); |
| 519 |
|
| 520 |
$item->addText( 'units_count', __( 'Units count', 'packeta' ) ) |
| 521 |
->addConditionOn( $activator, Form::FILLED ) |
| 522 |
->setRequired() |
| 523 |
->addRule( Form::INTEGER ) |
| 524 |
->addRule( ...FormRules::getGreaterThanParameters( 0 ) ); |
| 525 |
|
| 526 |
$item->addText( 'country_of_origin', __( 'Country of origin code', 'packeta' ) ) |
| 527 |
->addConditionOn( $activator, Form::FILLED ) |
| 528 |
->setRequired() |
| 529 |
->addRule( Form::LENGTH, null, 2 ); |
| 530 |
|
| 531 |
$item->addText( 'weight', __( 'Weight (kg)', 'packeta' ) ) |
| 532 |
->addConditionOn( $activator, Form::FILLED ) |
| 533 |
->setRequired() |
| 534 |
->addRule( Form::FLOAT ) |
| 535 |
->addRule( ...FormRules::getGreaterThanParameters( 0 ) ) |
| 536 |
->addFilter( |
| 537 |
static function ( float $value ): float { |
| 538 |
return CoreHelper::simplifyWeight( $value ); |
| 539 |
} |
| 540 |
) |
| 541 |
->addRule( ...FormRules::getGreaterThanParameters( 0 ) ); |
| 542 |
|
| 543 |
$item->addCheckbox( 'is_food_or_book', __( 'Food or book?', 'packeta' ) ); |
| 544 |
$item->addCheckbox( 'is_voc', __( 'Is VOC?', 'packeta' ) ); |
| 545 |
} |
| 546 |
|
| 547 |
/** |
| 548 |
* Handle file upload. |
| 549 |
* |
| 550 |
* @param string $key File key. |
| 551 |
* @param string $relatedFileIdKey Related file id key. |
| 552 |
* @param array $containerValues Container values. |
| 553 |
* @param Container $formContainer Form container. |
| 554 |
* @param string[] $fieldsToOmit Fields to omit. |
| 555 |
* |
| 556 |
* @return void |
| 557 |
*/ |
| 558 |
private function processUploadedFile( string $key, string $relatedFileIdKey, array &$containerValues, Container $formContainer, array &$fieldsToOmit ): void { |
| 559 |
$fileUpload = $containerValues[ $key ]; |
| 560 |
$uploadControl = $formContainer[ $key ]; |
| 561 |
|
| 562 |
if ( $uploadControl instanceof UploadControl ) { |
| 563 |
if ( $fileUpload->hasFile() && $fileUpload->getSize() <= 0 ) { |
| 564 |
$uploadControl->addError( __( 'Uploaded file is empty.', 'packeta' ) ); |
| 565 |
$fileUpload = new FileUpload( null ); |
| 566 |
} |
| 567 |
|
| 568 |
if ( $fileUpload->hasFile() && self::MAX_UPLOAD_FILE_MEGABYTES * 1024 * 1024 === $fileUpload->getSize() ) { |
| 569 |
// translators: %d is numeric value. |
| 570 |
$uploadControl->addError( sprintf( __( 'Uploaded file is too big for storage. Max size is %d MB.', 'packeta' ), self::MAX_UPLOAD_FILE_MEGABYTES ) ); |
| 571 |
$fileUpload = new FileUpload( null ); |
| 572 |
} |
| 573 |
|
| 574 |
if ( $fileUpload->hasFile() && $fileUpload->isOk() ) { |
| 575 |
$containerValues[ $key ] = static function () use ( $fileUpload ): string { |
| 576 |
return $fileUpload->getContents(); |
| 577 |
}; |
| 578 |
$containerValues[ $relatedFileIdKey ] = null; |
| 579 |
} |
| 580 |
|
| 581 |
if ( $fileUpload->hasFile() && $fileUpload->isOk() === false ) { |
| 582 |
$containerValues[ $key ] = null; |
| 583 |
$containerValues[ $relatedFileIdKey ] = null; |
| 584 |
$uploadControl->addError( __( 'File failed to upload.', 'packeta' ) ); |
| 585 |
} |
| 586 |
|
| 587 |
if ( $containerValues[ $key ] instanceof FileUpload ) { |
| 588 |
$containerValues[ $key ] = null; |
| 589 |
$containerValues[ $relatedFileIdKey ] = null; |
| 590 |
$fieldsToOmit[] = $key; |
| 591 |
$fieldsToOmit[] = $relatedFileIdKey; |
| 592 |
} |
| 593 |
} |
| 594 |
} |
| 595 |
} |
| 596 |
|