Merge pull request #26 from exciler/sendcloud

Basic Sendcloud integration with Shipment rework
This commit is contained in:
OpenXE-ERP 2023-03-13 12:59:27 +01:00 committed by GitHub
commit 7623f2fb6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 8973 additions and 6412 deletions

View File

@ -0,0 +1,20 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Bank
{
public string $accountOwner;
public string $bankName;
public string $iban;
public string $note1;
public string $note2;
public ?string $bic;
public ?string $accountreference;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Communication
{
public ?string $phone;
public ?string $email;
public ?string $contactPerson;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Contact
{
public ?Communication $Communication;
public ?NativeAddress $Address;
public ?Name $Name;
}

View File

@ -0,0 +1,24 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Country
{
public ?string $country;
public string $countryISOCode;
public ?string $state;
public static function Create(string $isoCode, ?string $state = null):Country {
$obj = new Country();
$obj->countryISOCode = $isoCode;
$obj->state = $state;
return $obj;
}
}

View File

@ -0,0 +1,20 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class CreateShipmentOrderRequest
{
public Version $Version;
public ShipmentOrder $ShipmentOrder;
public ?string $labelResponseType;
public ?string $groupProfileName;
public ?string $labelFormat;
public ?string $labelFormatRetoure;
public ?string $combinedPrinting;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class CreateShipmentOrderResponse
{
public Version $Version;
public Statusinformation $Status;
public ?CreationState $CreationState;
}

View File

@ -0,0 +1,17 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class CreationState
{
public string $sequenceNumber;
public ?string $shipmentNumber;
public ?string $returnShipmentNumber;
public LabelData $LabelData;
}

View File

@ -0,0 +1,20 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Customer
{
public Name $Name;
public ?string $vatID;
public string $EKP;
public NativeAddress $Address;
public Contact $Contact;
public ?Bank $Bank;
public ?string $note;
}

View File

@ -0,0 +1,15 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class DeleteShipmentOrderRequest
{
public Version $Version;
public string $shipmentNumber;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class DeleteShipmentOrderResponse
{
public Version $Version;
public Statusinformation $Status;
public ?DeletionState $DeletionState;
}

View File

@ -0,0 +1,15 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class DeletionState
{
public string $shipmentNumber;
public Statusinformation $Status;
}

View File

@ -0,0 +1,18 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class DeliveryAddress
{
public ?NativeAddress $NativeAddress;
public ?Postfiliale $PostOffice;
public ?PackStation $PackStation;
public ?string $streetNameCode;
public ?string $streetNumberCode;
}

View File

@ -0,0 +1,17 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Dimension
{
public int $length;
public int $width;
public int $height;
public ?string $unit;
}

View File

@ -0,0 +1,19 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ExportDocPosition
{
public string $description;
public string $countryCodeOrigin;
public string $customsTariffNumber;
public int $amount;
public float $netWeightInKG;
public float $customsValue;
}

View File

@ -0,0 +1,40 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ExportDocument
{
const TYPE_PRESENT = 'PRESENT';
const TYPE_DOCUMENT = 'DOCUMENT';
const TYPE_COMMERCIAL_GOODS = 'COMMERCIAL_GOODS';
const TYPE_COMMERCIAL_SAMPLE = 'COMMERCIAL_SAMPLE';
const TYPE_RETURN_OF_GOODS= 'RETURN_OF_GOODS';
const TYPE_OTHER = 'OTHER';
const TERMS_DDP = 'DDP';
const TERMS_DXV = 'DXV';
const TERMS_DAP = 'DAP';
const TERMS_DDX = 'DDX';
const TERMS_CPT = 'CPT';
public ?string $invoiceNumber;
public string $exportType;
public ?string $exportTypeDescription;
public ?string $termsOfTrade;
public string $placeOfCommital;
public ?float $additionalFee;
public ?string $customsCurrency;
public ?string $permitNumber;
public ?string $attestationNumber;
public ?string $addresseesCustomsReference;
public ?string $sendersCustomsReference;
public ?bool $WithElectronicExportNtfctn;
/** @var ExportDocPosition[] $ExportDocPosition */
public array $ExportDocPosition;
}

View File

@ -0,0 +1,23 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class LabelData
{
public Statusinformation $Status;
public ?string $shipmentNumber;
public ?string $labelUrl;
public ?string $labelData;
public ?string $returnLabelUrl;
public ?string $returnLabelData;
public ?string $exportLabelUrl;
public ?string $exportLabelData;
public ?string $codLabelUrl;
public ?string $codLabelData;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Name
{
public string $name1;
public ?string $name2;
public ?string $name3;
}

View File

@ -0,0 +1,25 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class NativeAddress
{
public string $streetName;
public ?string $streetNumber;
/**
* @var string[]
*/
public array $addressAddition;
public ?string $dispatchingInformation;
public string $zip;
public string $city;
public ?string $province;
public ?Country $Origin;
}

View File

@ -0,0 +1,18 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class NativeAddressNew
{
public string $streetName;
public ?string $streetNumber;
public string $zip;
public string $city;
public ?Country $Origin;
}

View File

@ -0,0 +1,19 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class PackStation
{
public string $postNumber;
public string $packstationNumber;
public string $zip;
public string $city;
public ?string $province;
public ?Country $Origin;
}

View File

@ -0,0 +1,18 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Postfiliale
{
public string $postfilialeNumber;
public string $postNumber;
public string $zip;
public string $city;
public ?Country $Origin;
}

View File

@ -0,0 +1,18 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Receiver
{
public string $name1;
public ?ReceiverNativeAddress $Address;
public ?PackStation $Packstation;
public ?Postfiliale $Postfiliale;
public ?Communication $Communication;
}

View File

@ -0,0 +1,23 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ReceiverNativeAddress
{
public ?string $name2;
public ?string $name3;
public string $streetName;
public ?string $streetNumber;
public array|string|null $addressAddition;
public ?string $dispatchingInformation;
public string $zip;
public string $city;
public ?string $province;
public ?Country $Origin;
}

View File

@ -0,0 +1,28 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Shipment
{
public ShipmentDetails $ShipmentDetails;
public Shipper $Shipper;
public string $ShipperReference;
public Receiver $Receiver;
public ?Shipper $ReturnReceiver;
public ?ExportDocument $ExportDocument;
public ?string $feederSystem;
public function __construct()
{
$this->ShipmentDetails = new ShipmentDetails();
$this->Shipper = new Shipper();
$this->ShipperReference = '';
$this->Receiver = new Receiver();
}
}

View File

@ -0,0 +1,34 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
use DateTimeImmutable;
class ShipmentDetails
{
public string $product;
public string $accountNumber;
public string $customerReference;
private string $shipmentDate;
public string $costCentre;
public string $returnShipmentAccountNumber;
public string $returnShipmentReference;
public ShipmentItem $ShipmentItem;
public ShipmentService $Service;
public ShipmentNotification $Notification;
public Bank $BankData;
public function SetShipmentDate(DateTimeImmutable $date): void {
$this->shipmentDate = $date->format('Y-m-d');
}
public function GetShipmentDate(): DateTimeImmutable {
return DateTimeImmutable::createFromFormat('Y-m-d', $this->shipmentDate);
}
}

View File

@ -0,0 +1,17 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ShipmentItem
{
public float $weightInKG;
public ?int $lengthInCM;
public ?int $widthInCM;
public ?int $heightInCM;
}

View File

@ -0,0 +1,15 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ShipmentNotification
{
public string $recipientEmailAddress;
public ?string $templateId;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ShipmentOrder
{
public string $sequenceNumber;
public Shipment $Shipment;
public ?Serviceconfiguration $PrintOnlyIfCodeable;
}

View File

@ -0,0 +1,13 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class ShipmentService
{
}

View File

@ -0,0 +1,22 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Shipper
{
public Name $Name;
public NativeAddressNew $Address;
public ?Communication $Communication;
public function __construct()
{
$this->Name = new Name();
$this->Address = new NativeAddressNew();
}
}

View File

@ -0,0 +1,15 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Status
{
public string $statuscode;
public string $statusDescription;
}

View File

@ -0,0 +1,15 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class StatusElement
{
public string $statusElement;
public string $statusMessage;
}

View File

@ -0,0 +1,19 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Statusinformation
{
public int $statusCode;
public string $statusText;
public array|string $statusMessage;
public string $statusType;
public StatusElement $errorMessage;
public StatusElement $warningMessage;
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl\Data;
class Version
{
public string $majorRelease;
public string $minorRelease;
public ?string $build;
}

View File

@ -0,0 +1,76 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\Dhl;
use SoapClient;
use SoapHeader;
use Xentral\Carrier\Dhl\Data\CreateShipmentOrderRequest;
use Xentral\Carrier\Dhl\Data\CreateShipmentOrderResponse;
use Xentral\Carrier\Dhl\Data\CreationState;
use Xentral\Carrier\Dhl\Data\LabelData;
use Xentral\Carrier\Dhl\Data\Shipment;
use Xentral\Carrier\Dhl\Data\ShipmentOrder;
use Xentral\Carrier\Dhl\Data\Statusinformation;
use Xentral\Carrier\Dhl\Data\Version;
class DhlApi
{
private SoapClient $soapClient;
private const SANDBOX_URL = 'https://cig.dhl.de/services/sandbox/soap';
private const PRODUCTION_URL = 'https://cig.dhl.de/services/production/soap';
private const NAMESPACE_CIS = 'http://dhl.de/webservice/cisbase';
public function __construct(string $user, string $signature)
{
$this->soapClient = new SoapClient(__DIR__ . '/Wsdl/geschaeftskundenversand-api-3.4.0.wsdl', [
'login' => 'OpenXE_1',
'password' => 'cjzNEpGXxbbnRwcYLISX3ZTTcQrQrz',
'location' => self::PRODUCTION_URL,
'trace' => 1,
'connection_timeout' => 30,
'classmap' => [
'CreateShipmentOrderResponse' => CreateShipmentOrderResponse::class,
'CreationState' => CreationState::class,
'LabelData' => LabelData::class,
'Statusinformation' => Statusinformation::class,
'Version' => Version::class,
]
]);
$authHeader = new SoapHeader(self::NAMESPACE_CIS, 'Authentification', [
'user' => $user,
'signature' => $signature
]);
$this->soapClient->__setSoapHeaders($authHeader);
}
public function CreateShipment(Shipment $shipment): CreateShipmentOrderResponse|string
{
$request = new CreateShipmentOrderRequest();
$request->Version = $this->getVersion();
$request->ShipmentOrder = new ShipmentOrder();
$request->ShipmentOrder->Shipment = $shipment;
$request->ShipmentOrder->sequenceNumber = '1';
$request->labelResponseType = "B64";
try {
$response = $this->soapClient->createShipmentOrder($request);
return $response;
} catch (\SoapFault $e) {
return $e->getMessage();
}
}
private function getVersion() {
$version = new Version();
$version->majorRelease = '3';
$version->minorRelease = '4';
return $version;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,340 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Version: 3.4.0
Date: 2022-08-01T22:00:51Z
--><wsdl:definitions xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:cis="http://dhl.de/webservice/cisbase"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:bcs="http://dhl.de/webservices/businesscustomershipping/3.0"
targetNamespace="http://dhl.de/webservices/businesscustomershipping/3.0">
<wsdl:types>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified">
<xs:import namespace="http://dhl.de/webservice/cisbase"
schemaLocation="geschaeftskundenversand-api-3.4.0-schema-cis_base.xsd"/>
<xs:import namespace="http://dhl.de/webservices/businesscustomershipping/3.0"
schemaLocation="geschaeftskundenversand-api-3.4.0-schema-bcs_base.xsd"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="AuthentificationHeaderMessage">
<wsdl:documentation>The authentication data.</wsdl:documentation>
<wsdl:part name="header" element="cis:Authentification"/>
</wsdl:message>
<wsdl:message name="createShipmentOrderMessage">
<wsdl:documentation>The shipmentdata for creating a shipment.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:CreateShipmentOrderRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="createShipmentOrderResponseMessage">
<wsdl:documentation>The status of the createShipment operation and the identifier for the
shipment.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:CreateShipmentOrderResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="validateShipmentMessage">
<wsdl:documentation>The shipmentdata for validating a shipment.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:ValidateShipmentOrderRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="validateShipmentResponseMessage">
<wsdl:documentation>The status of the validateShipment operation and the identifier for the
shipment.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:ValidateShipmentResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="deleteShipmentOrderMessage">
<wsdl:documentation>The identifier for the shipment which should be
deleted.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:DeleteShipmentOrderRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="deleteShipmentOrderResponseMessage">
<wsdl:documentation>The status of the deletion operation.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:DeleteShipmentOrderResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="doManifestMessage">
<wsdl:documentation>The identifier for the shipment which should be
manifested.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:DoManifestRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="doManifestResponseMessage">
<wsdl:documentation>The status of the manifest operation.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:DoManifestResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getLabelMessage">
<wsdl:documentation>The identifier for the DD shipment for which the label url is
requested.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetLabelRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getLabelResponseMessage">
<wsdl:documentation>The status of the operation and the label url (if
available).</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetLabelResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getVersionRequestMessage">
<wsdl:documentation>The version of webservice implementation.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:Version"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getVersionResponseMessage">
<wsdl:documentation>The version of webservice implementation.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetVersionResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getExportDocMessage">
<wsdl:documentation>The identifier for the DD shipment for which the label url is
requested.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetExportDocRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getExportDocResponseMessage">
<wsdl:documentation>The status of the operation and the label url (if
available).</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetExportDocResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getManifestRequestMessage">
<wsdl:documentation>Request a manifest of the given date / date range.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetManifestRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getManifestResponseMessage">
<wsdl:documentation>The status of the operation and the manifest url (if
available).</wsdl:documentation>
<wsdl:part name="part1" element="bcs:GetManifestResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="updateShipmentOrderRequestMessage">
<wsdl:documentation>Request a manifest of the given date / date range.</wsdl:documentation>
<wsdl:part name="part1" element="bcs:UpdateShipmentOrderRequest"> </wsdl:part>
</wsdl:message>
<wsdl:message name="updateShipmentOrderResponseMessage">
<wsdl:documentation>The status of the operation and the manifest url (if
available).</wsdl:documentation>
<wsdl:part name="part1" element="bcs:UpdateShipmentOrderResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="readShipmentOrderResponseMessage">
<wsdl:documentation>The status of the operation and the manifest url (if
available).</wsdl:documentation>
<wsdl:part name="part1" element="bcs:ReadShipmentOrderResponse"> </wsdl:part>
</wsdl:message>
<wsdl:portType name="GKV3XAPIServicePortType">
<wsdl:operation name="createShipmentOrder">
<wsdl:documentation>Creates shipments.</wsdl:documentation>
<wsdl:input message="bcs:createShipmentOrderMessage">
<wsdl:documentation>The shipment data.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:createShipmentOrderResponseMessage">
<wsdl:documentation>The status of the createShipment operation and the identifier for the
shipment.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="validateShipment">
<wsdl:documentation>Creates shipments.</wsdl:documentation>
<wsdl:input message="bcs:validateShipmentMessage">
<wsdl:documentation>The shipment data.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:validateShipmentResponseMessage">
<wsdl:documentation>The status of the validateShipment operation and the identifier for the
shipment.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deleteShipmentOrder">
<wsdl:documentation>Deletes the requested shipments.</wsdl:documentation>
<wsdl:input message="bcs:deleteShipmentOrderMessage">
<wsdl:documentation>The identifier for the shipment which should be
deleted.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:deleteShipmentOrderResponseMessage">
<wsdl:documentation>The status of the deletion operation.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="doManifest">
<wsdl:documentation>Manifest the requested DD shipments.</wsdl:documentation>
<wsdl:input message="bcs:doManifestMessage">
<wsdl:documentation>The identifier for the shipment which should be
manifested.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:doManifestResponseMessage">
<wsdl:documentation>The status of the manifest operation.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getLabel">
<wsdl:documentation>Returns the request-url for getting a label.</wsdl:documentation>
<wsdl:input message="bcs:getLabelMessage">
<wsdl:documentation>The identifier for the shipment for which the label url is
requested.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:getLabelResponseMessage">
<wsdl:documentation>The status of the operation and the label url (if
available).</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getVersion">
<wsdl:documentation>Returns the actual version of the implementation of the whole ISService
webservice.</wsdl:documentation>
<wsdl:input message="bcs:getVersionRequestMessage"/>
<wsdl:output message="bcs:getVersionResponseMessage">
<wsdl:documentation>The version of webservice implementation.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getExportDoc">
<wsdl:documentation>Returns the request-url for getting a export
document.</wsdl:documentation>
<wsdl:input message="bcs:getExportDocMessage">
<wsdl:documentation>The identifier for the shipment for which the export document url is
requested.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:getExportDocResponseMessage">
<wsdl:documentation>The status of the operation and the export document url (if
available).</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getManifest">
<wsdl:documentation>Request the manifest.</wsdl:documentation>
<wsdl:input message="bcs:getManifestRequestMessage">
<wsdl:documentation>The request data.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:getManifestResponseMessage">
<wsdl:documentation>The status of the getManifest operation and the manifest
url.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="updateShipmentOrder">
<wsdl:documentation>Updates a shipment order.</wsdl:documentation>
<wsdl:input message="bcs:updateShipmentOrderRequestMessage">
<wsdl:documentation>The shipment data.</wsdl:documentation>
</wsdl:input>
<wsdl:output message="bcs:updateShipmentOrderResponseMessage">
<wsdl:documentation>The status of the updateShipment operation and the identifier for the
shipment.</wsdl:documentation>
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="GKV3XAPISOAP11Binding" type="bcs:GKV3XAPIServicePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="createShipmentOrder">
<wsdl:documentation>Creates shipments.</wsdl:documentation>
<soap:operation soapAction="urn:createShipmentOrder" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment data.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation and the shipment
identifier.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="validateShipment">
<wsdl:documentation>Validates shipments.</wsdl:documentation>
<soap:operation soapAction="urn:validateShipment" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment data.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation and the shipment
identifier.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deleteShipmentOrder">
<wsdl:documentation>Deletes the requested shipments.</wsdl:documentation>
<soap:operation soapAction="urn:deleteShipmentOrder" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment
identifier.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="doManifest">
<wsdl:documentation>Manifest the requested shipments.</wsdl:documentation>
<soap:operation soapAction="urn:doManifest" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment
identifier.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getLabel">
<wsdl:documentation>Returns the request-url for getting a label.</wsdl:documentation>
<soap:operation soapAction="urn:getLabel" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment
identifier.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation and the url for requesting the
label.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getVersion">
<wsdl:documentation>Returns the actual version of the implementation of the whole ISService
webservice.</wsdl:documentation>
<soap:operation soapAction="urn:getVersion" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The version of the implementation.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getExportDoc">
<wsdl:documentation>Returns the request-url for getting a export
document.</wsdl:documentation>
<soap:operation soapAction="urn:getExportDoc" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment
identifier.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation and the url for requesting the export
document.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getManifest">
<wsdl:documentation>Requests the manifest.</wsdl:documentation>
<soap:operation soapAction="urn:getManifest" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment data.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation and the manifest url.</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="updateShipmentOrder">
<wsdl:documentation>Updates a shipment order.</wsdl:documentation>
<soap:operation soapAction="urn:updateShipmentOrder" style="document"/>
<wsdl:input>
<wsdl:documentation>The authentication data and the shipment data.</wsdl:documentation>
<soap:header message="bcs:AuthentificationHeaderMessage" part="header" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdl:documentation>The status of the operation</wsdl:documentation>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="GVAPI_2_0_de">
<wsdl:port name="GKVAPISOAP11port0" binding="bcs:GKV3XAPISOAP11Binding">
<soap:address location="https://cig.dhl.de/services/production/soap"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@ -0,0 +1,31 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class Document
{
public const TYPE_LABEL = 'label';
public const TYPE_CP71 = 'cp71';
public const TYPE_CN23 = 'cn23';
public const TYPE_CN23_DEFAULT = 'cn23-default';
public const TYPE_COMMERCIAL_INVOICE = 'commercial-invoice';
public string $Type;
public string $Size;
public string $Link;
public static function fromApiResponse(object $data): Document
{
$obj = new Document();
$obj->Type = $data->type;
$obj->Size = $data->size;
$obj->Link = $data->link;
return $obj;
}
}

View File

@ -0,0 +1,42 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
abstract class ParcelBase
{
public ?string $Name = null;
public ?string $CompanyName = null;
public ?string $Address = null;
public ?string $Address2 = null;
public ?string $HouseNumber = null;
public ?string $City = null;
public ?string $PostalCode = null;
public ?string $Telephone = null;
public bool $RequestLabel = true;
public ?string $EMail = null;
public ?string $Country = null;
public ?int $ShippingMethodId = null;
/**
* @var ?int weight in grams
*/
public ?int $Weight = null;
public ?string $OrderNumber = null;
public ?string $TotalOrderValueCurrency = null;
public ?float $TotalOrderValue = null;
public ?string $CountryState = null;
public ?string $CustomsInvoiceNr = null;
public ?int $CustomsShipmentType = null;
public ?string $ExternalReference = null;
public ?int $TotalInsuredValue = null;
public ?array $ParcelItems = array();
public bool $IsReturn = false;
public ?string $Length = null;
public ?string $Width = null;
public ?string $Height = null;
}

View File

@ -0,0 +1,47 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class ParcelCreation extends ParcelBase
{
public ?int $SenderAddressId = null;
public function toApiRequest(): array {
return [
'name' => $this->Name,
'company_name' => $this->CompanyName,
'address' => $this->Address,
'address_2' => $this->Address2,
'house_number' => $this->HouseNumber,
'city' => $this->City,
'postal_code' => $this->PostalCode,
'telephone' => $this->Telephone,
'request_label' => $this->RequestLabel,
'email' => $this->EMail,
'country' => $this->Country,
'shipment' => ['id' => $this->ShippingMethodId],
'weight' => number_format($this->Weight / 1000, 3, '.', null),
'order_number' => $this->OrderNumber,
'total_order_value_currency' => $this->TotalOrderValueCurrency,
'total_order_value' => number_format($this->TotalOrderValue, 2, '.', null),
'country_state' => $this->CountryState,
'sender_address' => $this->SenderAddressId,
'customs_invoice_nr' => $this->CustomsInvoiceNr,
'customs_shipment_type' => $this->CustomsShipmentType,
'external_reference' => $this->ExternalReference,
'total_insured_value' => $this->TotalInsuredValue ?? 0,
'parcel_items' => array_map(fn(ParcelItem $item)=>$item->toApiRequest(), $this->ParcelItems),
'is_return' => $this->IsReturn,
'length' => $this->Length,
'width' => $this->Width,
'height' => $this->Height,
];
}
}

View File

@ -0,0 +1,16 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class ParcelCreationError
{
public int $Code;
public string $Message;
public string $Request;
}

View File

@ -0,0 +1,52 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class ParcelItem
{
public string $HsCode;
/**
* @var int weight in grams
*/
public int $Weight;
public int $Quantity;
public string $Description;
public string $OriginCountry;
public float $Price;
public ?string $Sku = null;
public ?string $ProductId = null;
public function toApiRequest(): array {
return [
'hs_code' => $this->HsCode,
'weight' => number_format($this->Weight / 1000, 3, '.', null),
'quantity' => $this->Quantity,
'description' => $this->Description,
'value' => $this->Price,
'origin_country' => $this->OriginCountry,
'sku' => $this->Sku ?? '',
'product_id' => $this->ProductId ?? '',
];
}
public static function fromApiResponse(object $data): ParcelItem
{
$obj = new ParcelItem();
$obj->HsCode = $data->hs_code;
$obj->Weight = intval(floatval($data->weight)*1000);
$obj->Quantity = $data->quantity;
$obj->Description = $data->description;
$obj->Price = $data->value;
$obj->OriginCountry = $data->origin_country;
$obj->Sku = $data->sku;
$obj->ProductId = $data->product_id;
return $obj;
}
}

View File

@ -0,0 +1,82 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
use DateTimeImmutable;
use Exception;
class ParcelResponse extends ParcelBase
{
public int $Id;
public string $CarrierCode;
public DateTimeImmutable $DateCreated;
public DateTimeImmutable $DateUpdated;
public DateTimeImmutable $DateAnnounced;
public string $ShipmentMethodName;
public int $StatusId;
public string $StatusMessage;
public array $Documents;
public ?string $TrackingNumber = null;
public ?string $TrackingUrl = null;
public ?array $Errors;
public function GetDocumentByType(string $type): ?Document
{
/** @var Document $item */
foreach ($this->Documents as $item)
if ($item->Type == $type)
return $item;
return null;
}
/**
* @throws Exception
*/
public static function fromApiResponse(object $data): ParcelResponse
{
$obj = new ParcelResponse();
$obj->Address = $data->address_divided->street;
$obj->Address2 = $data->address_2;
$obj->HouseNumber = $data->address_divided->house_number;
$obj->CarrierCode = $data->carrier->code;
$obj->City = $data->city;
$obj->CompanyName = $data->company_name;
$obj->Country = $data->country->iso_2;
$obj->CustomsInvoiceNr = $data->customs_invoice_nr;
$obj->CustomsShipmentType = $data->customs_shipment_type;
$obj->DateCreated = new DateTimeImmutable($data->date_created);
$obj->DateUpdated = new DateTimeImmutable($data->date_updated);
$obj->DateAnnounced = new DateTimeImmutable($data->date_announced);
$obj->EMail = $data->email;
$obj->Id = $data->id;
$obj->Name = $data->name;
$obj->OrderNumber = $data->order_number;
$obj->ParcelItems = array_map(fn($item)=>ParcelItem::fromApiResponse($item), $data->parcel_items);
$obj->PostalCode = $data->postal_code;
$obj->ExternalReference = $data->external_reference;
$obj->ShippingMethodId = $data->shipment->id;
$obj->ShipmentMethodName = $data->shipment->name;
$obj->StatusId = $data->status->id;
$obj->StatusMessage = $data->status->message;
$obj->Documents = array_map(fn($item)=>Document::fromApiResponse($item), $data->documents);
$obj->Telephone = $data->telephone;
$obj->TotalInsuredValue = $data->total_insured_value;
$obj->TotalOrderValue = $data->total_order_value;
$obj->TotalOrderValueCurrency = $data->total_order_value_currency;
$obj->TrackingNumber = $data->tracking_number;
$obj->TrackingUrl = $data->tracking_url;
$obj->Weight = $data->weight;
$obj->Length = $data->length;
$obj->Height = $data->height;
$obj->Width = $data->width;
$obj->IsReturn = $data->is_return;
$obj->Errors = $data->errors->non_field_errors;
return $obj;
}
}

View File

@ -0,0 +1,59 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class SenderAddress {
public ?string $City;
public ?string $CompanyName;
public ?string $ContactName;
public string $Country;
public ?string $CountryState;
public ?string $Email;
public ?string $HouseNumber;
public int $Id;
public ?string $PostalBox;
public ?string $PostalCode;
public ?string $Street;
public ?string $Telephone;
public ?string $VatNumber;
public ?string $EoriNumber;
public int $BrandId;
public ?string $Label;
public ?string $SignatureFullName;
public ?string $SignatureInitials;
public function __toString(): string
{
return "$this->CompanyName; $this->ContactName; $this->Street $this->HouseNumber; $this->PostalCode; $this->City";
}
public static function fromApiResponse(object $data): SenderAddress {
$obj = new SenderAddress();
$obj->City = $data->city;
$obj->CompanyName = $data->company_name;
$obj->ContactName = $data->contact_name;
$obj->Country = $data->country;
$obj->CountryState = $data->country_state;
$obj->Email = $data->email;
$obj->HouseNumber = $data->house_number;
$obj->Id = $data->id;
$obj->PostalBox = $data->postal_box;
$obj->PostalCode = $data->postal_code;
$obj->Street = $data->street;
$obj->Telephone = $data->telephone;
$obj->VatNumber = $data->vat_number;
$obj->EoriNumber = $data->eori_number;
$obj->BrandId = $data->brand_id;
$obj->Label = $data->label;
$obj->SignatureFullName = $data->signature_full_name;
$obj->SignatureInitials = $data->signature_initials;
return $obj;
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class ShippingMethod {
public int $Id;
public string $Name;
public ?string $Carrier;
public int $MinWeight;
public int $MaxWeight;
public int $MaxLength;
public int $MaxWidth;
public int $MaxHeight;
public string $Unit;
public static function fromApiResponse(object $data):ShippingMethod {
$obj = new ShippingMethod();
$obj->Id = $data->id;
$obj->Name = $data->name;
$obj->Carrier = $data->carrier ?? null;
$obj->MinWeight = $data->properties->min_weight;
$obj->MaxWeight = $data->properties->max_weight;
$obj->MaxLength = $data->properties->max_dimensions->length;
$obj->MaxWidth = $data->properties->max_dimensions->width;
$obj->MaxHeight = $data->properties->max_dimensions->height;
$obj->Unit = $data->properties->max_dimensions->unit;
return $obj;
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud\Data;
class ShippingProduct {
public string $Name;
public string $Carrier;
public string $ServicePointsCarrier;
public string $Code;
public int $MinWeight;
public int $MaxWeight;
public array $ShippingMethods;
public static function fromApiResponse(object $data): ShippingProduct {
$obj = new ShippingProduct();
$obj->Name = $data->name;
$obj->Carrier = $data->carrier;
$obj->ServicePointsCarrier = $data->service_points_carrier;
$obj->Code = $data->code;
$obj->MinWeight = $data->weight_range->min_weight;
$obj->MaxWeight = $data->weight_range->max_weight;
foreach ($data->methods as $method) {
$child = ShippingMethod::fromApiResponse($method);
$child->Carrier = $obj->Carrier;
$obj->ShippingMethods[] = $child;
}
return $obj;
}
}

View File

@ -0,0 +1,163 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud;
use Exception;
use Xentral\Carrier\SendCloud\Data\Document;
use Xentral\Carrier\SendCloud\Data\ParcelCreation;
use Xentral\Carrier\SendCloud\Data\ParcelResponse;
use Xentral\Carrier\SendCloud\Data\SenderAddress;
use Xentral\Carrier\SendCloud\Data\ShippingProduct;
class SendCloudApi
{
/**
* @var ?string $public_key
*/
protected ?string $public_key;
/**
* @var ?string $private_key
*/
protected ?string $private_key;
const PROD_BASE_URI = 'https://panel.sendcloud.sc/api/v2';
public function __construct($public_key, $private_key)
{
$this->public_key = $public_key;
$this->private_key = $private_key;
}
/**
* @throws SendcloudApiException
*/
public function GetSenderAddresses(): array
{
$uri = self::PROD_BASE_URI . '/user/addresses/sender';
$response = $this->sendRequest($uri);
foreach ($response['body']->sender_addresses as $item)
$res[] = SenderAddress::fromApiResponse($item);
return $res ?? [];
}
/**
* @throws SendcloudApiException
*/
public function GetShippingProducts(string $sourceCountry, ?string $targetCountry = null, ?int $weight = null,
?int $height = null, ?int $length = null, ?int $width = null): array
{
$uri = self::PROD_BASE_URI . '/shipping-products';
$params = ['from_country' => $sourceCountry];
if ($targetCountry !== null)
$params['to_country'] = $targetCountry;
if ($weight !== null && $weight > 0)
$params['weight'] = $weight;
if ($height !== null && $height > 0) {
$params['height'] = $height;
$params['height_unit'] = 'centimeter';
}
if ($length !== null && $length > 0) {
$params['length'] = $length;
$params['length_unit'] = 'centimeter';
}
if ($width !== null && $width > 0) {
$params['width'] = $width;
$params['width_unit'] = 'centimeter';
}
$response = $this->sendRequest($uri, $params);
return array_map(fn($x) => ShippingProduct::fromApiResponse($x), $response['body'] ?? []);
}
/**
* @throws SendcloudApiException
*/
public function CreateParcel(ParcelCreation $parcel): ParcelResponse|string|null
{
$uri = self::PROD_BASE_URI . '/parcels';
$response = $this->sendRequest($uri, null, true, ['parcel' => $parcel->toApiRequest()], [200,400]);
switch ($response['code']) {
case 200:
if (isset($response['body']->parcel))
try {
return ParcelResponse::fromApiResponse($response['body']->parcel);
} catch (Exception $e) {
throw new SendcloudApiException(previous: $e);
}
break;
case 400:
if (isset($response->error))
return $response->error->message;
break;
}
throw SendcloudApiException::fromResponse($response);
}
/**
* @throws SendcloudApiException
*/
public function DownloadDocument(Document $document): string
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $document->Link,
CURLOPT_HTTPHEADER => [
"Authorization: Basic " . base64_encode($this->public_key . ':' . $this->private_key)
],
]);
$output = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
if ($code != 200)
throw SendcloudApiException::fromResponse(['code' => $code, 'body' => $output]);
return $output;
}
/**
* @throws SendcloudApiException
*/
function sendRequest(string $uri, array $query_params = null, bool $post = false, array $postFields = null,
array $allowedResponseCodes = [200]): ?array
{
if (empty($this->public_key) || empty($this->private_key))
return null;
$curl = curl_init();
if (is_array($query_params)) {
$uri .= '?' . http_build_query($query_params);
}
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $uri,
CURLOPT_HTTPHEADER => [
"Authorization: Basic " . base64_encode($this->public_key . ':' . $this->private_key),
'Content-Type: application/json'
],
]);
if ($post === true) {
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postFields)
]);
}
$output = json_decode(curl_exec($curl));
$code = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$ret = [
'code' => $code,
'body' => $output,
];
if (!in_array($code, $allowedResponseCodes))
throw SendcloudApiException::fromResponse($ret);
return $ret;
}
}

View File

@ -0,0 +1,24 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace Xentral\Carrier\SendCloud;
use Exception;
class SendcloudApiException extends Exception
{
public static function fromResponse(array $response) : SendcloudApiException {
if (!isset($response['body']) || !is_object($response['body']))
return new SendcloudApiException(print_r($response,true));
return new SendcloudApiException(
print_r($response['body'],true),
$response['code']
);
}
}

View File

@ -0,0 +1,19 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
namespace Xentral\Modules\ShippingMethod\Model;
class CreateShipmentResult
{
public bool $Success = false;
public array $Errors = [];
public ?string $Label;
public ?string $ExportDocuments;
public ?string $TrackingNumber;
public ?string $TrackingUrl;
}

View File

@ -0,0 +1,19 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
namespace Xentral\Modules\ShippingMethod\Model;
class CustomsInfo
{
const CUSTOMS_TYPE_GIFT = 0;
const CUSTOMS_TYPE_DOCUMENTS = 1;
const CUSTOMS_TYPE_GOODS = 2;
const CUSTOMS_TYPE_SAMPLE = 3;
const CUSTOMS_TYPE_RETURN = 4;
}

View File

@ -0,0 +1,63 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
namespace Xentral\Modules\ShippingMethod\Model;
class Product
{
const SERVICE_COD = 'cod';
const SERVICE_PREMIUM = 'premium';
public string $Id;
public string $Name;
public float $LengthMin = 0;
public float $LengthMax = 500;
public float $WidthMin = 0;
public float $WidthMax = 500;
public float $HeightMin = 0;
public float $HeightMax = 500;
public float $WeightMin = 0;
public float $WeightMax = 100;
public array $AvailableServices = [];
public static function Create(string $id, string $name):Product {
$obj = new Product();
$obj->Id = $id;
$obj->Name = $name;
return $obj;
}
public function WithLength(float $min, float $max): Product {
$this->LengthMin = $min;
$this->LengthMax = $max;
return $this;
}
public function WithWidth(float $min, float $max): Product {
$this->WidthMin = $min;
$this->WidthMax = $max;
return $this;
}
public function WithHeight(float $min, float $max): Product {
$this->HeightMin = $min;
$this->HeightMax = $max;
return $this;
}
public function WithWeight(float $min, float $max): Product {
$this->WeightMin = $min;
$this->WeightMax = $max;
return $this;
}
public function WithServices(array $services): Product {
$this->AvailableServices = $services;
return $this;
}
}

View File

@ -1,3 +1,10 @@
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
* SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
var ShippingMethodCreate = function ($) { var ShippingMethodCreate = function ($) {
'use strict'; 'use strict';
@ -11,35 +18,14 @@ var ShippingMethodCreate = function ($) {
vueElementId: '#shipment-create', vueElementId: '#shipment-create',
}, },
search: function (el) { search: function (el) {
$.ajax({ let val = $(el).val().toLowerCase();
url: 'index.php?module=versandarten&action=create&cmd=suche', $('.createbutton').each(function() {
type: 'POST', let desc = $(this).find('.tilegrid-tile-title').text();
dataType: 'json', if (desc.toLowerCase().indexOf(val)>=0)
data: { $(this).show();
val: $(el).val() else
} $(this).hide();
}) })
.done(function (data) {
if (typeof data != 'undefined' && data != null) {
if (typeof data.ausblenden != 'undefined' && data.ausblenden != null) {
me.storage.hideElements = data.ausblenden.split(';');
$.each(me.storage.hideElements, function (k, v) {
if (v != '') {
$('#' + v).hide();
}
});
}
if (typeof data.anzeigen != 'undefined' && data.anzeigen != null) {
me.storage.showElements = data.anzeigen.split(';');
$.each(me.storage.showElements, function (k, v) {
if (v != '') {
$('#' + v).show();
}
});
}
}
});
}, },
init: function () { init: function () {
if ($(me.selector.vueElementId).length === 0) { if ($(me.selector.vueElementId).length === 0) {

View File

@ -1,4 +1,11 @@
<?php <?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
* SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
/* /*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE **** **** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
* *
@ -163,28 +170,17 @@ class TemplateParser {
public function addMessage($class, $text, $html = false, $_var = 'MESSAGE') public function addMessage($class, $text, $html = false, $_var = 'MESSAGE')
{ {
$ret = ''; if(!in_array($class, ['error', 'warning', 'info', 'success']))
switch($class)
{
case 'error':
case 'warning':
case 'info':
break;
default:
$class = 'info'; $class = 'info';
break;
}
if(!$html) if(!$html)
{ {
$text = $this->htmlspecialchars($text); $text = $this->htmlspecialchars($text);
} }
$ret .= '<div class="'.$class.'">'.$text.'</div>'; $ret = sprintf('<div class="%s">%s</div>', $class, $text);
if($_var === 'return') if($_var === 'return')
{
return $ret; return $ret;
}
return $this->app->Tpl->Add($_var, $ret); $this->app->Tpl->Add($_var, $ret);
} }
public function addSelect($_var, $id, $name, $options, $selected = '', $class = '') public function addSelect($_var, $id, $name, $options, $selected = '', $class = '')

View File

@ -1,4 +1,11 @@
<?php <?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
* SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
/* /*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE **** **** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
* *
@ -15205,33 +15212,11 @@ if($id > 0)
} }
//@refactor ApplicationCore //@refactor ApplicationCore
function LoadVersandModul($modul, $id) function LoadVersandModul(string $modul, int $id): Versanddienstleister
{ {
if(empty($modul) || /** @var Versandarten $versandarten */
strpos($modul,'..') !== false || $versandarten = $this->app->loadModule('versandarten');
!@is_file(__DIR__.'/versandarten/'.$modul.'.php') return $versandarten->loadModule($modul, $id);
)
{
return;
}
$class_name = 'Versandart_'.$modul;
$class_name_custom = 'Versandart_'.$modul.'Custom';
if(!class_exists($class_name))
{
if(@is_file(__DIR__.'/versandarten/'.$modul.'_custom.php'))
{
include_once(__DIR__.'/versandarten/'.$modul.'_custom.php');
}else{
include_once(__DIR__.'/versandarten/'.$modul.'.php');
}
}
if(class_exists($class_name_custom))
{
return new $class_name_custom($this->app, $id);
}elseif(class_exists($class_name))
{
return new $class_name($this->app, $id);
}
} }
//@refactor versanddiestleister Modul //@refactor versanddiestleister Modul
@ -15620,23 +15605,6 @@ function Paketmarke($parsetarget,$sid="",$zusatz="",$typ="DHL")
if($kg=="") { if($kg=="") {
$kg = $this->VersandartMindestgewicht($id); $kg = $this->VersandartMindestgewicht($id);
} }
/*
//Brauchen wir nicht
$versandartenmodul = $this->app->DB->SelectArr("SELECT id, modul,bezeichnung FROM versandarten WHERE aktiv = 1 AND ausprojekt = 0 AND type = '".$this->app->DB->real_escape_string($versand)."' AND modul != '' AND (projekt = 0 OR projekt = '$projekt') ORDER BY projekt DESC LIMIT 1");
if($versandartenmodul && @is_file(dirname(__FILE__).'/versandarten/'.$versandartenmodul[0]['modul'].'.php'))
{
$class_name = 'Versandart_'.$versandartenmodul[0]['modul'];
if(!class_exists($class_name))include_once(dirname(__FILE__).'/versandarten/'.$versandartenmodul[0]['modul'].'.php');
if(class_exists($class_name))
{
$obj = new $class_name($this->app, $versandartenmodul[0]['id']);
if(method_exists($obj, 'TrackingReplace')){
$tracking = $obj->TrackingReplace($tracking);
}
}
}
*/
$trackingUser = !empty($this->app->User) && method_exists($this->app->User,'GetParameter')? $trackingUser = !empty($this->app->User) && method_exists($this->app->User,'GetParameter')?
$this->app->User->GetParameter('versand_lasttracking'):''; $this->app->User->GetParameter('versand_lasttracking'):'';
@ -15670,8 +15638,7 @@ function Paketmarke($parsetarget,$sid="",$zusatz="",$typ="DHL")
'SELECT zahlweise FROM rechnung WHERE id = %d', $rechnung 'SELECT zahlweise FROM rechnung WHERE id = %d', $rechnung
) )
); );
} } else {
else{
$rechnung_projekt = $this->app->DB->Select( $rechnung_projekt = $this->app->DB->Select(
sprintf( sprintf(
'SELECT projekt FROM auftrag WHERE id = %d', $auftrag 'SELECT projekt FROM auftrag WHERE id = %d', $auftrag
@ -15806,7 +15773,6 @@ function Paketmarke($parsetarget,$sid="",$zusatz="",$typ="DHL")
if($kg=="") $kg=$this->VersandartMindestgewicht($lieferschein); if($kg=="") $kg=$this->VersandartMindestgewicht($lieferschein);
//$versandartenmodul = $this->app->DB->SelectArr("SELECT id, modul FROM versanddienstleister WHERE aktiv = 1 AND modul = '".$this->app->DB->real_escape_string($typ)."' AND (projekt = 0 OR projekt = '$projekt') ORDER BY projekt DESC LIMIT 1");
$versandartenmodul = $this->app->DB->SelectArr("SELECT id, modul,bezeichnung, einstellungen_json FROM versandarten WHERE aktiv = 1 AND ausprojekt = 0 AND type = '".$this->app->DB->real_escape_string($typ)."' AND modul != '' AND (projekt = 0 OR projekt = '$projekt') ORDER BY projekt DESC LIMIT 1"); $versandartenmodul = $this->app->DB->SelectArr("SELECT id, modul,bezeichnung, einstellungen_json FROM versandarten WHERE aktiv = 1 AND ausprojekt = 0 AND type = '".$this->app->DB->real_escape_string($typ)."' AND modul != '' AND (projekt = 0 OR projekt = '$projekt') ORDER BY projekt DESC LIMIT 1");
if($versandartenmodul && @is_file(dirname(__FILE__).'/versandarten/'.$versandartenmodul[0]['modul'].'.php')) if($versandartenmodul && @is_file(dirname(__FILE__).'/versandarten/'.$versandartenmodul[0]['modul'].'.php'))
{ {
@ -15817,165 +15783,7 @@ function Paketmarke($parsetarget,$sid="",$zusatz="",$typ="DHL")
{ {
$error = $obj->Paketmarke($sid!=''?$sid:'lieferschein',$id); $error = $obj->Paketmarke($sid!=''?$sid:'lieferschein',$id);
}else $error[] = 'Versandmodul '.$typ.' fehlerhaft!'; }else $error[] = 'Versandmodul '.$typ.' fehlerhaft!';
}else{
switch($typ)
{
case "DHL":
if($nachnahme=="" && $versichert=="" && $extraversichert=="")
{
$this->EasylogPaketmarkeStandard($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg);
} else if ($nachnahme=="1" && $versichert=="" && $extraversichert=="")
{
$this->EasylogPaketmarkeNachnahme($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer);
} else if ($versichert=="1" && $extraversichert=="" && $nachnahme=="")
{
$this->EasylogPaketmarke2500($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg);
} else if ($versichert=="1" && $extraversichert=="" && $nachnahme=="1")
{
$this->EasylogPaketmarkeNachnahme2500($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer);
} else if ($versichert=="" && $extraversichert=="1" && $nachnahme=="1")
{
$this->EasylogPaketmarkeNachnahme25000($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer);
} else if ($extraversichert=="1" && $versichert=="" && $nachnahme=="")
{
$this->EasylogPaketmarke25000($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg);
} }
break;
case "Intraship":
$kg = (float)str_replace(',','.',$kg);
$abholdatum = $this->app->Secure->GetPOST("abholdatum");
$retourenlabel= $this->app->Secure->GetPOST("retourenlabel");
if($retourenlabel)
{
$this->app->Tpl->Set('RETOURENLABEL', ' checked="checked" ');
$zusaetzlich['retourenlabel'] = 1;
}
if($abholdatum){
$this->app->Tpl->Set('ABHOLDATUM',$abholdatum);
$zusaetzlich['abholdatum'] = date('Y-m-d', strtotime($abholdatum));
$this->app->User->SetParameter("paketmarke_abholdatum",$zusaetzlich['abholdatum']);
}
if($altersfreigabe)$zusaetzlich['altersfreigabe'] = 1;
if($nachnahme=="1")
$error = $this->IntrashipPaketmarkeNachnahme($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer,$zusaetzlich);
else
$error = $this->IntrashipPaketmarkeStandard($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,"",$rechnungsnummer,$zusaetzlich);
break;
case "UPS":
$error = $this->UPSPaketmarke($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer);
break;
case "FEDEX":
$error = $this->FEDEXPaketmarke($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer);
break;
case 'Go':
if($name && $strasse && $plz && $ort && (($hausnummer && (!$land || $land == 'DE') || ($land && $land != 'DE'))))
{
$kg = $this->app->Secure->GetPOST("kg");
if($kg=="") $kg=$this->VersandartMindestgewicht($lieferschein);
$kg = str_replace(',','.',$kg);
$frei = $this->app->Secure->GetPOST("frei")==1?1:0;
$auftragid = $this->app->DB->Select("SELECT auftragid FROM lieferschein where id = ".(int)$lieferschein." limit 1");
if($frei){
$this->app->Tpl->Set('FREI',' checked="checked" ');
$zusaetzlich['frei'] = 1;
}
$selbstabholung = $this->app->Secure->GetPOST("selbstabholung");
if($selbstabholung){
$this->app->Tpl->Set('SELBSTABHOLUNG',' checked="checked" ');
$zusaetzlich['selbstabholung'] = 1;
}
$landesvorwahl = $this->app->Secure->GetPOST("landesvorwahl");
if($landesvorwahl){
$this->app->Tpl->Set('LANDESVORWAHL',$landesvorwahl);
$zusaetzlich['landesvorwahl'] = $landesvorwahl;
}
$ortsvorwahl = $this->app->Secure->GetPOST("ortsvorwahl");
if($ortsvorwahl){
$this->app->Tpl->Set('ORTSVORWAHL',$ortsvorwahl);
$zusaetzlich['ortsvorwahl'] = $ortsvorwahl;
}
if($telefon)
{
$this->app->Tpl->Set('TELEFON',$telefon);
$zusaetzlich['telefon'] = $telefon;
}
if($email)
{
$this->app->Tpl->Set('EMAIL',trim($email));
$zusaetzlich['email'] = trim($email);
}
$selbstanlieferung = $this->app->Secure->GetPOST("selbstanlieferung");
if($selbstanlieferung){
$this->app->Tpl->Set('SELBSTANLIEFERUNG',' checked="checked" ');
$zusaetzlich['selbstanlieferung'] = 1;
}
$abholdatum = $this->app->Secure->GetPOST("abholdatum");
if($abholdatum){
$this->app->Tpl->Set('ABHOLDATUM',$abholdatum);
$zusaetzlich['abholdatum'] = $abholdatum;
$this->app->User->SetParameter("paketmarke_abholdatum",$zusaetzlich['abholdatum']);
}
$zustelldatum = $this->app->Secure->GetPOST("zustelldatum");
if(!$zustelldatum)
{
//$zustelldatum = $this->app->DB->Select("SELECT lieferdatum FROM rechnung where id = ".(int)$rechnungid." and lieferdatum > now() limit 1");
$zustelldatum = $this->app->DB->Select("SELECT lieferdatum FROM auftrag where id = ".(int)$auftragid." limit 1");
}
if($zustelldatum){
$this->app->Tpl->Set('ZUSTELLDATUM',$zustelldatum);
$zusaetzlich['zustelldatum'] = $zustelldatum;
}
if(!$abholdatum)
{
//$abholdatum = $this->app->DB->Select("SELECT tatsaechlicheslieferdatum FROM rechnung where id = ".(int)$rechnungid." and tatsaechlicheslieferdatum > now() limit 1");
$abholdatum = $this->app->DB->Select("SELECT date_format(now(),'%d.%m.%Y')");
/*if(!$abholdatum)
{
$projekt = $this->app->DB->Select("SELECT projekt FROM auftrag WHERE id='$auftragid' LIMIT 1");
$differenztage = $this->Projektdaten($projekt,"differenz_auslieferung_tage");
if($differenztage<0) $differenztage=2;
$abholdatum = $this->app->DB->Select("SELECT DATE_SUB(lieferdatum, INTERVAL $differenztage DAY) from auftrag WHERE id='$auftragid' and DATE_SUB(lieferdatum, INTERVAL $differenztage DAY) > now() LIMIT 1");
}*/
if($abholdatum)
{
$this->app->Tpl->Set('ABHOLDATUM',$abholdatum);
$zusaetzlich['abholdatum'] = $abholdatum;
$this->app->User->SetParameter("paketmarke_abholdatum",$zusaetzlich['abholdatum']);
}
}
$Zustellhinweise = $this->app->Secure->GetPOST("Zustellhinweise");
if($Zustellhinweise){
$this->app->Tpl->Set('ZUSTELLHINWEISE',$Zustellhinweise);
$zusaetzlich['Zustellhinweise'] = $Zustellhinweise;
}
$Abholhinweise = $this->app->Secure->GetPOST("Abholhinweise");
if($Abholhinweise){
$this->app->Tpl->Set('ABHOLHINWEISE',$Abholhinweise);
$zusaetzlich['Abholhinweise'] = $Abholhinweise;
}
if($anzahl)$zusaetzlich['menge'] = $anzahl;
$inhalt = $this->app->Secure->GetPOST("inhalt");
if($inhalt){
$this->app->Tpl->Set('INHALT',$inhalt);
$zusaetzlich['inhalt'] = $inhalt;
}
if(isset($nachnahme))$zusaetzlich['nachnahme'] = $nachnahme;
$this->GoPaketmarke($id,$name,$name2,$name3,$strasse,$hausnummer,$plz,$ort,$land,$kg,$betrag,$rechnungsnummer, $zusaetzlich);
} else header("Location: index.php?module=lieferschein&action=paketmarke&id=$id");
break;
}
}
if(!isset($error) || !$error)$this->app->DB->Update("UPDATE versand SET gewicht='$kg',paketmarkegedruckt=1,anzahlpakete='$anzahl' WHERE id='$id' LIMIT 1"); if(!isset($error) || !$error)$this->app->DB->Update("UPDATE versand SET gewicht='$kg',paketmarkegedruckt=1,anzahlpakete='$anzahl' WHERE id='$id' LIMIT 1");
} }
if(!$error) if(!$error)
@ -16008,8 +15816,7 @@ function Paketmarke($parsetarget,$sid="",$zusatz="",$typ="DHL")
break; break;
} }
$this->app->DB->Insert("INSERT INTO versandpakete (id,versand,gewicht,nr,versender) VALUES ('','$id','$kg','$anzahli','".$this->app->User->GetName()."')"); $this->app->DB->Insert("INSERT INTO versandpakete (id,versand,gewicht,nr,versender) VALUES ('','$id','$kg','$anzahli','".$this->app->User->GetName()."')"); }
}
} }

View File

@ -1,201 +1,228 @@
<?php <?php
class Versanddienstleister { /*
/** @var int $id */ * SPDX-FileCopyrightText: 2022 Andreas Palm
public $id; * SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
/** @var Application $app */ *
public $app; * SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
public function GetAdressdaten($id, $sid) use Xentral\Modules\ShippingMethod\Model\CreateShipmentResult;
use Xentral\Modules\ShippingMethod\Model\CustomsInfo;
use Xentral\Modules\ShippingMethod\Model\Product;
abstract class Versanddienstleister
{ {
if($sid==='rechnung'){ protected int $id;
$rechnung = $id; protected ApplicationCore $app;
} protected string $type;
else protected int $projectId;
protected ?int $labelPrinterId;
protected ?int $documentPrinterId;
protected bool $shippingMail;
protected ?int $businessLetterTemplateId;
protected ?object $settings;
public function __construct(ApplicationCore $app, ?int $id)
{ {
$rechnung =''; $this->app = $app;
if ($id === null || $id === 0)
return;
$this->id = $id;
$row = $this->app->DB->SelectRow("SELECT * FROM versandarten WHERE id=$this->id");
$this->type = $row['type'];
$this->projectId = $row['projekt'];
$this->labelPrinterId = $row['paketmarke_drucker'];
$this->documentPrinterId = $row['export_drucker'];
$this->shippingMail = $row['versandmail'];
$this->businessLetterTemplateId = $row['geschaeftsbrief_vorlage'];
$this->settings = json_decode($row['einstellungen_json']);
} }
if($sid==='versand') public function isEtikettenDrucker(): bool
{ {
$tid = $this->app->DB->Select("SELECT lieferschein FROM versand WHERE id='$id' LIMIT 1"); return false;
$rechnung = $this->app->DB->Select("SELECT rechnung FROM versand WHERE id='$id' LIMIT 1"); }
$sid = 'lieferschein';
} else { public abstract function GetName(): string;
$tid = $id;
public function GetAdressdaten($id, $sid): array
{
$auftragId = $lieferscheinId = $rechnungId = $versandId = 0;
if ($sid === 'rechnung')
$rechnungId = $id;
if ($sid === 'lieferschein') { if ($sid === 'lieferschein') {
$rechnung = $this->app->DB->Select("SELECT id FROM rechnung WHERE lieferschein = '$tid' LIMIT 1"); $lieferscheinId = $id;
$auftragId = $this->app->DB->Select("SELECT auftragid FROM lieferschein WHERE id=$lieferscheinId LIMIT 1");
$rechnungId = $this->app->DB->Select("SELECT id FROM rechnung WHERE lieferschein = '$lieferscheinId' LIMIT 1");
if ($rechnungId <= 0)
$rechnungId = $this->app->DB->Select("SELECT rechnungid FROM lieferschein WHERE id='$lieferscheinId' LIMIT 1");
} }
if($rechnung<=0) { if ($sid === 'versand') {
$rechnung = $this->app->DB->Select("SELECT rechnungid FROM lieferschein WHERE id='$tid' LIMIT 1"); $versandId = $id;
} $lieferscheinId = $this->app->DB->Select("SELECT lieferschein FROM versand WHERE id='$versandId' LIMIT 1");
} $rechnungId = $this->app->DB->Select("SELECT rechnung FROM versand WHERE id='$versandId' LIMIT 1");
$ret['tid'] = $tid; $sid = 'lieferschein';
$ret['rechnung'] = $rechnung;
if($rechnung){
$artikel_positionen = $this->app->DB->SelectArr("SELECT * FROM rechnung_position WHERE rechnung='$rechnung'");
} else {
$artikel_positionen = $this->app->DB->SelectArr(sprintf('SELECT * FROM `%s` WHERE `%s` = %d',$sid.'_position',$sid,$tid));
} }
if($sid==='rechnung' || $sid==='lieferschein' || $sid==='adresse') if ($auftragId <= 0 && $rechnungId > 0)
{ $auftragId = $this->app->DB->Select("SELECT auftragid FROM rechnung WHERE id=$rechnungId LIMIT 1");
$docArr = $this->app->DB->SelectRow(sprintf('SELECT * FROM `%s` WHERE id = %d LIMIT 1',$sid, $tid));
$name = trim($docArr['name']);//trim($this->app->DB->Select("SELECT name FROM $sid WHERE id='$tid' LIMIT 1")); if ($sid === 'rechnung' || $sid === 'lieferschein' || $sid === 'adresse') {
$name2 = trim($docArr['adresszusatz']);//trim($this->app->DB->Select("SELECT adresszusatz FROM $sid WHERE id='$tid' LIMIT 1")); $docArr = $this->app->DB->SelectRow("SELECT * FROM `$sid` WHERE id = $id LIMIT 1");
$abt = 0; $ret['addressId'] = $docArr['adresse'];
if($name2==='') $ret['auftragId'] = $auftragId;
{ $ret['rechnungId'] = $rechnungId;
$name2 = trim($docArr['abteilung']);//trim($this->app->DB->Select("SELECT abteilung FROM $sid WHERE id='$tid' LIMIT 1")); $ret['lieferscheinId'] = $lieferscheinId;
$abt=1;
}
$name3 = trim($docArr['ansprechpartner']);//trim($this->app->DB->Select("SELECT ansprechpartner FROM $sid WHERE id='$tid' LIMIT 1"));
if($name3==='' && $abt!==1){
$name3 = trim($docArr['abteilung']);//trim($this->app->DB->Select("SELECT abteilung FROM $sid WHERE id='$tid' LIMIT 1"));
}
//unterabteilung versuchen einzublenden $addressfields = ['name', 'adresszusatz', 'abteilung', 'ansprechpartner', 'unterabteilung', 'ort', 'plz',
if($name2==='') { 'strasse', 'land'];
$name2 = trim($docArr['unterabteilung']);//trim($this->app->DB->Select("SELECT unterabteilung FROM $sid WHERE id='$tid' LIMIT 1")); $ret['original'] = array_filter($docArr, fn($key) => in_array($key, $addressfields), ARRAY_FILTER_USE_KEY);
} else if ($name3==='') {
$name3 = trim($docArr['unterabteilung']);//trim($this->app->DB->Select("SELECT unterabteilung FROM $sid WHERE id='$tid' LIMIT 1"));
}
if($name3!=='' && $name2==='') { $ret['name'] = empty(trim($docArr['ansprechpartner'])) ? trim($docArr['name']) : trim($docArr['ansprechpartner']);
$name2=$name3; $ret['name2'] = !empty(trim($docArr['ansprechpartner'])) ? trim($docArr['name']) : '';
$name3=''; $ret['name3'] = join(';', array_filter([
} $docArr['abteilung'],
$docArr['unterabteilung']
], fn(string $item) => !empty(trim($item))));
$ret['address2'] = $docArr['adresszusatz'];
$ort = trim($docArr['ort']);//trim($this->app->DB->Select("SELECT ort FROM $sid WHERE id='$tid' LIMIT 1")); $ret['city'] = $docArr['ort'];
$plz = trim($docArr['plz']);//trim($this->app->DB->Select("SELECT plz FROM $sid WHERE id='$tid' LIMIT 1")); $ret['zip'] = $docArr['plz'];
$land = trim($docArr['land']);//trim($this->app->DB->Select("SELECT land FROM $sid WHERE id='$tid' LIMIT 1")); $ret['country'] = $docArr['land'];
$strasse = trim($docArr['strasse']);//trim($this->app->DB->Select("SELECT strasse FROM $sid WHERE id='$tid' LIMIT 1")); $ret['phone'] = $docArr['telefon'];
$strassekomplett = $strasse; $ret['email'] = $docArr['email'];
$ret['addresstype'] = 0;
$strasse = trim($docArr['strasse']);
$ret['streetwithnumber'] = $strasse;
$hausnummer = trim($this->app->erp->ExtractStreetnumber($strasse)); $hausnummer = trim($this->app->erp->ExtractStreetnumber($strasse));
$strasse = trim(str_replace($hausnummer, '', $strasse)); $strasse = trim(str_replace($hausnummer, '', $strasse));
$strasse = str_replace('.', '', $strasse); $strasse = str_replace('.', '', $strasse);
if($strasse=='') if ($strasse == '') {
{
$strasse = trim($hausnummer); $strasse = trim($hausnummer);
$hausnummer = ''; $hausnummer = '';
} }
$telefon = trim($docArr['telefon']);//trim($this->app->DB->Select("SELECT telefon FROM $sid WHERE id='$tid' LIMIT 1")); $ret['street'] = $strasse;
$email = trim($docArr['email']);//trim($this->app->DB->Select("SELECT email FROM $sid WHERE id='$tid' LIMIT 1")); $ret['streetnumber'] = $hausnummer;
if (str_contains($docArr['strasse'], 'Packstation')) {
$ret['addresstype'] = 1;
$ret['parcelstationNumber'] = $hausnummer;
} else if (str_contains($docArr['strasse'], 'Postfiliale')) {
$ret['addresstype'] = 2;
$ret['postofficeNumber'] = $hausnummer;
} }
$tmp = join(' ', [$docArr['ansprechpartner'], $docArr['abteilung'], $docArr['unterabteilung']]);
if (preg_match("/\d{6,10}/", $tmp, $match)) {
$ret['postnumber'] = $match[0];
}
if ($auftragId > 0) {
$internet = $this->app->DB->Select("SELECT internet FROM auftrag WHERE id = $auftragId LIMIT 1");
if (!empty($internet))
$orderNumberParts[] = $internet;
}
if (!empty($docArr['ihrebestellnummer'])) {
$orderNumberParts[] = $docArr['ihrebestellnummer'];
}
$orderNumberParts[] = $docArr['belegnr'];
$ret['order_number'] = implode(' / ', $orderNumberParts);
}
// wenn rechnung im spiel entweder durch versand oder direkt rechnung // wenn rechnung im spiel entweder durch versand oder direkt rechnung
if($rechnung >0) if ($rechnungId > 0) {
{ $invoice_data = $this->app->DB->SelectRow("SELECT zahlungsweise, soll, belegnr FROM rechnung WHERE id='$rechnungId' LIMIT 1");
$zahlungsweise = $this->app->DB->Select("SELECT zahlungsweise FROM rechnung WHERE id='$rechnung' LIMIT 1"); $ret['zahlungsweise'] = $invoice_data['zahlungsweise'];
$soll = $this->app->DB->Select("SELECT soll FROM rechnung WHERE id='$rechnung' LIMIT 1"); $ret['betrag'] = $invoice_data['soll'];
$ret['invoice_number'] = $invoice_data['belegnr'];
if($zahlungsweise==='nachnahme'){ if ($invoice_data['zahlungsweise'] === 'nachnahme') {
$nachnahme = true; $ret['nachnahme'] = true;
}
if($soll >= 500 && $soll <= 2500){
$versichert = true;
}
if($soll > 2500) {
$extraversichert = true;
} }
} }
if(isset($frei))$ret['frei'] = $frei; $sql = "SELECT
if(isset($inhalt))$ret['inhalt'] = $inhalt; lp.bezeichnung,
if(isset($keinealtersabfrage))$ret['keinealtersabfrage'] = $keinealtersabfrage; lp.menge,
if(isset($altersfreigabe))$ret['altersfreigabe'] = $altersfreigabe; coalesce(nullif(lp.zolltarifnummer, '0'), nullif(rp.zolltarifnummer, '0'), nullif(a.zolltarifnummer, '')) as zolltarifnummer,
if(isset($zahlungsweise))$ret['zahlungsweise'] = $zahlungsweise; coalesce(nullif(lp.herkunftsland, '0'), nullif(rp.herkunftsland, '0'), nullif(a.herkunftsland, '')) as herkunftsland,
if(isset($versichert))$ret['versichert'] = $versichert; coalesce(nullif(lp.zolleinzelwert, '0'), rp.preis *(1-rp.rabatt/100), 0) as zolleinzelwert,
if(isset($soll))$ret['betrag'] = $soll; coalesce(nullif(lp.zolleinzelgewicht, 0), a.gewicht) as zolleinzelgewicht,
if(isset($extraversichert))$ret['extraversichert'] = $extraversichert; lp.zollwaehrung
if(isset($nachnahme))$ret['nachnahme'] = $nachnahme; FROM lieferschein_position lp
$ret['name'] = $name; JOIN artikel a on lp.artikel = a.id
$ret['name2'] = $name2; LEFT JOIN auftrag_position ap on lp.auftrag_position_id = ap.id
$ret['name3'] = $name3; LEFT JOIN rechnung_position rp on ap.id = rp.auftrag_position_id
$ret['ort'] = $ort; LEFT JOIN rechnung r on rp.rechnung = r.id
$ret['plz'] = $plz; WHERE lp.lieferschein = $lieferscheinId
$ret['strasse'] = $strasse; AND a.lagerartikel = 1
$ret['strassekomplett'] = $strassekomplett; AND r.status != 'storniert'
$ret['hausnummer'] = $hausnummer; ORDER BY lp.sort";
$ret['land'] = $land; $ret['positions'] = $this->app->DB->SelectArr($sql);
$ret['telefon'] = $telefon;
$ret['phone'] = $telefon;
$ret['email'] = trim($email," \t\n\r\0\x0B\xc2\xa0");
$check_date = $this->app->DB->Select("SELECT date_format(now(),'%Y-%m-%d')");
$ret['abholdaumt'] = date('d.m.Y', strtotime($check_date));
$anzahl = $this->app->Secure->GetGET("anzahl");
if($anzahl <= 0)
{
$anzahl=1;
}
if ($sid === "lieferschein") { if ($sid === "lieferschein") {
$standardkg = $this->app->erp->VersandartMindestgewicht($tid); $standardkg = $this->app->erp->VersandartMindestgewicht($lieferscheinId);
} } else {
else{
$standardkg = $this->app->erp->VersandartMindestgewicht(); $standardkg = $this->app->erp->VersandartMindestgewicht();
} }
//$this->app->erp->PaketmarkeGewichtForm($anzahl, $standardkg, $this->VersandartMindestgewicht()); $ret['weight'] = $standardkg;
$ret['standardkg'] = $standardkg;
$ret['anzahl'] = $anzahl;
return $ret; return $ret;
} }
/** /**
* @param string $target * Returns an array of additional field definitions to be stored for this module:
* [
* 'field_name' => [
* 'typ' => text(default)|textarea|checkbox|select
* 'default' => default value
* 'optionen' => just for selects [key=>value]
* 'size' => size attribute for text fields
* 'placeholder' => placeholder attribute for text fields
* ]
* ]
* *
* @return string * @return array
*/ */
public function Einstellungen($target = 'return') public function AdditionalSettings(): array
{ {
if(!$this->id) return [];
{
return '';
} }
//$id = $this->id;
$struktur = $this->EinstellungenStruktur(); /**
if($this->app->Secure->GetPOST('speichern')) * Renders all additional settings as fields into $target
* @param string $target template placeholder for rendered output
* @param array $form data for form values (from database or form submit)
* @return void
*/
public function RenderAdditionalSettings(string $target, array $form): void
{ {
$fields = $this->AdditionalSettings();
if ($this->app->Secure->GetPOST('speichern')) {
$json = $this->app->DB->Select("SELECT einstellungen_json FROM versandarten WHERE id = '" . $this->id . "' LIMIT 1"); $json = $this->app->DB->Select("SELECT einstellungen_json FROM versandarten WHERE id = '" . $this->id . "' LIMIT 1");
$modul = $this->app->DB->Select("SELECT modul FROM versandarten WHERE id = '" . $this->id . "' LIMIT 1"); $modul = $this->app->DB->Select("SELECT modul FROM versandarten WHERE id = '" . $this->id . "' LIMIT 1");
if(!empty($json)) if (!empty($json)) {
{
$json = @json_decode($json, true); $json = @json_decode($json, true);
} else { } else {
$json = array(); $json = array();
foreach($struktur as $name => $val) foreach ($fields as $name => $val) {
{ if (isset($val['default'])) {
if(isset($val['default']))
{
$json[$name] = $val['default']; $json[$name] = $val['default'];
} }
} }
} }
if(empty($json)) if (empty($json)) {
{
$json = null; $json = null;
} }
foreach($struktur as $name => $val) foreach ($fields as $name => $val) {
{
if($modul === $this->app->Secure->GetPOST('modul_name')) if ($modul === $this->app->Secure->GetPOST('modul_name')) {
{
$json[$name] = $this->app->Secure->GetPOST($name, '', '', 1); $json[$name] = $this->app->Secure->GetPOST($name, '', '', 1);
} }
if(isset($val['replace'])) if (isset($val['replace'])) {
{ switch ($val['replace']) {
switch($val['replace'])
{
case 'lieferantennummer': case 'lieferantennummer':
$json[$name] = $this->app->erp->ReplaceLieferantennummer(1, $json[$name], 1); $json[$name] = $this->app->erp->ReplaceLieferantennummer(1, $json[$name], 1);
break; break;
@ -205,155 +232,81 @@ class Versanddienstleister {
$json_str = $this->app->DB->real_escape_string(json_encode($json)); $json_str = $this->app->DB->real_escape_string(json_encode($json));
$this->app->DB->Update("UPDATE versandarten SET einstellungen_json = '$json_str' WHERE id = '" . $this->id . "' LIMIT 1"); $this->app->DB->Update("UPDATE versandarten SET einstellungen_json = '$json_str' WHERE id = '" . $this->id . "' LIMIT 1");
} }
$id = $this->id;
$html = ''; $html = '';
$json = $this->app->DB->Select("SELECT einstellungen_json FROM versandarten WHERE id = '$id' LIMIT 1"); foreach ($fields as $name => $val) // set missing default values
if($json)
{ {
$json = json_decode($json, true); if (isset($val['default']) && !isset($form[$name])) {
}else{ $form[$name] = $val['default'];
$json = null;
}
$changed = false;
foreach($struktur as $name => $val)
{
if(isset($val['default']) && !isset($json[$name]))
{
$changed = true;
$json[$name] = $val['default'];
} }
} }
if($changed) foreach ($fields as $name => $val) {
{
$json_str = $this->app->DB->real_escape_string(json_encode($json));
$this->app->DB->Update("UPDATE versandarten SET einstellungen_json = '$json_str' WHERE id = '".$this->id."' LIMIT 1");
}
$first = true;
foreach($struktur as $name => $val)
{
if (isset($val['heading'])) if (isset($val['heading']))
{
$html .= '<tr><td colspan="2"><b>' . html_entity_decode($val['heading']) . '</b></td></tr>'; $html .= '<tr><td colspan="2"><b>' . html_entity_decode($val['heading']) . '</b></td></tr>';
}
$html .= '<tr><td>'.($first?'<input type="hidden" name="modul_name" value="'.$this->app->DB->Select("SELECT modul FROM versandarten WHERE id = '$id' LIMIT 1").'" />':'').(empty($val['bezeichnung'])?$name:$val['bezeichnung']).'</td><td>'; $html .= '<tr><td>' . ($val['bezeichnung'] ?? $name) . '</td><td>';
$typ = 'text'; if (isset($val['replace'])) {
if(!empty($val['typ'])) switch ($val['replace']) {
{
$typ = $val['typ'];
}
if(isset($val['replace']))
{
switch($val['replace'])
{
case 'lieferantennummer': case 'lieferantennummer':
$json[$name] = $this->app->erp->ReplaceLieferantennummer(0,$json[$name],0); $form[$name] = $this->app->erp->ReplaceLieferantennummer(0, $form[$name], 0);
if($target !== 'return')
{
$this->app->YUI->AutoComplete($name, 'lieferant', 1); $this->app->YUI->AutoComplete($name, 'lieferant', 1);
}
break; break;
case 'shop': case 'shop':
$json[$name] .= ($json[$name]?' '.$this->app->DB->Select("SELECT bezeichnung FROM shopexport WHERE id = '".(int)$json[$name]."'"):''); $form[$name] .= ($form[$name] ? ' ' . $this->app->DB->Select("SELECT bezeichnung FROM shopexport WHERE id = '" . (int)$form[$name] . "'") : '');
if($target !== 'return')
{
$this->app->YUI->AutoComplete($name, 'shopnameid'); $this->app->YUI->AutoComplete($name, 'shopnameid');
}
break; break;
case 'etiketten': case 'etiketten':
//$json[$name] = $this->app->erp->ReplaceLieferantennummer(0,$json[$name],0);
if($target !== 'return')
{
$this->app->YUI->AutoComplete($name, 'etiketten'); $this->app->YUI->AutoComplete($name, 'etiketten');
}
break; break;
} }
} }
/*if(!isset($json[$name]) && isset($val['default'])) switch ($val['typ'] ?? 'text') {
{
$json[$name] = $val['default'];
}*/
switch($typ)
{
case 'textarea': case 'textarea':
$html .= '<textarea name="'.$name.'" id="'.$name.'">'.(!isset($json[$name])?'':$json[$name]).'</textarea>'; $html .= '<textarea name="' . $name . '" id="' . $name . '">' . ($form[$name] ?? '') . '</textarea>';
break; break;
case 'checkbox': case 'checkbox':
$html .= '<input type="checkbox" name="'.$name.'" id="'.$name.'" value="1" '.((isset($json[$name]) && $json[$name])?' checked="checked" ':'').' />'; $html .= '<input type="checkbox" name="' . $name . '" id="' . $name . '" value="1" ' . ($form[$name] ?? false ? ' checked="checked" ' : '') . ' />';
break; break;
case 'select': case 'select':
$html .= '<select name="'.$name.'">'; $html .= $this->app->Tpl->addSelect('return', $name, $name, $val['optionen'], $form[$name]);
if(isset($val['optionen']) && is_array($val['optionen']))
{
foreach($val['optionen'] as $k => $v)
{
$html .= '<option value="'.$k.'"'.($k == (isset($json[$name])?$json[$name]:'')?' selected="selected" ':'').'>'.$v.'</option>';
}
}
$html .= '</select>';
break; break;
case 'submit': case 'submit':
if (isset($val['text'])) if (isset($val['text']))
{
$html .= '<form method="POST"><input type="submit" name="' . $name . '" value="' . $val['text'] . '"></form>'; $html .= '<form method="POST"><input type="submit" name="' . $name . '" value="' . $val['text'] . '"></form>';
}
break; break;
case 'custom': case 'custom':
if(isset($val['function'])) if (isset($val['function'])) {
{
$tmpfunction = $val['function']; $tmpfunction = $val['function'];
if(method_exists($this, $tmpfunction)) if (method_exists($this, $tmpfunction)) {
{
$html .= $this->$tmpfunction(); $html .= $this->$tmpfunction();
} }
} }
break; break;
default: default:
$html .= '<input type="text"'
$html .= '<input type="text" '.(!empty($val['size'])?' size="'.$val['size'].'" ':'').' '.(!empty($val['placeholder'])?' placeholder="'.$val['placeholder'].'" ':'').' name="'.$name.'" id="'.$name.'" value="'.(!isset($json[$name])?'':htmlspecialchars($json[$name])).'" />'; . (!empty($val['size']) ? ' size="' . $val['size'] . '"' : '')
. (!empty($val['placeholder']) ? ' placeholder="' . $val['placeholder'] . '"' : '')
. ' name="' . $name . '" id="' . $name . '" value="' . (isset($form[$name]) ? htmlspecialchars($form[$name]) : '') . '" />';
break; break;
} }
if(isset($val['info']) && $val['info'])$html .= ' <i>'.$val['info'].'</i>'; if (isset($val['info']) && $val['info'])
$html .= ' <i>' . $val['info'] . '</i>';
$html .= '</td></tr>'; $html .= '</td></tr>';
$first = false;
}
if($target === 'return') {
return $html;
} }
$this->app->Tpl->Add($target, $html); $this->app->Tpl->Add($target, $html);
return '';
} }
/** /**
* @param string $target * Validate form data for this module
* * Form data is passed by reference so replacements (id instead of text) can be performed here as well
* @return bool * @param array $form submitted form data
* @return array
*/ */
public function checkInputParameters($target = '') public function ValidateSettings(array &$form): array
{ {
$error = ''; return [];
if (trim($this->app->Secure->GetPOST('bezeichnung')) === '') {
$error = 'Bitte alle Pflichtfelder ausfüllen!';
$this->app->Tpl->Set('MSGBEZEICHNUNG','<span style="color:red">Pflichtfeld!</span>');
} }
if (trim($this->app->Secure->GetPOST('typ')) === '') {
$error = 'Bitte alle Pflichtfelder ausfüllen!';
$this->app->Tpl->Set('MSGTYP','<span style="color:red">Pflichtfeld!</span>');
}
if ($error !== '') {
$this->app->Tpl->Add($target, sprintf('<div class="error">%s</div>', $error));
return false;
}
return true;
}
/** /**
@ -408,11 +361,77 @@ class Versanddienstleister {
* *
* @return bool * @return bool
*/ */
public function Trackinglink($tracking, &$notsend, &$link, &$rawlink) { public function Trackinglink($tracking, &$notsend, &$link, &$rawlink)
{
$notsend = 0; $notsend = 0;
$rawlink = ''; $rawlink = '';
$link = ''; $link = '';
return true; return true;
} }
public function Paketmarke(string $target, string $docType, int $docId): void
{
$address = $this->GetAdressdaten($docId, $docType);
if (isset($_SERVER['CONTENT_TYPE']) && ($_SERVER['CONTENT_TYPE'] === 'application/json')) {
$json = json_decode(file_get_contents('php://input'));
$ret = [];
if ($json->submit == 'print') {
$result = $this->CreateShipment($json, $address);
if ($result->Success) {
$sql = "INSERT INTO versand
(adresse, lieferschein, versandunternehmen, gewicht, tracking, tracking_link, anzahlpakete)
VALUES
({$address['addressId']}, {$address['lieferscheinId']}, '$this->type',
'$json->weight', '$result->TrackingNumber', '$result->TrackingUrl', 1)";
$this->app->DB->Insert($sql);
$filename = $this->app->erp->GetTMP() . join('_', [$this->type, 'Label', $result->TrackingNumber]) . '.pdf';
file_put_contents($filename, $result->Label);
$this->app->printer->Drucken($this->labelPrinterId, $filename);
if (isset($result->ExportDocuments)) {
$filename = $this->app->erp->GetTMP() . join('_', [$this->type, 'ExportDoc', $result->TrackingNumber]) . '.pdf';
file_put_contents($filename, $result->ExportDocuments);
$this->app->printer->Drucken($this->documentPrinterId, $filename);
}
$ret['messages'][] = ['class' => 'info', 'text' => "Paketmarke wurde erfolgreich erstellt: $result->TrackingNumber"];
} else {
$ret['messages'] = array_map(fn(string $item) => ['class' => 'error', 'text' => $item], array_unique($result->Errors));
}
}
header('Content-Type: application/json');
echo json_encode($ret);
$this->app->ExitXentral();
}
$address['shipment_type'] = CustomsInfo::CUSTOMS_TYPE_GOODS;
$products = $this->GetShippingProducts();
$products = array_combine(array_column($products, 'Id'), $products);
$address['product'] = $products[0]->Id ?? '';
$json['form'] = $address;
$json['countries'] = $this->app->erp->GetSelectLaenderliste();
$json['products'] = $products;
$json['customs_shipment_types'] = [
CustomsInfo::CUSTOMS_TYPE_GIFT => 'Geschenk',
CustomsInfo::CUSTOMS_TYPE_DOCUMENTS => 'Dokumente',
CustomsInfo::CUSTOMS_TYPE_GOODS => 'Handelswaren',
CustomsInfo::CUSTOMS_TYPE_SAMPLE => 'Erprobungswaren',
CustomsInfo::CUSTOMS_TYPE_RETURN => 'Rücksendung'
];
$json['messages'] = [];
$json['form']['services'] = [
Product::SERVICE_PREMIUM => false
];
$this->app->Tpl->Set('JSON', json_encode($json));
$this->app->Tpl->Set('CARRIERNAME', $this->GetName());
$this->app->Tpl->Parse($target, 'createshipment.tpl');
}
public abstract function CreateShipment(object $json, array $address): CreateShipmentResult;
/**
* @return Product[]
*/
public abstract function GetShippingProducts(): array;
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
<!--
SPDX-FileCopyrightText: 2022 Andreas Palm
SPDX-License-Identifier: LicenseRef-EGPL-3.1
-->
<div class="container-fluid" id="createshipmentapp">
<form action="" method="post" v-on:submit.prevent="submit">
<div class="row">
<div v-for="msg in messages" :class="msg.class">{{msg.text}}</div>
<div>
<h1>{|Paketmarken Drucker f&uuml;r|} [CARRIERNAME]</h1>
</div>
<div class="col-md-4">
<h2>{|Empf&auml;nger|}</h2>
<table>
<tr>
<td>{|Adresstyp|}:</td>
<td>
<select v-model.number="form.addresstype">
<option value="0">Haus</option>
<option value="1">Packstation</option>
<option value="2">Filiale</option>
</select>
</td>
</tr>
<tr>
<td>{|Name / Zeile 1|}:</td>
<td><input type="text" size="36" v-model.trim="form.name"></td>
</tr>
<tr v-if="form.addresstype === 0">
<td>{|Firmenname / Zeile 2|}:</td>
<td><input type="text" size="36" v-model.trim="form.name2"></td>
</tr>
<tr v-if="form.addresstype === 1 || form.addresstype === 2">
<td>{|Postnummer|}:</td>
<td><input type="text" size="36" v-model.trim="form.postnumber"></td>
</tr>
<tr v-if="form.addresstype === 0">
<td>{|Firmenname / Zeile 3|}:</td>
<td><input type="text" size="36" v-model.trim="form.name3"></td>
</tr>
<tr v-if="form.addresstype === 0">
<td>{|Strasse/Hausnummer|}:</td>
<td>
<input type="text" size="30" v-model.trim="form.street">
<input type="text" size="5" v-model.trim="form.streetnumber">
</td>
</tr>
<tr v-if="form.addresstype === 1">
<td>{|Packstationsnummer|}:</td>
<td><input type="text" size="10" v-model.trim="form.parcelstationNumber"></td>
</tr>
<tr v-if="form.addresstype === 2">
<td>{|Postfilialnummer|}:</td>
<td><input type="text" size="10" v-model.trim="form.postofficeNumber"></td>
</tr>
<tr v-if="form.addresstype === 0">
<td>{|Adresszeile 2|}:</td>
<td><input type="text" size="36" v-model.trim="form.address2"></td>
</tr>
<tr>
<td>{|PLZ/Ort|}:</td>
<td><input type="text" size="5" v-model.trim="form.zip">
<input type="text" size="30" v-model.trim="form.city">
</td>
</tr>
<tr>
<td>{|Bundesland|}:</td>
<td><input type="text" size="36" v-model.trim="form.state"></td>
</tr>
<tr>
<td>{|Land|}:</td>
<td>
<select v-model="form.country" required>
<option v-for="(value, key) in countries" :value="key">{{value}}</option>
</select>
</td>
</tr>
<tr>
<td>{|Ansprechpartner|}:</td>
<td><input type="text" size="36" v-model="form.contactperson"></td>
</tr>
<tr>
<td>{|E-Mail|}:</td>
<td><input type="text" size="36" v-model.trim="form.email"></td>
</tr>
<tr>
<td>{|Telefon|}:</td>
<td><input type="text" size="36" v-model.trim="form.phone"></td>
</tr>
</table>
</div>
<div class="col-md-4" v-once>
<h2>vollst. Adresse</h2>
<table>
<tr>
<td>{|Name|}</td>
<td>{{form.original.name}}</td>
</tr>
<tr>
<td>{|Ansprechpartner|}</td>
<td>{{form.original.ansprechpartner}}</td>
</tr>
<tr>
<td>{|Abteilung|}</td>
<td>{{form.original.abteilung}}</td>
</tr>
<tr>
<td>{|Unterabteilung|}</td>
<td>{{form.original.unterabteilung}}</td>
</tr>
<tr>
<td>{|Adresszusatz|}</td>
<td>{{form.original.adresszusatz}}</td>
</tr>
<tr>
<td>{|Strasse|}</td>
<td>{{form.original.strasse}}</td>
</tr>
<tr>
<td>{|PLZ/Ort|}</td>
<td>{{form.original.plz}} {{form.original.ort}}</td>
</tr>
<tr>
<td>{|Bundesland|}</td>
<td>{{form.original.bundesland}}</td>
</tr>
<tr>
<td>{|Land|}</td>
<td>{{form.original.land}}</td>
</tr>
</table>
</div>
<div class="col-md-4">
<h2>{|Paket|}</h2>
<table>
<tr>
<td>{|Gewicht (in kg)|}:</td>
<td><input type="text" v-model.number="form.weight"></td>
</tr>
<tr>
<td>{|H&ouml;he (in cm)|}:</td>
<td><input type="text" size="10" v-model.number="form.height"></td>
</tr>
<tr>
<td>{|Breite (in cm)|}:</td>
<td><input type="text" size="10" v-model.number="form.width"></td>
</tr>
<tr>
<td>{|L&auml;nge (in cm)|}:</td>
<td><input type="text" size="10" v-model.number="form.length"></td>
</tr>
<tr>
<td>{|Produkt|}:</td>
<td>
<select v-model="form.product" required>
<option v-for="prod in products" :value="prod.Id">{{prod.Name}}</option>
</select>
</td>
</tr>
<tr v-if="serviceAvailable('premium')">
<td>{|Premium|}:</td>
<td><input type="checkbox" v-model="form.services.premium"></td>
</tr>
</table>
</div>
<div class="clearfix"></div>
<div class="col-md-12">
<h2>{|Bestellung|}</h2>
<table>
<tr>
<td>{|Bestellnummer|}:</td>
<td><input type="text" size="36" v-model="form.order_number"></td>
</tr>
<tr>
<td>{|Rechnungsnummer|}:</td>
<td><input type="text" size="36" v-model="form.invoice_number"></td>
</tr>
<tr>
<td>{|Sendungsart|}:</td>
<td>
<select v-model="form.shipment_type">
<option v-for="(value, key) in customs_shipment_types" :value="key">{{value}}</option>
</select>
</td>
</tr>
<tr>
<td>{|Versicherungssumme|}:</td>
<td><input type="text" size="10" v-model="form.total_insured_value"/></td>
</tr>
</table>
</div>
<div class="col-md-12">
<table>
<tr>
<th>{|Bezeichnung|}</th>
<th>{|Menge|}</th>
<th>{|HSCode|}</th>
<th>{|Herkunftsland|}</th>
<th>{|Einzelwert|}</th>
<th>{|Einzelgewicht|}</th>
<th>{|Gesamtwert|}</th>
<th>{|Gesamtgewicht|}</th>
<th><a v-on:click="addPosition"><img src="themes/new/images/add.png"></a></
</th>
</tr>
<tr v-for="(pos, index) in form.positions">
<td><input type="text" v-model.trim="pos.bezeichnung" required></td>
<td><input type="text" v-model.number="pos.menge" required></td>
<td><input type="text" v-model.trim="pos.zolltarifnummer"></td>
<td><input type="text" v-model.trim="pos.herkunftsland"></td>
<td><input type="text" v-model.number="pos.zolleinzelwert"></td>
<td><input type="text" v-model.number="pos.zolleinzelgewicht"></td>
<td>{{Number(pos.menge*pos.zolleinzelwert || 0).toFixed(2)}}</td>
<td>{{Number(pos.menge*pos.zolleinzelgewicht || 0).toFixed(3)}}</td>
<td><a v-on:click="deletePosition(index)"><img src="themes/new/images/delete.svg"></a></td>
</tr>
<tr>
<td colspan="6"></td>
<td>{{total_value.toFixed(2)}}</td>
<td>{{total_weight.toFixed(3)}}</td>
</tr>
</table>
</div>
<div>
<input class="btnGreen" type="submit" value="{|Paketmarke drucken|}" name="drucken">&nbsp;
<!--<input type="button" value="{|Andere Versandart auswählen|}" name="anders">&nbsp;-->
</div>
</div>
</form>
</div>
<script type="text/javascript">
const createshipmentapp = new Vue({
el: '#createshipmentapp',
data: [JSON],
computed: {
total_value() {
let sum = 0;
for (const pos of this.form.positions) {
sum += (pos.menge * pos.zolleinzelwert) || 0;
}
return sum;
},
total_weight() {
let sum = 0;
for (const pos of this.form.positions) {
sum += (pos.menge * pos.zolleinzelgewicht) || 0;
}
return sum;
}
},
methods: {
submit: function () {
let app = this;
let xhr = new XMLHttpRequest();
xhr.open('POST', location.href, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function () {
let json = JSON.parse(this.response);
app.messages = json.messages;
}
xhr.send(JSON.stringify($.extend({submit:'print'}, this.form)));
},
addPosition: function () {
this.form.positions.push({});
},
deletePosition: function (index) {
this.form.positions.splice(index, 1);
},
serviceAvailable: function (service) {
if (!this.products.hasOwnProperty(this.form.product))
return false;
return this.products[this.form.product].AvailableServices.indexOf(service) >= 0;
}
}
})
</script>

View File

@ -1,84 +0,0 @@
<br><br><table id="paketmarketab" align="center">
<tr>
<td align="center">
<br>
<form action="" method="post">
[ERROR]
<h1>Paketmarken Drucker f&uuml;r [ZUSATZ]</h1>
<br>
<b>Empf&auml;nger</b>
<br>
<br>
<table>
<tr><td>
<table style="float:left;">
<tr><td>Name:</td><td><input type="text" size="36" value="[NAME]" name="name" id="name"><script type="text/javascript">document.getElementById("name").focus(); </script></td></tr>
<tr><td>Name 2:</td><td><input type="text" size="36" value="[NAME2]" name="name2"></td></tr>
<tr><td>Name 3:</td><td><input type="text" size="36" value="[NAME3]" name="name3"></td></tr>
<tr><td>Land:</td><td>[EPROO_SELECT_LAND]</td></tr>
<tr><td>PLZ/ort:</td><td><input type="text" name="plz" size="5" value="[PLZ]">&nbsp;<input type="text" size="30" name="ort" value="[ORT]"></td></tr>
<tr><td>Strasse/Hausnummer:</td><td><input type="text" size="30" value="[STRASSE]" name="strasse">&nbsp;<input type="text" size="5" name="hausnummer" value="[HAUSNUMMER]"></td></tr>
<tr><td>E-Mail:</td><td><input type="text" size="36" value="[EMAIL]" name="email"></td></tr>
<tr><td>Telefon:</td><td><input type="text" size="36" value="[TELEFON]" name="telefon"></td></tr>
</table>
<table style="float:left;">
<!--<tr><td width="180">Anzahl Pakete:</td><td nowrap><input type="text" name="anzahl" size="5" value="[ANZAHL]" id="anzahl">&nbsp;<input type="button" onclick=window.location.href="index.php?module=versanderzeugen&action=frankieren&id=[ID]&land=[LAND]&anzahl="+document.getElementById('anzahl').value value="erstellen"></td></tr>-->
[GEWICHT]
<!--<tr><td>Foto:</td><td><img src="http://t3.gstatic.com/images?q=tbn:QTV_X4YJEI2p7M:http://notebook.pege.org/2005-inode/paket.jpg"></td></tr>
<tr><td></td><td><input type="button" value="Nochmal Wiegen+Foto"></td></tr>-->
</table>
<!--
<table>
<tr><td>Gewicht:</td><td><input type="text" size="5"></td></tr>
<tr><td>Foto:</td><td><img src="http://t3.gstatic.com/images?q=tbn:QTV_X4YJEI2p7M:http://notebook.pege.org/2005-inode/paket.jpg"></td></tr>
<tr><td></td><td><input type="button" value="Nochmal Wiegen+Foto"></td></tr>
</table>
-->
</tr>
</table>
<br><br>
<table align="center">
<tr><td colspan="2"><b>Service</b></td></tr>
<tr><td>Nachnahme:</td><td style="min-width:200px;"><input type="checkbox" name="nachnahme" value="1" [NACHNAHME]> (Betrag: [BETRAG] EUR)<input type="hidden" name="betrag" value="[BETRAG]"></td></tr>
<!--<tr><td>Versichert 2500 EUR:</td><td><input type="checkbox" name="versichert" value="1" [VERSICHERT]></td></tr>
<tr><td>Versichert 25000 EUR:</td><td><input type="checkbox" name="extraversichert" value="1" [EXTRAVERSICHERT]></td></tr>-->
<tr><td nowrap>Extra Versicherung:</td><td><input type="checkbox" name="versichert" value="1" [VERSICHERT] /></td></tr>
<tr class="versicherung"><td>Versicherungssumme:</td><td><input type="text" size="10" id="versicherungssumme" name="versicherungssumme" value="[VERSICHERUNGSSUMME]" /></td></tr>
<tr><td>Leitcodierung:</td><td style="min-width:200px;"><input type="checkbox" name="leitcodierung" value="1" [LEITCODIERUNG]>&nbsp;<i>ohne Leitcodierung können extra Kosten entstehen</i></td></tr>
<tr><td>Abholdatum:</td><td><input type="text" size="10" id="abholdatum" name="abholdatum" value="[ABHOLDATUM]" /></td></tr>
<tr><td>Wunschtermin:</td><td><input type="checkbox" name="wunschtermin" value="1" [WUNSCHTERMIN] /></td></tr>
<tr class="wunschzeitraum"><td>Wunschlieferdatum:</td><td><input type="text" size="10" id="wunschlieferdatum" name="wunschlieferdatum" value="[WUNSCHLIEFERDATUM]" /></td></tr>
<tr class="wunschzeitraum"><td>Wunschlieferzeitraum:</td>
<td><!--<input type="radio" name="wunschzeitraum" id="wunsch10001200" value="10001200" [WUNSCH10001200] /> 10:00 - 12:00
<input type="radio" name="wunschzeitraum" id="wunsch12001400" value="12001400" [WUNSCH12001400] /> 12:00 - 14:00
<input type="radio" name="wunschzeitraum" id="wunsch14001600" value="14001600" [WUNSCH14001600] /> 14:00 - 16:00
<input type="radio" name="wunschzeitraum" id="wunsch16001800" value="16001800" [WUNSCH16001800] /> 16:00 - 18:00 -->
<input type="radio" name="wunschzeitraum" id="wunsch18002000" value="18002000" [WUNSCH18002000] /> 18:00 - 20:00
<input type="radio" name="wunschzeitraum" id="wunsch19002100" value="19002100" [WUNSCH19002100] /> 19:00 - 21:00
</td></tr>
[VORRETOURENLABEL]<tr><td nowrap>Retourenlabel drucken:</td><td><input type="checkbox" value="1" id="retourenlabel" name="retourenlabel" [RETOURENLABEL] /></td></tr>[NACHRETOURENLABEL]
[VORALTERSFREIGABE]<tr><td nowrap>Altersfreigabe notwendig:</td><td><input type="checkbox" name="altersfreigabe" value="1" [ALTERSFREIGABE]></td></tr>[NACHALTERSFREIGABE]
</table>
<br><br>
<center><input class="btnGreen" type="submit" value="Paketmarke drucken" name="drucken">&nbsp;
[TRACKINGMANUELL]
&nbsp;<input type="button" value="{|Andere Versandart auswählen|}" onclick="window.location.href='index.php?module=versanderzeugen&action=wechsel&id=[ID]'" name="anders">&nbsp;
<!--<input type="button" value="Abbrechen">--></center>
</form>
</td></tr></table>
<br><br>
<script type="text/JavaScript" language="javascript">
$(document).ready(function() {
$( "#abholdatum" ).datepicker({ dateFormat: 'dd.mm.yy',dayNamesMin: ['SO', 'MO', 'DI', 'MI', 'DO', 'FR', 'SA'], firstDay:1,
showWeek: true, monthNames: ['Januar', 'Februar', 'März', 'April', 'Mai',
'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], });
});
</script>

View File

@ -1,79 +0,0 @@
<br><br><table id="paketmarketab" align="center">
<tr>
<td align="center">
<br>
<form action="" method="post">
[ERROR]
<h1>{|Paketmarken Drucker f&uuml;r|} [ZUSATZ]</h1>
<br>
<b>{|Empf&auml;nger|}</b>
<br>
<br>
<table>
<tr><td>
<table style="float:left;">
<tr><td>{|Name|}:</td><td><input type="text" size="36" value="[NAME]" name="name" id="name"><script type="text/javascript">document.getElementById("name").focus(); </script></td></tr>
<tr><td>{|Name 2|}:</td><td><input type="text" size="36" value="[NAME2]" name="name2"></td></tr>
<tr><td>{|Name 3|}:</td><td><input type="text" size="36" value="[NAME3]" name="name3"></td></tr>
<tr><td>{|Land|}:</td><td>[EPROO_SELECT_LAND]</td></tr>
<tr><td>{|PLZ/Ort|}:</td><td><input type="text" name="plz" size="5" value="[PLZ]">&nbsp;<input type="text" size="30" name="ort" value="[ORT]"></td></tr>
<tr><td>{|Strasse/Hausnummer|}:</td><td><input type="text" size="30" value="[STRASSE]" name="strasse">&nbsp;<input type="text" size="5" name="hausnummer" value="[HAUSNUMMER]"></td></tr>
<tr><td>{|E-Mail|}:</td><td><input type="text" size="36" value="[EMAIL]" name="email"></td></tr>
<tr><td>{|Telefon|}:</td><td><input type="text" size="36" value="[TELEFON]" name="telefon"></td></tr>
[PRODUCT_LIST]
<tr style="[VERSTECKEN]"><td colspan="2">&nbsp;</td></tr>
<tr id="us-states" style="[VERSTECKEN]"><td>{|Bundesland|}:</td><td>[EPROO_SELECT_BUNDESSTAAT]</td></tr>
<tr id="states" style="[VERSTECKEN]"><td>{|Bundesland|}:</td><td><input type="text" size="36" value="[BUNDESLAND]" name="state"></td></tr>
<tr style="[VERSTECKEN]"><td>{|Rechnungsnummer|}:</td><td><input type="text" size="36" value="[RECHNUNGSNUMMER]" name="rechnungsnummer"></td></tr>
<tr style="[VERSTECKEN]"><td>{|Sendungsart|}:</td><td><select name="sendungsart">
<option value="0">{|Geschenk|}</option>
<option value="1">{|Dokumente|}</option>
<option value="2" selected>{|Kommerzielle Waren|}</option>
<option value="3">{|Erprobungswaren|}</option>
<option value="4">{|Rücksendung|}</option>
</select></td></tr>
<tr><td nowrap>{|Extra Versicherung|}:</td><td><input type="checkbox" name="versichert" value="1" [VERSICHERT] /></td></tr>
<tr class="versicherung"><td>{|Versicherungssumme|}:</td><td><input type="text" size="10" id="versicherungssumme" name="versicherungssumme" value="[VERSICHERUNGSSUMME]" /></td></tr>
</table>
<table style="float:right;">
[GEWICHT]
<tr>
<td>{|H&ouml;he (in cm)|}:</td>
<td>
<input type="text" size="10" value="[HEIGHT]" name="height">
</td>
</tr>
<tr>
<td>{|Breite (in cm)|}:</td>
<td>
<input type="text" size="10" value="[WIDTH]" name="width">
</td>
</tr>
<tr>
<td>{|L&auml;nge (in cm)|}:</td>
<td>
<input type="text" size="10" value="[LENGTH]" name="length">
</td>
</tr>
</table>
<div style="clear:both"></div>
<br><br>
<center><input class="btnGreen" type="submit" value="{|Paketmarke drucken|}" name="drucken">&nbsp;
[TRACKINGMANUELL]
&nbsp;<input type="button" value="{|Andere Versandart auswählen|}" onclick="window.location.href='index.php?module=versanderzeugen&action=wechsel&id=[ID]'" name="anders">&nbsp;
<!--<input type="button" value="Abbrechen">--></center>
</td></tr></table>
</form>
<br><br>
</td></tr></table>

View File

@ -1,69 +0,0 @@
<br><br><table id="paketmarketab" align="center">
<tr>
<td align="center">
<br>
<form action="" method="post">
[ERROR]
<h1>Paketmarken Drucker f&uuml;r [ZUSATZ]</h1>
<br>
<b>Empf&auml;nger</b>
<br>
<br>
<table>
<tr><td>
<table style="float:left;">
<tr><td>Name:</td><td><input type="text" size="36" value="[NAME]" name="name" id="name"><script type="text/javascript">document.getElementById("name").focus(); </script></td></tr>
<tr><td>Name 2:</td><td><input type="text" size="36" value="[NAME2]" name="name2"></td></tr>
<tr><td>p. Adr.:</td><td><input type="text" size="36" value="[NAME3]" name="name3"></td></tr>
<tr><td>Land:</td><td>[EPROO_SELECT_LAND]</td></tr>
<tr><td>PLZ/Ort:</td><td><input type="text" name="plz" size="5" value="[PLZ]">&nbsp;<input type="text" size="30" name="ort" value="[ORT]"></td></tr>
<tr><td>Strasse/Hausnummer:</td><td><input type="text" size="30" value="[STRASSE]" name="strasse">&nbsp;<input type="text" size="5" name="hausnummer" value="[HAUSNUMMER]"></td></tr>
<tr><td>E-Mail:</td><td><input type="text" size="36" value="[EMAIL]" name="email"></td></tr>
<tr><td>Telefon:</td><td><input type="text" size="36" value="[TELEFON]" name="telefon"></td></tr>
</table>
<table style="float:right;">
[GEWICHT]
<tr>
<td>Höhe (in cm):</td>
<td>
<input type="text" size="10" value="[HEIGHT]" name="height">
</td>
</tr>
<tr>
<td>Breite (in cm):</td>
<td>
<input type="text" size="10" value="[WIDTH]" name="width">
</td>
</tr>
<tr>
<td>Länge (in cm):</td>
<td>
<input type="text" size="10" value="[LENGTH]" name="length">
</td>
</tr>
</table>
<div style="clear:both"></div>
<!-- <br><br>
<table align="center">
<tr><td colspan="2"><b>Service</b></td></tr>
<tr><td>Nachnahme:</td><td><input type="checkbox" name="nachnahme" value="1" [NACHNAHME]> (Betrag: [BETRAG] EUR)<input type="hidden" name="betrag" value="[BETRAG]"></td></tr>
</table>-->
<br><br>
<center><input class="btnGreen" type="submit" value="Paketmarke drucken" name="drucken">&nbsp;
[TRACKINGMANUELL]
&nbsp;<input type="button" value="{|Andere Versandart auswählen|}" onclick="window.location.href='index.php?module=versanderzeugen&action=wechsel&id=[ID]'" name="anders">&nbsp;
<!--<input type="button" value="Abbrechen">--></center>
</td></tr></table>
</form>
<br><br>
</td></tr></table>

View File

@ -1,19 +0,0 @@
<br><br><table id="paketmarketab" align="center">
<tr>
<td align="center">
<br>
<form action="" method="post">
[ERROR]
<h1>[ZUSATZ]</h1>
<!--<br>
<h3 style="color:red;">Beim Versand ins Ausland mit UPS müssen die Felder <b>Name</b>, <b>Name 2</b> und <b>Telefon</b> ausgefüllt werden!</h3>-->
<br>
<br>
<br>
<center><input class="btnGreen" type="submit" value="{|Weiter|}" name="drucken">&nbsp;
&nbsp;<input type="button" value="{|Andere Versandart auswählen|}" onclick="window.location.href='index.php?module=versanderzeugen&action=wechsel&id=[ID]'" name="anders">&nbsp;
<!--<input type="button" value="Abbrechen">--></center>
</form>
</td></tr></table>
<br><br>

View File

@ -1,691 +1,222 @@
<?php <?php
use Xentral\Components\Database\Database; /*
use Xentral\Components\Http\JsonResponse; * SPDX-FileCopyrightText: 2022 Andreas Palm
use Xentral\Modules\Dhl\Api\DhlApi;
use Xentral\Modules\Dhl\Content\PackageContent;
use Xentral\Modules\Dhl\Exception\DhlBaseException;
use Xentral\Modules\Dhl\Exception\InvalidCredentialsException;
use Xentral\Modules\Dhl\Exception\InvalidRequestDataException;
use Xentral\Modules\Dhl\Exception\UnknownProductException;
use Xentral\Modules\Dhl\Factory\DhlApiFactory;
use Xentral\Modules\Dhl\Request\CreateInterationalShipmentRequest;
use Xentral\Modules\Dhl\Request\CreateNationalShipmentRequest;
require_once dirname(__DIR__) . '/class.versanddienstleister.php';
class Versandart_dhl extends Versanddienstleister
{
private $einstellungen;
private $info;
private $credentials;
public $paketmarke_drucker;
public $export_drucker;
public $errors;
public $name;
protected $voucherId;
/**
* Versandart_internetmarke constructor.
* *
* @param ApplicationCore $app * SPDX-License-Identifier: LicenseRef-EGPL-3.1
* @param int $id
*/ */
function __construct($app, $id)
use Xentral\Carrier\Dhl\Data\Communication;
use Xentral\Carrier\Dhl\Data\Country;
use Xentral\Carrier\Dhl\Data\CreateShipmentOrderResponse;
use Xentral\Carrier\Dhl\Data\PackStation;
use Xentral\Carrier\Dhl\Data\Postfiliale;
use Xentral\Carrier\Dhl\Data\ReceiverNativeAddress;
use Xentral\Carrier\Dhl\Data\Shipment;
use Xentral\Carrier\Dhl\Data\ShipmentItem;
use Xentral\Carrier\Dhl\DhlApi;
use Xentral\Modules\ShippingMethod\Model\CreateShipmentResult;
use Xentral\Modules\ShippingMethod\Model\Product;
require_once(dirname(__DIR__).'/class.versanddienstleister.php');
class Versandart_dhl extends Versanddienstleister{
public function GetName():string
{ {
$this->id = $id; return 'DHL';
$this->app = $app;
$einstellungenArr = $this->app->DB->SelectRow("SELECT einstellungen_json,paketmarke_drucker,export_drucker FROM versandarten WHERE id = '$id' LIMIT 1");
$einstellungen_json = $einstellungenArr['einstellungen_json'];
$this->paketmarke_drucker = $einstellungenArr['paketmarke_drucker'];
$this->export_drucker = $einstellungenArr['export_drucker'];
$this->name = 'DHL 3.0';
if($einstellungen_json){
$this->einstellungen = json_decode($einstellungen_json, true);
}else{
$this->einstellungen = [];
}
$this->errors = [];
} }
function ShowUserdata() public function AdditionalSettings(): array
{
if(isset($this->app->Conf->WFuserdata)){
return 'Userdata-Ordner: ' . $this->app->Conf->WFuserdata;
}
}
public function Einstellungen($target = 'return')
{
if($this->app->Secure->GetPOST('testen')){
$parameter1 = $this->einstellungen['pfad'];
if($parameter1){
if(is_dir($parameter1)){
if(substr($parameter1, -1) !== '/'){
$parameter1 .= '/';
}
if(file_put_contents($parameter1 . 'wawision_test.txt', 'TEST')){
$this->app->Tpl->Add('MESSAGE',
'<div class="info">Datei ' . $parameter1 . 'wawision_test.txt' . ' wurde erstellt!</div>');
}else{
$this->app->Tpl->Add('MESSAGE', '<div class="error">Datei konnte nicht angelegt werden!</div>');
}
}else{
$this->app->Tpl->Add('MESSAGE',
'<div class="error">Speicherort existiert nicht oder ist nicht erreichbar!</div>');
}
}else{
$this->app->Tpl->Add('MESSAGE', '<div class="error">Bitte einen Speicherort angeben!</div>');
}
}
parent::Einstellungen($target);
}
//TODO ....
/*function Trackinglink($tracking, &$notsend, &$link, &$rawlink)
{
$notsend = 0;
//$rawlink = 'https://tracking.dpd.de/parcelstatus/?locale=de_DE&query='.$tracking;
$rawlink = ' https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DE03/DE/5004.htm?txtRefNo='.$tracking.'&txtAction=71000';
$link = 'GLS Versand: '.$tracking.' ('.$rawlink.')';
}*/
public function GetBezeichnung()
{
return 'DHL 3.0';
}
/**
* @return array[]
*/
public function getCreateForm()
{ {
return [ return [
[ 'user' => array('typ' => 'text', 'bezeichnung' => 'Benutzer:', 'info' => 'geschaeftskunden_api (Versenden/Intraship-Benutzername)'),
'id' => 0, 'signature' => array('typ' => 'text', 'bezeichnung' => 'Signature:', 'info' => 'Dhl_ep_test1 (Versenden/IntrashipPasswort)'),
'name' => 'usernameGroup', 'ekp' => array('typ' => 'text', 'bezeichnung' => 'EKP', 'info' => '5000000000 (gültige DHL Kundennummer)'),
'inputs' => [ 'accountnumber' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Paket:'),
[ 'accountnumber_int' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Paket International:'),
'label' => 'Benutzername', 'accountnumber_euro' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Europaket:'),
'type' => 'text', 'accountnumber_connect' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Paket Connect:'),
'name' => 'dhl_username', 'accountnumber_wp' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Warenpost:'),
'validation' => true, 'accountnumber_wpint' => array('typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer Warenpost International:'),
], // 'intraship_retourenaccount' => array('typ' => 'text', 'bezeichnung' => 'Retouren Account:', 'info' => '14 Stellige DHL-Retoure Abrechnungsnummer'),
], // 'intraship_retourenlabel' => array('typ' => 'checkbox', 'bezeichnung' => 'Vorauswahl Retourenlabel:', 'info' => 'Druckt Retourenlabel mit'),
],
[ 'sender_name1' => array('typ' => 'text', 'bezeichnung' => 'Versender Firma:'),
'id' => 1, 'sender_street' => array('typ' => 'text', 'bezeichnung' => 'Versender Strasse:'),
'name' => 'passwordGroup', 'sender_streetnumber' => array('typ' => 'text', 'bezeichnung' => 'Versender Strasse Nr.:'),
'inputs' => [ 'sender_zip' => array('typ' => 'text', 'bezeichnung' => 'Versender PLZ:'),
[ 'sender_city' => array('typ' => 'text', 'bezeichnung' => 'Versender Stadt:'),
'label' => 'Passwort', 'sender_country' => array('typ' => 'text', 'bezeichnung' => 'Versender ISO Code:', 'info' => 'DE'),
'type' => 'text', 'sender_email' => array('typ' => 'text', 'bezeichnung' => 'Versender E-Mail:'),
'name' => 'dhl_password', 'sender_phone' => array('typ' => 'text', 'bezeichnung' => 'Versender Telefon:'),
'validation' => true, 'sender_web' => array('typ' => 'text', 'bezeichnung' => 'Versender Web:'),
] 'sender_contact_person' => array('typ' => 'text', 'bezeichnung' => 'Versender Ansprechpartner:'),
],
], 'cod_account_owner' => array('typ' => 'text', 'bezeichnung' => 'Nachnahme Kontoinhaber:'),
[ 'cod_bank_name' => array('typ' => 'text', 'bezeichnung' => 'Nachnahme Bank Name:'),
'id' => 2, 'cod_account_iban' => array('typ' => 'text', 'bezeichnung' => 'Nachnahme IBAN:'),
'name' => 'accountNumberGroup', 'cod_account_bic' => array('typ' => 'text', 'bezeichnung' => 'Nachnahme BIC:'),
'inputs' => [ 'cod_extra_fee' => array('typ' => 'text', 'bezeichnung' => 'Nachnahme Gebühr:', 'info' => 'z.B. 2,00 wird auf Rechnungsbetrag addiert, da DHL dies als extra Gebühr für sich behält'),
[
'label' => 'Abrechnungsnummer', 'weight' => array('typ' => 'text', 'bezeichnung' => 'Standard Gewicht:', 'info' => 'in KG'),
'type' => 'text', 'length' => array('typ' => 'text', 'bezeichnung' => 'Standard Länge:', 'info' => 'in cm'),
'name' => 'dhl_accountnumber', 'width' => array('typ' => 'text', 'bezeichnung' => 'Standard Breite:', 'info' => 'in cm'),
'validation' => true, 'height' => array('typ' => 'text', 'bezeichnung' => 'Standard Höhe:', 'info' => 'in cm'),
]
], 'product' => array('typ' => 'text', 'bezeichnung' => 'Standard Produkt:', 'info' => 'z.B. in DE: V01PAK oder AT: V86PARCEL'),
] 'use_premium' => array('typ' => 'checkbox', 'bezeichnung' => 'Premiumversand verwenden:'),
/*
'intraship_vorausverfuegung' => array('typ' => 'select', 'bezeichnung' => 'Vorausverf&uuml;gung: ', 'optionen' => array('-' => 'keine Vorausverf&uuml;gung', 'IMMEDIATE' => 'Sofortige R&uuml;cksendung an den Absender', 'AFTER_DEADLINE' => 'R&uuml;cksenden an den Absender nach Ablauf der Frist', 'ABANDONMENT' => 'Preisgabe des Pakets durch den Absender (entgeltfrei)')),
'sperrgut' => array('typ' => 'checkbox', 'bezeichnung' => 'Sperrgut:'),
'keineversicherung' => array('typ' => 'checkbox', 'bezeichnung' => 'Extra Versicherung ausschalten:', 'info' => 'Option muss von Hand im Paketmarkendialog gesetzt werden.'),
'leitcodierung' => array('typ' => 'checkbox', 'bezeichnung' => 'Leitcodierung aktivieren:'),
'use_shipping_article_from_order_on_export' => ['typ' => 'checkbox', 'bezeichnung' => 'Bei Export Porto aus Auftrag senden:'],
'autotracking' => array('typ' => 'checkbox', 'bezeichnung' => 'Tracking übernehmen:'),
'log' => array('typ' => 'checkbox', 'bezeichnung' => 'Logging')*/
]; ];
} }
/** public function CreateShipment(object $json, array $address): CreateShipmentResult
* @param array $postData
*
* @return array
*/
public function updatePostDataForAssistent($postData): array
{ {
$name = $this->app->erp->Firmendaten('name'); $shipment = new Shipment();
$street = $this->app->erp->Firmendaten('strasse'); $shipment->ShipmentDetails->product = $json->product;
$zip = $this->app->erp->Firmendaten('plz'); $shipment->ShipmentDetails->accountNumber = $this->GetAccountNumber($json->product);
$city = $this->app->erp->Firmendaten('ort'); $shipment->ShipmentDetails->SetShipmentDate(new DateTimeImmutable('today'));
$country = $this->app->erp->Firmendaten('land'); $shipment->ShipmentDetails->ShipmentItem = new ShipmentItem();
$houseNo = ''; $shipment->ShipmentDetails->ShipmentItem->weightInKG = $json->weight ?? 0;
$shipment->ShipmentDetails->ShipmentItem->lengthInCM = $json->length;
$streetParts = explode(' ', $street); $shipment->ShipmentDetails->ShipmentItem->widthInCM = $json->width;
$partsCount = count($streetParts); $shipment->ShipmentDetails->ShipmentItem->heightInCM = $json->height;
$shipment->Shipper->Name->name1 = $this->settings->sender_name1 ?? '';
if($partsCount >= 2){ $shipment->Shipper->Address->streetName = $this->settings->sender_street ?? '';
$street = implode(' ', array_slice($streetParts, 0, $partsCount - 1)); $shipment->Shipper->Address->streetNumber = $this->settings->sender_streetnumber;
$houseNo = $streetParts[$partsCount - 1]; $shipment->Shipper->Address->zip = $this->settings->sender_zip ?? '';
$shipment->Shipper->Address->city = $this->settings->sender_city ?? '';
$shipment->Shipper->Address->Origin = Country::Create($this->settings->sender_country ?? 'DE');
$shipment->Shipper->Communication = new Communication();
$shipment->Shipper->Communication->phone = $this->settings->sender_phone;
$shipment->Shipper->Communication->email = $this->settings->sender_email;
$shipment->Shipper->Communication->contactPerson = $this->settings->sender_contact_person;
$shipment->Receiver->name1 = $json->name;
switch ($json->addresstype) {
case 0:
$shipment->Receiver->Address = new ReceiverNativeAddress();
$shipment->Receiver->Address->name2 = $json->name2;
$shipment->Receiver->Address->streetName = $json->street ?? '';
$shipment->Receiver->Address->streetNumber = $json->streetnumber;
$shipment->Receiver->Address->city = $json->city ?? '';
$shipment->Receiver->Address->zip = $json->zip ?? '';
$shipment->Receiver->Address->Origin = Country::Create($json->country ?? 'DE', $json->state);
if (isset($json->address2) && !empty($json->address2))
$shipment->Receiver->Address->addressAddition[] = $json->address2;
break;
case 1:
$shipment->Receiver->Packstation = new PackStation();
$shipment->Receiver->Packstation->postNumber = $json->postnumber;
$shipment->Receiver->Packstation->packstationNumber = $json->parcelstationNumber;
$shipment->Receiver->Packstation->city = $json->city ?? '';
$shipment->Receiver->Packstation->zip = $json->zip ?? '';
$shipment->Receiver->Packstation->Origin = Country::Create($json->country ?? 'DE', $json->state);
break;
case 2:
$shipment->Receiver->Postfiliale = new Postfiliale();
$shipment->Receiver->Postfiliale->postNumber = $json->postnumber;
$shipment->Receiver->Postfiliale->postfilialeNumber = $json->postofficeNumber;
$shipment->Receiver->Postfiliale->city = $json->city ?? '';
$shipment->Receiver->Postfiliale->zip = $json->zip ?? '';
$shipment->Receiver->Postfiliale->Origin = Country::Create($json->country ?? 'DE', $json->state);
break;
} }
$shipment->Receiver->Communication = new Communication();
$shipment->Receiver->Communication->email = $json->email;
$shipment->Receiver->Communication->phone = $json->phone;
$api = new DhlApi($this->settings->user, $this->settings->signature);
$postData['dhl_origin_name'] = $name; $ret = new CreateShipmentResult();
$postData['dhl_origin_street'] = $street; $result = $api->CreateShipment($shipment);
$postData['dhl_origin_houseno'] = $houseNo; if (!$result instanceof CreateShipmentOrderResponse) {
$postData['dhl_origin_zip'] = $zip; $ret->Errors[] = $result;
$postData['dhl_origin_city'] = $city; return $ret;
$postData['dhl_origin_country'] = $country;
return $postData;
} }
if ($result->Status->statusCode === 0) {
/** $ret->Success = true;
* @return JsonResponse|null $ret->TrackingNumber = $result->CreationState->shipmentNumber;
*/ $ret->TrackingUrl = sprintf('https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?piececode=%s', $ret->TrackingNumber);
public function AuthByAssistent() if (isset($result->CreationState->LabelData->labelData))
{ $ret->Label = base64_decode($result->CreationState->LabelData->labelData);
$step = (int)$this->app->Secure->GetPOST('step'); if (isset($result->CreationState->LabelData->exportLabelData))
if($step == 0){ $ret->ExportDocuments = base64_decode($result->CreationState->LabelData->exportLabelData);
$username = $this->app->Secure->GetPOST('dhl_username'); } else if (isset($result->CreationState)) {
$password = $this->app->Secure->GetPOST('dhl_password'); if (is_array($result->CreationState->LabelData->Status->statusMessage))
$accountnumber = $this->app->Secure->GetPOST('dhl_accountnumber'); $ret->Errors = $result->CreationState->LabelData->Status->statusMessage;
else
$error = null; $ret->Errors[] = $result->CreationState->LabelData->Status->statusMessage;
if(empty($username)){ } else {
$error = 'Bitte Nutzernamen eingeben'; $ret->Errors[] = $result->Status->statusText;
}else if(empty($password)){
$error = 'Bitte Passwort eingeben';
}else if(empty($accountnumber)){
$error = 'Bitte Abrechnungsnummer eingeben';
} }
if($error != null) {
return new JsonResponse(
['error' => $error],
JsonResponse::HTTP_BAD_REQUEST
);
}
try{
$this->testCredentials($username, $password, $accountnumber);
}catch (DhlBaseException $e){
return new JsonResponse(
['error' => $e->getMessage()],
JsonResponse::HTTP_BAD_REQUEST
);
}
}
return null;
}
/**
* @return array
*/
public function getStructureDataForClickByClickSave(): array
{
return $this->updatePostDataForAssistent([]);
}
function EinstellungenStruktur()
{
if(!empty($this->einstellungen['dhl_username']) && !empty($this->einstellungen['dhl_password'])){
try{
$this->testCredentials($this->einstellungen['dhl_username'], $this->einstellungen['dhl_password'], $this->einstellungen['dhl_accountnumber']);
$this->app->Tpl->Set('MESSAGE', '<div class="info">Zugangsdaten erfolgreich &uuml;berpr&uuml;ft</div>');
}catch (DhlBaseException $e){
$this->app->Tpl->Set('MESSAGE', '<div class="error">' . $e->getMessage() . '</div>');
}
}
return [
'dhl_username' => ['typ' => 'text', 'bezeichnung' => 'Benutzername:'],
'dhl_password' => ['typ' => 'text', 'bezeichnung' => 'Passwort:'],
'dhl_accountnumber' => ['typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer:'],
'dhl_origin_name' => ['typ' => 'text', 'bezeichnung' => 'Versender Name:'],
'dhl_origin_street' => ['typ' => 'text', 'bezeichnung' => 'Versender Strasse:'],
'dhl_origin_houseno' => ['typ' => 'text', 'bezeichnung' => 'Versender Hausnummer:'],
'dhl_origin_city' => ['typ' => 'text', 'bezeichnung' => 'Versender Ort:'],
'dhl_origin_zip' => ['typ' => 'text', 'bezeichnung' => 'Versender PLZ:'],
'dhl_origin_country' => ['typ' => 'text', 'bezeichnung' => 'Versender Land (2-stellig):'],
'dhl_origin_email' => ['typ' => 'text', 'bezeichnung' => 'Versender Email:'],
'dhl_height' => ['typ' => 'text', 'bezeichnung' => 'Standardh&ouml;he'],
'dhl_width' => ['typ' => 'text', 'bezeichnung' => 'Standardbreite'],
'dhl_length' => ['typ' => 'text', 'bezeichnung' => 'Standardl&auml;nge'],
'dhl_export_product_type' => [
'typ' => 'select',
'bezeichnung' => 'Export Producttyp',
'optionen' => [
'PRESENT' => 'Geschenke',
'COMMERCIAL_SAMPLE' => 'Kommerzielle Probe',
'DOCUMENT' => 'Dokumente',
'RETURN_OF_GOODS' => 'Rücksendungen',
'OTHER' => 'Andere',
]
],
'dhl_export_product_type_description' => [
'typ' => 'text',
'bezeichnung' => 'Beschreibung im Falle von "Andere"'
],
'dhl_product' => [
'typ' => 'select',
'bezeichnung' => 'Produkt:',
'optionen' => [
'V01PAK' => 'Paket national',
'V53WPAK' => 'Paket international'
],
],
'dhl_coding' => ['typ' => 'checkbox', 'bezeichnung' => 'Leitcodierung aktivieren'],
'autotracking' => ['typ' => 'checkbox', 'bezeichnung' => 'Tracking übernehmen:'],
];
}
public function testCredentials($username, $password, $accountNumber){
/** @var DhlApiFactory $dhlApiFactory */
$dhlApiFactory = $this->app->Container->get('DhlApiFactory');
/** @var DhlApi $dhlApi */
$dhlApi = $dhlApiFactory->createProductionInstance(
$username,
$password,
$accountNumber,
'',
'',
'',
'',
'',
'',
''
);
try {
$dhlApi->validateShipment(new CreateNationalShipmentRequest(
date("Y-m-d"),
1.0,
10,
20,
30,
"Max muster",
'',
'',
'Teststr. 1',
'11',
'86153',
'Augsburg',
'DE',
'max.muster@xentral.com',
false
));
}catch (InvalidRequestDataException $e){
// do nothing, test data is invalid
}
}
public function PaketmarkeDrucken($id, $sid)
{
$adressdaten = $this->GetAdressdaten($id, $sid);
$ret = $this->Paketmarke($sid, $id, '', false, $adressdaten);
if($sid === 'lieferschein'){
$deliveryNoteArr = $this->app->DB->SelectRow("SELECT adresse,projekt,versandart,auftragid FROM lieferschein WHERE id = '$id' LIMIT 1");
$adresse = $deliveryNoteArr['adresse'];
$projekt = $deliveryNoteArr['projekt'];
$versandart = $deliveryNoteArr['versandart'];
$adressvalidation = 2;
if($ret){
$adressvalidation = 1;
}
$tracking = '';
if(isset($adressdaten['tracking'])){
$tracking = $adressdaten['tracking'];
}
if(!isset($adressdaten['versandid'])){
$adressdaten['versandid'] = $this->app->DB->Select("SELECT id FROM versand WHERE abgeschlossen = 0 AND tracking = '' AND lieferschein = '$id' LIMIT 1");
}
if(!isset($adressdaten['versandid'])){
$this->app->DB->Insert("INSERT INTO versand (versandunternehmen, tracking,
versendet_am,abgeschlossen,lieferschein,freigegeben,firma,adresse,projekt,paketmarkegedruckt,adressvalidation)
VALUES ($versandart','$tracking',NOW(),1,'$id',1,'1','$adresse','$projekt',1,'$adressvalidation') ");
$adressdaten['versandid'] = $this->app->DB->GetInsertID();
}elseif($tracking){
$this->app->DB->Update("UPDATE versand SET freigegeben = 1, abgeschlossen = 1, tracking =1, paketmarkegedruckt = 1, tracking= '$tracking',adressvalidation = '$adressvalidation', versendet_am = now() WHERE id = '" . $adressdaten['versandid'] . "' LIMIT 1");
$this->app->DB->Update("UPDATE versand SET versandunternehmen = versandart WHERE id = '" . $adressdaten['versandid'] . "' AND versandunternehmen = '' LIMIT 1");
$this->app->DB->Update("UPDATE versand SET versandunternehmen = '$versandart' WHERE id = '" . $adressdaten['versandid'] . "' AND versandunternehmen = '' LIMIT 1");
}
$auftragid = $deliveryNoteArr['auftragid'];
if($auftragid){
$this->app->DB->Update("UPDATE auftrag SET schreibschutz = 1, status = 'abgeschlossen' WHERE id = '$auftragid' AND status = 'freigegeben' LIMIT 1");
}
if($adressvalidation == 1){
$this->app->erp->LieferscheinProtokoll($id, 'Paketmarke automatisch gedruckt');
if($adressdaten['versandid']){
return $adressdaten['versandid'];
}
}elseif($adressvalidation == 2){
$this->app->erp->LieferscheinProtokoll($id, 'automatisches Paketmarke Drucken fehlgeschlagen');
}
}
return $ret; return $ret;
} }
public function Paketmarke($doctyp, $docid, $target = '', $error = false, &$adressdaten = null) public function GetShippingProducts(): array
{ {
$id = $docid; $result = [];
$sid = $doctyp; if ($this->settings->accountnumber) {
if($adressdaten === null){ $result[] = Product::Create('V01PAK', 'DHL Paket')
$drucken = $this->app->Secure->GetPOST('drucken'); ->WithLength(15, 120)
$anders = $this->app->Secure->GetPOST('anders'); ->WithWidth(11, 60)
$tracking_again = $this->app->Secure->GetGET('tracking_again'); ->WithHeight(1, 60)
$module = $this->app->Secure->GetPOST('module'); ->WithWeight(0.01, 31.5);
if(empty($module)){
$module = $doctyp;
} }
}else{ if ($this->settings->accountnumber_int) {
$drucken = 1; $result[] = Product::Create('V53WPAK', 'DHL Paket International')
$anders = ''; ->WithLength(15, 120)
$tracking_again = ''; ->WithWidth(11, 60)
$module = $doctyp; ->WithHeight(1, 60)
->WithWeight(0.01, 31.5)
->WithServices([Product::SERVICE_PREMIUM]);
}
if ($this->settings->accountnumber_euro) {
$result[] = Product::Create('V54EPAK', 'DHL Europaket')
->WithLength(15, 120)
->WithWidth(11, 60)
->WithHeight(3.5, 60)
->WithWeight(0.01, 31.5);
}
if ($this->settings->accountnumber_connect) {
$result[] = Product::Create('V55PAK', 'DHL Paket Connect')
->WithLength(15, 120)
->WithWidth(11, 60)
->WithHeight(3.5, 60)
->WithWeight(0.01, 31.5);
}
if ($this->settings->accountnumber_wp) {
$result[] = Product::Create('V62WP', 'DHL Warenpost')
->WithLength(10, 35)
->WithWidth(7, 25)
->WithHeight(0.1, 5)
->WithWeight(0.01, 1);
}
if ($this->settings->accountnumber_wpint) {
$result[] = Product::Create('V66WPI', 'DHL Warenpost International')
->WithLength(10, 35)
->WithWidth(7, 25)
->WithHeight(0.1, 10)
->WithWeight(0.01, 1)
->WithServices([Product::SERVICE_PREMIUM]);
}
return $result;
} }
private function GetAccountNumber(string $product):?string {
/** @var DhlApiFactory $dhlApiFactory */ switch ($product) {
$dhlApiFactory = $this->app->Container->get('DhlApiFactory'); case 'V01PAK': return $this->settings->accountnumber;
case 'V53WPAK': return $this->settings->accountnumber_int;
/** @var DhlApi $dhlApi */ case 'V54EPAK': return $this->settings->accountnumber_euro;
$dhlApi = $dhlApiFactory->createProductionInstance( case 'V55PAK': return $this->settings->accountnumber_connect;
$this->einstellungen['dhl_username'], case 'V62WP': return $this->settings->accountnumber_wp;
$this->einstellungen['dhl_password'], case 'V66WPI': return $this->settings->accountnumber_wpint;
$this->einstellungen['dhl_accountnumber'],
$this->einstellungen['dhl_origin_name'],
$this->einstellungen['dhl_origin_street'],
$this->einstellungen['dhl_origin_houseno'],
$this->einstellungen['dhl_origin_zip'],
$this->einstellungen['dhl_origin_city'],
$this->einstellungen['dhl_origin_country'],
$this->einstellungen['dhl_origin_email']
);
if($drucken != '' || $tracking_again == '1'){
if($tracking_again != "1"){
$versandId = 0;
if($module === 'retoure'){
$Query = $this->app->DB->SelectRow("SELECT * FROM retoure where id='$id'");
}elseif($module === 'versand'){
$versandId = $id;
$lieferschein = $this->app->DB->Select("SELECT lieferschein WHERE id = '$id' LIMIT 1");
$Query = $this->app->DB->SelectRow("SELECT * FROM lieferschein where id='$lieferschein'");
}else{
$Query = $this->app->DB->SelectRow("SELECT * FROM lieferschein where id='$id'");
} }
$projekt = $Query['projekt']; return null;
$Adresse = $this->app->DB->SelectRow("SELECT * FROM adresse WHERE id='" . $Query['adresse'] . "'");
$product = '';
$Country = $Query['land'];
if($adressdaten === null){
$versandmit = $this->app->Secure->GetPOST("versandmit");
$trackingsubmit = $this->app->Secure->GetPOST("trackingsubmit");
$versandmitbutton = $this->app->Secure->GetPOST("versandmitbutton");
$tracking = $this->app->Secure->GetPOST("tracking");
$trackingsubmitcancel = $this->app->Secure->GetPOST("trackingsubmitcancel");
$retourenlabel = $this->app->Secure->GetPOST("retourenlabel");
//$Weight = $this->app->Secure->GetPOST("kg1");
$Name = $this->app->Secure->GetPOST("name");
$Name2 = $this->app->Secure->GetPOST("name2");
$Name3 = $this->app->Secure->GetPOST("name3");
$Street = $this->app->Secure->GetPOST("strasse");
$HouseNo = $this->app->Secure->GetPOST("hausnummer");
$ZipCode = $this->app->Secure->GetPOST("plz");
$City = $this->app->Secure->GetPOST("ort");
$Mail = $this->app->Secure->GetPOST("email");
$Phone = $this->app->Secure->GetPOST("phone");
$Country = $this->app->Secure->GetPOST("land");
$Weight = $this->app->Secure->GetPOST('kg1');
$height = $this->app->Secure->GetPOST('height');
$wigth = $this->app->Secure->GetPOST('width');
$length = $this->app->Secure->GetPOST('length');
$coding = $this->app->Secure->GetPOST('coding') == '1';
}else{
$versandmit = '';//$this->app->Secure->GetPOST("versandmit");
$trackingsubmit = '';//$this->app->Secure->GetPOST("trackingsubmit");
$versandmitbutton = '';//$this->app->Secure->GetPOST("versandmitbutton");
$tracking = '';//$this->app->Secure->GetPOST("tracking");
$trackingsubmitcancel = '';//$this->app->Secure->GetPOST("trackingsubmitcancel");
$retourenlabel = '';// $this->app->Secure->GetPOST("retourenlabel");
$Name = $adressdaten["name"];
$Name2 = $adressdaten["name2"];
$Name3 = $adressdaten["name3"];
$Street = $adressdaten["strasse"];
$HouseNo = $adressdaten["hausnummer"];
$ZipCode = $adressdaten['plz'];
$City = $adressdaten['ort'];
$Mail = $adressdaten['email'];
$Phone = $adressdaten["telefon"];
$Country = $adressdaten["land"];
$Company = "Company";
$Weight = $adressdaten["standardkg"];
$coding = $this->einstellungen['dhl_coding'] == 1;
$height = $this->einstellungen('dhl_height');
$wigth = $this->einstellungen('dhl_width');
$length = $this->einstellungen('dhl_length');
}
try {
$shipmentDate = date("Y-m-d");
switch ($this->einstellungen['dhl_product']) {
case 'V01PAK':
{
$shipmentData = new CreateNationalShipmentRequest(
$shipmentDate,
$Weight,
$length,
$wigth,
$height,
$Name,
$Name2,
$Name3,
$Street,
$HouseNo,
$ZipCode,
$City,
$Country,
$Mail,
$coding
);
break;
}
case 'V53WPAK':
{
$shipmentData = new CreateInterationalShipmentRequest(
$shipmentDate,
$Weight,
$length,
$wigth,
$height,
$Name,
$Name2,
$Name3,
$Street,
$HouseNo,
$ZipCode,
$City,
$Country,
$Mail,
$coding,
$this->einstellungen['dhl_export_product_type'],
$this->einstellungen['dhl_export_product_type_description'],
$this->getPackageContents($Query['id'])
);
break;
}
default:
{
throw new UnknownProductException();
} }
} }
$createResponse = $dhlApi->createShipment($shipmentData);
if($this->einstellungen['autotracking'] == "1")
$this->SetTracking($createResponse->getShipmentNumber(), $sid === 'versand' ? $id : 0, $lieferschein);
$data['drucker'] = $this->paketmarke_drucker;
$data['druckerlogistikstufe2'] = $this->export_drucker;
if(!$data['drucker']){
if($this->app->erp->GetStandardPaketmarkendrucker() > 0){
$data['drucker'] = $this->app->erp->GetStandardPaketmarkendrucker();
}
}
if(!$data['druckerlogistikstufe2']){
if($this->app->erp->GetStandardVersanddrucker($projekt) > 0){
$data['druckerlogistikstufe2'] = $this->app->erp->GetStandardVersanddrucker($projekt);
}
}
$pdf = $createResponse->getLabelAsPdf();
$datei = $this->app->erp->GetTMP() . 'DhlLabel_' . $createResponse->getShipmentNumber() . '.pdf';
file_put_contents($datei, $pdf);
$spoolerId = $this->app->printer->Drucken($data['drucker'], $datei);
if($spoolerId > 0 && $versandId > 0){
$this->app->DB->Update(
sprintf(
'UPDATE versand SET lastspooler_id = %d, lastprinter = %d WHERE id = %d',
$spoolerId, $data['drucker'], $versandId
)
);
}
if($module === 'retoure'){
if(@is_file($datei) && @filesize($datei)){
$fileid = $this->app->erp->CreateDatei('DhlMarkeLabel_' . $this->app->DB->Select("SELECT belegnr FROM retoure WHERE id = '$id' LIMIT 1") . '.pdf',
'Anhang', '', "", $datei,
$this->app->DB->real_escape_string($this->app->User->GetName()));
$this->app->erp->AddDateiStichwort($fileid, 'anhang', 'retoure', $id);
}
}
unlink($datei);
if($adressdaten !== null){
return true;
}
if($createResponse->containsExportDocuments()){
$tmppdf = $this->app->erp->GetTMP() . 'DhlExport_' . $createResponse->getShipmentNumber() . '.pdf';
file_put_contents($tmppdf, $createResponse->getExportPaperAsPdf());
$spoolerId = $this->app->printer->Drucken($data['druckerlogistikstufe2'], $tmppdf);
if($versandId && $spoolerId){
$this->app->DB->Update(
sprintf(
'UPDATE versand SET lastexportspooler_id = %d, lastexportprinter = %d WHERE id = %d',
$spoolerId, $data['druckerlogistikstufe2'], $versandId
)
);
}
if($module === 'retoure'){
if(@is_file($tmppdf) && @filesize($tmppdf)){
$fileid = $this->app->erp->CreateDatei('Export_' . $this->app->DB->Select("SELECT belegnr FROM retoure WHERE id = '$id' LIMIT 1") . '.pdf', 'Anhang', '', "", $tmppdf, $this->app->DB->real_escape_string($this->app->User->GetName()));
$this->app->erp->AddDateiStichwort($fileid, 'anhang', 'retoure', $id);
}
}
unlink($tmppdf);
}
} catch (DhlBaseException $e) {
$this->errors[] = $e->getMessage();
}
}
}
if($adressdaten !== null){
return false;
}
if($target){
if($this->einstellungen['dhl_coding'] == '1'){
$this->app->Tpl->Set('DHL_CODING_CHECKED', 'checked="checked"');
}
$this->app->Tpl->Add("HEIGHT", $this->einstellungen['dhl_height']);
$this->app->Tpl->Add("WIDTH", $this->einstellungen['dhl_width']);
$this->app->Tpl->Add("LENGTH", $this->einstellungen['dhl_length']);
$this->app->Tpl->Parse($target, 'versandarten_dhl.tpl');
}
if(count($this->errors) > 0){
return $this->errors;
}
}
private function getPackageContents($deliveryNoteId)
{
$contents = [];
/** @var Database $db */
$db = $this->app->Container->get('Database');
$select = $db->select()
->from('lieferschein_position AS l')
->cols([
'l.bezeichnung',
'l.menge',
'l.zolltarifnummer',
'l.herkunftsland',
'a.umsatz_netto_einzeln',
'g.gewicht'
])
->leftJoin('auftrag_position AS a', 'l.auftrag_position_id = a.id')
->leftJoin('artikel AS g', 'l.artikel = g.id')
->where('l.lieferschein=:id')
->bindValue('id', $deliveryNoteId);
$positions = $db->fetchAll($select->getStatement(), $select->getBindValues());
foreach ($positions as $position) {
$contents[] = new PackageContent(
(int)$position['menge'],
$position['bezeichnung'],
$position['umsatz_netto_einzeln'],
$position['herkunftsland'],
$position['zolltarifnummer'],
$position['gewicht']
);
}
return $contents;
}
public function Export($daten)
{
}
private function log($message)
{
if(isset($this->einstellungen['log'])){
if(is_array($message) || is_object($message)){
error_log(print_r($message, true));
}else{
error_log($message);
}
}
}
}

View File

@ -0,0 +1,691 @@
<?php
use Xentral\Components\Database\Database;
use Xentral\Components\Http\JsonResponse;
use Xentral\Modules\Dhl\Api\DhlApi;
use Xentral\Modules\Dhl\Content\PackageContent;
use Xentral\Modules\Dhl\Exception\DhlBaseException;
use Xentral\Modules\Dhl\Exception\InvalidCredentialsException;
use Xentral\Modules\Dhl\Exception\InvalidRequestDataException;
use Xentral\Modules\Dhl\Exception\UnknownProductException;
use Xentral\Modules\Dhl\Factory\DhlApiFactory;
use Xentral\Modules\Dhl\Request\CreateInterationalShipmentRequest;
use Xentral\Modules\Dhl\Request\CreateNationalShipmentRequest;
require_once dirname(__DIR__) . '/class.versanddienstleister.php';
class Versandart_dhl extends Versanddienstleister
{
private $einstellungen;
private $info;
private $credentials;
public $paketmarke_drucker;
public $export_drucker;
public $errors;
public $name;
protected $voucherId;
/**
* Versandart_internetmarke constructor.
*
* @param ApplicationCore $app
* @param int $id
*/
function __construct($app, $id)
{
$this->id = $id;
$this->app = $app;
$einstellungenArr = $this->app->DB->SelectRow("SELECT einstellungen_json,paketmarke_drucker,export_drucker FROM versandarten WHERE id = '$id' LIMIT 1");
$einstellungen_json = $einstellungenArr['einstellungen_json'];
$this->paketmarke_drucker = $einstellungenArr['paketmarke_drucker'];
$this->export_drucker = $einstellungenArr['export_drucker'];
$this->name = 'DHL 3.0';
if($einstellungen_json){
$this->einstellungen = json_decode($einstellungen_json, true);
}else{
$this->einstellungen = [];
}
$this->errors = [];
}
function ShowUserdata()
{
if(isset($this->app->Conf->WFuserdata)){
return 'Userdata-Ordner: ' . $this->app->Conf->WFuserdata;
}
}
public function Einstellungen($target = 'return')
{
if($this->app->Secure->GetPOST('testen')){
$parameter1 = $this->einstellungen['pfad'];
if($parameter1){
if(is_dir($parameter1)){
if(substr($parameter1, -1) !== '/'){
$parameter1 .= '/';
}
if(file_put_contents($parameter1 . 'wawision_test.txt', 'TEST')){
$this->app->Tpl->Add('MESSAGE',
'<div class="info">Datei ' . $parameter1 . 'wawision_test.txt' . ' wurde erstellt!</div>');
}else{
$this->app->Tpl->Add('MESSAGE', '<div class="error">Datei konnte nicht angelegt werden!</div>');
}
}else{
$this->app->Tpl->Add('MESSAGE',
'<div class="error">Speicherort existiert nicht oder ist nicht erreichbar!</div>');
}
}else{
$this->app->Tpl->Add('MESSAGE', '<div class="error">Bitte einen Speicherort angeben!</div>');
}
}
parent::Einstellungen($target);
}
//TODO ....
/*function Trackinglink($tracking, &$notsend, &$link, &$rawlink)
{
$notsend = 0;
//$rawlink = 'https://tracking.dpd.de/parcelstatus/?locale=de_DE&query='.$tracking;
$rawlink = ' https://www.gls-group.eu/276-I-PORTAL-WEB/content/GLS/DE03/DE/5004.htm?txtRefNo='.$tracking.'&txtAction=71000';
$link = 'GLS Versand: '.$tracking.' ('.$rawlink.')';
}*/
public function GetBezeichnung()
{
return 'DHL 3.0';
}
/**
* @return array[]
*/
public function getCreateForm()
{
return [
[
'id' => 0,
'name' => 'usernameGroup',
'inputs' => [
[
'label' => 'Benutzername',
'type' => 'text',
'name' => 'dhl_username',
'validation' => true,
],
],
],
[
'id' => 1,
'name' => 'passwordGroup',
'inputs' => [
[
'label' => 'Passwort',
'type' => 'text',
'name' => 'dhl_password',
'validation' => true,
]
],
],
[
'id' => 2,
'name' => 'accountNumberGroup',
'inputs' => [
[
'label' => 'Abrechnungsnummer',
'type' => 'text',
'name' => 'dhl_accountnumber',
'validation' => true,
]
],
]
];
}
/**
* @param array $postData
*
* @return array
*/
public function updatePostDataForAssistent($postData): array
{
$name = $this->app->erp->Firmendaten('name');
$street = $this->app->erp->Firmendaten('strasse');
$zip = $this->app->erp->Firmendaten('plz');
$city = $this->app->erp->Firmendaten('ort');
$country = $this->app->erp->Firmendaten('land');
$houseNo = '';
$streetParts = explode(' ', $street);
$partsCount = count($streetParts);
if($partsCount >= 2){
$street = implode(' ', array_slice($streetParts, 0, $partsCount - 1));
$houseNo = $streetParts[$partsCount - 1];
}
$postData['dhl_origin_name'] = $name;
$postData['dhl_origin_street'] = $street;
$postData['dhl_origin_houseno'] = $houseNo;
$postData['dhl_origin_zip'] = $zip;
$postData['dhl_origin_city'] = $city;
$postData['dhl_origin_country'] = $country;
return $postData;
}
/**
* @return JsonResponse|null
*/
public function AuthByAssistent()
{
$step = (int)$this->app->Secure->GetPOST('step');
if($step == 0){
$username = $this->app->Secure->GetPOST('dhl_username');
$password = $this->app->Secure->GetPOST('dhl_password');
$accountnumber = $this->app->Secure->GetPOST('dhl_accountnumber');
$error = null;
if(empty($username)){
$error = 'Bitte Nutzernamen eingeben';
}else if(empty($password)){
$error = 'Bitte Passwort eingeben';
}else if(empty($accountnumber)){
$error = 'Bitte Abrechnungsnummer eingeben';
}
if($error != null) {
return new JsonResponse(
['error' => $error],
JsonResponse::HTTP_BAD_REQUEST
);
}
try{
$this->testCredentials($username, $password, $accountnumber);
}catch (DhlBaseException $e){
return new JsonResponse(
['error' => $e->getMessage()],
JsonResponse::HTTP_BAD_REQUEST
);
}
}
return null;
}
/**
* @return array
*/
public function getStructureDataForClickByClickSave(): array
{
return $this->updatePostDataForAssistent([]);
}
function EinstellungenStruktur()
{
if(!empty($this->einstellungen['dhl_username']) && !empty($this->einstellungen['dhl_password'])){
try{
$this->testCredentials($this->einstellungen['dhl_username'], $this->einstellungen['dhl_password'], $this->einstellungen['dhl_accountnumber']);
$this->app->Tpl->Set('MESSAGE', '<div class="info">Zugangsdaten erfolgreich &uuml;berpr&uuml;ft</div>');
}catch (DhlBaseException $e){
$this->app->Tpl->Set('MESSAGE', '<div class="error">' . $e->getMessage() . '</div>');
}
}
return [
'dhl_username' => ['typ' => 'text', 'bezeichnung' => 'Benutzername:'],
'dhl_password' => ['typ' => 'text', 'bezeichnung' => 'Passwort:'],
'dhl_accountnumber' => ['typ' => 'text', 'bezeichnung' => 'Abrechnungsnummer:'],
'dhl_origin_name' => ['typ' => 'text', 'bezeichnung' => 'Versender Name:'],
'dhl_origin_street' => ['typ' => 'text', 'bezeichnung' => 'Versender Strasse:'],
'dhl_origin_houseno' => ['typ' => 'text', 'bezeichnung' => 'Versender Hausnummer:'],
'dhl_origin_city' => ['typ' => 'text', 'bezeichnung' => 'Versender Ort:'],
'dhl_origin_zip' => ['typ' => 'text', 'bezeichnung' => 'Versender PLZ:'],
'dhl_origin_country' => ['typ' => 'text', 'bezeichnung' => 'Versender Land (2-stellig):'],
'dhl_origin_email' => ['typ' => 'text', 'bezeichnung' => 'Versender Email:'],
'dhl_height' => ['typ' => 'text', 'bezeichnung' => 'Standardh&ouml;he'],
'dhl_width' => ['typ' => 'text', 'bezeichnung' => 'Standardbreite'],
'dhl_length' => ['typ' => 'text', 'bezeichnung' => 'Standardl&auml;nge'],
'dhl_export_product_type' => [
'typ' => 'select',
'bezeichnung' => 'Export Producttyp',
'optionen' => [
'PRESENT' => 'Geschenke',
'COMMERCIAL_SAMPLE' => 'Kommerzielle Probe',
'DOCUMENT' => 'Dokumente',
'RETURN_OF_GOODS' => 'Rücksendungen',
'OTHER' => 'Andere',
]
],
'dhl_export_product_type_description' => [
'typ' => 'text',
'bezeichnung' => 'Beschreibung im Falle von "Andere"'
],
'dhl_product' => [
'typ' => 'select',
'bezeichnung' => 'Produkt:',
'optionen' => [
'V01PAK' => 'Paket national',
'V53WPAK' => 'Paket international'
],
],
'dhl_coding' => ['typ' => 'checkbox', 'bezeichnung' => 'Leitcodierung aktivieren'],
'autotracking' => ['typ' => 'checkbox', 'bezeichnung' => 'Tracking übernehmen:'],
];
}
public function testCredentials($username, $password, $accountNumber){
/** @var DhlApiFactory $dhlApiFactory */
$dhlApiFactory = $this->app->Container->get('DhlApiFactory');
/** @var DhlApi $dhlApi */
$dhlApi = $dhlApiFactory->createProductionInstance(
$username,
$password,
$accountNumber,
'',
'',
'',
'',
'',
'',
''
);
try {
$dhlApi->validateShipment(new CreateNationalShipmentRequest(
date("Y-m-d"),
1.0,
10,
20,
30,
"Max muster",
'',
'',
'Teststr. 1',
'11',
'86153',
'Augsburg',
'DE',
'max.muster@xentral.com',
false
));
}catch (InvalidRequestDataException $e){
// do nothing, test data is invalid
}
}
public function PaketmarkeDrucken($id, $sid)
{
$adressdaten = $this->GetAdressdaten($id, $sid);
$ret = $this->Paketmarke($sid, $id, '', false, $adressdaten);
if($sid === 'lieferschein'){
$deliveryNoteArr = $this->app->DB->SelectRow("SELECT adresse,projekt,versandart,auftragid FROM lieferschein WHERE id = '$id' LIMIT 1");
$adresse = $deliveryNoteArr['adresse'];
$projekt = $deliveryNoteArr['projekt'];
$versandart = $deliveryNoteArr['versandart'];
$adressvalidation = 2;
if($ret){
$adressvalidation = 1;
}
$tracking = '';
if(isset($adressdaten['tracking'])){
$tracking = $adressdaten['tracking'];
}
if(!isset($adressdaten['versandid'])){
$adressdaten['versandid'] = $this->app->DB->Select("SELECT id FROM versand WHERE abgeschlossen = 0 AND tracking = '' AND lieferschein = '$id' LIMIT 1");
}
if(!isset($adressdaten['versandid'])){
$this->app->DB->Insert("INSERT INTO versand (versandunternehmen, tracking,
versendet_am,abgeschlossen,lieferschein,freigegeben,firma,adresse,projekt,paketmarkegedruckt,adressvalidation)
VALUES ($versandart','$tracking',NOW(),1,'$id',1,'1','$adresse','$projekt',1,'$adressvalidation') ");
$adressdaten['versandid'] = $this->app->DB->GetInsertID();
}elseif($tracking){
$this->app->DB->Update("UPDATE versand SET freigegeben = 1, abgeschlossen = 1, tracking =1, paketmarkegedruckt = 1, tracking= '$tracking',adressvalidation = '$adressvalidation', versendet_am = now() WHERE id = '" . $adressdaten['versandid'] . "' LIMIT 1");
$this->app->DB->Update("UPDATE versand SET versandunternehmen = versandart WHERE id = '" . $adressdaten['versandid'] . "' AND versandunternehmen = '' LIMIT 1");
$this->app->DB->Update("UPDATE versand SET versandunternehmen = '$versandart' WHERE id = '" . $adressdaten['versandid'] . "' AND versandunternehmen = '' LIMIT 1");
}
$auftragid = $deliveryNoteArr['auftragid'];
if($auftragid){
$this->app->DB->Update("UPDATE auftrag SET schreibschutz = 1, status = 'abgeschlossen' WHERE id = '$auftragid' AND status = 'freigegeben' LIMIT 1");
}
if($adressvalidation == 1){
$this->app->erp->LieferscheinProtokoll($id, 'Paketmarke automatisch gedruckt');
if($adressdaten['versandid']){
return $adressdaten['versandid'];
}
}elseif($adressvalidation == 2){
$this->app->erp->LieferscheinProtokoll($id, 'automatisches Paketmarke Drucken fehlgeschlagen');
}
}
return $ret;
}
public function Paketmarke($doctyp, $docid, $target = '', $error = false, &$adressdaten = null)
{
$id = $docid;
$sid = $doctyp;
if($adressdaten === null){
$drucken = $this->app->Secure->GetPOST('drucken');
$anders = $this->app->Secure->GetPOST('anders');
$tracking_again = $this->app->Secure->GetGET('tracking_again');
$module = $this->app->Secure->GetPOST('module');
if(empty($module)){
$module = $doctyp;
}
}else{
$drucken = 1;
$anders = '';
$tracking_again = '';
$module = $doctyp;
}
/** @var DhlApiFactory $dhlApiFactory */
$dhlApiFactory = $this->app->Container->get('DhlApiFactory');
/** @var DhlApi $dhlApi */
$dhlApi = $dhlApiFactory->createProductionInstance(
$this->einstellungen['dhl_username'],
$this->einstellungen['dhl_password'],
$this->einstellungen['dhl_accountnumber'],
$this->einstellungen['dhl_origin_name'],
$this->einstellungen['dhl_origin_street'],
$this->einstellungen['dhl_origin_houseno'],
$this->einstellungen['dhl_origin_zip'],
$this->einstellungen['dhl_origin_city'],
$this->einstellungen['dhl_origin_country'],
$this->einstellungen['dhl_origin_email']
);
if($drucken != '' || $tracking_again == '1'){
if($tracking_again != "1"){
$versandId = 0;
if($module === 'retoure'){
$Query = $this->app->DB->SelectRow("SELECT * FROM retoure where id='$id'");
}elseif($module === 'versand'){
$versandId = $id;
$lieferschein = $this->app->DB->Select("SELECT lieferschein WHERE id = '$id' LIMIT 1");
$Query = $this->app->DB->SelectRow("SELECT * FROM lieferschein where id='$lieferschein'");
}else{
$Query = $this->app->DB->SelectRow("SELECT * FROM lieferschein where id='$id'");
}
$projekt = $Query['projekt'];
$Adresse = $this->app->DB->SelectRow("SELECT * FROM adresse WHERE id='" . $Query['adresse'] . "'");
$product = '';
$Country = $Query['land'];
if($adressdaten === null){
$versandmit = $this->app->Secure->GetPOST("versandmit");
$trackingsubmit = $this->app->Secure->GetPOST("trackingsubmit");
$versandmitbutton = $this->app->Secure->GetPOST("versandmitbutton");
$tracking = $this->app->Secure->GetPOST("tracking");
$trackingsubmitcancel = $this->app->Secure->GetPOST("trackingsubmitcancel");
$retourenlabel = $this->app->Secure->GetPOST("retourenlabel");
//$Weight = $this->app->Secure->GetPOST("kg1");
$Name = $this->app->Secure->GetPOST("name");
$Name2 = $this->app->Secure->GetPOST("name2");
$Name3 = $this->app->Secure->GetPOST("name3");
$Street = $this->app->Secure->GetPOST("strasse");
$HouseNo = $this->app->Secure->GetPOST("hausnummer");
$ZipCode = $this->app->Secure->GetPOST("plz");
$City = $this->app->Secure->GetPOST("ort");
$Mail = $this->app->Secure->GetPOST("email");
$Phone = $this->app->Secure->GetPOST("phone");
$Country = $this->app->Secure->GetPOST("land");
$Weight = $this->app->Secure->GetPOST('kg1');
$height = $this->app->Secure->GetPOST('height');
$wigth = $this->app->Secure->GetPOST('width');
$length = $this->app->Secure->GetPOST('length');
$coding = $this->app->Secure->GetPOST('coding') == '1';
}else{
$versandmit = '';//$this->app->Secure->GetPOST("versandmit");
$trackingsubmit = '';//$this->app->Secure->GetPOST("trackingsubmit");
$versandmitbutton = '';//$this->app->Secure->GetPOST("versandmitbutton");
$tracking = '';//$this->app->Secure->GetPOST("tracking");
$trackingsubmitcancel = '';//$this->app->Secure->GetPOST("trackingsubmitcancel");
$retourenlabel = '';// $this->app->Secure->GetPOST("retourenlabel");
$Name = $adressdaten["name"];
$Name2 = $adressdaten["name2"];
$Name3 = $adressdaten["name3"];
$Street = $adressdaten["strasse"];
$HouseNo = $adressdaten["hausnummer"];
$ZipCode = $adressdaten['plz'];
$City = $adressdaten['ort'];
$Mail = $adressdaten['email'];
$Phone = $adressdaten["telefon"];
$Country = $adressdaten["land"];
$Company = "Company";
$Weight = $adressdaten["standardkg"];
$coding = $this->einstellungen['dhl_coding'] == 1;
$height = $this->einstellungen('dhl_height');
$wigth = $this->einstellungen('dhl_width');
$length = $this->einstellungen('dhl_length');
}
try {
$shipmentDate = date("Y-m-d");
switch ($this->einstellungen['dhl_product']) {
case 'V01PAK':
{
$shipmentData = new CreateNationalShipmentRequest(
$shipmentDate,
$Weight,
$length,
$wigth,
$height,
$Name,
$Name2,
$Name3,
$Street,
$HouseNo,
$ZipCode,
$City,
$Country,
$Mail,
$coding
);
break;
}
case 'V53WPAK':
{
$shipmentData = new CreateInterationalShipmentRequest(
$shipmentDate,
$Weight,
$length,
$wigth,
$height,
$Name,
$Name2,
$Name3,
$Street,
$HouseNo,
$ZipCode,
$City,
$Country,
$Mail,
$coding,
$this->einstellungen['dhl_export_product_type'],
$this->einstellungen['dhl_export_product_type_description'],
$this->getPackageContents($Query['id'])
);
break;
}
default:
{
throw new UnknownProductException();
}
}
$createResponse = $dhlApi->createShipment($shipmentData);
if($this->einstellungen['autotracking'] == "1")
$this->SetTracking($createResponse->getShipmentNumber(), $sid === 'versand' ? $id : 0, $lieferschein);
$data['drucker'] = $this->paketmarke_drucker;
$data['druckerlogistikstufe2'] = $this->export_drucker;
if(!$data['drucker']){
if($this->app->erp->GetStandardPaketmarkendrucker() > 0){
$data['drucker'] = $this->app->erp->GetStandardPaketmarkendrucker();
}
}
if(!$data['druckerlogistikstufe2']){
if($this->app->erp->GetStandardVersanddrucker($projekt) > 0){
$data['druckerlogistikstufe2'] = $this->app->erp->GetStandardVersanddrucker($projekt);
}
}
$pdf = $createResponse->getLabelAsPdf();
$datei = $this->app->erp->GetTMP() . 'DhlLabel_' . $createResponse->getShipmentNumber() . '.pdf';
file_put_contents($datei, $pdf);
$spoolerId = $this->app->printer->Drucken($data['drucker'], $datei);
if($spoolerId > 0 && $versandId > 0){
$this->app->DB->Update(
sprintf(
'UPDATE versand SET lastspooler_id = %d, lastprinter = %d WHERE id = %d',
$spoolerId, $data['drucker'], $versandId
)
);
}
if($module === 'retoure'){
if(@is_file($datei) && @filesize($datei)){
$fileid = $this->app->erp->CreateDatei('DhlMarkeLabel_' . $this->app->DB->Select("SELECT belegnr FROM retoure WHERE id = '$id' LIMIT 1") . '.pdf',
'Anhang', '', "", $datei,
$this->app->DB->real_escape_string($this->app->User->GetName()));
$this->app->erp->AddDateiStichwort($fileid, 'anhang', 'retoure', $id);
}
}
unlink($datei);
if($adressdaten !== null){
return true;
}
if($createResponse->containsExportDocuments()){
$tmppdf = $this->app->erp->GetTMP() . 'DhlExport_' . $createResponse->getShipmentNumber() . '.pdf';
file_put_contents($tmppdf, $createResponse->getExportPaperAsPdf());
$spoolerId = $this->app->printer->Drucken($data['druckerlogistikstufe2'], $tmppdf);
if($versandId && $spoolerId){
$this->app->DB->Update(
sprintf(
'UPDATE versand SET lastexportspooler_id = %d, lastexportprinter = %d WHERE id = %d',
$spoolerId, $data['druckerlogistikstufe2'], $versandId
)
);
}
if($module === 'retoure'){
if(@is_file($tmppdf) && @filesize($tmppdf)){
$fileid = $this->app->erp->CreateDatei('Export_' . $this->app->DB->Select("SELECT belegnr FROM retoure WHERE id = '$id' LIMIT 1") . '.pdf', 'Anhang', '', "", $tmppdf, $this->app->DB->real_escape_string($this->app->User->GetName()));
$this->app->erp->AddDateiStichwort($fileid, 'anhang', 'retoure', $id);
}
}
unlink($tmppdf);
}
} catch (DhlBaseException $e) {
$this->errors[] = $e->getMessage();
}
}
}
if($adressdaten !== null){
return false;
}
if($target){
if($this->einstellungen['dhl_coding'] == '1'){
$this->app->Tpl->Set('DHL_CODING_CHECKED', 'checked="checked"');
}
$this->app->Tpl->Add("HEIGHT", $this->einstellungen['dhl_height']);
$this->app->Tpl->Add("WIDTH", $this->einstellungen['dhl_width']);
$this->app->Tpl->Add("LENGTH", $this->einstellungen['dhl_length']);
$this->app->Tpl->Parse($target, 'versandarten_dhl.tpl');
}
if(count($this->errors) > 0){
return $this->errors;
}
}
private function getPackageContents($deliveryNoteId)
{
$contents = [];
/** @var Database $db */
$db = $this->app->Container->get('Database');
$select = $db->select()
->from('lieferschein_position AS l')
->cols([
'l.bezeichnung',
'l.menge',
'l.zolltarifnummer',
'l.herkunftsland',
'a.umsatz_netto_einzeln',
'g.gewicht'
])
->leftJoin('auftrag_position AS a', 'l.auftrag_position_id = a.id')
->leftJoin('artikel AS g', 'l.artikel = g.id')
->where('l.lieferschein=:id')
->bindValue('id', $deliveryNoteId);
$positions = $db->fetchAll($select->getStatement(), $select->getBindValues());
foreach ($positions as $position) {
$contents[] = new PackageContent(
(int)$position['menge'],
$position['bezeichnung'],
$position['umsatz_netto_einzeln'],
$position['herkunftsland'],
$position['zolltarifnummer'],
$position['gewicht']
);
}
return $contents;
}
public function Export($daten)
{
}
private function log($message)
{
if(isset($this->einstellungen['log'])){
if(is_array($message) || is_object($message)){
error_log(print_r($message, true));
}else{
error_log($message);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
<?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
use Xentral\Carrier\SendCloud\Data\Document;
use Xentral\Carrier\SendCloud\Data\ParcelCreation;
use Xentral\Carrier\SendCloud\Data\ParcelItem;
use Xentral\Carrier\SendCloud\Data\ParcelResponse;
use Xentral\Carrier\SendCloud\SendCloudApi;
use Xentral\Carrier\SendCloud\Data\SenderAddress;
use Xentral\Carrier\SendCloud\Data\ShippingProduct;
use Xentral\Carrier\SendCloud\Data\ShippingMethod;
use Xentral\Carrier\SendCloud\SendcloudApiException;
use Xentral\Modules\ShippingMethod\Model\CreateShipmentResult;
use Xentral\Modules\ShippingMethod\Model\Product;
require_once dirname(__DIR__) . '/class.versanddienstleister.php';
class Versandart_sendcloud extends Versanddienstleister
{
protected SendCloudApi $api;
protected array $options;
public function __construct(ApplicationCore $app, ?int $id)
{
parent::__construct($app, $id);
if (!isset($this->id))
return;
$this->api = new SendCloudApi($this->settings->public_key, $this->settings->private_key);
}
public function GetName(): string
{
return "SendCloud";
}
protected function FetchOptionsFromApi()
{
if (isset($this->options))
return;
try {
$list = $this->api->GetSenderAddresses();
foreach ($list as $item) {
/* @var SenderAddress $item */
$senderAddresses[$item->Id] = $item;
}
$senderCountry = $senderAddresses[$this->settings->sender_address]->Country ?? 'DE';
$list = $this->api->GetShippingProducts($senderCountry);
foreach ($list as $item) {
/* @var ShippingProduct $item */
$shippingProducts[$item->Code] = $item;
}
} catch (SendcloudApiException $e) {
$this->app->Tpl->addMessage('error', $e->getMessage());
}
$this->options['senders'] = array_map(fn(SenderAddress $x) => strval($x), $senderAddresses ?? []);
$this->options['products'] = array_map(fn(ShippingProduct $x) => $x->Name, $shippingProducts ?? []);
$this->options['products'][0] = '';
$this->options['selectedProduct'] = $shippingProducts[$this->settings->shipping_product] ?? [];
natcasesort($this->options['products']);
}
public function AdditionalSettings(): array
{
$this->FetchOptionsFromApi();
return [
'public_key' => ['typ' => 'text', 'bezeichnung' => 'API Public Key:'],
'private_key' => ['typ' => 'text', 'bezeichnung' => 'API Private Key:'],
'sender_address' => ['typ' => 'select', 'bezeichnung' => 'Absender-Adresse:', 'optionen' => $this->options['senders']],
'shipping_product' => ['typ' => 'select', 'bezeichnung' => 'Versand-Produkt:', 'optionen' => $this->options['products']],
];
}
public function CreateShipment(object $json, array $address): CreateShipmentResult
{
$parcel = new ParcelCreation();
$parcel->SenderAddressId = $this->settings->sender_address;
$parcel->ShippingMethodId = $json->product;
$parcel->Name = $json->name;
switch ($json->addresstype) {
case 0:
$parcel->CompanyName = trim("$json->name2 $json->name3");
$parcel->Address = $json->street;
$parcel->Address2 = $json->address2;
$parcel->HouseNumber = $json->streetnumber;
break;
case 1:
$parcel->CompanyName = $json->postnumber;
$parcel->Address = "Packstation";
$parcel->HouseNumber = $json->parcelstationNumber;
break;
case 2:
$parcel->CompanyName = $json->postnumber;
$parcel->Address = "Postfiliale";
$parcel->HouseNumber = $json->postofficeNumber;
break;
}
$parcel->Country = $json->country;
$parcel->PostalCode = $json->zip;
$parcel->City = $json->city;
$parcel->EMail = $json->email;
$parcel->Telephone = $json->phone;
$parcel->CountryState = $json->state;
$parcel->CustomsInvoiceNr = $json->invoice_number;
$parcel->CustomsShipmentType = $json->shipment_type;
$parcel->TotalInsuredValue = $json->total_insured_value;
$parcel->OrderNumber = $json->order_number;
foreach ($json->positions as $pos) {
$item = new ParcelItem();
$item->HsCode = $pos->zolltarifnummer;
$item->Description = $pos->bezeichnung;
$item->Quantity = $pos->menge;
$item->OriginCountry = $pos->herkunftsland;
$item->Price = $pos->zolleinzelwert;
$item->Weight = $pos->zolleinzelgewicht * 1000;
$parcel->ParcelItems[] = $item;
}
$parcel->Weight = floatval($json->weight) * 1000;
$ret = new CreateShipmentResult();
try {
$result = $this->api->CreateParcel($parcel);
if ($result instanceof ParcelResponse) {
$ret->Success = true;
$ret->TrackingNumber = $result->TrackingNumber;
$ret->TrackingUrl = $result->TrackingUrl;
$doc = $result->GetDocumentByType(Document::TYPE_LABEL);
$ret->Label = $this->api->DownloadDocument($doc);
$doc = $result->GetDocumentByType(Document::TYPE_CN23);
if ($doc)
$ret->ExportDocuments = $this->api->DownloadDocument($doc);
} else {
$ret->Errors[] = $result;
}
} catch (SendcloudApiException $e) {
$ret->Errors[] = strval($e);
}
return $ret;
}
public function GetShippingProducts(): array
{
$this->FetchOptionsFromApi();
/** @var ShippingProduct $product */
$product = $this->options['selectedProduct'];
$result = [];
/** @var ShippingMethod $item */
foreach ($product->ShippingMethods as $item) {
$p = new Product();
$p->Id = $item->Id;
$p->Name = $item->Name;
$result[] = $p;
}
return $result;
}
}

View File

@ -1,4 +1,9 @@
<!--
SPDX-FileCopyrightText: 2022 Andreas Palm
SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
SPDX-License-Identifier: LicenseRef-EGPL-3.1
-->
<!-- gehort zu tabview --> <!-- gehort zu tabview -->
<div id="tabs"> <div id="tabs">
<ul> <ul>
@ -10,19 +15,60 @@
[FORMHANDLEREVENT] [FORMHANDLEREVENT]
<fieldset> <fieldset>
<legend>{|Einstellungen|}</legend> <legend>{|Einstellungen|}</legend>
<table width="100%" border="0" class="mkTableFormular"> <table class="mkTableFormular">
<tr><td>{|Bezeichnung|}: </td><td><input type="text" name="bezeichnung" value="[BEZEICHNUNG]" size="40" data-lang="versandart_bezeichnung_[ID]">[MSGBEZEICHNUNG]</td></tr> <tr>
<tr><td>{|Typ|}:</td><td><input type="text" name="typ" value="[TYP]" size="40">[MSGTYP] <i>{|z.B. dhl,ups,etc.|}</i></td></tr> <td>{|Bezeichnung|}:</td>
<tr><td>{|Modul|}:</td><td><select name="selmodul" id="selmodul" onchange="changemodul();">[SELMODUL]</select></td></tr> <td>
<tr><td>{|Projekt|}:</td><td><input type="text" id="projekt" name="projekt" value="[PROJEKT]" size="30"></td></tr> <input type="text" name="bezeichnung" value="[BEZEICHNUNG]" size="40"
<tr><td>{|Aktiv|}:</td><td><input type="checkbox" name="aktiv" value="1" [AKTIV]><i>{|Aktiv. Nicht mehr verwendete Versandarten können deaktiviert werden.|}</i></td></tr> data-lang="versandart_bezeichnung_[ID]" required>
<tr><td>{|Kein Portocheck|}:</td><td><input type="checkbox" name="keinportocheck" value="1" [KEINPORTOCHECK]><i>{|Porto-Check im Auftrag deaktivieren.|}</i></td></tr> </td>
</tr>
<tr><td>{|Drucker Paketmarke|}:</td><td><select name="paketmarke_drucker" id="paketmarke_drucker">[PAKETMARKE_DRUCKER]</select></td></tr> <tr>
<tr><td>{|Drucker Export|}:</td><td><select name="export_drucker" id="export_drucker">[EXPORT_DRUCKER]</select></td></tr> <td>{|Typ|}:</td>
<tr><td>{|Versandmail|}:</td><td><select name="versandmail" id="versandmail">[SELVERSANDMAIL]</select></td></tr> <td>
<tr class="versandbetreff"><td>{|Textvorlage|}:</td><td><select name="geschaeftsbrief_vorlage" id="geschaeftsbrief_vorlage">[SELGESCHAEFTSBRIEF_VORLAGE]</select></td></tr> <input type="text" name="type" value="[TYPE]" size="40" required>
[JSON] <i>{|z.B. dhl,ups,etc.|}</i>
</td>
</tr>
<tr>
<td>{|Modul|}:</td>
<td>[SELMODUL]</td>
</tr>
<tr>
<td>{|Projekt|}:</td>
<td><input type="text" id="projekt" name="projekt" value="[PROJEKT]" size="30"></td>
</tr>
<tr>
<td>{|Aktiv|}:</td>
<td>
<input type="checkbox" name="aktiv" value="1" [AKTIV]>
<i>{|Aktiv. Nicht mehr verwendete Versandarten können deaktiviert werden.|}</i>
</td>
</tr>
<tr>
<td>{|Kein Portocheck|}:</td>
<td>
<input type="checkbox" name="keinportocheck" value="1" [KEINPORTOCHECK]>
<i>{|Porto-Check im Auftrag deaktivieren.|}</i>
</td>
</tr>
<tr>
<td>{|Drucker Paketmarke|}:</td>
<td>[PAKETMARKE_DRUCKER]</td>
</tr>
<tr>
<td>{|Drucker Export|}:</td>
<td>[EXPORT_DRUCKER]</td>
</tr>
<tr>
<td>{|Versandmail|}:</td>
<td>[SELVERSANDMAIL]</td>
</tr>
<tr class="versandbetreff">
<td>{|Textvorlage|}:</td>
<td>[SELGESCHAEFTSBRIEF_VORLAGE]</td>
</tr>
[MODULESETTINGS]
</table> </table>
</fieldset> </fieldset>
<input type="submit" name="speichern" value="{|Speichern|}" id="speichern" style="float:right"/> <input type="submit" name="speichern" value="{|Speichern|}" id="speichern" style="float:right"/>
@ -31,16 +77,14 @@
</div> </div>
<script> <script>
var modulname = '[AKTMODUL]'; var modulname = '[AKTMODUL]';
function changemodul() function changemodul() {
{ if ($('#selmodul').val() != modulname) {
if($('#selmodul').val() != modulname) if (confirm('{|Wollen Sie das Modul wirklich ändern? Die Einstellungen werden dabei überschrieben|}')) {
{
if(confirm('{|Wollen Sie das Modul wirklich ändern? Die Einstellungen werden dabei überschrieben|}'))
{
$('#speichern').trigger('click'); $('#speichern').trigger('click');
} else { } else {
$('#selmodul').val(modulname); $('#selmodul').val(modulname);
} }
} }
} }
$('#selmodul').on('change', changemodul);
</script> </script>

View File

@ -1,3 +1,9 @@
<!--
SPDX-FileCopyrightText: 2022 Andreas Palm
SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
SPDX-License-Identifier: LicenseRef-EGPL-3.1
-->
<!-- gehort zu tabview --> <!-- gehort zu tabview -->
<div id="tabs"> <div id="tabs">
<ul> <ul>
@ -12,17 +18,10 @@
<fieldset class="moduleList"> <fieldset class="moduleList">
<legend>{|Auswahl|}</legend> <legend>{|Auswahl|}</legend>
<div id="searchdiv"> <div id="searchdiv">
<label for="suche">{|Suche|}:</label> <input type="text" id="suche" /> <label for="suche">{|Suche|}:</label> <input type="text" id="createSearchInput" />
</div> </div>
[MODULEINSTALLIERT] [MODULEINSTALLIERT]
</fieldset> </fieldset>
[BEFOREMODULESTOBUY]
<fieldset class="moduleList">
<legend>{|Kaufschnittstellen|}</legend>
[MODULEVERFUEGBAR]
<br />
</fieldset>
[AFTERMODULESTOBUY]
[TAB1NEXT] [TAB1NEXT]
</div> </div>

View File

@ -1,4 +1,12 @@
<?php <?php
/*
* SPDX-FileCopyrightText: 2022 Andreas Palm
* SPDX-FileCopyrightText: 2019 Xentral (c) Xentral ERP Software GmbH, Fuggerstrasse 11, D-86150 Augsburg, Germany
*
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
*/
/* /*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE **** **** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
* *
@ -447,36 +455,24 @@ class Lieferschein extends GenLieferschein
function LieferscheinPaketmarke() function LieferscheinPaketmarke()
{ {
$id = $this->app->Secure->GetGET("id"); $id = (int)$this->app->Secure->GetGET("id");
$versandart = $this->app->DB->Select("SELECT versandart FROM lieferschein WHERE id='$id' LIMIT 1");
$projekt = $this->app->DB->Select("SELECT projekt FROM lieferschein WHERE id = '$id' LIMIT 1");
$this->LieferscheinMenu(); $this->LieferscheinMenu();
$this->app->Tpl->Set('TABTEXT',"Paketmarke"); $this->app->Tpl->Set('TABTEXT',"Paketmarke");
$versandart = strtolower($versandart); $result = $this->app->DB->SelectRow(
$versandartenmodul = $this->app->DB->SelectArr("SELECT id, modul FROM versandarten WHERE aktiv = 1 AND ausprojekt = 0 AND modul != '' AND type = '".$this->app->DB->real_escape_string($versandart)."' AND (projekt = '$projekt' || projekt = 0) ORDER BY projekt DESC LIMIT 1"); "SELECT v.id, v.modul
if($versandartenmodul && is_file(dirname(__DIR__).'/lib/versandarten/'.$versandartenmodul[0]['modul'].'.php')) FROM lieferschein l
{ LEFT JOIN versandarten v ON (l.versandart=v.type AND v.projekt in (l.projekt, 0))
$this->app->erp->Paketmarke('TAB1','lieferschein',"",$versandart); WHERE l.id=$id
}else{ AND v.aktiv = 1 AND v.ausprojekt = 0 AND v.modul != ''
if($versandart=="dpd") ORDER BY v.projekt DESC LIMIT 1");
$this->app->erp->PaketmarkeDPDEmbedded('TAB1',"lieferschein"); if (empty($result['modul']) || empty($result['id'])) {
else if($versandart=="express_dpd") $this->app->Tpl->addMessage('error', 'Bitte zuerst eine gültige Versandart auswählen', false, 'PAGE');
$this->app->erp->PaketmarkeDPDEmbedded('TAB1',"lieferschein","express"); return;
else if($versandart=="export_dpd")
$this->app->erp->PaketmarkeDPDEmbedded('TAB1',"lieferschein","export");
else if($versandart=="ups")
$this->app->erp->PaketmarkeUPSEmbedded('TAB1',"lieferschein");
else if($versandart=="fedex")
$this->app->erp->PaketmarkeFEDEXEmbedded('TAB1',"lieferschein");
else if($versandart=="go")
$this->app->erp->PaketmarkeGo('TAB1',"lieferschein");
else {
$this->app->erp->Paketmarke('TAB1','lieferschein',"","");
}
//$this->app->erp->PaketmarkeDHLEmbedded('TAB1',"lieferschein");
} }
$versandmodul = $this->app->erp->LoadVersandModul($result['modul'], $result['id']);
$versandmodul->Paketmarke('TAB1', 'lieferschein', $id);
$this->app->Tpl->Parse('PAGE',"tabview.tpl"); $this->app->Tpl->Parse('PAGE',"tabview.tpl");
} }

File diff suppressed because it is too large Load Diff

View File

@ -66,7 +66,6 @@ function xentral_autoloader($class) {
'ICS'=>__DIR__.'/www/plugins/class.ics.php', 'ICS'=>__DIR__.'/www/plugins/class.ics.php',
'USTID'=>__DIR__.'/www/lib/class.ustid.php', 'USTID'=>__DIR__.'/www/lib/class.ustid.php',
'phpprint'=>__DIR__.'/www/plugins/php-print.php', 'phpprint'=>__DIR__.'/www/plugins/php-print.php',
'DHLBusinessShipment'=>__DIR__.'/www/lib/class.intraship.php',
'Navigation'=>__DIR__.'/www/lib/class.navigation_edit.php', 'Navigation'=>__DIR__.'/www/lib/class.navigation_edit.php',
'GoShipment'=>__DIR__.'/www/lib/class.go.php', 'GoShipment'=>__DIR__.'/www/lib/class.go.php',
'UPSShipment'=>__DIR__.'/www/lib/class.ups.php', 'UPSShipment'=>__DIR__.'/www/lib/class.ups.php',