Repository: horstoeko/zugferd (php)

Issue:
[QUESTION] Allow public access to document context?
Hello,

would it be possible that you make the  `ZugferdDocument#getInvoiceObject()` method public?

This would make it easier to access its `getExchangedDocumentContext()` method.

Another variant would be that `ZugferdDocument` provides a direct accessor for the document context.

Thank you very much for your work!



Pull request description:
#263 Added ZugferdDocumentProfileConverter
# Description

Convert between profiles

Fixes #263 

## Type of change

Please delete options that are not relevant.

- [X] New feature (non-breaking change which adds functionality)

Patch:
diff --git a/build/phpunit.xml b/build/phpunit.xml
index 39767a6..ea4850f 100644
--- a/build/phpunit.xml
+++ b/build/phpunit.xml
@@ -28,6 +28,9 @@
             <file>../tests/testcases/BuilderEn16931Test.php</file>
             <file>../tests/testcases/BuilderExtendedTest.php</file>
         </testsuite>
+        <testsuite name="ProfileConverter">
+            <file>../tests/testcases/ProfileConverterTest.php</file>
+        </testsuite>
         <testsuite name="PDFReader">
             <file>../tests/testcases/PdfReaderGeneralTest.php</file>
             <file>../tests/testcases/PdfReaderMinimumTest.php</file>
diff --git a/make/genmethoddocs.php b/make/genmethoddocs.php
index 8f3fcb4..b6e7d64 100644
--- a/make/genmethoddocs.php
+++ b/make/genmethoddocs.php
@@ -13,6 +13,7 @@ use horstoeko\zugferd\ZugferdDocumentPdfBuilder;
 use horstoeko\zugferd\ZugferdDocumentPdfMerger;
 use horstoeko\zugferd\ZugferdDocumentPdfReader;
 use horstoeko\zugferd\ZugferdDocumentPdfReaderExt;
+use horstoeko\zugferd\ZugferdDocumentProfileConverter;
 use horstoeko\zugferd\ZugferdDocumentReader;
 use horstoeko\zugferd\ZugferdDocumentValidator;
 use horstoeko\zugferd\ZugferdKositValidator;
@@ -691,6 +692,7 @@ BatchMarkDownGenerator::generate([
     ZugferdQuickDescriptorXRechnung::class => __DIR__ . '/Class-ZugferdQuickDescriptorXRechnung.md',
     ZugferdQuickDescriptorXRechnung2::class => __DIR__ . '/Class-ZugferdQuickDescriptorXRechnung2.md',
     ZugferdQuickDescriptorXRechnung3::class => __DIR__ . '/Class-ZugferdQuickDescriptorXRechnung3.md',
+    ZugferdDocumentProfileConverter::class => __DIR__ . '/Class-ZugferdDocumentProfileConverter.md',
 ], [
     \horstoeko\zugferd\ZugferdDocumentPdfBuilder::class . '::generateDocument',
     \horstoeko\zugferd\ZugferdDocumentPdfMerger::class . '::generateDocument',
diff --git a/src/ZugferdDocument.php b/src/ZugferdDocument.php
index 9e21376..1c47895 100644
--- a/src/ZugferdDocument.php
+++ b/src/ZugferdDocument.php
@@ -168,7 +168,7 @@ class ZugferdDocument
      * @return ZugferdDocument
      * @throws ZugferdUnknownProfileIdException
      */
-    private function initProfile(int $profile): ZugferdDocument
+    protected function initProfile(int $profile): ZugferdDocument
     {
         $this->profileId = $profile;
         $this->profileDefinition = ZugferdProfileResolver::resolveProfileDefById($profile);
@@ -181,7 +181,7 @@ class ZugferdDocument
      *
      * @return ZugferdDocument
      */
-    private function initObjectHelper(): ZugferdDocument
+    protected function initObjectHelper(): ZugferdDocument
     {
         $this->objectHelper = new ZugferdObjectHelper($this->profileId);
 
@@ -196,7 +196,7 @@ class ZugferdDocument
      * @throws InvalidArgumentException
      * @throws RuntimeException
      */
-    private function initSerialzer(): ZugferdDocument
+    protected function initSerialzer(): ZugferdDocument
     {
         $this->serializerBuilder = SerializerBuilder::create();
 
diff --git a/src/ZugferdDocumentProfileConverter.php b/src/ZugferdDocumentProfileConverter.php
new file mode 100644
index 0000000..30083de
--- /dev/null
+++ b/src/ZugferdDocumentProfileConverter.php
@@ -0,0 +1,291 @@
+<?php
+
+/**
+ * This file is a part of horstoeko/zugferd.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace horstoeko\zugferd;
+
+use horstoeko\zugferd\exception\ZugferdFileNotFoundException;
+use horstoeko\zugferd\exception\ZugferdFileNotReadableException;
+use horstoeko\zugferd\exception\ZugferdUnknownProfileException;
+use horstoeko\zugferd\exception\ZugferdUnknownProfileIdException;
+use horstoeko\zugferd\exception\ZugferdUnknownProfileParameterException;
+use horstoeko\zugferd\exception\ZugferdUnknownXmlContentException;
+use JMS\Serializer\Exception\InvalidArgumentException;
+use JMS\Serializer\Exception\RuntimeException;
+
+/**
+ * Class representing a converter to change a document's profile to another profile
+ *
+ * @category Zugferd
+ * @package  Zugferd
+ * @author   D. Erling <horstoeko@erling.com.de>
+ * @license  https://opensource.org/licenses/MIT MIT
+ * @link     https://github.com/horstoeko/zugferd
+ */
+class ZugferdDocumentProfileConverter extends ZugferdDocument
+{
+    /**
+     * The source
+     *
+     * @var string
+     */
+    protected $convertFromContent = "";
+
+    /**
+     * The new profile ID
+     *
+     * @var int
+     */
+    protected $convertToProfileId = -1;
+
+    /**
+     * Path to the profile id
+     */
+    protected const PATH_1 = 'getExchangedDocumentContext.getGuidelineSpecifiedDocumentContextParameter.setID';
+
+    /**
+     * Path to the context parameter
+     */
+    protected const PATH_2 = 'getExchangedDocumentContext.setBusinessProcessSpecifiedDocumentContextParameter';
+
+    /**
+     * Path to the context parameter id
+     */
+    protected const PATH_3 = 'getExchangedDocumentContext.getBusinessProcessSpecifiedDocumentContextParameter.setID';
+
+    /**
+     * Convert from file to file
+     *
+     * @param  string $fromFilename
+     * @param  string $toFile
+     * @param  int    $newProfileId
+     * @return void
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdFileNotFoundException
+     * @throws ZugferdFileNotReadableException
+     * @throws ZugferdUnknownProfileException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     * @throws ZugferdUnknownXmlContentException
+     */
+    public static function convertFromFileToFile(string $fromFilename, string $toFile, int $newProfileId): void
+    {
+        static::convertFromFile($fromFilename, $newProfileId)->convertToFile($toFile);
+    }
+
+    /**
+     * Convert from file to string
+     *
+     * @param  string $fromFilename
+     * @param  int    $newProfileId
+     * @return string
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdFileNotFoundException
+     * @throws ZugferdFileNotReadableException
+     * @throws ZugferdUnknownProfileException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     * @throws ZugferdUnknownXmlContentException
+     */
+    public static function convertFromFileToString(string $fromFilename, int $newProfileId): string
+    {
+        return static::convertFromFile($fromFilename, $newProfileId)->convertToString();
+    }
+
+    /**
+     * Convert from content to file
+     *
+     * @param  string $fromContent
+     * @param  string $toFile
+     * @param  int    $newProfileId
+     * @return void
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdUnknownProfileException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     * @throws ZugferdUnknownXmlContentException
+     */
+    public static function convertFromContentToFile(string $fromContent, string $toFile, int $newProfileId): void
+    {
+        static::convertFromContent($fromContent, $newProfileId)->convertToFile($toFile);
+    }
+
+    /**
+     * Convert from content to string
+     *
+     * @param  string $fromContent
+     * @param  int    $newProfileId
+     * @return string
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdUnknownProfileException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     * @throws ZugferdUnknownXmlContentException
+     */
+    public static function convertFromContentToString(string $fromContent, int $newProfileId): string
+    {
+        return static::convertFromContent($fromContent, $newProfileId)->convertToString();
+    }
+
+    /**
+     * Create an instance by filename
+     *
+     * @param  string $fromFilename
+     * @param  int    $newProfileId
+     * @return ZugferdDocumentProfileConverter
+     * @throws ZugferdFileNotFoundException
+     * @throws ZugferdFileNotReadableException
+     * @throws ZugferdUnknownXmlContentException
+     * @throws ZugferdUnknownProfileException
+     */
+    protected static function convertFromFile(string $fromFilename, int $newProfileId): ZugferdDocumentProfileConverter
+    {
+        if (!file_exists($fromFilename)) {
+            throw new ZugferdFileNotFoundException($fromFilename);
+        }
+
+        $fromContent = file_get_contents($fromFilename);
+
+        if ($fromContent === false) {
+            throw new ZugferdFileNotReadableException($fromFilename);
+        }
+
+        return static::convertFromContent($fromContent, $newProfileId);
+    }
+
+    /**
+     * Create an instance by cpntent
+     *
+     * @param  string $fromContent
+     * @param  int    $newProfileId
+     * @return ZugferdDocumentProfileConverter
+     * @throws ZugferdUnknownXmlContentException
+     * @throws ZugferdUnknownProfileException
+     */
+    protected static function convertFromContent(string $fromContent, int $newProfileId): ZugferdDocumentProfileConverter
+    {
+        $fromProfileId = ZugferdProfileResolver::resolveProfileId($fromContent);
+
+        $profileConverter = new static($fromProfileId);
+        $profileConverter->setConvertFromContent($fromContent);
+        $profileConverter->setConvertToProfileId($newProfileId);
+
+        return $profileConverter;
+    }
+
+    /**
+     * Set the destination (the new) profile id
+     *
+     * @param  int $toProfileId
+     * @return ZugferdDocumentProfileConverter
+     */
+    protected function setConvertToProfileId(int $toProfileId): ZugferdDocumentProfileConverter
+    {
+        $this->convertToProfileId = $toProfileId;
+
+        return $this;
+    }
+
+    /**
+     * Set the source-content
+     *
+     * @param  string $fromContent
+     * @return ZugferdDocumentProfileConverter
+     */
+    protected function setConvertFromContent(string $fromContent): ZugferdDocumentProfileConverter
+    {
+        $this->convertFromContent = $fromContent;
+
+        return $this;
+    }
+
+    /**
+     * Convert and save to file
+     *
+     * @param  string $toFile
+     * @return ZugferdDocumentProfileConverter
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     */
+    protected function convertToFile(string $toFile): ZugferdDocumentProfileConverter
+    {
+        file_put_contents($toFile, $this->performConversion()->convertToString());
+
+        return $this;
+    }
+
+    /**
+     * Convert and get xml content as string
+     *
+     * @return string
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     */
+    protected function convertToString(): string
+    {
+        return $this->performConversion()->serializeAsXml();
+    }
+
+    /**
+     * Internal conversion method
+     *
+     * @return ZugferdDocumentProfileConverter
+     * @throws InvalidArgumentException
+     * @throws RuntimeException
+     * @throws ZugferdUnknownProfileIdException
+     * @throws ZugferdUnknownProfileParameterException
+     */
+    protected function performConversion(): ZugferdDocumentProfileConverter
+    {
+        $this->initProfile($this->convertToProfileId);
+        $this->initObjectHelper();
+        $this->initSerialzer();
+        $this->deserialize($this->convertFromContent);
+        $this->updateProfileInInvoiceObject();
+
+        return $this;
+    }
+
+    /**
+     * Update profile parameters in the internal invoice object
+     *
+     * @return void
+     * @throws ZugferdUnknownProfileIdException
+     */
+    protected function updateProfileInInvoiceObject()
+    {
+        $profileDef = ZugferdProfileResolver::resolveProfileDefById($this->convertToProfileId);
+
+        $this->getObjectHelper()->tryCallByPath(
+            $this->getInvoiceObject(),
+            static::PATH_1,
+            $this->getObjectHelper()->getIdType($profileDef['contextparameter'])
+        );
+
+        if ($profileDef['businessprocess']) {
+            $this->getObjectHelper()->tryCallByPath(
+                $this->getInvoiceObject(),
+                static::PATH_2,
+                $this->getObjectHelper()->createClassInstance('ram\DocumentContextParameterType')
+            );
+            $this->getObjectHelper()->tryCallByPath(
+                $this->getInvoiceObject(),
+                static::PATH_3,
+                $this->getObjectHelper()->getIdType($profileDef['businessprocess'])
+            );
+        }
+    }
+}


Test patch:
diff --git a/tests/testcases/ProfileConverterTest.php b/tests/testcases/ProfileConverterTest.php
new file mode 100644
index 0000000..e913d1a
--- /dev/null
+++ b/tests/testcases/ProfileConverterTest.php
@@ -0,0 +1,225 @@
+<?php
+
+namespace horstoeko\zugferd\tests\testcases;
+
+use horstoeko\zugferd\tests\TestCase;
+use horstoeko\zugferd\ZugferdProfiles;
+use horstoeko\zugferd\tests\traits\HandlesXmlTests;
+use horstoeko\zugferd\ZugferdDocumentProfileConverter;
+use horstoeko\zugferd\exception\ZugferdFileNotFoundException;
+
+class ProfileConverterTest extends TestCase
+{
+    use HandlesXmlTests;
+
+    public function testComvertFromFileToFileXRechnung3(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $tofile = __DIR__ . "/../assets/converterresult.xml";
+        $converterResult = ZugferdDocumentProfileConverter::convertFromFileToFile($fromfile, $tofile, ZugferdProfiles::PROFILE_XRECHNUNG_3);
+
+        $this->registerFileForTeardown($tofile);
+
+        $this->assertNull($converterResult);
+        $this->assertFileExists($tofile);
+
+        $tofileContent = file_get_contents($tofile);
+
+        $this->assertIsString($tofileContent);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $tofileContent);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+    }
+
+    public function testConvertFromFileToStringXRechnung3(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $converterResult = ZugferdDocumentProfileConverter::convertFromFileToString($fromfile, ZugferdProfiles::PROFILE_XRECHNUNG_3);
+
+        $this->assertIsString($converterResult);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $converterResult);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+    }
+
+    public function testConvertFromContentToFileXRechnung3(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $tofile = __DIR__ . "/../assets/converterresult.xml";
+        $fromfileContent = file_get_contents($fromfile);
+        $converterResult = ZugferdDocumentProfileConverter::convertFromContentToFile($fromfileContent, $tofile, ZugferdProfiles::PROFILE_XRECHNUNG_3);
+
+        $this->registerFileForTeardown($tofile);
+
+        $this->assertNull($converterResult);
+        $this->assertFileExists($tofile);
+
+        $tofileContent = file_get_contents($tofile);
+
+        $this->assertIsString($tofileContent);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $tofileContent);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+    }
+
+    public function testConvertFromContentToStringXRechnung3(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $fromfileContent = file_get_contents($fromfile);
+        $converterResult = ZugferdDocumentProfileConverter::convertFromContentToString($fromfileContent, ZugferdProfiles::PROFILE_XRECHNUNG_3);
+
+        $this->assertIsString($converterResult);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $converterResult);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+    }
+
+    public function testComvertFromFileToFileEn16931(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $tofile = __DIR__ . "/../assets/converterresult.xml";
+        $converterResult = ZugferdDocumentProfileConverter::convertFromFileToFile($fromfile, $tofile, ZugferdProfiles::PROFILE_EN16931);
+
+        $this->registerFileForTeardown($tofile);
+
+        $this->assertNull($converterResult);
+        $this->assertFileExists($tofile);
+
+        $tofileContent = file_get_contents($tofile);
+
+        $this->assertIsString($tofileContent);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $tofileContent);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringNotContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringNotContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $tofileContent);
+        $this->assertStringNotContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+    }
+
+    public function testConvertFromFileToStringEn16931(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $converterResult = ZugferdDocumentProfileConverter::convertFromFileToString($fromfile, ZugferdProfiles::PROFILE_EN16931);
+
+        $this->assertIsString($converterResult);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $converterResult);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $converterResult);
+        $this->assertStringNotContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+    }
+
+    public function testConvertFromContentToFileEn16931(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $tofile = __DIR__ . "/../assets/converterresult.xml";
+        $fromfileContent = file_get_contents($fromfile);
+        $converterResult = ZugferdDocumentProfileConverter::convertFromContentToFile($fromfileContent, $tofile, ZugferdProfiles::PROFILE_EN16931);
+
+        $this->registerFileForTeardown($tofile);
+
+        $this->assertNull($converterResult);
+        $this->assertFileExists($tofile);
+
+        $tofileContent = file_get_contents($tofile);
+
+        $this->assertIsString($tofileContent);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $tofileContent);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017</ram:ID>', $tofileContent);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringNotContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+        $this->assertStringNotContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $tofileContent);
+        $this->assertStringNotContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $tofileContent);
+    }
+
+    public function testConvertFromContentToStringEn16931(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_en16931_1.xml";
+        $fromfileContent = file_get_contents($fromfile);
+        $converterResult = ZugferdDocumentProfileConverter::convertFromContentToString($fromfileContent, ZugferdProfiles::PROFILE_EN16931);
+
+        $this->assertIsString($converterResult);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $converterResult);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $converterResult);
+        $this->assertStringNotContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+    }
+
+    public function testComvertFromFileWhichNotExistsToFile(): void
+    {
+        $this->expectException(ZugferdFileNotFoundException::class);
+
+        $fromfile = __DIR__ . "/../assets/not_existing_file.xml";
+        $tofile = __DIR__ . "/../assets/converterresult.xml";
+
+        ZugferdDocumentProfileConverter::convertFromFileToFile($fromfile, $tofile, ZugferdProfiles::PROFILE_XRECHNUNG_3);
+    }
+
+    public function testComvertFromFileToFileExtendedToEn16931(): void
+    {
+        $fromfile = __DIR__ . "/../assets/xml_extended_1.xml";
+        $converterResult = ZugferdDocumentProfileConverter::convertFromFileToString($fromfile, ZugferdProfiles::PROFILE_EN16931);
+
+        $this->assertIsString($converterResult);
+        $this->assertStringStartsWith('<?xml version="1.0" encoding="UTF-8"?>', $converterResult);
+        $this->assertStringContainsString('<ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringContainsString('<ram:ID>urn:cen.eu:en16931:2017</ram:ID>', $converterResult);
+        $this->assertStringContainsString('</ram:GuidelineSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+        $this->assertStringNotContainsString('<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>', $converterResult);
+        $this->assertStringNotContainsString('</ram:BusinessProcessSpecifiedDocumentContextParameter>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:TestIndicator>', $converterResult);
+        $this->assertStringNotContainsString('<udt:Indicator>true</udt:Indicator>', $converterResult);
+        $this->assertStringNotContainsString('</ram:TestIndicator>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:Name>KOSTENRECHNUNG</ram:Name>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:ContentCode>ST3</ram:ContentCode>', $converterResult);
+        $this->assertStringNotContainsString('<ram:ContentCode>EEV</ram:ContentCode>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:IndustryAssignedID>IndustryId</ram:IndustryAssignedID>', $converterResult);
+        $this->assertStringNotContainsString('<ram:BatchID>BatchId</ram:BatchID>', $converterResult);
+        $this->assertStringNotContainsString('<ram:BrandName>BrandeName</ram:BrandName>', $converterResult);
+        $this->assertStringNotContainsString('<ram:ModelName>ModelName</ram:ModelName>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:DeliveryNoteReferencedDocument>', $converterResult);
+        $this->assertStringNotContainsString('<ram:IssuerAssignedID>L87654321012</ram:IssuerAssignedID>', $converterResult);
+        $this->assertStringNotContainsString('</ram:DeliveryNoteReferencedDocument>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:InvoiceeTradeParty>', $converterResult);
+        $this->assertStringNotContainsString('</ram:InvoiceeTradeParty>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:SpecifiedLogisticsServiceCharge>', $converterResult);
+        $this->assertStringNotContainsString('</ram:SpecifiedLogisticsServiceCharge>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:ApplicableTradePaymentDiscountTerms>', $converterResult);
+        $this->assertStringNotContainsString('</ram:ApplicableTradePaymentDiscountTerms>', $converterResult);
+
+        $this->assertStringNotContainsString('<ram:ApplicableTradePaymentPenaltyTerms>', $converterResult);
+        $this->assertStringNotContainsString('</ram:ApplicableTradePaymentPenaltyTerms>', $converterResult);
+    }
+}