diff --git a/breaking270.md b/breaking270.md new file mode 100644 index 00000000..df6c9b90 --- /dev/null +++ b/breaking270.md @@ -0,0 +1,52 @@ +# Breaking changes since 2.7.0 +Release ... added multiple new resources, but also broke several existing ones. + +Breaking changes are present in: +- Bank Transactions (Separate API connector completely removed and functionality moved to general Transactions API Connector) +- Articles +- Customers +- Sales Invoices +- Suppliers +- Transactions +- Vat Codes + +Except for Bank Transactions, the breaking changes are primarily due to the fact that most fields and methods are now properly type cast. + +This means (among others) that all booleans are now type cast as bool, all monetary values are now Money\Money instances and several fields now use Enums instead of strings. + +Another big change is that retrieved fields that are instances of another entity in Twinfield and this library are now retrieved and set in the same way as was already done with Office or Customer codes. +So for example a VAT code retrieved from or set to a PhpTwinfield\Article will now become an instance of PhpTwinfield\VatCode with its $code set to "VH" instead of begin just a string with the value "VH". + +See the tables per class below for breaking changes and suggestions for fixes/replacement methods. + +## Bank Transactions + +-TODO + +## Articles + +-TODO + +### Article Lines + +-TODO + +## Customers + +-TODO + +## Sales Invoices + +-TODO + +## Suppliers + +-TODO + +## Cash/Journal/Purchase/Sale Transactions + +-TODO + +## VAT + +-TODO \ No newline at end of file diff --git a/composer.json b/composer.json index 499e9f7a..3b7386d7 100644 --- a/composer.json +++ b/composer.json @@ -54,6 +54,7 @@ "eloquent/liberator": "^2.0", "league/oauth2-client": "^2.2", "mediact/dependency-guard": "^1.0", + "mockery/mockery": "dev-master", "phpstan/phpstan": "^0.10.1", "phpunit/phpunit": "^7.3" } diff --git a/examples/Activity.php b/examples/Activity.php new file mode 100644 index 00000000..d71dcb1f --- /dev/null +++ b/examples/Activity.php @@ -0,0 +1,358 @@ + accessrules = 0 +if ($executeListAllWithFilter) { + $options = array('accessrules' => 0); + + try { + $activities = $activityApiConnector->listAll("A*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $activities = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activities);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $activities = $activityApiConnector->listAll(); + } catch (ResponseException $e) { + $activities = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activities);
+    echo "
"; +} + +/* Activity + * \PhpTwinfield\Activity + * Available getters: getBehaviour, getCode, getInUse, getMessages, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUID, getVatCode, hasMessages, getProjects + * Available setters: fromCode, setBehaviour, setCode, setName, setOffice, setShortName, setStatus, setType, setVatCode, setProjects + */ + +/* ActivityProjects + * \PhpTwinfield\ActivityProjects + * Available getters: getAuthoriser, getAuthoriserToString, getAuthoriserInherit, getAuthoriserInheritToString, getAuthoriserLocked, getAuthoriserLockedToString, getBillable, getBillableToString, getBillableForRatio, getBillableForRatioToString, + * getBillableInherit, getBillableInheritToString, getBillableLocked, getBillableLockedToString, getCustomer, getCustomerToString, getCustomerInherit, getCustomerInheritToString, getCustomerLocked, getCustomerLockedToString, getInvoiceDescription, getMessages, + * getRate, getRateToString, getRateInherit, getRateInheritToString, getRateLocked, getRateLockedToString, getResult, getValidFrom, getValidTill, hasMessages, getQuantities + * + * Available setters: setAuthoriser, setAuthoriserInherit, setAuthoriserLocked, setBillable, setBillableForRatio, setBillableInherit, setBillableLocked, setCustomer, setCustomerInherit, setCustomerLocked, setInvoiceDescription, setRate, setRateInherit, + * setRateLocked, setValidFrom, setValidTill, addQuantity, removeQuantity + * + */ + +/* ActivityQuantity + * \PhpTwinfield\ActivityQuantity + * Available getters: getBillable, getBillableToString, getBillableLocked, getBillableLockedToString, getLabel, getMandatory, getMessages, getRate, getRateToString, getResult, hasMessages + * Available setters: setBillable, setBillableLocked, setLabel, setMandatory, setRate + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($activities as $key => $activity) { + echo "Activity {$key}
"; + echo "Code: {$activity->getCode()}
"; + echo "Name: {$activity->getName()}

"; + } +} + +// Read an Activity based off the passed in code and optionally the office. +if ($executeRead) { + try { + $activity = $activityApiConnector->get("A000", $office); + } catch (ResponseException $e) { + $activity = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activity);
+    echo "
"; + + echo "Activity
"; + echo "Behaviour: {$activity->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$activity->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + echo "InUse (bool): {$activity->getInUse()}
"; // bool|null Indicates whether the activity is used in a transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($activity->getInUse()) . "
"; // string|null + + if ($activity->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($activity->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$activity->getName()}
"; // string|null Activity description. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($activity->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($activity->getOffice()) . "
"; // string|null + echo "Result: {$activity->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$activity->getShortName()}
"; // string|null Short activity description. + echo "Status: {$activity->getStatus()}
"; // Status|null Status of the activity. + echo "Touched: {$activity->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($activity->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of activities is ACT. + echo "Type (string): " . Util::objectToStr($activity->getType()) . "
"; // string|null + echo "UID: {$activity->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($activity->getVatCode(), true) . "

"; // VatCode|null The VAT code if one code will apply for all activities within the project. Note that if any VAT codes are + echo "VatCode (string): " . Util::objectToStr($activity->getVatCode()) . "
"; // string|null defined on activity level, these will apply regardless of what is defined on project level. + + $activityProjects = $activity->getProjects(); // ActivityProjects|null ActivityProjects object. + + echo "Authoriser (\\PhpTwinfield\\User):
" . print_r($activityProjects->getAuthoriser(), true) . "

"; // User|null A specific authoriser for an activity. + echo "Authoriser (string): " . Util::objectToStr($activityProjects->getAuthoriser()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Authoriser Inherit (bool): {$activityProjects->getAuthoriserInherit()}
"; // bool|null + echo "Authoriser Inherit (string): " . Util::formatBoolean($activityProjects->getAuthoriserInherit()) . "
"; // string|null If "change" = disallow then locked = true and inherit = false + echo "Authoriser Locked (bool): {$activityProjects->getAuthoriserLocked()}
"; // bool|null + echo "Authoriser Locked (string): " . Util::formatBoolean($activityProjects->getAuthoriserLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Billable (bool): {$activityProjects->getBillable()}
"; // bool|null Choose to make an activity billable (true) or not (false) and whether or not it should be included when calculating the "productivity" ratio (@forratio). + echo "Billable (string): " . Util::formatBoolean($activityProjects->getBillable()) . "
"; // string|null You could also decide that these settings should be inherited from project or user level (@inherit). + echo "Billable ForRatio (bool): {$activityProjects->getBillableForRatio()}
"; // bool|null You can also set whether a change of these settings is allowed or disallowed when a user is entering their timesheet (@locked). + echo "Billable ForRatio (string): " . Util::formatBoolean($activityProjects->getBillableForRatio()) . "
"; // string|null If "change" = allow then locked = false and inherit = false. + echo "Billable Inherit (bool): {$activityProjects->getBillableInherit()}
"; // bool|null + echo "Billable Inherit (string): " . Util::formatBoolean($activityProjects->getBillableInherit()) . "
"; // string|null If "change" = disallow then locked = true and inherit = false. + echo "Billable Locked (bool): {$activityProjects->getBillableLocked()}
"; // bool|null + echo "Billable Locked (string): " . Util::formatBoolean($activityProjects->getBillableLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Customer (\\PhpTwinfield\\Customer):
" . print_r($activityProjects->getCustomer(), true) . "

"; // Customer|null An activity always needs to be linked to a customer. + echo "Customer (string): " . Util::objectToStr($activityProjects->getCustomer()) . "
"; // string|null Choose to have the customer ‘inherited’ (from a project) or you can specify the customer here. + echo "Customer Inherit (bool): {$activityProjects->getCustomerInherit()}
"; // bool|null + echo "Customer Inherit (string): " . Util::formatBoolean($activityProjects->getCustomerInherit()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Customer Locked (bool): {$activityProjects->getCustomerLocked()}
"; // bool|null If "change" = disallow then locked = true and inherit = false + echo "Customer Locked (string): " . Util::formatBoolean($activityProjects->getCustomerLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Invoice Description: {$activityProjects->getInvoiceDescription()}
"; // string|null This field can be used to enter a longer activity description which will be available on the invoice template. + + if ($activityProjects->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($activityProjects->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Rate (\\PhpTwinfield\\Rate):
" . print_r($activityProjects->getRate(), true) . "

"; // Rate|null Choose to define a specific rate code here or you could also decide that these settings should be inherited from project or user level (@inherit). + echo "Rate (string): " . Util::objectToStr($activityProjects->getRate()) . "
"; // string|null You can also set whether a change of the rate code is allowed or disallowed when a user is entering their timesheet (@locked). + echo "Rate Inherit (bool): {$activityProjects->getRateInherit()}
"; // bool|null + echo "Rate Inherit (string): " . Util::formatBoolean($activityProjects->getRateInherit()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Rate Locked (bool): {$activityProjects->getRateLocked()}
"; // bool|null If "change" = disallow then locked = true and inherit = false + echo "Rate Locked (string): " . Util::formatBoolean($activityProjects->getRateLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Result: {$activityProjects->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Valid From (\\DateTimeInterface):
" . print_r($activityProjects->getValidFrom(), true) . "

"; // DateTimeInterface|null An activity can be set to only be valid for certain dates. Users will then only be able to book hours to the activity during these dates. + echo "Valid From (string): " . Util::formatDate($activityProjects->getValidFrom()) . "
"; // string|null + echo "Valid Till (\\DateTimeInterface):
" . print_r($activityProjects->getValidTill(), true) . "

"; // DateTimeInterface|null An activity can be set to only be valid for certain dates. Users will then only be able to book hours to the activity during these dates. + echo "Valid Till (string): " . Util::formatDate($activityProjects->getValidTill()) . "
"; // string|null + + $activityQuantities = $activityProjects->getQuantities(); // array|null Array of ActivityQuantity objects. + + foreach ($activityQuantities as $key => $activityQuantity) { + echo "ActivityQuantity {$key}
"; + + echo "Billable (bool): {$activityQuantity->getBillable()}
"; // bool|null Is the quantity line billable or not. + echo "Billable (string): " . Util::formatBoolean($activityQuantity->getBillable()) . "
"; // string|null If "billable" = true and "change is not allowed" then locked = true + echo "Billable Locked (bool): {$activityQuantity->getBillableLocked()}
"; // bool|null If "billable" = true and "change is allowed" then locked = false + echo "Billable Locked (string): " . Util::formatBoolean($activityQuantity->getBillableLocked()) . "
"; // string|null + + if ($activityQuantity->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($activityQuantity->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Label: {$activityQuantity->getLabel()}
"; // string|null The label of the quantity. + echo "Mandatory (bool): {$activityQuantity->getMandatory()}
"; // bool|null Is the quantity line mandatory or not. + echo "Mandatory (string): " . Util::formatBoolean($activityQuantity->getMandatory()) . "
"; // string|null + echo "Rate (\\PhpTwinfield\\Rate):
" . print_r($activityQuantity->getRate(), true) . "

"; // Rate|null The rate. + echo "Rate (string): " . Util::objectToStr($activityQuantity->getRate()) . "
"; // string|null + echo "Result: {$activityQuantity->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + } +} + +// Copy an existing Activity to a new entity +if ($executeCopy) { + try { + $activity = $activityApiConnector->get("A000", $office); + } catch (ResponseException $e) { + $activity = $e->getReturnedObject(); + } + + $activity->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$activity->setCode('A100'); // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + + try { + $activityCopy = $activityApiConnector->send($activity); + } catch (ResponseException $e) { + $activityCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activityCopy);
+    echo "
"; + + echo "Result of copy process: {$activityCopy->getResult()}
"; + echo "Code of copied Activity: {$activityCopy->getCode()}
"; + echo "Status of copied Activity: {$activityCopy->getStatus()}
"; +} + +// Create a new Activity from scratch, alternatively read an existing Activity as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $activity = new \PhpTwinfield\Activity; + + // Required values for creating a new Activity + $activity->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$activity->setCode('A100'); // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + $activity->setName("Example Activity"); // string|null Activity description. + $activity->setOffice($office); // Office|null Office code. + $activity->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Activity + $activity->setShortName("ExmplAct"); // string|null Short activity description. + //$activity->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$activity->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case an activity is in use, its status has been changed into hide. Hidden activities can be activated by using active. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $activity->setVatCode($vatCode); // VatCode|null The VAT code if one code will apply for all activities within the project. Note that if any VAT codes are + $activity->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null defined on activity level, these will apply regardless of what is defined on project level. + + $activityProjects = new \PhpTwinfield\ActivityProjects; + + $authoriser = new \PhpTwinfield\User; + $authoriser->setCode('TWINAPPS'); + $activityProjects->setAuthoriser($authoriser); // User|null A specific authoriser for an activity. + $activityProjects->setAuthoriser(\PhpTwinfield\User::fromCode('TWINAPPS')); // string|null If "change" = allow then locked = false and inherit = false + $activityProjects->setAuthoriserInherit(false); // bool|null + $activityProjects->setAuthoriserLocked(false); // bool|null + $activityProjects->setBillable(false); // bool|null Choose to make an activity billable (true) or not (false) and whether or not it should be included when calculating the "productivity" ratio (@forratio). + $activityProjects->setBillableForRatio(false); // bool|null You can also set whether a change of these settings is allowed or disallowed when a user is entering their timesheet (@locked). + $activityProjects->setBillableInherit(false); // bool|null + $activityProjects->setBillableLocked(false); // bool|null + $customer = new \PhpTwinfield\Customer; + $customer->setCode('1000'); + //$activityProjects->setCustomer($customer); // Customer|null An activity always needs to be linked to a customer. + //$activityProjects->setCustomer(\PhpTwinfield\Customer::fromCode('1000')); // string|null Choose to have the customer ‘inherited’ (from a project) or you can specify the customer here. + $activityProjects->setCustomerInherit(true); // bool|null + $activityProjects->setCustomerLocked(true); // bool|null If "change" = disallow then locked = true and inherit = false + $activityProjects->setInvoiceDescription('Example Invoice Description'); // string|null This field can be used to enter a longer activity description which will be available on the invoice template. + $rate = new \PhpTwinfield\Rate; + $rate->setCode('DIRECT'); + $activityProjects->setRate($rate); // Rate|null Choose to define a specific rate code here or you could also decide that these settings should be inherited from project or user level (@inherit). + $activityProjects->setRate(\PhpTwinfield\Rate::fromCode('DIRECT')); // string|null You can also set whether a change of the rate code is allowed or disallowed when a user is entering their timesheet (@locked). + $activityProjects->setRateInherit(false); // bool|null + $activityProjects->setRateLocked(true); // bool|null If "change" = disallow then locked = true and inherit = false + $validFrom = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $activityProjects->setValidFrom($validFrom); // DateTimeInterface|null An activity can be set to only be valid for certain dates. Users will then only be able to book hours to the activity during these dates. + $activityProjects->setValidFrom(Util::parseDate('20190101')); // string|null + $validTill = \DateTime::createFromFormat('d-m-Y', '31-12-2019'); + $activityProjects->setValidTill($validTill); // DateTimeInterface|null An activity can be set to only be valid for certain dates. Users will then only be able to book hours to the activity during these dates. + $activityProjects->setValidTill(Util::parseDate('20191231')); // string|null + + // The minimum amount of ActivityQuantities linked to an ActivityProjects object is 0, the maximum amount is 4 + $activityQuantity = new \PhpTwinfield\ActivityQuantity; + $activityQuantity->setBillable(false); // bool|null Is the quantity line billable or not. + $activityQuantity->setBillableLocked(false); // bool|null + $activityQuantity->setLabel('Example Quantity'); // string|null + $activityQuantity->setMandatory(false); // bool|null Is the quantity line mandatory or not. + $rate = new \PhpTwinfield\Rate; + $rate->setCode('KILOMETERS'); + $activityQuantity->setRate($rate); // Rate|null The rate. + $activityQuantity->setRate(\PhpTwinfield\Rate::fromCode('KILOMETERS')); // string|null + + $activityProjects->addQuantity($activityQuantity); // ActivityQuantity Add an ActivityQuantity object to the ActivityProjects object + //$activityProjects->removeQuantity(0); // int Remove a quantity based on the index of the quantity within the array + + $activity->setProjects($activityProjects); // ActivityProjects Set the ActivityProjects object tot the Activity object + + try { + $activityNew = $activityApiConnector->send($activity); + } catch (ResponseException $e) { + $activityNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activityNew);
+    echo "
"; + + echo "Result of creation process: {$activityNew->getResult()}
"; + echo "Code of new Activity: {$activityNew->getCode()}
"; + echo "Status of new Activity: {$activityNew->getStatus()}
"; +} + +// Delete an Activity based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $activityDeleted = $activityApiConnector->delete("A100", $office); + } catch (ResponseException $e) { + $activityDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($activityDeleted);
+    echo "
"; + + echo "Result of deletion process: {$activityDeleted->getResult()}
"; + echo "Code of deleted Activity: {$activityDeleted->getCode()}
"; + echo "Status of deleted Activity: {$activityDeleted->getStatus()}
"; +} diff --git a/examples/Article.php b/examples/Article.php new file mode 100644 index 00000000..79c62b5b --- /dev/null +++ b/examples/Article.php @@ -0,0 +1,305 @@ + vat = 'inclusive' +if ($executeListAllWithFilter) { + $options = array('vat' => 'inclusive'); + + try { + $articles = $articleApiConnector->listAll("O*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $articles = $e->getReturnedObject(); + } + + echo "
";
+    print_r($articles);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $articles = $articleApiConnector->listAll(); + } catch (ResponseException $e) { + $articles = $e->getReturnedObject(); + } + + echo "
";
+    print_r($articles);
+    echo "
"; +} + +/* Article + * \PhpTwinfield\Article + * Available getters: getAllowChangePerformanceType, getAllowChangeUnitsPrice, getAllowChangeVatCode, getAllowDecimalQuantity, getAllowDiscountOrPremium, + * getAllowDiscountOrPremiumToString, getCode, getMessages, getName, getOffice, getPercentage, getPerformanceType, getResult, getShortName, getStatus, getType, getUnitNamePlural, getUnitNameSingular, getVatCode, hasMessages, getLines + * + * Available setters: fromCode, setAllowChangePerformanceType, setAllowChangeUnitsPrice, setAllowChangeVatCode, setAllowDecimalQuantity, setAllowDiscountOrPremium, + * setCode, setName, setOffice, setPercentage, setPerformanceType, setShortName, setStatus, setType, setUnitNamePlural, setUnitNameSingular, setVatCode, addLine, removeLine + * + */ + +/* ArticleLine + * \PhpTwinfield\ArticleLine + * Available getters: getFreeText1, getFreeText2, getFreeText3, getID, getInUse, getMessages, getName, getResult, getShortName, getStatus, getSubCode, getUnits, getUnitsPriceExcl, getUnitsPriceInc, hasMessages + * Available setters: setFreeText1, setFreeText2, setFreeText3, setID, setName, setShortName, setStatus, setSubCode, setUnits, setUnitsPriceExcl, setUnitsPriceInc + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($articles as $key => $article) { + echo "Article {$key}
"; + echo "Code: {$article->getCode()}
"; + echo "Name: {$article->getName()}

"; + } +} + +// Read an Article based off the passed in code and optionally the office. +if ($executeRead) { + try { + $article = $articleApiConnector->get("9060", $office); + } catch (ResponseException $e) { + $article = $e->getReturnedObject(); + } + + echo "
";
+    print_r($article);
+    echo "
"; + + echo "Article
"; + echo "AllowChangePerformanceType (bool): {$article->getAllowChangePerformanceType()}
"; // bool|null Is it allowed to change the performance type. + echo "AllowChangePerformanceType (string): " . Util::formatBoolean($article->getAllowChangePerformanceType()) . "
"; // string|null + echo "AllowChangeUnitsPrice (bool): {$article->getAllowChangeUnitsPrice()}
"; // bool|null Is it allowed to change the units price. + echo "AllowChangeUnitsPrice (string): " . Util::formatBoolean($article->getAllowChangeUnitsPrice()) . "
"; // string|null + echo "AllowChangeVatCode (bool): {$article->getAllowChangeVatCode()}
"; // bool|null Is it allowed to change the VAT. + echo "AllowChangeVatCode (string): " . Util::formatBoolean($article->getAllowChangeVatCode()) . "
"; // string|null + echo "AllowDecimalQuantity (bool): {$article->getAllowDecimalQuantity()}
"; // bool|null Are decimals allowed. + echo "AllowDecimalQuantity (string): " . Util::formatBoolean($article->getAllowDecimalQuantity()) . "
"; // string|null + echo "AllowDiscountOrPremium (bool): {$article->getAllowDiscountOrPremium()}
"; // bool|null Is discount or premium allowed. + echo "AllowDiscountOrPremium (string): " . Util::formatBoolean($article->getAllowDiscountOrPremium()) . "
"; // string|null + echo "Code: {$article->getCode()}
"; // string|null Article code. + + if ($article->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($article->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$article->getName()}
"; // string|null Article description. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($article->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($article->getOffice()) . "
"; // string|null + echo "Percentage (bool): {$article->getPercentage()}
"; // bool|null Only available when article type is discount or premium. + echo "Percentage (string): " . Util::formatBoolean($article->getPercentage()) . "
"; // string|null + echo "PerformanceType: {$article->getPerformanceType()}
"; // PerformanceType|null The performance type. + echo "Result: {$article->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$article->getShortName()}
"; // string|null Short article description. + echo "Status: {$article->getStatus()}
"; // Status|null Status of the article. + echo "Type: {$article->getType()}
"; // ArticleType|null Set to normal in case special item is none. Set to either discount or premium in case special item is deduction or premium respectively. + echo "UnitNamePlural: {$article->getUnitNamePlural()}
"; // string|null Unit name for multiple items. + echo "UnitNameSingular: {$article->getUnitNameSingular()}
"; // string|null Unit name for a single item. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($article->getVatCode(), true) . "

"; // VatCode|null Default VAT code. + echo "VatCode (string): " . Util::objectToStr($article->getVatCode()) . "
"; // string|null + + $articleLines = $article->getLines(); // array|null Array of ArticleLine objects. + + foreach ($articleLines as $key => $articleLine) { + echo "ArticleLine {$key}
"; + + echo "FreeText1 (\\PhpTwinfield\\GeneralLedger):
" . print_r($articleLine->getFreeText1(), true) . "

"; // GeneralLedger|null Mandatory. The general ledger code linked to the article. + echo "FreeText1 (string): " . Util::objectToStr($articleLine->getFreeText1()) . "
"; // string|null + echo "FreeText2 (\\PhpTwinfield\\CostCenter):
" . print_r($articleLine->getFreeText2(), true) . "

"; // CostCenter|null Optional. The cost center linked to the article. + echo "FreeText2 (string): " . Util::objectToStr($articleLine->getFreeText2()) . "
"; // string|null + echo "FreeText3: {$articleLine->getFreeText3()}
"; // string|null Free text element 3 + echo "ID: {$articleLine->getID()}
"; // int|null Line ID + echo "InUse (bool): {$articleLine->getInUse()}
"; // bool|null Read-only attribute. Indicates that the sub item has been used in an invoice. + echo "InUse (string): " . Util::formatBoolean($articleLine->getInUse()) . "
"; // string|null + + if ($articleLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($articleLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$articleLine->getName()}
"; // string|null Sub article name. + echo "Result: {$articleLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$articleLine->getShortName()}
"; // string|null Sub article short name. + echo "Status: {$articleLine->getStatus()}
"; // Status|null Status of the sub article. + echo "SubCode: {$articleLine->getSubCode()}
"; // string|null Can only be empty if there is just one sub article + echo "Units: {$articleLine->getUnits()}
"; // int|null The number of units of the article per quantity + echo "UnitsPriceExcl (\\Money\\Money):
" . print_r($articleLine->getUnitsPriceExcl(), true) . "

"; // Money|null Price excluding VAT + echo "UnitsPriceExcl (string): " . Util::formatMoney($articleLine->getUnitsPriceExcl()) . "
"; // string|null + echo "UnitsPriceInc (\\Money\\Money):
" . print_r($articleLine->getUnitsPriceInc(), true) . "

"; // Money|null Price including VAT + echo "UnitsPriceInc (string): " . Util::formatMoney($articleLine->getUnitsPriceInc()) . "
"; // string|null + } +} + +// Copy an existing Article to a new entity +if ($executeCopy) { + try { + $article = $articleApiConnector->get("9060", $office); + } catch (ResponseException $e) { + $article = $e->getReturnedObject(); + } + + $article->setCode("9061"); + + try { + $articleCopy = $articleApiConnector->send($article); + } catch (ResponseException $e) { + $articleCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($articleCopy);
+    echo "
"; + + echo "Result of copy process: {$articleCopy->getResult()}
"; + echo "Code of copied Article: {$articleCopy->getCode()}
"; + echo "Status of copied Article: {$articleCopy->getStatus()}
"; +} + +// Create a new Article from scratch, alternatively read an existing Article as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $article = new \PhpTwinfield\Article; + + // Required values for creating a new Article + $article->setCode('9061'); // string|null Article code. + $article->setName("Example Article"); // string|null Article description. + $article->setOffice($office); // Office|null Office code. + $article->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + $article->setUnitNamePlural("Example Art Units"); // string|null Unit name for multiple items + $article->setUnitNameSingular("Example Art Unit"); // string|null Unit name for a single item + + // Optional values for creating a new Article + $article->setAllowChangePerformanceType(true); // bool|null Is it allowed to change the performance type. + $article->setAllowChangeUnitsPrice(true); // bool|null Is it allowed to change the units price. + $article->setAllowChangeVatCode(true); // bool|null Is it allowed to change the VAT. + $article->setAllowDecimalQuantity(true); // bool|null Are decimals allowed. + $article->setAllowDiscountOrPremium(true); // bool|null Is discount or premium allowed. + $article->setPercentage(false); // bool|null Only available when article type is discount or premium + $article->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null The performance type. + $article->setShortName("ExmplArt"); // string|null Short article description. + //$article->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$article->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case an article is in use, its status has been changed into hide. Hidden articles can be activated by using active. + $article->setType(\PhpTwinfield\Enums\ArticleType::NORMAL()); // ArticleType|null Set to normal in case special item is none. Set to either discount or premium in case special item is deduction or premium respectively. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $article->setVatCode($vatCode); // VatCode|null Default VAT code + $article->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + // The minimum amount of ArticleLines linked to an Article object is 1 + $articleLine = new \PhpTwinfield\ArticleLine; + + $freeText1 = new \PhpTwinfield\GeneralLedger; + $freeText1->setCode('9060'); + $articleLine->setFreeText1($freeText1); // GeneralLedger|null Mandatory. The general ledger code linked to the article. + $articleLine->setFreeText1(\PhpTwinfield\GeneralLedger::fromCode('9060')); // string|null + $freeText2 = new \PhpTwinfield\CostCenter; + $freeText2->setCode('00000'); + //$articleLine->setFreeText2($freeText1); // CostCenter|null Optional. The cost center linked to the article. + //$articleLine->setFreeText2(\PhpTwinfield\CostCenter::fromCode('00000')); // string|null + //$articleLine->setFreeText3(""); // string|null Free text element 3 + $articleLine->setID(1); // int|null Line ID. + $articleLine->setName("Example Sub Article"); // string|null Sub article name. + $articleLine->setShortName("ExmplSubArt"); // string|null Sub article short name. + + $articleLine->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null Allows you to delete sub items and to recover them (if sub item is @inuse). + //$articleLine->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + $articleLine->setSubCode('9061'); // string|null Can only be empty if there is just one sub article + $articleLine->setUnits(1); // int|null The number of units of the article per quantity + $articleLine->setUnitsPriceExcl(\Money\Money::EUR(1000)); // Money|null Price excluding VAT (equals 10.00 EUR) + //$articleLine->setUnitsPriceInc(\Money\Money::EUR(1210)); // Money|null Price including VAT (equals 12.10 EUR) + + $article->addLine($articleLine); // ArticleLine Add an ArticleLine object to the Article object + //$article->removeLine(0); // int Remove an article line based on the index of the article line + + try { + $articleNew = $articleApiConnector->send($article); + } catch (ResponseException $e) { + $articleNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($articleNew);
+    echo "
"; + + echo "Result of creation process: {$articleNew->getResult()}
"; + echo "Code of new Article: {$articleNew->getCode()}
"; + echo "Status of new Article: {$articleNew->getStatus()}
"; +} + +// Delete a Article based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $articleDeleted = $articleApiConnector->delete("9061", $office); + } catch (ResponseException $e) { + $articleDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($articleDeleted);
+    echo "
"; + + echo "Result of deletion process: {$articleDeleted->getResult()}
"; + echo "Code of deleted Article: {$articleDeleted->getCode()}
"; + echo "Status of deleted Article: {$articleDeleted->getStatus()}
"; +} diff --git a/examples/AssetMethod.php b/examples/AssetMethod.php new file mode 100644 index 00000000..0c5b9030 --- /dev/null +++ b/examples/AssetMethod.php @@ -0,0 +1,355 @@ +listAll("10*", 0, 1, 10); + } catch (ResponseException $e) { + $assetMethods = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethods);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $assetMethods = $assetMethodApiConnector->listAll(); + } catch (ResponseException $e) { + $assetMethods = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethods);
+    echo "
"; +} + +/* AssetMethod + * \PhpTwinfield\AssetMethod + * Available getters: getCalcMethod, getCode, getCreated, getDepreciateReconciliation, getInUse, getMessages, getModified, getName, getNrOfPeriods, getOffice, getPercentage, getResult, getShortName, getStatus, getTouched, getUser, hasMessages, getBalanceAccounts, getFreeTexts, getProfitLossAccounts + * Available setters: fromCode, setBalanceAccounts, setCalcMethod, setCode, setDepreciateReconciliation, setName, setNrOfPeriods, setOffice, setPercentage, setProfitLossAccounts, setShortName, setStatus, addFreeText, removeFreeText + */ + +/* AssetMethodBalanceAccounts + * \PhpTwinfield\AssetMethodBalanceAccounts + * Available getters: getAssetsToActivate, getDepreciation, getDepreciationGroup, getMessages, getPurchaseValue, getPurchaseValueGroup, getReconciliation, getResult, getToBeInvoiced, hasMessages + * Available setters: setAssetsToActivate, setDepreciation, setDepreciationGroup, setPurchaseValue, setPurchaseValueGroup, setReconciliation, setToBeInvoiced + */ + +/* AssetMethodProfitLossAccounts + * \PhpTwinfield\AssetMethodProfitLossAccounts + * Available getters: getDepreciation, getMessages, getReconciliation, getResult, getSales, hasMessages + * Available setters: setDepreciation, setReconciliation, setSales + */ + +/* AssetMethodFreeText + * \PhpTwinfield\AssetMethodFreeText + * Available getters: getElementValue, getID, getMessages, getResult, getType, hasMessages + * Available setters: setElementValue, setID, setType + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($assetMethods as $key => $assetMethod) { + echo "AssetMethod {$key}
"; + echo "Code: {$assetMethod->getCode()}
"; + echo "Name: {$assetMethod->getName()}

"; + } +} + +// Read an AssetMethod based off the passed in code and optionally the office. +if ($executeRead) { + try { + $assetMethod = $assetMethodApiConnector->get("101", $office); + } catch (ResponseException $e) { + $assetMethod = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethod);
+    echo "
"; + + echo "AssetMethod
"; + echo "CalcMethod: {$assetMethod->getCalcMethod()}
"; // CalcMethod|null The calculation method. + echo "Code: {$assetMethod->getCode()}
"; // string|null Asset method code. + echo "Created (\\DateTimeInterface):
" . print_r($assetMethod->getCreated(), true) . "

"; // \DateTimeInterface|null Date/time the asset method is created. + echo "Created (string): " . Util::formatDate($assetMethod->getCreated()) . "
"; // string|null + echo "DepreciateReconciliation: {$assetMethod->getDepreciateReconciliation()}
"; // DepreciateReconciliation|null Depreciate as of the revaluation date. Depreciate in retrospect, back to the purchase date. + echo "InUse (bool): {$assetMethod->getInUse()}
"; // bool|null + echo "InUse (string): " . Util::formatBoolean($assetMethod->getInUse()) . "
"; // string|null + + if ($assetMethod->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($assetMethod->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Modified (\\DateTimeInterface):
" . print_r($assetMethod->getModified(), true) . "

"; // \DateTimeInterface|null Date/time the asset method is modified the last time. + echo "Modified (string): " . Util::formatDate($assetMethod->getModified()) . "
"; // string|null + echo "Name: {$assetMethod->getName()}
"; // string|null The name of the asset method. + echo "NrOfPeriods: {$assetMethod->getNrOfPeriods()}
"; // int|null The number of periods over which the asset linked to the asset method should be depreciated. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($assetMethod->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($assetMethod->getOffice()) . "
"; // string|null + echo "Percentage: {$assetMethod->getPercentage()}
"; // int|null + echo "Result: {$assetMethod->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$assetMethod->getShortName()}
"; // string|null The short name of the asset method. + echo "Status: {$assetMethod->getStatus()}
"; // Status|null Status of the asset method. + echo "Touched: {$assetMethod->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "User (\\PhpTwinfield\\User):
" . print_r($assetMethod->getUser(), true) . "

"; // User|null The user who modified the asset method the last time. + echo "User (string): " . Util::objectToStr($assetMethod->getUser()) . "
"; // string|null + + echo "AssetMethodBalanceAccounts
"; + $assetMethodBalanceAccounts = $assetMethod->getBalanceAccounts(); // AssetMethodBalanceAccounts|null AssetMethodBalanceAccounts object. + + echo "AssetsToActivate (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodBalanceAccounts->getAssetsToActivate(), true) . "

"; // GeneralLedger|null Assets to activate balance sheet. + echo "AssetsToActivate (string): " . Util::objectToStr($assetMethodBalanceAccounts->getAssetsToActivate()) . "
"; // string|null + echo "Depreciation (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodBalanceAccounts->getDepreciation(), true) . "

"; // GeneralLedger|null Cumulative depreciation balance sheet. + echo "Depreciation (string): " . Util::objectToStr($assetMethodBalanceAccounts->getDepreciation()) . "
"; // string|null + echo "DepreciationGroup (\\PhpTwinfield\\DimensionGroup):
" . print_r($assetMethodBalanceAccounts->getDepreciationGroup(), true) . "

"; // DimensionGroup|null Depreciation group. + echo "DepreciationGroup (string): " . Util::objectToStr($assetMethodBalanceAccounts->getDepreciationGroup()) . "
"; // string|null + + if ($assetMethodBalanceAccounts->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($assetMethodBalanceAccounts->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PurchaseValue (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodBalanceAccounts->getPurchaseValue(), true) . "

"; // GeneralLedger|null Purchase value balance sheet. + echo "PurchaseValue (string): " . Util::objectToStr($assetMethodBalanceAccounts->getPurchaseValue()) . "
"; // string|null + echo "PurchaseValueGroup (\\PhpTwinfield\\DimensionGroup):
" . print_r($assetMethodBalanceAccounts->getPurchaseValueGroup(), true) . "

"; // DimensionGroup|null Purchase value group. + echo "PurchaseValueGroup (string): " . Util::objectToStr($assetMethodBalanceAccounts->getPurchaseValueGroup()) . "
"; // string|null + echo "Reconciliation (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodBalanceAccounts->getReconciliation(), true) . "

"; // GeneralLedger|null Revaluation of purchase value balance sheet. + echo "Reconciliation (string): " . Util::objectToStr($assetMethodBalanceAccounts->getReconciliation()) . "
"; // string|null + echo "Result: {$assetMethodBalanceAccounts->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ToBeInvoiced (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodBalanceAccounts->getToBeInvoiced(), true) . "

"; // GeneralLedger|null Disposal value to be invoiced balance sheet. + echo "ToBeInvoiced (string): " . Util::objectToStr($assetMethodBalanceAccounts->getToBeInvoiced()) . "
"; // string|null + + echo "AssetMethodProfitLossAccounts
"; + $assetMethodProfitLossAccounts = $assetMethod->getProfitLossAccounts(); // AssetMethodProfitLossAccounts|null AssetMethodProfitLossAccounts object. + + echo "Depreciation (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodProfitLossAccounts->getDepreciation(), true) . "

"; // GeneralLedger|null Depreciation costs profit and loss account. + echo "Depreciation (string): " . Util::objectToStr($assetMethodProfitLossAccounts->getDepreciation()) . "
"; // string|null + + if ($assetMethodProfitLossAccounts->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($assetMethodProfitLossAccounts->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Reconciliation (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodProfitLossAccounts->getReconciliation(), true) . "

"; // GeneralLedger|null Revaluation reserve profit and loss account. + echo "Reconciliation (string): " . Util::objectToStr($assetMethodProfitLossAccounts->getReconciliation()) . "
"; // string|null + echo "Result: {$assetMethodProfitLossAccounts->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Sales (\\PhpTwinfield\\GeneralLedger):
" . print_r($assetMethodProfitLossAccounts->getSales(), true) . "

"; // GeneralLedger|null Disposal result profit and loss account. + echo "Sales (string): " . Util::objectToStr($assetMethodProfitLossAccounts->getSales()) . "
"; // string|null + + $assetMethodFreeTexts = $assetMethod->getFreeTexts(); // array|null Array of AssetMethodFreeText objects. + + foreach ($assetMethodFreeTexts as $key => $assetMethodFreeText) { + echo "AssetMethodFreeText {$key}
"; + + echo "ElementValue: {$assetMethodFreeText->getElementValue()}
"; // string|null Free text. + echo "ID: {$assetMethodFreeText->getID()}
"; // int|null Free text id. In total, five free text fields are available. + + if ($assetMethodFreeText->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($assetMethodFreeText->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$assetMethodFreeText->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Type: {$assetMethodFreeText->getType()}
"; // FreeTextType|null Free text type. + } +} + +// Copy an existing AssetMethod to a new entity +if ($executeCopy) { + try { + $assetMethod = $assetMethodApiConnector->get("101", $office); + } catch (ResponseException $e) { + $assetMethod = $e->getReturnedObject(); + } + + $assetMethod->setCode('102'); // string|null Dimension code, must be compliant with the mask of the BAS or PNL Dimension type. + + try { + $assetMethodCopy = $assetMethodApiConnector->send($assetMethod); + } catch (ResponseException $e) { + $assetMethodCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethodCopy);
+    echo "
"; + + echo "Result of copy process: {$assetMethodCopy->getResult()}
"; + echo "Code of copied AssetMethod: {$assetMethodCopy->getCode()}
"; + echo "Status of copied AssetMethod: {$assetMethodCopy->getStatus()}
"; +} + +// Create a new AssetMethod from scratch, alternatively read an existing AssetMethod as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $assetMethod = new \PhpTwinfield\AssetMethod; + + // Required values for creating a new AssetMethod + $assetMethod->setCalcMethod(\PhpTwinfield\Enums\CalcMethod::NONE()); // CalcMethod|null The calculation method. + $assetMethod->setCode('102'); // string|null + $assetMethod->setName("Example AssetMethod"); // string|null The name of the asset method. + $assetMethod->setOffice($office); // Office|null Office code. + $assetMethod->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + $assetMethodBalanceAccounts = new \PhpTwinfield\AssetMethodBalanceAccounts; + + $depreciation = new \PhpTwinfield\GeneralLedger; + $depreciation->setCode('0150'); + $assetMethodBalanceAccounts->setDepreciation($depreciation); // GeneralLedger|null Cumulative depreciation balance sheet. + $assetMethodBalanceAccounts->setDepreciation(\PhpTwinfield\GeneralLedger::fromCode('0150')); // string|null + $purchasevalue = new \PhpTwinfield\GeneralLedger; + $purchasevalue->setCode('0155'); + $assetMethodBalanceAccounts->setPurchaseValue($purchasevalue); // GeneralLedger|null Purchase value balance sheet. + $assetMethodBalanceAccounts->setPurchaseValue(\PhpTwinfield\GeneralLedger::fromCode('0155')); // string|null + + $assetMethod->setBalanceAccounts($assetMethodBalanceAccounts); // AssetMethodBalanceAccounts Set the AssetMethodBalanceAccounts object tot the AssetMethod object + + $assetMethodProfitLossAccounts = new \PhpTwinfield\AssetMethodProfitLossAccounts; + + $depreciation = new \PhpTwinfield\GeneralLedger; + $depreciation->setCode('4750'); + $assetMethodProfitLossAccounts->setDepreciation($depreciation); // GeneralLedger|null Depreciation costs profit and loss account. + $assetMethodProfitLossAccounts->setDepreciation(\PhpTwinfield\GeneralLedger::fromCode('4750')); // string|null + + $assetMethod->setProfitLossAccounts($assetMethodProfitLossAccounts); // AssetMethodProfitLossAccounts Set the AssetMethodProfitLossAccounts object tot the AssetMethod object + + // Optional values for creating a new AssetMethod + //$assetMethod->setDepreciateReconciliation(\PhpTwinfield\Enums\DepreciateReconciliation::FROMPURCHASEDATE()); // DepreciateReconciliation|null Depreciate as of the revaluation date. Depreciate in retrospect, back to the purchase date. + //$assetMethod->setNrOfPeriods(1); // int|null The number of periods over which the asset linked to the asset method should be depreciated. + //$assetMethod->setPercentage(1); // int|null + $assetMethod->setShortName("ExmplAsstMthd"); // string|null The short name of the asset method. + $assetMethod->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$assetMethod->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case a dimension that is used in a transaction is deleted, its status has been changed into hide. Hidden dimensions can be activated by using active. + + $assetsToActivate = new \PhpTwinfield\GeneralLedger; + $assetsToActivate->setCode('0180'); + //$assetMethodBalanceAccounts->setAssetsToActivate($assetsToActivate); // GeneralLedger|null Assets to activate balance sheet. + //$assetMethodBalanceAccounts->setAssetsToActivate(\PhpTwinfield\GeneralLedger::fromCode('0180')); // string|null + $depreciationGroup = new \PhpTwinfield\DimensionGroup; + $depreciationGroup->setCode('EXAMPLEGRP'); + //$assetMethodBalanceAccounts->setDepreciationGroup($depreciationGroup); // DimensionGroup|null Depreciation group. + //$assetMethodBalanceAccounts->setDepreciationGroup(\PhpTwinfield\DimensionGroup::fromCode('EXAMPLEGRP')); // string|null + $purchasevalueGroup = new \PhpTwinfield\DimensionGroup; + $purchasevalueGroup->setCode('EXAMPLEGRP'); + //$assetMethodBalanceAccounts->setPurchaseValueGroup($purchasevalueGroup); // DimensionGroup|null Purchase value group. + //$assetMethodBalanceAccounts->setPurchaseValueGroup(\PhpTwinfield\DimensionGroup::fromCode('EXAMPLEGRP')); // string|null + $reconciliation = new \PhpTwinfield\GeneralLedger; + $reconciliation->setCode('0845'); + //$assetMethodBalanceAccounts->setReconciliation($reconciliation); // GeneralLedger|null Revaluation of purchase value balance sheet. + //$assetMethodBalanceAccounts->setReconciliation(\PhpTwinfield\GeneralLedger::fromCode('0845')); // string|null + $toBeInvoiced = new \PhpTwinfield\GeneralLedger; + $toBeInvoiced->setCode('1260'); + //$assetMethodBalanceAccounts->setToBeInvoiced($toBeInvoiced); // GeneralLedger|null Disposal value to be invoiced balance sheet. + //$assetMethodBalanceAccounts->setToBeInvoiced(\PhpTwinfield\GeneralLedger::fromCode('1260')); // string|null + + $assetMethod->setBalanceAccounts($assetMethodBalanceAccounts); // AssetMethodBalanceAccounts Set the AssetMethodBalanceAccounts object tot the AssetMethod object + + $reconciliation = new \PhpTwinfield\GeneralLedger; + $reconciliation->setCode('0845'); + //$assetMethodProfitLossAccounts->setReconciliation($reconciliation); // GeneralLedger|null Revaluation reserve profit and loss account. + //$assetMethodProfitLossAccounts->setReconciliation(\PhpTwinfield\GeneralLedger::fromCode('0845')); // string|null + $sales = new \PhpTwinfield\GeneralLedger; + $sales->setCode('0155'); + //$assetMethodProfitLossAccounts->setSales($sales); // GeneralLedger|null Disposal result profit and loss account. + //$assetMethodProfitLossAccounts->setSales(\PhpTwinfield\GeneralLedger::fromCode('0155')); // string|null + + $assetMethod->setProfitLossAccounts($assetMethodProfitLossAccounts); // AssetMethodProfitLossAccounts Set the AssetMethodProfitLossAccounts object tot the AssetMethod object + + // The minimum amount of AssetMethodFreeTexts linked to an AssetMethod object is 0, the maximum amount is 5 + $assetMethodFreeText = new \PhpTwinfield\AssetMethodFreeText; + + $assetMethodFreeText->setID(1); // int|null Free text id. In total, five free text fields are available. + $assetMethodFreeText->setType(\PhpTwinfield\Enums\FreeTextType::TEXT()); // FreeTextType|null Free text type. + $assetMethodFreeText->setElementValue('Example free text'); // string|null Free text. + + $assetMethod->addFreeText($assetMethodFreeText); // AssetMethodFreeText Add an AssetMethodFreeText object to the AssetMethod object + //$assetMethod->removeFreeText(0); // int Remove a free text based on the index of the free text + + try { + $assetMethodNew = $assetMethodApiConnector->send($assetMethod); + } catch (ResponseException $e) { + $assetMethodNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethodNew);
+    echo "
"; + + echo "Result of creation process: {$assetMethodNew->getResult()}
"; + echo "Code of new AssetMethod: {$assetMethodNew->getCode()}
"; + echo "Status of new AssetMethod: {$assetMethodNew->getStatus()}
"; +} + +// Delete an AssetMethod based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $assetMethodDeleted = $assetMethodApiConnector->delete("102", $office); + } catch (ResponseException $e) { + $assetMethodDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($assetMethodDeleted);
+    echo "
"; + + echo "Result of deletion process: {$assetMethodDeleted->getResult()}
"; + echo "Code of deleted AssetMethod: {$assetMethodDeleted->getCode()}
"; + echo "Status of deleted AssetMethod: {$assetMethodDeleted->getStatus()}
"; +} diff --git a/examples/Authorization.php b/examples/Authorization.php new file mode 100644 index 00000000..60b3e45b --- /dev/null +++ b/examples/Authorization.php @@ -0,0 +1,113 @@ + $twin_client_id, + 'clientSecret' => $twin_client_secret, + 'redirectUri' => $twin_redirect_uri, +]); + +// If we don't have an authorization code then get one. +if (!isset($_GET['code'])) { + //Optionally limit your scope if you don't require all. + $options = [ + 'scope' => ['twf.user','twf.organisation','twf.organisationUser','offline_access','openid'] + ]; + + $authorizationUrl = $provider->getAuthorizationUrl($options); + + // Get the state generated for you and store it to the session. + $_SESSION['oauth2state'] = $provider->getState(); + + // Redirect the user to the authorization URL. + header('Location: ' . $authorizationUrl); + exit; + +// Check given state against previously stored one to mitigate CSRF attack. +} elseif (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) { + if (isset($_SESSION['oauth2state'])) { + unset($_SESSION['oauth2state']); + } + + exit('Invalid state'); +} else { + try { + // Try to get an access token using the authorization code grant. + $accessToken = $provider->getAccessToken('authorization_code', [ + 'code' => $_GET['code'] + ]); + + /* Twinfield's refresh token is valid for 550 days. + * Renewing the refresh token can be done by requesting the user to reload this page and logging into Twinfield before the refresh token is invalidated after 550 days. + * NOTE: Remember to put in place functionality to request the user to renew their authorization, see RenewAuthorization.php for an example. + */ + + $refresh_expiry = strtotime(date('Ymd') . " +550 days"); + + // Save refresh token and refresh token expiry time to storage. + $refreshTokenStorage = array(); + $refreshTokenStorage['refresh_token'] = $accessToken->getRefreshToken(); + $refreshTokenStorage['refresh_expiry'] = $refresh_expiry; + + SaveRefreshTokenToStore($refreshTokenStorage); + + /* Optionally save access token, access token expiry time and access cluster to storage. + * If you choose to use an always valid access token to login to speed up your requests you need to put in place functionality to automatically renew the access token using the save refresh token. + * As the access token is valid for 60 minutes you need to create a task scheduler/cron that runs at least once every hour, see RenewAccessToken.php for an example. + */ + + $validationUrl = "https://login.twinfield.com/auth/authentication/connect/accesstokenvalidation?token="; + $validationResult = @file_get_contents($validationUrl . urlencode($accessToken->getToken())); + + if ($validationResult !== false) { + $resultDecoded = \json_decode($validationResult, true); + $accessTokenStorage = array(); + $accessTokenStorage['access_token'] = $accessToken->getToken(); + $accessTokenStorage['access_expiry'] = $accessToken->getExpires(); + $accessTokenStorage['access_cluster'] = $resultDecoded["twf.clusterUrl"]; + + SaveAccessTokenToStore($accessTokenStorage); + } + } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) { + // Failed to get the access token or user details. + exit($e->getMessage()); + } +} diff --git a/examples/BankTransaction.php b/examples/BankTransaction.php new file mode 100644 index 00000000..f1df5c80 --- /dev/null +++ b/examples/BankTransaction.php @@ -0,0 +1,344 @@ +get(\PhpTwinfield\BankTransaction::class, "BNK", 201900011, $office); + } catch (ResponseException $e) { + $bankTransaction = $e->getReturnedObject(); + } + + echo "
";
+    print_r($bankTransaction);
+    echo "
"; + + echo "BankTransaction
"; + echo "AutoBalanceVat (bool): {$bankTransaction->getAutoBalanceVat()}
"; // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + echo "AutoBalanceVat (string): " . Util::formatBoolean($bankTransaction->getAutoBalanceVat()) . "
"; // string|null + echo "BookingReference (\\PhpTwinfield\\BookingReference):
" . print_r($bankTransaction->getBookingReference(), true) . "

"; // BookingReference|null The Booking reference + echo "CloseValue (\\Money\\Money):
" . print_r($bankTransaction->getCloseValue(), true) . "

"; // Money|null Closing balance. If not provided, the closing balance is set to zero. + echo "CloseValue (string): " . Util::formatMoney($bankTransaction->getCloseValue()) . "
"; // string|null + echo "Code: {$bankTransaction->getCode()}
"; // string|null Transaction type code. + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($bankTransaction->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($bankTransaction->getCurrency()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($bankTransaction->getDate(), true) . "

"; // DateTimeInterface|null Transaction date. + echo "Date (string): " . Util::formatDate($bankTransaction->getDate()) . "
"; // string|null + echo "DateRaiseWarning (bool): {$bankTransaction->getDateRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + echo "DateRaiseWarning (string): {$bankTransaction->getDateRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + echo "Destiny: {$bankTransaction->getDestiny()}
"; // Destiny|null Attribute to indicate the destiny of the bank transaction. Only used in the request XML. temporary = bank transaction will be saved as provisional. final = bank transaction will be saved as final. + echo "FreeText1: {$bankTransaction->getFreeText1()}
"; // string|null Free text field 1 as entered on the transaction type. + echo "FreeText2: {$bankTransaction->getFreeText2()}
"; // string|null Free text field 2 as entered on the transaction type. + echo "FreeText3: {$bankTransaction->getFreeText3()}
"; // string|null Free text field 3 as entered on the transaction type. + echo "InputDate (\\DateTimeInterface):
" . print_r($bankTransaction->getInputDate(), true) . "

"; // DateTimeInterface|null The date/time on which the transaction was created. Read-only attribute. + echo "InputDate (string): " . Util::formatDate($bankTransaction->getInputDate()) . "
"; // string|null + + if ($bankTransaction->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($bankTransaction->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ModificationDate (\\DateTimeInterface):
" . print_r($bankTransaction->getModificationDate(), true) . "

"; // DateTimeInterface|null The date/time on which the bank transaction was modified the last time. Read-only attribute. + echo "ModificationDate (string): " . Util::formatDate($bankTransaction->getModificationDate()) . "
"; // string|null + echo "Number: {$bankTransaction->getNumber()}
"; // int|null Transaction number. When creating a new bank transaction, don't include this tag as the transaction number is determined by the system. When updating a bank transaction, the related transaction number should be provided. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($bankTransaction->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($bankTransaction->getOffice()) . "
"; // string|null + echo "Origin: {$bankTransaction->getOrigin()}
"; // string|null The bank transaction origin. Read-only attribute. + echo "Period: {$bankTransaction->getPeriod()}
"; // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + echo "RaiseWarning (bool): {$bankTransaction->getRaiseWarning()}
"; // bool|null Should warnings be given true or not false? Default true. + echo "RaiseWarning (string): " . Util::formatBoolean($bankTransaction->getRaiseWarning()) . "
"; // string|null + echo "Result: {$bankTransaction->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "StartValue (\\Money\\Money):
" . print_r($bankTransaction->getStartValue(), true) . "

"; // Money|null Opening balance. If not provided, the opening balance is set to zero. + echo "StartValue (string): " . Util::formatMoney($bankTransaction->getStartValue()) . "
"; // string|null + echo "StatementNumber: {$bankTransaction->getStatementNumber()}
"; // int|null Number of the bank statement. Don't confuse this number with the transaction number. + + $bankTransactionLines = $bankTransaction->getLines(); // array|null Array of BankTransactionLine objects. + + foreach ($bankTransactionLines as $key => $bankTransactionLine) { + echo "BankTransactionLine {$key}
"; + + echo "BaseValue (\\Money\\Money):
" . print_r($bankTransactionLine->getBaseValue(), true) . "

"; // Money|null Amount in the base currency. + echo "BaseValue (string): " . Util::formatMoney($bankTransactionLine->getBaseValue()) . "
"; // string|null + echo "BaseValueOpen (\\Money\\Money):
" . print_r($bankTransactionLine->getBaseValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in base currency. Read-only attribute. + echo "BaseValueOpen (string): " . Util::formatMoney($bankTransactionLine->getBaseValueOpen()) . "
"; // string|null + echo "Comment: {$bankTransactionLine->getComment()}
"; // string|null Comment set on the transaction line. + echo "CurrencyDate (\\DateTimeInterface):
" . print_r($bankTransactionLine->getCurrencyDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the bank book is set to Allowed or Mandatory. + echo "CurrencyDate (string): " . Util::formatDate($bankTransactionLine->getCurrencyDate()) . "
"; // string|null + echo "DebitCredit: {$bankTransactionLine->getDebitCredit()}
"; // DebitCredit|null If line type = total, based on the sum of the individual bank transaction lines. In case of a bank addition debit. In case of a bank withdrawal credit. If line type = detail, credit in case money is received and debit in case money is paid. If line type = vat, based on the sum of the vat amounts of the individual bank transaction lins. In case of a bank addition credit. In case of a bank withdrawal debit. + echo "Description: {$bankTransactionLine->getDescription()}
"; // string|null Description of the transaction line. + echo "DestOffice (\\PhpTwinfield\\Office):
" . print_r($bankTransactionLine->getDestOffice(), true) . "

"; // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + echo "DestOffice (string): " . Util::objectToStr($bankTransactionLine->getDestOffice()) . "
"; // string|null + echo "Dim1:
" . print_r($bankTransactionLine->getDim1(), true) . "

"; // object|null If line type = total the bank balance account. If line type = detail the customer or supplier balance account or profit and loss account. + echo "Dim1 (string): " . Util::objectToStr($bankTransactionLine->getDim1()) . "
"; // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + echo "Dim2:
" . print_r($bankTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the customer or supplier or the cost center or empty. + echo "Dim2 (string): " . Util::objectToStr($bankTransactionLine->getDim2()) . "
"; // string|null If line type = vat empty. + echo "Dim3:
" . print_r($bankTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the project or asset or empty. + echo "Dim3 (string): " . Util::objectToStr($bankTransactionLine->getDim3()) . "
"; // string|null If line type = vat empty. + echo "FreeChar: {$bankTransactionLine->getFreeChar()}
"; // string|null Free character field. + echo "ID: {$bankTransactionLine->getID()}
"; // int|null Line ID. + echo "LineType: {$bankTransactionLine->getLineType()}
"; // LineType|null Line type. + echo "MatchLevel: {$bankTransactionLine->getMatchLevel()}
"; // int|null Only if line type is detail. The level of the matchable dimension. Read-only attribute. + echo "MatchStatus: {$bankTransactionLine->getMatchStatus()}
"; // MatchStatus|null Payment status of the bank transaction. If line type total or vat always notmatchable. Read-only attribute. + + if ($bankTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($bankTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceCountry (\\PhpTwinfield\\Country):
" . print_r($bankTransactionLine->getPerformanceCountry(), true) . "

"; // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + echo "PerformanceCountry (string): " . Util::objectToStr($bankTransactionLine->getPerformanceCountry()) . "
"; // string|null + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($bankTransactionLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + echo "PerformanceDate (string): " . Util::formatDate($bankTransactionLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$bankTransactionLine->getPerformanceType()}
"; // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + echo "PerformanceVatNumber: {$bankTransactionLine->getPerformanceVatNumber()}
"; // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + echo "Rate: {$bankTransactionLine->getRate()}
"; // float|null The exchange rate used for the calculation of the base amount. + echo "Reference (\\PhpTwinfield\\MatchReference):
" . print_r($bankTransactionLine->getReference(), true) . "

"; // MatchReference|null Match reference + echo "Relation: {$bankTransactionLine->getRelation()}
"; // int|null Only if line type is detail. Read-only attribute. + echo "RepRate: {$bankTransactionLine->getRepRate()}
"; // float|null The exchange rate used for the calculation of the reporting amount. + echo "RepValue (\\Money\\Money):
" . print_r($bankTransactionLine->getRepValue(), true) . "

"; // Money|null Amount in the reporting currency. + echo "RepValue (string): " . Util::formatMoney($bankTransactionLine->getRepValue()) . "
"; // string|null + echo "RepValueOpen (\\Money\\Money):
" . print_r($bankTransactionLine->getRepValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + echo "RepValueOpen (string): " . Util::formatMoney($bankTransactionLine->getRepValueOpen()) . "
"; // string|null + echo "Result: {$bankTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SignedValue (\\Money\\Money):
" . print_r($bankTransactionLine->getSignedValue(), true) . "

"; // Money|null + echo "SignedValue (string): " . Util::formatMoney($bankTransactionLine->getSignedValue()) . "
"; // string|null + echo "Value (\\Money\\Money):
" . print_r($bankTransactionLine->getValue(), true) . "

"; // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + echo "Value (string): " . Util::formatMoney($bankTransactionLine->getValue()) . "
"; // string|null + echo "VatBaseTotal (\\Money\\Money):
" . print_r($bankTransactionLine->getVatBaseTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in base currency. + echo "VatBaseTotal (string): " . Util::formatMoney($bankTransactionLine->getVatBaseTotal()) . "
"; // string|null + echo "VatBaseTurnover (\\Money\\Money):
" . print_r($bankTransactionLine->getVatBaseTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + echo "VatBaseTurnover (string): " . Util::formatMoney($bankTransactionLine->getVatBaseTurnover()) . "
"; // string|null + echo "VatBaseValue (\\Money\\Money):
" . print_r($bankTransactionLine->getVatBaseValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in base currency. + echo "VatBaseValue (string): " . Util::formatMoney($bankTransactionLine->getVatBaseValue()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($bankTransactionLine->getVatCode(), true) . "

"; // VatCode|null Only if line type is detail or vat. VAT code. + echo "VatCode (string): " . Util::objectToStr($bankTransactionLine->getVatCode()) . "
"; // string|null + echo "VatRepTotal (\\Money\\Money):
" . print_r($bankTransactionLine->getVatRepTotal(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepTotal (string): " . Util::formatMoney($bankTransactionLine->getVatRepTotal()) . "
"; // string|null + echo "VatRepTurnover (\\Money\\Money):
" . print_r($bankTransactionLine->getVatRepTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + echo "VatRepTurnover (string): " . Util::formatMoney($bankTransactionLine->getVatRepTurnover()) . "
"; // string|null + echo "VatRepValue (\\Money\\Money):
" . print_r($bankTransactionLine->getVatRepValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepValue (string): " . Util::formatMoney($bankTransactionLine->getVatRepValue()) . "
"; // string|null + echo "VatTotal (\\Money\\Money):
" . print_r($bankTransactionLine->getVatTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in the currency of the bank transaction. + echo "VatTotal (string): " . Util::formatMoney($bankTransactionLine->getVatTotal()) . "
"; // string|null + echo "VatTurnover (\\Money\\Money):
" . print_r($bankTransactionLine->getVatTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the bank transaction. + echo "VatTurnover (string): " . Util::formatMoney($bankTransactionLine->getVatTurnover()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($bankTransactionLine->getVatValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in the currency of the bank transaction. + echo "VatValue (string): " . Util::formatMoney($bankTransactionLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing BankTransaction to a new entity +if ($executeCopy) { + try { + $bankTransaction = $transactionApiConnector->get(\PhpTwinfield\BankTransaction::class, "BNK", 201900011, $office); + } catch (ResponseException $e) { + $bankTransaction = $e->getReturnedObject(); + } + + $bankTransaction->setNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $bankTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); + + try { + $bankTransactionCopy = $transactionApiConnector->send($bankTransaction); + } catch (ResponseException $e) { + $bankTransactionCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($bankTransactionCopy);
+    echo "
"; + + echo "Result of copy process: {$bankTransactionCopy->getResult()}
"; + echo "Number of copied BankTransaction: {$bankTransactionCopy->getNumber()}
"; +} + +// Create a new BankTransaction from scratch, alternatively read an existing BankTransaction as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $bankTransaction = new \PhpTwinfield\BankTransaction; + + // Required values for creating a new BankTransaction + $bankTransaction->setCode('BNK'); // string|null Transaction type code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $bankTransaction->setCurrency($currency); // Currency|null Currency code. + //$bankTransaction->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $bankTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); // Destiny|null Attribute to indicate the destiny of the bank transaction. Only used in the request XML. temporary = bank transaction will be saved as provisional. + //$bankTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::FINAL()); // Destiny|null final = bank transaction will be saved as final. + $bankTransaction->setOffice($office); // Office|null Office code. + $bankTransaction->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new BankTransaction + $bankTransaction->setAutoBalanceVat(true); // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + $date = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + $bankTransaction->setDate($date); // DateTimeInterface|null Transaction date. Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + $bankTransaction->setDate(Util::parseDate("20190901")); // string|null This overwrites the value of the raisewarning attribute as set on the root element. + $bankTransaction->setDateRaiseWarning(false); // bool|null + //$bankTransaction->setFreeText1('Example FreeText 1'); // string|null Free text field 1 as entered on the transaction type. + //$bankTransaction->setFreeText2('Example FreeText 2'); // string|null Free text field 2 as entered on the transaction type. + //$bankTransaction->setFreeText3('Example FreeText 3'); // string|null Free text field 3 as entered on the transaction type. + //$bankTransaction->setNumber(201900011); // int|null Transaction number. When creating a new bank transaction, don't include this tag as the transaction number is determined by the system. When updating a bank transaction, the related transaction number should be provided. + //$bankTransaction->setPeriod("2019/07"); // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + $bankTransaction->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + //$bankTransactionLine->setStartValue(\Money\Money::EUR(1000)); // Money|null Opening balance. If not provided, the opening balance is set to zero. (Equals 10.00 EUR) + $bankTransaction->setStatementNumber(20); // int|null Number of the bank statement. Don't confuse this number with the transaction number. + + // The minimum amount of BankTransactionLines linked to an BankTransaction object is 2 (1 total, 1 detail) + $bankTransactionLine1 = new \PhpTwinfield\BankTransactionLine; + $bankTransactionLine1->setLineType(\PhpTwinfield\Enums\LineType::TOTAL()); // LineType|null Line type. + + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('1010'); + $bankTransactionLine1->setDim1($dim1); // object|null If line type = total the bank balance account. If line type = detail the customer or supplier balance account or profit and loss account. + $bankTransactionLine1->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1010')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $bankTransactionLine1->setID(1); // int|null Line ID. + $bankTransactionLine1->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + //$bankTransactionLine1->setVatBaseTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in base currency. + //$bankTransactionLine1->setVatRepTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in reporting currency. + //$bankTransactionLine1->setVatTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in the currency of the bank transaction. + + $bankTransaction->addLine($bankTransactionLine1); // BankTransactionLine Add a BankTransactionLine object to the BankTransaction object + + $bankTransactionLine2 = new \PhpTwinfield\BankTransactionLine; + $bankTransactionLine2->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $bankTransactionLine2->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $bankTransactionLine2->setDescription("Example Description on line with ID 2"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $bankTransactionLine2->setDim1($dim1); // object|null If line type = total the bank balance account. If line type = detail the customer or supplier balance account or profit and loss account. + $bankTransactionLine2->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $bankTransactionLine2->setID(2); // int|null Line ID. + $bankTransactionLine2->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + + //$bankTransactionLine2->setComment('Example Comments'); // string|null Comment set on the transaction line. + $currencyDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$bankTransaction->setCurrencyDate($currencyDate); // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the bank book is set to Allowed or Mandatory. + //$bankTransaction->setCurrencyDate(Util::parseDate("20190901")); // string|null + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('1234'); + //$bankTransaction->setDestOffice($destOffice); // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + //$bankTransaction->setDestOffice(\PhpTwinfield\Office::fromCode('1234')); // string|null + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1001'); + //$bankTransactionLine2->setDim2($dim2); // object|null If line type = total empty. If line type = detail the customer or supplier or the cost center or empty. If line type = vat empty. + //$bankTransactionLine2->setDim2(\PhpTwinfield\Customer::fromCode('1001')); // string|null + $dim3 = new \PhpTwinfield\Project; + $dim3->setCode('P0000'); + //$bankTransactionLine2->setDim3($dim3); // object|null If line type = total empty. If line type = detail the project or asset or empty. If line type = vat empty. + //$bankTransactionLine2->setDim3(\PhpTwinfield\Project::fromCode('P0000')); // string|null + //$bankTransactionLine2->setFreeChar('A'); // string|null Free character field. + $performanceCountry = new \PhpTwinfield\Country; + $performanceCountry->setCode('NL'); + //$bankTransactionLine2->setPerformanceCountry($performanceCountry); // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + //$bankTransactionLine2->setPerformanceCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$bankTransactionLine2->setPerformanceDate($performanceDate); // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + //$bankTransactionLine2->setPerformanceDate(Util::parseDate("20190901")); // string|null + //$bankTransactionLine2->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + //$bankTransactionLine2->setPerformanceVatNumber('NL1234567890B01'); // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + //$bankTransactionLine2->setRepValue(\Money\Money::EUR(-10000)); // Money|null Amount in the reporting currency. + //$bankTransactionLine2->setRate(1); // float|null The exchange rate used for the calculation of the base amount. + //$bankTransactionLine2->setRepRate(1); // float|null The exchange rate used for the calculation of the reporting amount. + //$bankTransactionLine2->setVatBaseValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in base currency. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VN'); + //$bankTransactionLine2->setVatCode($vatCode); // VatCode|null Only if line type is detail or vat. VAT code. + //$bankTransactionLine2->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); // string|null + //$bankTransactionLine2->setVatRepValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in reporting currency. + //$bankTransactionLine2->setVatValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in the currency of the bank transaction. + + $bankTransaction->addLine($bankTransactionLine2); + + //$bankTransactionLine3 = new \PhpTwinfield\BankTransactionLine; + //$bankTransactionLine3->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Line type. + //$bankTransactionLine3->setVatBaseTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + //$bankTransactionLine3->setVatRepTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + //$bankTransactionLine3->setVatTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the bank transaction. + + try { + $bankTransactionNew = $transactionApiConnector->send($bankTransaction); + } catch (ResponseException $e) { + $bankTransactionNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($bankTransactionNew);
+    echo "
"; + + echo "Result of creation process: {$bankTransactionNew->getResult()}
"; + echo "Number of new BankTransaction: {$bankTransactionNew->getNumber()}
"; +} + +// Delete a BrankTransaction based off the passed in office, code, number and given reason +if ($executeDelete) { + $bookingReference = new \PhpTwinfield\BookingReference($office, 'BNK', 201900026); + + try { + $bankTransactionDeleted = $transactionApiConnector->delete($bookingReference, 'Example reason'); + } catch (ResponseException $e) { + $bankTransactionDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($bankTransactionDeleted);
+    echo "
"; +} diff --git a/examples/BrowseData.php b/examples/BrowseData.php new file mode 100644 index 00000000..c33fe90d --- /dev/null +++ b/examples/BrowseData.php @@ -0,0 +1,268 @@ +getBrowseDefinition('000'); + } catch (ResponseException $e) { + $browseDefinition = $e->getReturnedObject(); + } + + echo "
";
+    print_r($browseDefinition);
+    echo "
"; +} + +/* BrowseField + * \PhpTwinfield\BrowseField + * Available getters: getCode, getDataType, getFinder, getOptions, isCanOrder + * Available setters: setCanOrder, setCode, setDataType, setFinder, addOption + */ + +/* BrowseFieldOption + * \PhpTwinfield\BrowseFieldOption + * Available getters: getCode, getName + * Available setters: setCode, setName + */ + +if ($executeListBrowseFields) { + try { + $browseFields = $browseDataApiConnector->getBrowseFields(); + } catch (ResponseException $e) { + $browseFields = $e->getReturnedObject(); + } + + echo "
";
+    print_r($browseFields);
+    echo "
"; +} + +/* BrowseSortField + * \PhpTwinfield\BrowseSortField + * Available getters: getCode, getOrder + * Available setters: setCode, setOrder + */ + +/* BrowseData + * \PhpTwinfield\BrowseData + * Available getters: getFirst, getHeaders, getLast, getRows, getTotal + * Available setters: setFirst, setLast, setTotal, addHeader, addRow + */ + + /* BrowseDataHeader + * \PhpTwinfield\BrowseDataHeader + * Available getters: getCode, getLabel, getType, isHideForUser + * Available setters: setCode, setHideForUser, setLabel, setType + */ + +/* BrowseDataRow + * \PhpTwinfield\BrowseDataRow + * Available getters: getCells, getCode, getLine, getNumber, getOffice + * Available setters: setCode, setLine, setNumber, setOffice, addCell + */ + +/* BrowseDataCell + * \PhpTwinfield\BrowseDataCell + * Available getters: getField, getType, getValue, isHideForUser + * Available setters: setField, setHideForUser, setType, setValue + */ + +if ($executeGetBrowseData) { + // First, create the columns that you want to retrieve (see the browse definition for which columns are available) + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.head.yearperiod') + ->setLabel('Period') + ->setVisible(true) + ->setAsk(true) + ->setOperator(\PhpTwinfield\Enums\BrowseColumnOperator::BETWEEN()) + ->setFrom('2018/01') + ->setTo('2050/12'); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.head.code') + ->setLabel('Transaction type') + ->setVisible(true); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.head.shortname') + ->setLabel('Name') + ->setVisible(true); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.head.number') + ->setLabel('Trans. no.') + ->setVisible(true); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.line.dim1') + ->setLabel('General ledger') + ->setVisible(true) + ->setAsk(true) + ->setOperator(\PhpTwinfield\Enums\BrowseColumnOperator::BETWEEN()) + ->setFrom('1300') + ->setTo('1300'); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.head.curcode') + ->setLabel('Currency') + ->setVisible(true); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.line.valuesigned') + ->setLabel('Value') + ->setVisible(true); + + $columns[] = (new \PhpTwinfield\BrowseColumn()) + ->setField('fin.trs.line.description') + ->setLabel('Description') + ->setVisible(true); + + // Second, create sort fields + $sortFields[] = new \PhpTwinfield\BrowseSortField('fin.trs.head.code'); + + try { + // Get the browse data + $browseData = $browseDataApiConnector->getBrowseData('000', $columns, $sortFields); + } catch (ResponseException $e) { + $browseData = $e->getReturnedObject(); + } + + echo "
";
+    print_r($browseData);
+    echo "
"; + + echo "Browse Data
"; + echo "First: {$browseData->getFirst()}
"; + echo "Last: {$browseData->getLast()}
"; + echo "Total: {$browseData->getTotal()}

"; + + $browseDataHeaders = $browseData->getHeaders(); + $tableHeader = array("Result #", "Office", "Code", "Number", "Line"); + + foreach ($browseDataHeaders as $browseDataHeader) { + $tableHeader[] = $browseDataHeader->getLabel(); + } + + $browseDataRows = $browseData->getRows(); + + foreach ($browseDataRows as $key => $browseDataRow) { + $tableRows[$key][] = $key; + $tableRows[$key][] = $browseDataRow->getOffice(); + $tableRows[$key][] = $browseDataRow->getCode(); + $tableRows[$key][] = $browseDataRow->getNumber(); + $tableRows[$key][] = $browseDataRow->getLine(); + + $browseDataCells = $browseDataRow->getCells(); + + foreach ($browseDataCells as $browseDataCell) { + $tableRows[$key][] = $browseDataCell->getValue(); + } + } + + ?> + + + {$tableHeaderColumn}"; } ?> + + "; foreach ($tableRow as $tableColumn) { echo ""; } echo ""; } ?> +
{$tableColumn}
+ + banktype = 0 +if ($executeListAllWithFilter) { + $options = array('banktype' => 0); + + try { + $cashBankBooks = $cashBankBookApiConnector->listAll('BNK', 0, 1, 10, $options); + } catch (ResponseException $e) { + $cashBankBooks = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashBankBooks);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $cashBankBooks = $cashBankBookApiConnector->listAll(); + } catch (ResponseException $e) { + $cashBankBooks = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashBankBooks);
+    echo "
"; +} + +/* CashBankBook + * \PhpTwinfield\CashBankBook + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($cashBankBooks as $key => $cashBankBook) { + echo "CashBankBook {$key}
"; + echo "Code: {$cashBankBook->getCode()}
"; + echo "Name: {$cashBankBook->getName()}

"; + } +} diff --git a/examples/CashTransaction.php b/examples/CashTransaction.php new file mode 100644 index 00000000..ca7ffce7 --- /dev/null +++ b/examples/CashTransaction.php @@ -0,0 +1,344 @@ +get(\PhpTwinfield\CashTransaction::class, "KAS", 201900011, $office); + } catch (ResponseException $e) { + $cashTransaction = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashTransaction);
+    echo "
"; + + echo "CashTransaction
"; + echo "AutoBalanceVat (bool): {$cashTransaction->getAutoBalanceVat()}
"; // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + echo "AutoBalanceVat (string): " . Util::formatBoolean($cashTransaction->getAutoBalanceVat()) . "
"; // string|null + echo "BookingReference (\\PhpTwinfield\\BookingReference):
" . print_r($cashTransaction->getBookingReference(), true) . "

"; // BookingReference|null The Booking reference + echo "CloseValue (\\Money\\Money):
" . print_r($cashTransaction->getCloseValue(), true) . "

"; // Money|null Closing balance. If not provided, the closing balance is set to zero. + echo "CloseValue (string): " . Util::formatMoney($cashTransaction->getCloseValue()) . "
"; // string|null + echo "Code: {$cashTransaction->getCode()}
"; // string|null Transaction type code. + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($cashTransaction->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($cashTransaction->getCurrency()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($cashTransaction->getDate(), true) . "

"; // DateTimeInterface|null Transaction date. + echo "Date (string): " . Util::formatDate($cashTransaction->getDate()) . "
"; // string|null + echo "DateRaiseWarning (bool): {$cashTransaction->getDateRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + echo "DateRaiseWarning (string): {$cashTransaction->getDateRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + echo "Destiny: {$cashTransaction->getDestiny()}
"; // Destiny|null Attribute to indicate the destiny of the cash transaction. Only used in the request XML. temporary = cash transaction will be saved as provisional. final = cash transaction will be saved as final. + echo "FreeText1: {$cashTransaction->getFreeText1()}
"; // string|null Free text field 1 as entered on the transaction type. + echo "FreeText2: {$cashTransaction->getFreeText2()}
"; // string|null Free text field 2 as entered on the transaction type. + echo "FreeText3: {$cashTransaction->getFreeText3()}
"; // string|null Free text field 3 as entered on the transaction type. + echo "InputDate (\\DateTimeInterface):
" . print_r($cashTransaction->getInputDate(), true) . "

"; // DateTimeInterface|null The date/time on which the transaction was created. Read-only attribute. + echo "InputDate (string): " . Util::formatDate($cashTransaction->getInputDate()) . "
"; // string|null + + if ($cashTransaction->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($cashTransaction->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ModificationDate (\\DateTimeInterface):
" . print_r($cashTransaction->getModificationDate(), true) . "

"; // DateTimeInterface|null The date/time on which the cash transaction was modified the last time. Read-only attribute. + echo "ModificationDate (string): " . Util::formatDate($cashTransaction->getModificationDate()) . "
"; // string|null + echo "Number: {$cashTransaction->getNumber()}
"; // int|null Transaction number. When creating a new cash transaction, don't include this tag as the transaction number is determined by the system. When updating a cash transaction, the related transaction number should be provided. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($cashTransaction->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($cashTransaction->getOffice()) . "
"; // string|null + echo "Origin: {$cashTransaction->getOrigin()}
"; // string|null The cash transaction origin. Read-only attribute. + echo "Period: {$cashTransaction->getPeriod()}
"; // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + echo "RaiseWarning (bool): {$cashTransaction->getRaiseWarning()}
"; // bool|null Should warnings be given true or not false? Default true. + echo "RaiseWarning (string): " . Util::formatBoolean($cashTransaction->getRaiseWarning()) . "
"; // string|null + echo "Result: {$cashTransaction->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "StartValue (\\Money\\Money):
" . print_r($cashTransaction->getStartValue(), true) . "

"; // Money|null Opening balance. If not provided, the opening balance is set to zero. + echo "StartValue (string): " . Util::formatMoney($cashTransaction->getStartValue()) . "
"; // string|null + echo "StatementNumber: {$cashTransaction->getStatementNumber()}
"; // int|null Number of the cash statement. Don't confuse this number with the transaction number. + + $cashTransactionLines = $cashTransaction->getLines(); // array|null Array of CashTransactionLine objects. + + foreach ($cashTransactionLines as $key => $cashTransactionLine) { + echo "CashTransactionLine {$key}
"; + + echo "BaseValue (\\Money\\Money):
" . print_r($cashTransactionLine->getBaseValue(), true) . "

"; // Money|null Amount in the base currency. + echo "BaseValue (string): " . Util::formatMoney($cashTransactionLine->getBaseValue()) . "
"; // string|null + echo "BaseValueOpen (\\Money\\Money):
" . print_r($cashTransactionLine->getBaseValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in base currency. Read-only attribute. + echo "BaseValueOpen (string): " . Util::formatMoney($cashTransactionLine->getBaseValueOpen()) . "
"; // string|null + echo "Comment: {$cashTransactionLine->getComment()}
"; // string|null Comment set on the transaction line. + echo "CurrencyDate (\\DateTimeInterface):
" . print_r($cashTransactionLine->getCurrencyDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the cash book is set to Allowed or Mandatory. + echo "CurrencyDate (string): " . Util::formatDate($cashTransactionLine->getCurrencyDate()) . "
"; // string|null + echo "DebitCredit: {$cashTransactionLine->getDebitCredit()}
"; // DebitCredit|null If line type = total, based on the sum of the individual cash transaction lines. In case of a cash addition debit. In case of a cash withdrawal credit. If line type = detail, credit in case money is received and debit in case money is paid. If line type = vat, based on the sum of the vat amounts of the individual cash transaction lins. In case of a cash addition credit. In case of a cash withdrawal debit. + echo "Description: {$cashTransactionLine->getDescription()}
"; // string|null Description of the transaction line. + echo "DestOffice (\\PhpTwinfield\\Office):
" . print_r($cashTransactionLine->getDestOffice(), true) . "

"; // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + echo "DestOffice (string): " . Util::objectToStr($cashTransactionLine->getDestOffice()) . "
"; // string|null + echo "Dim1:
" . print_r($cashTransactionLine->getDim1(), true) . "

"; // object|null If line type = total the cash balance account. If line type = detail the customer or supplier balance account or profit and loss account. + echo "Dim1 (string): " . Util::objectToStr($cashTransactionLine->getDim1()) . "
"; // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + echo "Dim2:
" . print_r($cashTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the customer or supplier or the cost center or empty. + echo "Dim2 (string): " . Util::objectToStr($cashTransactionLine->getDim2()) . "
"; // string|null If line type = vat empty. + echo "Dim3:
" . print_r($cashTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the project or asset or empty. + echo "Dim3 (string): " . Util::objectToStr($cashTransactionLine->getDim3()) . "
"; // string|null If line type = vat empty. + echo "FreeChar: {$cashTransactionLine->getFreeChar()}
"; // string|null Free character field. + echo "ID: {$cashTransactionLine->getID()}
"; // int|null Line ID. + echo "LineType: {$cashTransactionLine->getLineType()}
"; // LineType|null Line type. + echo "MatchLevel: {$cashTransactionLine->getMatchLevel()}
"; // int|null Only if line type is detail. The level of the matchable dimension. Read-only attribute. + echo "MatchStatus: {$cashTransactionLine->getMatchStatus()}
"; // MatchStatus|null Payment status of the cash transaction. If line type total or vat always notmatchable. Read-only attribute. + + if ($cashTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($cashTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceCountry (\\PhpTwinfield\\Country):
" . print_r($cashTransactionLine->getPerformanceCountry(), true) . "

"; // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + echo "PerformanceCountry (string): " . Util::objectToStr($cashTransactionLine->getPerformanceCountry()) . "
"; // string|null + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($cashTransactionLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + echo "PerformanceDate (string): " . Util::formatDate($cashTransactionLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$cashTransactionLine->getPerformanceType()}
"; // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + echo "PerformanceVatNumber: {$cashTransactionLine->getPerformanceVatNumber()}
"; // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + echo "Rate: {$cashTransactionLine->getRate()}
"; // float|null The exchange rate used for the calculation of the base amount. + echo "Reference (\\PhpTwinfield\\MatchReference):
" . print_r($cashTransactionLine->getReference(), true) . "

"; // MatchReference|null Match reference + echo "Relation: {$cashTransactionLine->getRelation()}
"; // int|null Only if line type is detail. Read-only attribute. + echo "RepRate: {$cashTransactionLine->getRepRate()}
"; // float|null The exchange rate used for the calculation of the reporting amount. + echo "RepValue (\\Money\\Money):
" . print_r($cashTransactionLine->getRepValue(), true) . "

"; // Money|null Amount in the reporting currency. + echo "RepValue (string): " . Util::formatMoney($cashTransactionLine->getRepValue()) . "
"; // string|null + echo "RepValueOpen (\\Money\\Money):
" . print_r($cashTransactionLine->getRepValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + echo "RepValueOpen (string): " . Util::formatMoney($cashTransactionLine->getRepValueOpen()) . "
"; // string|null + echo "Result: {$cashTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SignedValue (\\Money\\Money):
" . print_r($cashTransactionLine->getSignedValue(), true) . "

"; // Money|null + echo "SignedValue (string): " . Util::formatMoney($cashTransactionLine->getSignedValue()) . "
"; // string|null + echo "Value (\\Money\\Money):
" . print_r($cashTransactionLine->getValue(), true) . "

"; // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + echo "Value (string): " . Util::formatMoney($cashTransactionLine->getValue()) . "
"; // string|null + echo "VatBaseTotal (\\Money\\Money):
" . print_r($cashTransactionLine->getVatBaseTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in base currency. + echo "VatBaseTotal (string): " . Util::formatMoney($cashTransactionLine->getVatBaseTotal()) . "
"; // string|null + echo "VatBaseTurnover (\\Money\\Money):
" . print_r($cashTransactionLine->getVatBaseTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + echo "VatBaseTurnover (string): " . Util::formatMoney($cashTransactionLine->getVatBaseTurnover()) . "
"; // string|null + echo "VatBaseValue (\\Money\\Money):
" . print_r($cashTransactionLine->getVatBaseValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in base currency. + echo "VatBaseValue (string): " . Util::formatMoney($cashTransactionLine->getVatBaseValue()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($cashTransactionLine->getVatCode(), true) . "

"; // VatCode|null Only if line type is detail or vat. VAT code. + echo "VatCode (string): " . Util::objectToStr($cashTransactionLine->getVatCode()) . "
"; // string|null + echo "VatRepTotal (\\Money\\Money):
" . print_r($cashTransactionLine->getVatRepTotal(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepTotal (string): " . Util::formatMoney($cashTransactionLine->getVatRepTotal()) . "
"; // string|null + echo "VatRepTurnover (\\Money\\Money):
" . print_r($cashTransactionLine->getVatRepTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + echo "VatRepTurnover (string): " . Util::formatMoney($cashTransactionLine->getVatRepTurnover()) . "
"; // string|null + echo "VatRepValue (\\Money\\Money):
" . print_r($cashTransactionLine->getVatRepValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepValue (string): " . Util::formatMoney($cashTransactionLine->getVatRepValue()) . "
"; // string|null + echo "VatTotal (\\Money\\Money):
" . print_r($cashTransactionLine->getVatTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in the currency of the cash transaction. + echo "VatTotal (string): " . Util::formatMoney($cashTransactionLine->getVatTotal()) . "
"; // string|null + echo "VatTurnover (\\Money\\Money):
" . print_r($cashTransactionLine->getVatTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the cash transaction. + echo "VatTurnover (string): " . Util::formatMoney($cashTransactionLine->getVatTurnover()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($cashTransactionLine->getVatValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in the currency of the cash transaction. + echo "VatValue (string): " . Util::formatMoney($cashTransactionLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing CashTransaction to a new entity +if ($executeCopy) { + try { + $cashTransaction = $transactionApiConnector->get(\PhpTwinfield\CashTransaction::class, "KAS", 201900011, $office); + } catch (ResponseException $e) { + $cashTransaction = $e->getReturnedObject(); + } + + $cashTransaction->setNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $cashTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); + + try { + $cashTransactionCopy = $transactionApiConnector->send($cashTransaction); + } catch (ResponseException $e) { + $cashTransactionCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashTransactionCopy);
+    echo "
"; + + echo "Result of copy process: {$cashTransactionCopy->getResult()}
"; + echo "Number of copied CashTransaction: {$cashTransactionCopy->getNumber()}
"; +} + +// Create a new CashTransaction from scratch, alternatively read an existing CashTransaction as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $cashTransaction = new \PhpTwinfield\CashTransaction; + + // Required values for creating a new CashTransaction + $cashTransaction->setCode('KAS'); // string|null Transaction type code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $cashTransaction->setCurrency($currency); // Currency|null Currency code. + //$cashTransaction->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $cashTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); // Destiny|null Attribute to indicate the destiny of the cash transaction. Only used in the request XML. temporary = cash transaction will be saved as provisional. + //$cashTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::FINAL()); // Destiny|null final = cash transaction will be saved as final. + $cashTransaction->setOffice($office); // Office|null Office code. + $cashTransaction->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new CashTransaction + $cashTransaction->setAutoBalanceVat(true); // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + $date = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + $cashTransaction->setDate($date); // DateTimeInterface|null Transaction date. Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + $cashTransaction->setDate(Util::parseDate("20190901")); // string|null This overwrites the value of the raisewarning attribute as set on the root element. + $cashTransaction->setDateRaiseWarning(false); // bool|null + //$cashTransaction->setFreeText1('Example FreeText 1'); // string|null Free text field 1 as entered on the transaction type. + //$cashTransaction->setFreeText2('Example FreeText 2'); // string|null Free text field 2 as entered on the transaction type. + //$cashTransaction->setFreeText3('Example FreeText 3'); // string|null Free text field 3 as entered on the transaction type. + //$cashTransaction->setNumber(201900011); // int|null Transaction number. When creating a new cash transaction, don't include this tag as the transaction number is determined by the system. When updating a cash transaction, the related transaction number should be provided. + //$cashTransaction->setPeriod("2019/07"); // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + $cashTransaction->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + //$cashTransactionLine->setStartValue(\Money\Money::EUR(1000)); // Money|null Opening balance. If not provided, the opening balance is set to zero. (Equals 10.00 EUR) + $cashTransaction->setStatementNumber(20); // int|null Number of the cash statement. Don't confuse this number with the transaction number. + + // The minimum amount of CashTransactionLines linked to an CashTransaction object is 2 (1 total, 1 detail) + $cashTransactionLine1 = new \PhpTwinfield\CashTransactionLine; + $cashTransactionLine1->setLineType(\PhpTwinfield\Enums\LineType::TOTAL()); // LineType|null Line type. + + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('1010'); + $cashTransactionLine1->setDim1($dim1); // object|null If line type = total the cash balance account. If line type = detail the customer or supplier balance account or profit and loss account. + $cashTransactionLine1->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1010')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $cashTransactionLine1->setID(1); // int|null Line ID. + $cashTransactionLine1->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + //$cashTransactionLine1->setVatBaseTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in base currency. + //$cashTransactionLine1->setVatRepTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in reporting currency. + //$cashTransactionLine1->setVatTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in the currency of the cash transaction. + + $cashTransaction->addLine($cashTransactionLine1); // CashTransactionLine Add a CashTransactionLine object to the CashTransaction object + + $cashTransactionLine2 = new \PhpTwinfield\CashTransactionLine; + $cashTransactionLine2->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $cashTransactionLine2->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $cashTransactionLine2->setDescription("Example Description on line with ID 2"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $cashTransactionLine2->setDim1($dim1); // object|null If line type = total the cash balance account. If line type = detail the customer or supplier balance account or profit and loss account. + $cashTransactionLine2->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $cashTransactionLine2->setID(2); // int|null Line ID. + $cashTransactionLine2->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + + //$cashTransactionLine2->setComment('Example Comments'); // string|null Comment set on the transaction line. + $currencyDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$cashTransaction->setCurrencyDate($currencyDate); // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the cash book is set to Allowed or Mandatory. + //$cashTransaction->setCurrencyDate(Util::parseDate("20190901")); // string|null + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('1234'); + //$cashTransaction->setDestOffice($destOffice); // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + //$cashTransaction->setDestOffice(\PhpTwinfield\Office::fromCode('1234')); // string|null + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1001'); + //$cashTransactionLine2->setDim2($dim2); // object|null If line type = total empty. If line type = detail the customer or supplier or the cost center or empty. If line type = vat empty. + //$cashTransactionLine2->setDim2(\PhpTwinfield\Customer::fromCode('1001')); // string|null + $dim3 = new \PhpTwinfield\Project; + $dim3->setCode('P0000'); + //$cashTransactionLine2->setDim3($dim3); // object|null If line type = total empty. If line type = detail the project or asset or empty. If line type = vat empty. + //$cashTransactionLine2->setDim3(\PhpTwinfield\Project::fromCode('P0000')); // string|null + //$cashTransactionLine2->setFreeChar('A'); // string|null Free character field. + $performanceCountry = new \PhpTwinfield\Country; + $performanceCountry->setCode('NL'); + //$cashTransactionLine2->setPerformanceCountry($performanceCountry); // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + //$cashTransactionLine2->setPerformanceCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$cashTransactionLine2->setPerformanceDate($performanceDate); // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + //$cashTransactionLine2->setPerformanceDate(Util::parseDate("20190901")); // string|null + //$cashTransactionLine2->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + //$cashTransactionLine2->setPerformanceVatNumber('NL1234567890B01'); // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + //$cashTransactionLine2->setRepValue(\Money\Money::EUR(-10000)); // Money|null Amount in the reporting currency. + //$cashTransactionLine2->setRate(1); // float|null The exchange rate used for the calculation of the base amount. + //$cashTransactionLine2->setRepRate(1); // float|null The exchange rate used for the calculation of the reporting amount. + //$cashTransactionLine2->setVatBaseValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in base currency. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VN'); + //$cashTransactionLine2->setVatCode($vatCode); // VatCode|null Only if line type is detail or vat. VAT code. + //$cashTransactionLine2->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); // string|null + //$cashTransactionLine2->setVatRepValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in reporting currency. + //$cashTransactionLine2->setVatValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in the currency of the cash transaction. + + $cashTransaction->addLine($cashTransactionLine2); + + //$cashTransactionLine3 = new \PhpTwinfield\CashTransactionLine; + //$cashTransactionLine3->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Line type. + //$cashTransactionLine3->setVatBaseTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + //$cashTransactionLine3->setVatRepTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + //$cashTransactionLine3->setVatTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the cash transaction. + + try { + $cashTransactionNew = $transactionApiConnector->send($cashTransaction); + } catch (ResponseException $e) { + $cashTransactionNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashTransactionNew);
+    echo "
"; + + echo "Result of creation process: {$cashTransactionNew->getResult()}
"; + echo "Number of new CashTransaction: {$cashTransactionNew->getNumber()}
"; +} + +// Delete a BrankTransaction based off the passed in office, code, number and given reason +if ($executeDelete) { + $bookingReference = new \PhpTwinfield\BookingReference($office, 'KAS', 201900026); + + try { + $cashTransactionDeleted = $transactionApiConnector->delete($bookingReference, 'Example reason'); + } catch (ResponseException $e) { + $cashTransactionDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($cashTransactionDeleted);
+    echo "
"; +} diff --git a/examples/Connection.php b/examples/Connection.php new file mode 100644 index 00000000..0430c415 --- /dev/null +++ b/examples/Connection.php @@ -0,0 +1,69 @@ + $twin_client_id, + 'clientSecret' => $twin_client_secret, + 'redirectUri' => $twin_redirect_uri, +]); + +// Retrieve a stored refresh token from storage. +$refreshTokenStorage = RetrieveRefreshTokenFromStore(); + +// Optionally retrieve access token, access token expiry time and cluster from storage. +$accessTokenStorage = RetrieveAccessTokenFromStore(); + +// Create a new Office object from the $officeCode +$office = \PhpTwinfield\Office::fromCode($officeCode); + +// Create a new connection using either the refresh token, access token and access cluster (approximately 2 seconds faster) or only the refresh token. +if ($accessTokenStorage['access_expiry'] > time()) { + $connection = new \PhpTwinfield\Secure\OpenIdConnectAuthentication($provider, $refreshTokenStorage['refresh_token'], $office, $accessTokenStorage['access_token'], $accessTokenStorage['access_cluster']); +} else { + $connection = new \PhpTwinfield\Secure\OpenIdConnectAuthentication($provider, $refreshTokenStorage['refresh_token'], $office); +} diff --git a/examples/CostCenter.php b/examples/CostCenter.php new file mode 100644 index 00000000..7bb37cef --- /dev/null +++ b/examples/CostCenter.php @@ -0,0 +1,221 @@ + modifiedsince = '20190101100000', group = 'DimensionGroup' +if ($executeListAllWithFilter) { + $options = array('modifiedsince' => '20190101100000', 'group' => 'DimensionGroup'); + + try { + $costCenters = $costCenterApiConnector->listAll("Apeldoorn", 0, 1, 10, $options); + } catch (ResponseException $e) { + $costCenters = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenters);
+    echo "
"; +} + + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $costCenters = $costCenterApiConnector->listAll(); + } catch (ResponseException $e) { + $costCenters = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenters);
+    echo "
"; +} + +/* CostCenter + * \PhpTwinfield\CostCenter + * Available getters: getBehaviour, getCode, getInUse, getMessages, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUID, hasMessages + * Available setters: fromCode, setBehaviour, setCode, setName, setOffice, setShortName, setStatus, setType + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($costCenters as $key => $costCenter) { + echo "CostCenter {$key}
"; + echo "Code: {$costCenter->getCode()}
"; + echo "Name: {$costCenter->getName()}

"; + } +} + +// Read a CostCenter based off the passed in code and optionally the office. +if ($executeRead) { + try { + $costCenter = $costCenterApiConnector->get("00000", $office); + } catch (ResponseException $e) { + $costCenter = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenter);
+    echo "
"; + + echo "CostCenter
"; + echo "Behaviour: {$costCenter->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$costCenter->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the KPL Dimension type. + echo "InUse (bool): {$costCenter->getInUse()}
"; // bool|null Indicates whether the cost center is used in a financial transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($costCenter->getInUse()) . "
"; // string|null + + if ($costCenter->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($costCenter->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$costCenter->getName()}
"; // string|null Name of the dimension. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($costCenter->getOffice(), true) . "

"; // Office|null Office. + echo "Office (string): " . Util::objectToStr($costCenter->getOffice()) . "
"; // string|null + echo "Result: {$costCenter->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$costCenter->getShortName()}
"; // string|null Not in use. + echo "Status: {$costCenter->getStatus()}
"; // Status|null Status of the cost center. + echo "Touched: {$costCenter->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($costCenter->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of cost centers is KPL. + echo "Type (string): " . Util::objectToStr($costCenter->getType()) . "
"; // string|null + echo "UID: {$costCenter->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. +} + +// Copy an existing CostCenter to a new entity +if ($executeCopy) { + try { + $costCenter = $costCenterApiConnector->get("00000", $office); + } catch (ResponseException $e) { + $costCenter = $e->getReturnedObject(); + } + + $costCenter->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$costCenter->setCode("00010"); // string|null Dimension code, must be compliant with the mask of the KPL Dimension type. + + try { + $costCenterCopy = $costCenterApiConnector->send($costCenter); + } catch (ResponseException $e) { + $costCenterCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenterCopy);
+    echo "
"; + + echo "Result of copy process: {$costCenterCopy->getResult()}
"; + echo "Code of copied CostCenter: {$costCenterCopy->getCode()}
"; + echo "Status of copied CostCenter: {$costCenterCopy->getStatus()}
"; +} + +// Create a new CostCenter from scratch, alternatively read an existing CostCenter as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $costCenter = new \PhpTwinfield\CostCenter; + + // Required values for creating a new CostCenter + $costCenter->setName("CostCenterName"); // string|null Name of the dimension. + $costCenter->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$costCenter->setCode('00020'); // string|null Dimension code, must be compliant with the mask of the KPL Dimension type. + $costCenter->setOffice($office); // Office|null Office. + $costCenter->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new CostCenter + $costCenter->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. + //$costCenter->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null For deleting deleted should be used. In case a dimension that is used in a transaction is deleted, + // its status has been changed into hide. Hidden dimensions can be activated by using active. + try { + $costCenterNew = $costCenterApiConnector->send($costCenter); + } catch (ResponseException $e) { + $costCenterNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenterNew);
+    echo "
"; + + echo "Result of creation process: {$costCenterNew->getResult()}
"; + echo "Code of new CostCenter: {$costCenterNew->getCode()}
"; + echo "Status of new CostCenter: {$costCenterNew->getStatus()}
"; +} + +// Delete a CostCenter based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $costCenterDeleted = $costCenterApiConnector->delete("00020", $office); + } catch (ResponseException $e) { + $costCenterDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($costCenterDeleted);
+    echo "
"; + + echo "Result of deletion process: {$costCenterDeleted->getResult()}
"; + echo "Code of deleted CostCenter: {$costCenterDeleted->getCode()}
"; + echo "Status of deleted CostCenter: {$costCenterDeleted->getStatus()}
"; +} diff --git a/examples/Country.php b/examples/Country.php new file mode 100644 index 00000000..e2523e02 --- /dev/null +++ b/examples/Country.php @@ -0,0 +1,87 @@ +listAll('NL', 0, 1, 10); + } catch (ResponseException $e) { + $countries = $e->getReturnedObject(); + } + + echo "
";
+    print_r($countries);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $countries = $countryApiConnector->listAll(); + } catch (ResponseException $e) { + $countries = $e->getReturnedObject(); + } + + echo "
";
+    print_r($countries);
+    echo "
"; +} + +/* Country + * \PhpTwinfield\Country + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($countries as $key => $country) { + echo "Country {$key}
"; + echo "Code: {$country->getCode()}
"; + echo "Name: {$country->getName()}

"; + } +} diff --git a/examples/Currency.php b/examples/Currency.php new file mode 100644 index 00000000..75a94cdd --- /dev/null +++ b/examples/Currency.php @@ -0,0 +1,235 @@ +listAll("EUR", 0, 1, 10); + } catch (ResponseException $e) { + $currencies = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currencies);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $currencies = $currencyApiConnector->listAll(); + } catch (ResponseException $e) { + $currencies = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currencies);
+    echo "
"; +} + +/* Currency + * \PhpTwinfield\Currency + * Available getters: getCode, getMessages, getName, getOffice, getResult, getShortName, getStatus, hasMessages, getRates + * Available setters: fromCode, setCode, setName, setOffice, setShortName, setStatus, addRate, removeRate + */ + +/* CurrencyRate + * \PhpTwinfield\CurrencyRate + * Available getters: getMessages, getRate, getResult, getStartDate, getStatus, hasMessages + * Available setters: setRate ,setStartDate, setStatus + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($currencies as $key => $currency) { + echo "Currency {$key}
"; + echo "Code: {$currency->getCode()}
"; + echo "Name: {$currency->getName()}

"; + } +} + +// Read a Currency based off the passed in code and optionally the office. +if ($executeRead) { + try { + $currency = $currencyApiConnector->get("USD", $office); + } catch (ResponseException $e) { + $currency = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currency);
+    echo "
"; + + echo "Currency
"; + echo "Code: {$currency->getCode()}
"; // string|null The code of the currency. + + if ($currency->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($currency->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$currency->getName()}
"; // string|null Name of the currency. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($currency->getOffice(), true) . "

"; // Office|null Office of the currency. + echo "Office (string): " . Util::objectToStr($currency->getOffice()) . "
"; // string|null + echo "Result: {$currency->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$currency->getShortName()}
"; // string|null Short name of the currency. NOTE: Because of the "hackish" way a currency is read (because Twinfield does not officially support reading currencies) the get() method will not return the current Short Name + echo "Status: {$currency->getStatus()}
"; // Status|null Status of the currency. + + $currencyRates = $currency->getRates(); // Array|null Array of CurrencyRate objects. + + foreach ($currencyRates as $key => $currencyRate) { + echo "CurrencyRate {$key}
"; + + if ($currencyRate->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($currencyRate->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Rate: {$currencyRate->getRate()}
"; // float|null Conversion rate to be used as of the start date. + echo "Result: {$currencyRate->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "StartDate (\\DateTimeInterface):
" . print_r($currencyRate->getStartDate(), true) . "

"; // DateTimeInterface|null Starting date of the rate. + echo "StartDate (string): " . Util::formatDate($currencyRate->getStartDate()) . "
"; // string|null + echo "Status: {$currencyRate->getStatus()}
"; // Status|null Status of the currency rate. + } +} + +// Copy an existing Currency to a new entity +if ($executeCopy) { + try { + $currency = $currencyApiConnector->get("USD", $office); + } catch (ResponseException $e) { + $currency = $e->getReturnedObject(); + } + + $currency->setCode("USD2"); + + try { + $currencyCopy = $currencyApiConnector->send($currency); + } catch (ResponseException $e) { + $currencyCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currencyCopy);
+    echo "
"; + + echo "Result of copy process: {$currencyCopy->getResult()}
"; + echo "Code of copied Currency: {$currencyCopy->getCode()}
"; + echo "Status of copied Currency: {$currencyCopy->getStatus()}
"; +} + +// Create a new Currency from scratch, alternatively read an existing Currency as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $currency = new \PhpTwinfield\Currency; + + // Required values for creating a new Currency + $currency->setCode('JPY'); // string|null The code of the currency. + $currency->setName("Japanese yen"); // string|null Name of the currency. + $currency->setOffice($office); // Office|null Office code of the currency. + $currency->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Currency + $currency->setShortName("Yen"); // string|null Short name of the currency. + //$currency->setShortName("¥"); // string|null + $currency->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. + //$currency->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null For deleting deleted should be used. In case a dimension that is used in a transaction is deleted, + // its status has been changed into hide. Hidden dimensions can be activated by using active. + + // The minimum amount of CurrencyRates linked to a Currency object is 0 + $currencyRate = new \PhpTwinfield\CurrencyRate; + $currencyRate->setRate(122.87); // float|null Conversion rate to be used as of the start date. + $startDate = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $currencyRate->setStartDate($startDate); // DateTimeInterface|null Starting date of the rate. + $currencyRate->setStartDate(Util::parseDate('20190101')); // string|null + //$currencyRate->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null For creating and updating status may be left empty. NOTE: Do not use $currencyRate->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); + // For deleting deleted should be used. + + $currency->addRate($currencyRate); // CurrencyRate Add a CurrencyRate object to the Currency object + //$currency->removeRate(0); // int Remove a rate based on the index of the rate within the array + + try { + $currencyNew = $currencyApiConnector->send($currency); + } catch (ResponseException $e) { + $currencyNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currencyNew);
+    echo "
"; + + echo "Result of creation process: {$currencyNew->getResult()}
"; + echo "Code of new Currency: {$currencyNew->getCode()}
"; + echo "Status of new Currency: {$currencyNew->getStatus()}
"; +} + +// Delete a Currency based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $currencyDeleted = $currencyApiConnector->delete("JPY", $office); + } catch (ResponseException $e) { + $currencyDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($currencyDeleted);
+    echo "
"; + + echo "Result of deletion process: {$currencyDeleted->getResult()}
"; + echo "Code of deleted Currency: {$currencyDeleted->getCode()}
"; + echo "Status of deleted Currency: {$currencyDeleted->getStatus()}
"; +} diff --git a/examples/Customer.php b/examples/Customer.php new file mode 100644 index 00000000..69c5ce99 --- /dev/null +++ b/examples/Customer.php @@ -0,0 +1,672 @@ + matchtype = 'relation' +if ($executeListAllWithFilter) { + $options = array('matchtype' => 'relation'); + + try { + $customers = $customerApiConnector->listAll("2*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $customers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customers);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $customers = $customerApiConnector->listAll(); + } catch (ResponseException $e) { + $customers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customers);
+    echo "
"; +} + +/* Customer + * \PhpTwinfield\Customer + * Available getters: getBeginPeriod, getBeginYear, getBehaviour, getCode, getDiscountArticle, getDiscountArticleID, getEndPeriod, getEndYear, getGroup, getInUse, getMessages, getName, getOffice, + * getPaymentConditionDiscountDays, getPaymentConditionDiscountPercentage, getRemittanceAdviceSendMail, getRemittanceAdviceSendType, getResult, getShortName, getStatus, getTouched, getType, getUID, getWebsite, hasMessages, getAddresses, getBanks, getCreditManagement, getFinancials, getPostingRules + * + * Available setters: fromCode, setBeginPeriod, setBeginYear, setBehaviour, setCode, setDiscountArticle, setDiscountArticleID, setEndPeriod, setEndYear, setGroup, setName, setOffice, setPaymentConditionDiscountDays, + * setPaymentConditionDiscountPercentage, setRemittanceAdviceSendMail, setRemittanceAdviceSendType, setShortName, setStatus, setType, setWebsite, setCreditManagement, setFinancials, addAddress, addBank, addPostingRule, removeAddress, removeBank, removePostingRule + * + */ + +/* CustomerFinancials + * \PhpTwinfield\CustomerFinancials + * Available getters: getAccountType, getCollectionSchema, getDueDays, getEBillMail, getEBilling, getLevel, getMatchType, getMeansOfPayment, getMessages, getPayAvailable, getPayCode, getPayCodeID, + * getResult, getSubAnalyse, getSubstituteWith, getSubstituteWithID, getSubstitutionLevel, getVatCode, getVatCodeFixed, getChildValidations, getCollectMandate, hasMessages + * + * Available setters: setAccountType, setCollectionSchema, setDueDays, setEBillMail, setEBilling, setLevel, setMatchType, setMeansOfPayment, + * setPayAvailable, setPayCode, setPayCodeID, setSubAnalyse, setSubstituteWith, setSubstituteWithID, setSubstitutionLevel, setVatCode, setVatCodeFixed, setCollectMandate, addChildValidation, removeChildValidation + * + */ + +/* CustomerCollectMandate + * \PhpTwinfield\CustomerCollectMandate + * Available getters: getFirstRunDate, getID, getMessages, getResult, getSignatureDate, hasMessages + * Available setters: setFirstRunDate, setID, setSignatureDate + */ + +/* CustomerChildValidation + * \PhpTwinfield\CustomerChildValidation + * Available getters: getElementValue, getLevel, getMessages, getResult, getType, hasMessages + * Available setters: setElementValue, setLevel, setType + */ + +/* CustomerCreditManagement + * \PhpTwinfield\CustomerCreditManagement + * Available getters: getBaseCreditLimit, getBlocked, getBlockedLocked, getBlockedModified, getComment, getFreeText1, getFreeText2, getFreeText3, getMessages, getReminderEmail, getResponsibleUser, getResult, getSendReminder, hasMessages + * Available setters: setBaseCreditLimit, setBlocked, setBlockedLocked, setBlockedModified, setComment, setFreeText1, setFreeText2, setFreeText3, setReminderEmail, setResponsibleUser, setSendReminder + */ + +/* CustomerAddress + * \PhpTwinfield\CustomerAddress + * Available getters: getCity, getCountry, getDefault, getEmail, getField1, getField2, getField3, getField4, getField5, getField6, getID, getMessages, getName, getPostcode, getResult, getTelefax, getTelephone, getType, hasMessages + * Available setters: setCity, setCountry, setDefault, setEmail, setField1, setField2, setField3, setField4, setField5, setField6, setID, setName, setPostcode, setTelefax, setTelephone, setType + */ + +/* CustomerBank + * \PhpTwinfield\CustomerBank + * Available getters: getAccountNumber, getAddressField2, getAddressField3, getAscription, getBankName, getBicCode, getBlocked, getCity, getCountry, getDefault, getID, getIban, getMessages, getNatBicCode, getPostcode, getResult, getState, hasMessages + * Available setters: setAccountNumber, setAddressField2, setAddressField3, setAscription, setBankName, setBicCode, setBlocked, setCity, setCountry, setDefault, setID, setIban, setNatBicCode, setPostcode, setState + */ + +/* CustomerPostingRule + * \PhpTwinfield\CustomerPostingRule + * Available getters: getAmount, getCurrency, getDescription, getID, getMessages, getResult, getStatus, getLines, hasMessages + * Available setters: setAmount, setCurrency, setDescription, setID, setStatus, addLine, removeLine + */ + +/* CustomerLine + * \PhpTwinfield\CustomerLine + * Available getters: getDescription, getDimension1, getDimension1ID, getDimension2, getDimension2ID, getDimension3, getDimension3ID, getMessages, getOffice, getRatio, getResult, getVatCode, hasMessages + * Available setters: setDescription, setDimension1, setDimension1ID, setDimension2, setDimension2ID, setDimension3, setDimension3ID, setOffice, setRatio, setVatCode + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($customers as $key => $customer) { + echo "Customer {$key}
"; + echo "Code: {$customer->getCode()}
"; + echo "Name: {$customer->getName()}

"; + } +} + +// Read a Customer based off the passed in code and optionally the office. +if ($executeRead) { + try { + $customer = $customerApiConnector->get("1000", $office); + } catch (ResponseException $e) { + $customer = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customer);
+    echo "
"; + + echo "Customer
"; + echo "BeginPeriod: {$customer->getBeginPeriod()}
"; // int|null Determines together with beginyear the period from which the dimension may be used. + echo "BeginYear: {$customer->getBeginYear()}
"; // int|null Determines together with beginperiod the period from which the dimension may be used. + echo "Behaviour: {$customer->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$customer->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the DEB Dimension type. + echo "DiscountArticle (\\PhpTwinfield\\Article):
" . print_r($customer->getDiscountArticle(), true) . "

"; // Article|null The discount or premium article. + echo "DiscountArticle (string): " . Util::objectToStr($customer->getDiscountArticle()) . "
"; // string|null + echo "DiscountArticleID: {$customer->getDiscountArticleID()}
"; // string|null + echo "EndPeriod: {$customer->getEndPeriod()}
"; // int|null Determines together with endyear the period till which the dimension may be used. + echo "EndYear: {$customer->getEndYear()}
"; // int|null Determines together with endperiod the period till which the dimension may be used. + echo "Group (\\PhpTwinfield\\DimensionGroup):
" . print_r($customer->getGroup(), true) . "

"; // DimensionGroup|null Sets the dimension group. See Dimension group. + echo "Group (string): " . Util::objectToStr($customer->getGroup()) . "
"; // string|null + echo "InUse (bool): {$customer->getInUse()}
"; // bool|null Indicates whether the dimension is used in a financial transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($customer->getInUse()) . "
"; // string|null + + if ($customer->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customer->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$customer->getName()}
"; // string|null Name of the dimension. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($customer->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($customer->getOffice()) . "
"; // string|null + echo "PaymentCondition:
"; // Sets the payment condition of a dimension. + echo "PaymentCondition DiscountDays: {$customer->getPaymentConditionDiscountDays()}
"; // int|null Number of discount days. + echo "PaymentCondition DiscountPercentage: {$customer->getPaymentConditionDiscountPercentage()}
"; // float|null Discount percentage. + echo "RemittanceAdvice:
"; // + echo "RemittanceAdvice SendMail: {$customer->getRemittanceAdviceSendMail()}
"; // string|null Mandatory if sendtype = ByEmail, remittance advice will be sent using this e-mail address. + echo "RemittanceAdvice SendType: {$customer->getRemittanceAdviceSendType()}
"; // RemittanceAdviceSendType|null To file manager, By e-mail + echo "Result: {$customer->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$customer->getShortName()}
"; // string|null Short name of the dimension. + echo "Status: {$customer->getStatus()}
"; // Status|null Status of the customer. + echo "Touched: {$customer->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($customer->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of customers is DEB. + echo "Type (string): " . Util::objectToStr($customer->getType()) . "
"; // string|null + echo "UID: {$customer->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + echo "Website: {$customer->getWebsite()}
"; // string|null Website of the dimension. + + $customerAddresses = $customer->getAddresses(); // array|null Array of CustomerAddress objects. + + foreach ($customerAddresses as $key => $customerAddress) { + echo "CustomerAddress {$key}
"; + + echo "City: {$customerAddress->getCity()}
"; // string|null City. + echo "Country (\\PhpTwinfield\\Country):
" . print_r($customerAddress->getCountry(), true) . "

"; // Country|null Country code. The ISO country codes are used. + echo "Country (string): " . Util::objectToStr($customerAddress->getCountry()) . "
"; // string|null + echo "Default (bool): {$customerAddress->getDefault()}
"; // bool|null Is this the default address, only one default address is possible. + echo "Default (string): " . Util::formatBoolean($customerAddress->getDefault()) . "
"; // string|null + echo "Email: {$customerAddress->getEmail()}
"; // string|null + echo "Field1: {$customerAddress->getField1()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field2: {$customerAddress->getField2()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field3: {$customerAddress->getField3()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field4: {$customerAddress->getField4()}
"; // string|null User defined fields, the labels are configured in the Dimension type. Currently, field4 is reserved for VAT numbers. So only valid VAT numbers may be filled in. + echo "Field5: {$customerAddress->getField5()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field6: {$customerAddress->getField6()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "ID: {$customerAddress->getID()}
"; // int|null Sequence number of the address line. + + if ($customerAddress->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerAddress->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$customerAddress->getName()}
"; // string|null Company name. + echo "Postcode: {$customerAddress->getPostcode()}
"; // string|null Postcode. + echo "Result: {$customerAddress->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Telefax: {$customerAddress->getTelefax()}
"; // string|null Fax number. + echo "Telephone: {$customerAddress->getTelephone()}
"; // string|null Telephone number. + echo "Type: {$customerAddress->getType()}
"; // AddressType|null The type of the address. + } + + $customerBanks = $customer->getBanks(); + + foreach ($customerBanks as $key => $customerBank) { + echo "CustomerBank {$key}
"; + + echo "AccountNumber: {$customerBank->getAccountNumber()}
"; // string|null Account number. + echo "AddressField2: {$customerBank->getAddressField2()}
"; // string|null Bank address. + echo "AddressField3: {$customerBank->getAddressField3()}
"; // string|null Bank address number. + echo "Ascription: {$customerBank->getAscription()}
"; // string|null Account holder. + echo "BankName: {$customerBank->getBankName()}
"; // string|null Bank name. + echo "BicCode: {$customerBank->getBicCode()}
"; // string|null BIC code. + + echo "Blocked (bool): {$customerBank->getBlocked()}
"; // bool|null + echo "Blocked (string): " . Util::formatBoolean($customerBank->getBlocked()) . "
"; // string|null + echo "City: {$customerBank->getCity()}
"; // string|null City. + echo "Country (\\PhpTwinfield\\Country):
" . print_r($customerBank->getCountry(), true) . "

"; // Country|null Bank country code. The ISO country codes are used. + echo "Country (string): " . Util::objectToStr($customerBank->getCountry()) . "
"; // string|null + echo "Default (bool): {$customerBank->getDefault()}
"; // bool|null Is this the default bank account, only one default bank account is possible. + echo "Default (string): " . Util::formatBoolean($customerBank->getDefault()) . "
"; // string|null + echo "ID: {$customerBank->getID()}
"; // int|null Sequence number of the bank account line. When adding a new bank, do not supply the @id. When changing a bank account, supply the corresponding @id. + echo "IBAN: {$customerBank->getIban()}
"; // string|null IBAN account number. + + if ($customerBank->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerBank->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "NatBicCode: {$customerBank->getNatBicCode()}
"; // string|null National bank code. + echo "Postcode: {$customerBank->getPostcode()}
"; // string|null Postcode. + echo "Result: {$customerBank->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "State: {$customerBank->getState()}
"; // string|null State. + } + + $customerCreditManagement = $customer->getCreditManagement(); // CustomerCreditManagement|null CustomerCreditManagement object. + + echo "CustomerCreditManagement
"; + echo "BaseCreditLimit (\\Money\\Money):
" . print_r($customerCreditManagement->getBaseCreditLimit(), true) . "

"; // Money|null The credit limit amount. + echo "BaseCreditLimit (string): " . Util::formatMoney($customerCreditManagement->getBaseCreditLimit()) . "
"; // string|null + echo "Blocked (bool): {$customerCreditManagement->getBlocked()}
"; // bool|null Indicates if related projects for this customer are blocked in time & expenses. + echo "Blocked (string): " . Util::formatBoolean($customerCreditManagement->getBlocked()) . "
"; // string|null + echo "Blocked Locked (bool): {$customerCreditManagement->getBlockedLocked()}
"; // bool|null + echo "Blocked Locked (string): " . Util::formatBoolean($customerCreditManagement->getBlockedLocked()) . "
"; // string|null + echo "Blocked Modified (\\DateTimeInterface):
" . print_r($customerCreditManagement->getBlockedModified(), true) . "

"; // \DateTimeInterface|null + echo "Blocked Modified (string): " . Util::formatBoolean($customerCreditManagement->getBlockedModified()) . "
"; // string|null + echo "Comment: {$customerCreditManagement->getComment()}
"; // string|null Comment. + echo "Freetext1 (bool): {$customerCreditManagement->getFreeText1()}
"; // bool|null Right of use. + echo "Freetext1 (string): " . Util::formatBoolean($customerCreditManagement->getFreeText1()) ."
"; // string|null + echo "Freetext2: {$customerCreditManagement->getFreeText2()}
"; // string|null Segment code. + echo "Freetext3: {$customerCreditManagement->getFreeText3()}
"; // string|null Not in use. + + if ($customerCreditManagement->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerCreditManagement->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ReminderEmail: {$customerCreditManagement->getReminderEmail()}
"; // string|null Mandatory if sendreminder is email. + echo "ResponsibleUser (\\PhpTwinfield\\User):
" . print_r($customerCreditManagement->getResponsibleUser(), true) . "

"; // User|null The credit manager. + echo "ResponsibleUser (string): " . Util::objectToStr($customerCreditManagement->getResponsibleUser()) . "
"; // string|null + echo "Result: {$customerCreditManagement->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SendReminder: {$customerCreditManagement->getSendReminder()}
"; // SendReminder|null Determines if and how a customer will be reminded. + + echo "CustomerFinancials
"; + $customerFinancials = $customer->getFinancials(); // CustomerFinancials|null CustomerFinancials object. + + echo "AccountType: {$customerFinancials->getAccountType()}
"; // AccountType|null Fixed value inherit. + echo "CollectionSchema: {$customerFinancials->getCollectionSchema()}
"; // CollectionSchema|null Collection schema information. Apply this information only when the customer invoices are collected by SEPA direct debit. + echo "DueDays: {$customerFinancials->getDueDays()}
"; // int|null The number of due days. + echo "EBillMail: {$customerFinancials->getEBillMail()}
"; // string|null The mail address the electronic sales invoice is sent to. + echo "EBilling (bool): {$customerFinancials->getEBilling()}
"; // bool|null Determines if the sales invoices will be sent electronically to the customer. + echo "EBilling (string): " . Util::formatBoolean($customerFinancials->getEBilling()) . "
"; // string|null + echo "Level: {$customerFinancials->getLevel()}
"; // int|null Specifies the dimension level. Normally the level of customers is level 2. Read-only attribute. + echo "MatchType: {$customerFinancials->getMatchType()}
"; // MatchType|null Fixed value customersupplier. + echo "MeansOfPayment: {$customerFinancials->getMeansOfPayment()}
"; // MeansOfPayment|null The option none is only allowed in case payavailable is set to false. The option paymentfile is only allowed in case payavailable is set to true. + + if ($customerFinancials->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerFinancials->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PayAvailable (bool): {$customerFinancials->getPayAvailable()}
"; // bool|null Determines if direct debit is possible. + echo "PayAvailable (string): " . Util::formatBoolean($customerFinancials->getPayAvailable()) . "
"; // string|null + echo "PayCode (\\PhpTwinfield\\PayCode):
" . print_r($customerFinancials->getPayCode(), true) . "

"; // PayCode|null The code of the payment type in case direct debit is possible. + echo "PayCode (string): " . Util::objectToStr($customerFinancials->getPayCode()) . "
"; // string|null + echo "PayCodeID: {$customerFinancials->getPayCodeID()}
"; // string|null + echo "Result: {$customerFinancials->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SubAnalyse: {$customerFinancials->getSubAnalyse()}
"; // SubAnalyse|null Fixed value false. + echo "SubstituteWith (\\PhpTwinfield\\GeneralLedger):
" . print_r($customerFinancials->getSubstituteWith(), true) . "

"; // GeneralLedger|null Default customer balancesheet account. + echo "SubstituteWith (string): " . Util::objectToStr($customerFinancials->getSubstituteWith()) . "
"; // string|null + echo "SubstituteWithID: {$customerFinancials->getSubstituteWithID()}
"; // string|null + echo "SubstitutionLevel: {$customerFinancials->getSubstitutionLevel()}
"; // int|null Level of the balancesheet account. Fixed value 1. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($customerFinancials->getVatCode(), true) . "

"; // VatCode|null Default VAT code. + echo "VatCode (string): " . Util::objectToStr($customerFinancials->getVatCode()) . "
"; // string|null + echo "VatCode Fixed (bool): {$customerFinancials->getVatCodeFixed()}
"; // bool|null + echo "VatCode Fixed (string): " . Util::formatBoolean($customerFinancials->getVatCodeFixed()) . "
"; // string|null + + $customerChildValidations = $customerFinancials->getChildValidations(); // array|null Array of CustomerChildValidations objects. + + foreach ($customerChildValidations as $key => $customerChildValidation) { + echo "CustomerChildValidation {$key}
"; + + echo "ElementValue: {$customerChildValidation->getElementValue()}
"; // string|null + echo "Level: {$customerChildValidation->getLevel()}
"; // int|null + + if ($customerChildValidation->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerChildValidation->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$customerChildValidation->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Type: {$customerChildValidation->getType()}
"; // ChildValidationType|null + } + + $customerCollectMandate = $customerFinancials->getCollectMandate(); // CollectMandate|null CollectMandate object. + + echo "CustomerCollectMandate
"; + echo "FirstRunDate (\\DateTimeInterface):
" . print_r($customerCollectMandate->getFirstRunDate(), true) . "

"; // \DateTimeInterface|null Date on which the first run was collected. + echo "FirstRunDate (string): " . Util::formatDate($customerCollectMandate->getFirstRunDate()) . "
"; // string|null + echo "ID: {$customerCollectMandate->getID()}
"; // string|null Mandate id which the debtor can collect with. + + if ($customerCollectMandate->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerCollectMandate->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "SignatureDate (\\DateTimeInterface):
" . print_r($customerCollectMandate->getSignatureDate(), true) . "

"; // \DateTimeInterface|null Date on which the mandate is signed. + echo "SignatureDate (string): " . Util::formatDate($customerCollectMandate->getSignatureDate()) . "
"; // string|null + + $customerPostingRules = $customer->getPostingRules(); // array|null Array of CustomerPostingRule objects. + + foreach ($customerPostingRules as $key => $customerPostingRule) { + echo "CustomerPostingRule {$key}
"; + + echo "Amount (\\Money\\Money):
" . print_r($customerPostingRule->getAmount(), true) . "

"; // Money|null Amount. + echo "Amount (string): " . Util::formatMoney($customerPostingRule->getAmount()) . "
"; // string|null + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($customerPostingRule->getCurrency(), true) . "

"; // Currency|null Currency. + echo "Currency (string): " . Util::objectToStr($customerPostingRule->getCurrency()) . "
"; // string|null + echo "Description: {$customerPostingRule->getDescription()}
"; // string|null Description. + echo "ID: {$customerPostingRule->getID()}
"; // int|null Sequence number of the posting rule. Fixed value 1. + + if ($customerPostingRule->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerPostingRule->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$customerPostingRule->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Status: {$customerPostingRule->getStatus()}
"; // Status|null Status of the posting rule. + + $customerLines = $customerPostingRule->getLines(); // array|null Array of CustomerLine objects. + + foreach ($customerLines as $key => $customerLine) { + echo "CustomerLine {$key}
"; + + echo "Description: {$customerLine->getDescription()}
"; // string|null Description. + echo "Dimension1 (\\PhpTwinfield\\GeneralLedger):
" . print_r($customerLine->getDimension1(), true) . "

"; // GeneralLedger|null General ledger. + echo "Dimension1 (string): " . Util::objectToStr($customerLine->getDimension1()) . "
"; // string|null + echo "Dimension1ID: {$customerLine->getDimension1ID()}
"; // string|null + echo "Dimension2 (\\PhpTwinfield\\CostCenter):
" . print_r($customerLine->getDimension2(), true) . "

"; // CostCenter|null Cost center. + echo "Dimension2 (string): " . Util::objectToStr($customerLine->getDimension2()) . "
"; // string|null + echo "Dimension2ID: {$customerLine->getDimension2ID()}
"; // string|null + echo "Dimension3:
" . print_r($customerLine->getDimension3(), true) . "

"; // Project|Activity|null Project or asset. + echo "Dimension3 (string): " . Util::objectToStr($customerLine->getDimension3()) . "
"; // string|null + echo "Dimension3ID: {$customerLine->getDimension3ID()}
"; // string|null + + if ($customerLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($customerLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Office (\\PhpTwinfield\\Office):
" . print_r($customerLine->getOffice(), true) . "

"; // Office|null Destination company. + echo "Office (string): " . Util::objectToStr($customerLine->getOffice()) . "
"; // string|null + echo "Ratio: {$customerLine->getRatio()}
"; // float|null The ratio of the posting rule line. + echo "Result: {$customerLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($customerLine->getVatCode(), true) . "

"; // VatCode|null VAT code. + echo "VatCode (string): " . Util::objectToStr($customerLine->getVatCode()) . "
"; // string|null + } + } +} + +// Copy an existing Customer to a new entity +if ($executeCopy) { + try { + $customer = $customerApiConnector->get("1000", $office); + } catch (ResponseException $e) { + $customer = $e->getReturnedObject(); + } + + $customer->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$customer->setCode('1100'); // string|null Dimension code, must be compliant with the mask of the DEB Dimension type. + + //Twinfield does not accept BankID's on new entities + $customerBanks = $customer->getBanks(); + + foreach ($customerBanks as $customerBank) { + $customerBank->setID(null); + } + + try { + $customerCopy = $customerApiConnector->send($customer); + } catch (ResponseException $e) { + $customerCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customerCopy);
+    echo "
"; + + echo "Result of copy process: {$customerCopy->getResult()}
"; + echo "Code of copied Customer: {$customerCopy->getCode()}
"; + echo "Status of copied Customer: {$customerCopy->getStatus()}
"; +} + +// Create a new Customer from scratch, alternatively read an existing Customer as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $customer = new \PhpTwinfield\Customer; + + // Required values for creating a new Customer + $customer->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$customer->setCode('1100'); // string|null Dimension code, must be compliant with the mask of the DEB Dimension type. + $customer->setName("Example Customer"); // string|null Name of the dimension. + $customer->setOffice($office); // Office|null Office code. + $customer->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Customer + $customer->setBeginPeriod(0); // int|null Determines together with beginyear the period from which the dimension may be used. + $customer->setBeginYear(0); // int|null Determines together with beginperiod the period from which the dimension may be used. + $customer->setEndPeriod(0); // int|null Determines together with endyear the period till which the dimension may be used. + $customer->setEndYear(0); // int|null Determines together with endperiod the period till which the dimension may be used. + $customer->setShortName("ExmplCust"); // string|null Short name of the dimension. + //$customer->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$customer->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case a dimension that is used in a transaction is deleted, its status has been changed into hide. Hidden dimensions can be activated by using active. + $customer->setWebsite("www.example.com"); // string|null Website of the dimension. + + $article = new \PhpTwinfield\Article; + $article->setCode('9060'); + $customer->setDiscountArticle($article); // Article|null The discount or premium article. + $customer->setDiscountArticle(\PhpTwinfield\Article::fromCode("9060")); // string|null + + $dimensionGroup = new \PhpTwinfield\DimensionGroup; + $dimensionGroup->setCode('DIMGROUP'); + //$customer->setGroup($dimensionGroup); // DimensionGroup|null Sets the dimension group. See Dimension group. + //$customer->setGroup(\PhpTwinfield\DimensionGroup::fromCode("DIMGROUP")); // string|null + + $customer->setPaymentConditionDiscountDays(3); // int|null Number of discount days. + $customer->setPaymentConditionDiscountPercentage(25); // int|null Discount percentage. + + $customer->setRemittanceAdviceSendMail("test@example.com"); // string|null Mandatory if sendtype = ByEmail, remittance advice will be sent using this e-mail address. + $customer->setRemittanceAdviceSendType(\PhpTwinfield\Enums\RemittanceAdviceSendType::BYEMAIL()); // RemittanceAdviceSendMail|null To file manager, By e-mail + + $customerCreditManagement = new \PhpTwinfield\CustomerCreditManagement; + $customerCreditManagement->setBaseCreditLimit(\Money\Money::EUR(1000000)); // Money|null The credit limit amount. (Equals 10000.00 EUR) + $customerCreditManagement->setBlocked(false); // bool|null Indicates if related projects for this customer are blocked in time & expenses. + $customerCreditManagement->setBlockedLocked(false); // bool|null + $customerCreditManagement->setComment('Comment'); // string|null Comment. + $customerCreditManagement->setFreeText1(true); // bool|null Right of use. + $customerCreditManagement->setFreeText2(2); // string|null Segment code. + $customerCreditManagement->setFreeText3(''); // string|null + $customerCreditManagement->setReminderEmail('test@example.com'); // string|null Mandatory if sendreminder is email. + $user = new \PhpTwinfield\User; + $user->setCode('TWINAPPS'); + $customerCreditManagement->setResponsibleUser($user); // User|null The credit manager. + $customerCreditManagement->setResponsibleUser(\PhpTwinfield\User::fromCode('TWINAPPS')); // string|null + $customerCreditManagement->setSendReminder(\PhpTwinfield\Enums\SendReminder::EMAIL()); // SendReminder|null Determines if and how a customer will be reminded. + + $customer->setCreditManagement($customerCreditManagement); // CustomerCreditManagement Set the CustomerCreditManagement object tot the Customer object + + $customerFinancials = new \PhpTwinfield\CustomerFinancials; + $customerFinancials->setCollectionSchema(\PhpTwinfield\Enums\CollectionSchema::CORE()); + $customerFinancials->setDueDays(14); // int|null The number of due days. + $customerFinancials->setEBillMail('test@example.com'); // string|null The mail address the electronic sales invoice is sent to. + $customerFinancials->setEBilling(true); // bool|null Determines if the sales invoices will be sent electronically to the customer. + $customerFinancials->setMeansOfPayment(\PhpTwinfield\Enums\MeansOfPayment::PAYMENTFILE()); // MeansOfPayment|null The option none is only allowed in case payavailable is set to false. The option paymentfile is only allowed in case payavailable is set to true. + $customerFinancials->setPayAvailable(true); // bool|null Determines if direct debit is possible. + $payCode = new \PhpTwinfield\PayCode; + $payCode->setCode('SEPANLCT'); + $customerFinancials->setPayCode($payCode); // PayCode|null The code of the payment type in case direct debit is possible. + $customerFinancials->setPayCode(\PhpTwinfield\PayCode::fromCode('SEPANLCT')); // string|null + $substituteWith = new \PhpTwinfield\GeneralLedger; + $substituteWith->getCode('1535'); + $customerFinancials->setSubstituteWith($substituteWith); // GeneralLedger|null Default customer balancesheet account. + $customerFinancials->setSubstituteWith(\PhpTwinfield\GeneralLedger::fromCode('1535')); // string|null + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $customerFinancials->setVatCode($vatCode); // VatCode|null Default VAT code. + $customerFinancials->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + $customerCollectMandate = new \PhpTwinfield\CustomerCollectMandate; + $firstRunDate = \DateTime::createFromFormat('d-m-Y', '01-07-2019'); + $customerCollectMandate->setFirstRunDate($firstRunDate); // DateTimeInterface|null Date on which the first run was collected. + $customerCollectMandate->setFirstRunDate(Util::parseDate('20190701')); // string|null + $customerCollectMandate->setID('1010'); // string|null Mandate id which the debtor can collect with. + $signatureDate = \DateTime::createFromFormat('d-m-Y', '01-07-2019'); + $customerCollectMandate->setSignatureDate($signatureDate); // DateTimeInterface|null Date on which the first run was collected. + $customerCollectMandate->setSignatureDate(Util::parseDate('20190701')); // string|null + + $customerFinancials->setCollectMandate($customerCollectMandate); // CustomerCollectMandate Set the CustomerCollectMandate object tot the CustomerFinancials object + + $customer->setFinancials($customerFinancials); // CustomerFinancials Set the CustomerFinancials object tot the Customer object + + $customerAddress = new \PhpTwinfield\CustomerAddress; + $customerAddress->setCity('Amsterdam'); // string|null City. + $country = new \PhpTwinfield\Country; + $country->setCode('NL'); + $customerAddress->setCountry($country); // Country|null Country code. The ISO country codes are used. + $customerAddress->setCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $customerAddress->setDefault(true); // bool|null Is this the default address, only one default address is possible. + $customerAddress->setEmail('test@example.com'); // string|null + $customerAddress->setField1(''); // string|null User defined fields, the labels are configured in the Dimension type. + $customerAddress->setField2(''); // string|null User defined fields, the labels are configured in the Dimension type. + $customerAddress->setField3(''); // string|null User defined fields, the labels are configured in the Dimension type. + $customerAddress->setField4(null); // string|null User defined fields, the labels are configured in the Dimension type. Currently, field4 is reserved for VAT numbers. So only valid VAT numbers may be filled in. + $customerAddress->setField5(''); // string|null User defined fields, the labels are configured in the Dimension type. + $customerAddress->setField6(''); // string|null User defined fields, the labels are configured in the Dimension type. + $customerAddress->setID(1); // string|null Sequence number of the address line. + $customerAddress->setName('Example Customer'); // string|null Company name. + $customerAddress->setPostcode('9876YZ'); // string|null Postcode. + $customerAddress->setTelefax('012-3456789'); // string|null Fax number. + $customerAddress->setTelephone('987-654321'); // string|null Telephone number. + $customerAddress->setType(\PhpTwinfield\Enums\AddressType::INVOICE()); // AddressType|null The type of the address. + + $customer->addAddress($customerAddress); // CustomerAddress Add a CustomerAddress object to the Customer object + //$customer->removeAddress(0); // int Remove an address based on the index of the address within the array + + $customerBank = new \PhpTwinfield\CustomerBank; + $customerBank->setAccountNumber('123456789'); // string|null Account number. + $customerBank->setAddressField2('Example Street'); // string|null Bank address. + $customerBank->setAddressField3('12'); // string|null Bank address number. + $customerBank->setAscription('Example Customer'); // string|null Account holder. + $customerBank->setBankName('Example Bank'); // string|null Bank name. + $customerBank->setBicCode('ABNANL2A'); // string|null BIC code. + $customerBank->setBlocked(false); // bool|null + $customerBank->setCity('Amsterdam'); // string|null City. + $country = new \PhpTwinfield\Country; + $country->setCode('NL'); + $customerBank->setCountry($country); // Country|null Bank country code. The ISO country codes are used. + $customerBank->setCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $customerBank->setDefault(true); // bool|null Is this the default bank account, only one default bank account is possible. + $customerBank->setID(null); // int|null Sequence number of the bank account line. When adding a new bank, do not supply the @id. When changing a bank account, supply the corresponding @id. + $customerBank->setIban(null); // string|null IBAN account number. + $customerBank->setNatBicCode('NL'); // string|null National bank code. + $customerBank->setPostcode('1234AB'); // string|null Postcode. + $customerBank->setState('Noord-Holland'); // string|null State. + + $customer->addBank($customerBank); // CustomerBank Add a CustomerBank object to the Customer object + //$customer->removeBank(0); // int Remove a bank based on the index of the bank within the array + + $customerPostingRule = new \PhpTwinfield\CustomerPostingRule; + $customerPostingRule->setAmount(\Money\Money::EUR(10000)); // Money|null Amount. (Equals 100.00 EUR) + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $customerPostingRule->setCurrency($currency); // Currency|null Currency. + $customerPostingRule->setCurrency(\PhpTwinfield\Currency::fromCode('EUR')); // string|null + $customerPostingRule->setDescription('Example PostingRule'); // string|null Description. + $customerPostingRule->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating active should be used. For deleting deleted should be used. + //$customerPostingRule->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + + $customerLine = new \PhpTwinfield\CustomerLine; + $customerLine->setDescription('Example Line'); // string|null Description. + $dimension1 = new \PhpTwinfield\GeneralLedger; + $dimension1->setCode('1535'); + $customerLine->setDimension1($dimension1); // GeneralLedger|null General ledger. + $customerLine->setDimension1(\PhpTwinfield\GeneralLedger::fromCode('1535')); // string|null + $costCenter = new \PhpTwinfield\CostCenter; + $costCenter->setCode('00000'); + $customerLine->setDimension2($costCenter); // CostCenter|null Cost center. + $customerLine->setDimension2(\PhpTwinfield\CostCenter::fromCode('00000')); // string|null + $activity = new \PhpTwinfield\Activity; + $activity->setCode('P0000'); + $customerLine->setDimension3($activity); // Project|Activity|null Project or asset. + $customerLine->setDimension3(\PhpTwinfield\Activity::fromCode('P0000')); // string|null + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('NLA0000001'); + //$customerLine->setOffice($destOffice); // Office|null Destination company. + //$customerLine->setOffice(\PhpTwinfield\Office::fromCode('NLA0000001')); // string|null + $customerLine->setRatio(1); // float|null The ratio of the posting rule line. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $customerLine->setVatCode($vatCode); // VatCode|null Default VAT code. + $customerLine->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + $customerPostingRule->addLine($customerLine); // CustomerLine Add a CustomerLine object to the CustomerPostingRule object + //$customerPostingRule->removeLine(0); // int Remove a line based on the index of the line within the array + + $customer->addPostingRule($customerPostingRule); // CustomerPostingRule Add a CustomerPostingRule object to the Customer object + //$customer->removePostingRule(0); // int Remove a posting rule based on the index of the posting rule within the array + + try { + $customerNew = $customerApiConnector->send($customer); + } catch (ResponseException $e) { + $customerNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customerNew);
+    echo "
"; + + echo "Result of creation process: {$customerNew->getResult()}
"; + echo "Code of new Customer: {$customerNew->getCode()}
"; + echo "Status of new Customer: {$customerNew->getStatus()}
"; +} + +// Delete a Customer based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $customerDeleted = $customerApiConnector->delete("1003", $office); + } catch (ResponseException $e) { + $customerDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($customerDeleted);
+    echo "
"; + + echo "Result of deletion process: {$customerDeleted->getResult()}
"; + echo "Code of deleted Customer: {$customerDeleted->getCode()}
"; + echo "Status of deleted Customer: {$customerDeleted->getStatus()}
"; +} diff --git a/examples/DimensionGroup.php b/examples/DimensionGroup.php new file mode 100644 index 00000000..1204bcaa --- /dev/null +++ b/examples/DimensionGroup.php @@ -0,0 +1,245 @@ + dimtype = 'BAS' +if ($executeListAllWithFilter) { + $options = array('dimtype' => 'BAS'); + + try { + $dimensionGroups = $dimensionGroupApiConnector->listAll("*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $dimensionGroups = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroups);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $dimensionGroups = $dimensionGroupApiConnector->listAll(); + } catch (ResponseException $e) { + $dimensionGroups = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroups);
+    echo "
"; +} + +/* DimensionGroup + * \PhpTwinfield\DimensionGroup + * Available getters: getCode, getMessages, getName, getOffice, getResult, getShortName, getStatus, hasMessages, getDimensions + * Available setters: fromCode, setCode, setName, setOffice, setShortName, setStatus, addDimension,removeDimension + */ + +/* DimensionGroupDimension + * \PhpTwinfield\DimensionGroupDimension + * Available getters: getCode, getMessages, getResult, getType, hasMessages + * Available setters: setCode, setType + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($dimensionGroups as $key => $dimensionGroup) { + echo "DimensionGroup {$key}
"; + echo "Code: {$dimensionGroup->getCode()}
"; + echo "Name: {$dimensionGroup->getName()}

"; + } +} + +// Read a DimensionGroup based off the passed in code and optionally the office. +if ($executeRead) { + try { + $dimensionGroup = $dimensionGroupApiConnector->get("TSTDIMGRP", $office); + } catch (ResponseException $e) { + $dimensionGroup = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroup);
+    echo "
"; + + echo "DimensionGroup
"; + echo "Code: {$dimensionGroup->getCode()}
"; // string|null Dimension group code. + + if ($dimensionGroup->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($dimensionGroup->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$dimensionGroup->getName()}
"; // string|null Name of the dimension group. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($dimensionGroup->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($dimensionGroup->getOffice()) . "
"; // string|null + echo "Result: {$dimensionGroup->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$dimensionGroup->getShortName()}
"; // string|null Short name of the dimension group. + echo "Status: {$dimensionGroup->getStatus()}
"; // Status|null Status of the dimension group. + + $dimensionGroupDimensions = $dimensionGroup->getDimensions(); // Array|null Array of DimensionGroupDimension objects. + + foreach ($dimensionGroupDimensions as $key => $dimensionGroupDimension) { + echo "DimensionGroupDimension {$key}
"; + + if ($dimensionGroupDimension->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($dimensionGroupDimension->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Code:
" . print_r($dimensionGroupDimension->getCode(), true) . "

"; // object|null Code of the dimension. + echo "Code (string): " . Util::objectToStr($dimensionGroupDimension->getCode()) . "
"; // string|null + echo "Result: {$dimensionGroupDimension->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($dimensionGroupDimension->getType(), true) . "

"; // DimensionType|null Dimension type. + echo "Type (string): " . Util::objectToStr($dimensionGroupDimension->getType()) . "
"; // string|null + } +} + +// Copy an existing DimensionGroup to a new entity +if ($executeCopy) { + try { + $dimensionGroup = $dimensionGroupApiConnector->get("TSTDIMGRP", $office); + } catch (ResponseException $e) { + $dimensionGroup = $e->getReturnedObject(); + } + + $dimensionGroup->setCode("TSTDIMGRP2"); + + try { + $dimensionGroupCopy = $dimensionGroupApiConnector->send($dimensionGroup); + } catch (ResponseException $e) { + $dimensionGroupCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroupCopy);
+    echo "
"; + + echo "Result of copy process: {$dimensionGroupCopy->getResult()}
"; + echo "Code of copied DimensionGroup: {$dimensionGroupCopy->getCode()}
"; + echo "Status of copied DimensionGroup: {$dimensionGroupCopy->getStatus()}
"; +} + +// Create a new DimensionGroup from scratch, alternatively read an existing DimensionGroup as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $dimensionGroup = new \PhpTwinfield\DimensionGroup; + + // Required values for creating a new DimensionGroup + $dimensionGroup->setCode('DIMGRP2'); // string|null Dimension group code. + $dimensionGroup->setName("Dimension Group 2"); // string|null Name of the dimension group. + $dimensionGroup->setOffice($office); // Office|null Office code. + $dimensionGroup->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + $dimensionGroup->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating active should be used. For deleting deleted should be used. + //$dimensionGroup->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + + // Optional values for creating a new DimensionGroup + $dimensionGroup->setShortName("DIM GRP 2"); // string|null Short name of the dimension group. + + // The minimum amount of DimensionGroupDimensions linked to a DimensionGroup object is 0 + $dimensionGroupDimension = new \PhpTwinfield\DimensionGroupDimension; + $code = new \PhpTwinfield\GeneralLedger; + $code->setCode('1010'); + $dimensionGroupDimension->setCode($code); // object|null Code of the dimension. + $dimensionGroupDimension->setCode(\PhpTwinfield\GeneralLedger::fromCode('1010')); // string|null + $type = new \PhpTwinfield\DimensionType; + $type->setCode('BAS'); + $dimensionGroupDimension->setType($type); // DimensionType|null Dimension type. + $dimensionGroupDimension->setType(\PhpTwinfield\DimensionType::fromCode('BAS')); // string|null + + $dimensionGroup->addDimension($dimensionGroupDimension); // DimensionGroupDimension Add a DimensionGroupDimension object to the DimensionGroup object + //$dimensionGroup->removeDimension(0); // int Remove a dimension based on the index of the dimension within the array + + try { + $dimensionGroupNew = $dimensionGroupApiConnector->send($dimensionGroup); + } catch (ResponseException $e) { + $dimensionGroupNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroupNew);
+    echo "
"; + + echo "Result of creation process: {$dimensionGroupNew->getResult()}
"; + echo "Code of new DimensionGroup: {$dimensionGroupNew->getCode()}
"; + echo "Status of new DimensionGroup: {$dimensionGroupNew->getStatus()}
"; +} + +// Delete a DimensionGroup based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $dimensionGroupDeleted = $dimensionGroupApiConnector->delete("DIMGRP2", $office); + } catch (ResponseException $e) { + $dimensionGroupDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionGroupDeleted);
+    echo "
"; + + echo "Result of deletion process: {$dimensionGroupDeleted->getResult()}
"; + echo "Code of deleted DimensionGroup: {$dimensionGroupDeleted->getCode()}
"; + echo "Status of deleted DimensionGroup: {$dimensionGroupDeleted->getStatus()}
"; +} diff --git a/examples/DimensionType.php b/examples/DimensionType.php new file mode 100644 index 00000000..2d305185 --- /dev/null +++ b/examples/DimensionType.php @@ -0,0 +1,208 @@ + finlevel = 2 +if ($executeListAllWithFilter) { + $options = array('finlevel' => 2); + + try { + $dimensionTypes = $dimensionTypeApiConnector->listAll("*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $dimensionTypes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionTypes);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $dimensionTypes = $dimensionTypeApiConnector->listAll(); + } catch (ResponseException $e) { + $dimensionTypes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionTypes);
+    echo "
"; +} + +/* DimensionType + * \PhpTwinfield\DimensionType + * Available getters: getCode, getMask, getMessages, getName, getOffice, getResult, getShortName, getStatus, hasMessages, getAddress, getLevels + * Available setters: fromCode, setCode, setMask, setName, setOffice, setShortName, setStatus, setAddress, setLevels + */ + +/* DimensionTypeLevels + * \PhpTwinfield\DimensionTypeLevels + * Available getters: getFinancials, getMessages, getResult, getTime, hasMessages + * Available setters: setFinancials, setTime + */ + +/* DimensionTypeAddress + * \PhpTwinfield\DimensionTypeAddress + * Available getters: getLabel1, getLabel2, getLabel3, getLabel4, getLabel5, getLabel6, getMessages, getResult, hasMessages + * Available setters: setLabel1, setLabel2, setLabel3, setLabel4, setLabel5, setLabel6 + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($dimensionTypes as $key => $dimensionType) { + echo "DimensionType {$key}
"; + echo "Code: {$dimensionType->getCode()}
"; + echo "Name: {$dimensionType->getName()}

"; + } +} + +// Read a DimensionType based off the passed in code and optionally the office. +if ($executeRead) { + try { + $dimensionType = $dimensionTypeApiConnector->get("ACT", $office); + } catch (ResponseException $e) { + $dimensionType = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionType);
+    echo "
"; + + echo "DimensionType
"; + echo "Code: {$dimensionType->getCode()}
"; // string|null Dimension type. + echo "Mask: {$dimensionType->getMask()}
"; // string|null Dimension type mask. + + if ($dimensionType->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($dimensionType->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$dimensionType->getName()}
"; // string|null Dimension type name. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($dimensionType->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($dimensionType->getOffice()) . "
"; // string|null + echo "Result: {$dimensionType->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$dimensionType->getShortName()}
"; // string|null Dimension type short name. + echo "Status: {$dimensionType->getStatus()}
"; // Status|null Status of the dimension type. + + $dimensionTypeLevels = $dimensionType->getLevels(); // DimensionTypeLevels|null DimensionTypeLevels object. + + echo "Financials: {$dimensionTypeLevels->getFinancials()}
"; // int|null Read-only attribute. Financial level. + + if ($dimensionTypeLevels->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($dimensionTypeLevels->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$dimensionTypeLevels->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Time: {$dimensionTypeLevels->getTime()}
"; // int|null Read-only attribute. Level in time & expenses. + + $dimensionTypeAddress = $dimensionType->getAddress(); // DimensionTypeAddress|null DimensionTypeAddress object. + + echo "Label 1: {$dimensionTypeAddress->getLabel1()}
"; // string|null Address labels, description of field1 in the dimension address element. + echo "Label 2: {$dimensionTypeAddress->getLabel2()}
"; // string|null Address labels, description of field2 in the dimension address element. + echo "Label 3: {$dimensionTypeAddress->getLabel3()}
"; // string|null Address labels, description of field3 in the dimension address element. + echo "Label 4: {$dimensionTypeAddress->getLabel4()}
"; // string|null Address labels, description of field4 in the dimension address element. + echo "Label 5: {$dimensionTypeAddress->getLabel5()}
"; // string|null Address labels, description of field5 in the dimension address element. + echo "Label 6: {$dimensionTypeAddress->getLabel6()}
"; // string|null Address labels, description of field6 in the dimension address element. + + if ($dimensionTypeAddress->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($dimensionTypeAddress->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$dimensionTypeAddress->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). +} + +// Copy an existing DimensionType to a new entity +if ($executeModify) { + try { + $dimensionType = $dimensionTypeApiConnector->get("CRD", $office); + } catch (ResponseException $e) { + $dimensionType = $e->getReturnedObject(); + } + + $dimensionType->setMask("2[0-9][0-9][0-9]"); // string|null Dimension type mask. + $dimensionType->setName("Creditors"); // string|null Dimension type name. + $dimensionType->setShortName("Cred"); // string|null Dimension type short name. + + $dimensionTypeAddress = $dimensionType->getAddress(); + + $dimensionTypeAddress->setLabel1('Tav'); // string|null Address labels, description of field1 in the dimension address element. + $dimensionTypeAddress->setLabel2('Address'); // string|null Address labels, description of field2 in the dimension address element. + $dimensionTypeAddress->setLabel4('VAT'); // string|null Address labels, description of field4 in the dimension address element. + $dimensionTypeAddress->setLabel5('CoC'); // string|null Address labels, description of field5 in the dimension address element. + + try { + $dimensionTypeModify = $dimensionTypeApiConnector->send($dimensionType); + } catch (ResponseException $e) { + $dimensionTypeModify = $e->getReturnedObject(); + } + + echo "
";
+    print_r($dimensionTypeModify);
+    echo "
"; + + echo "Result of modify process: {$dimensionTypeModify->getResult()}
"; + echo "Code of modified DimensionType: {$dimensionTypeModify->getCode()}
"; + echo "Status of modified DimensionType: {$dimensionTypeModify->getStatus()}
"; +} diff --git a/examples/FixedAsset.php b/examples/FixedAsset.php new file mode 100644 index 00000000..ebcf3248 --- /dev/null +++ b/examples/FixedAsset.php @@ -0,0 +1,436 @@ + modifiedsince = '20190101170000' +if ($executeListAllWithFilter) { + $options = array('modifiedsince' => '20190101170000'); + + try { + $fixedAssets = $fixedAssetApiConnector->listAll("6*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $fixedAssets = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAssets);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $fixedAssets = $fixedAssetApiConnector->listAll(); + } catch (ResponseException $e) { + $fixedAssets = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAssets);
+    echo "
"; +} + +/* FixedAsset + * \PhpTwinfield\FixedAsset + * Available getters: getBehaviour, getCode, getGroup, getInUse, getMessages, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUID, hasMessages, getFinancials, getFixedAssets + * Available setters: fromCode, setBehaviour, setCode, setGroup, setName, setOffice, setShortName, setStatus, setType, setTypeFromString, setFinancials, setFixedAssets + */ + +/* FixedAssetFinancials + * \PhpTwinfield\FixedAssetFinancials + * Available getters: getAccountType, getLevel, getMatchType, getMessages, getResult, getSubAnalyse, getSubstituteWith, getSubstituteWithID, getSubstitutionLevel, getVatCode, getVatCodeFixed, hasMessages + * Available setters: setAccountType, setLevel, setMatchType, setSubAnalyse, setSubstituteWith, setSubstituteWithID, setSubstitutionLevel, setVatCode, setVatCodeFixed + */ + +/* FixedAssetFixedAssets + * \PhpTwinfield\FixedAssetFixedAssets + * Available getters: getBeginPeriod, getBeginPeriodLocked, getFreeText1, getFreeText1Locked, getFreeText2, getFreeText2Locked, getFreeText3, getFreeText3Locked, getFreeText4, getFreeText4Locked, getFreeText5, getFreeText5Locked, getLastDepreciation, getLastDepreciationLocked, getMessages, getMethod, getMethodLocked, + * getNrOfPeriods, getNrOfPeriodsInherited, getNrOfPeriodsLocked, getPercentage, getPercentageLocked, getPurchaseDate, getPurchaseDateLocked, getResidualValue, getResidualValueLocked, getResult, getSellDate, getSellDateLocked, getStatus, getStatusLocked, getStopValue, getStopValueLocked, getTransactionLinesLocked, hasMessages, getTransactionLines + * + * Available setters: setBeginPeriod, setBeginPeriodLocked, setFreeText1, setFreeText1Locked, setFreeText2, setFreeText2Locked, setFreeText3, setFreeText3Locked, setFreeText4, setFreeText4Locked, setFreeText5, setFreeText5Locked, setLastDepreciation, setLastDepreciationLocked, setMethod, setMethodLocked, + * setNrOfPeriods, setNrOfPeriodsInherited, setNrOfPeriodsLocked, setPercentage, setPercentageLocked, setPurchaseDate, setPurchaseDateLocked, setResidualValue, setResidualValueLocked, setSellDate, setSellDateLocked, setStatus, setStatusLocked, setStopValue, setStopValueLocked, setTransactionLinesLocked, addTransactionLine, removeTransactionLine + * + */ + +/* FixedAssetTransactionLine + * \PhpTwinfield\FixedAssetTransactionLine + * Available getters: getAmount, getAmountLocked, getCode, getCodeLocked, getDim1, getDim1Locked, getDim2, getDim2Locked, getDim3, getDim3Locked, getDim4, getDim4Locked, getDim5, getDim5Locked, getDim6, getDim6Locked, getLine, getLineLocked, getMessages, getNumber, getNumberLocked, getPeriod, getPeriodLocked, getResult, hasMessages + * Available setAmount, setAmountLocked, setCode, setCodeLocked, setDim1, setDim1Locked, setDim2, setDim2Locked, setDim3, setDim3Locked, setDim4, setDim4Locked, setDim5, setDim5Locked, setDim6, setDim6Locked, setLine, setLineLocked, setNumber, setNumberLocked, setPeriod, setPeriodLocked + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($fixedAssets as $key => $fixedAsset) { + echo "FixedAsset {$key}
"; + echo "Code: {$fixedAsset->getCode()}
"; + echo "Name: {$fixedAsset->getName()}

"; + } +} + +// Read a FixedAsset based off the passed in code and optionally the office. +if ($executeRead) { + try { + $fixedAsset = $fixedAssetApiConnector->get("60001", $office); + } catch (ResponseException $e) { + $fixedAsset = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAsset);
+    echo "
"; + + echo "FixedAsset
"; + echo "Behaviour: {$fixedAsset->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$fixedAsset->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the AST Dimension type. + echo "Group (\\PhpTwinfield\\DimensionGroup):
" . print_r($fixedAsset->getGroup(), true) . "

"; // DimensionGroup|null Sets the dimension group. See Dimension group. + echo "Group (string): " . Util::objectToStr($fixedAsset->getGroup()) . "
"; // string|null + echo "InUse (bool): {$fixedAsset->getInUse()}
"; // bool|null Indicates whether the fixed asset is used in a financial transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($fixedAsset->getInUse()) . "
"; // string|null + + if ($fixedAsset->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($fixedAsset->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$fixedAsset->getName()}
"; // string|null Name of the dimension. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($fixedAsset->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($fixedAsset->getOffice()) . "
"; // string|null + echo "Result: {$fixedAsset->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$fixedAsset->getShortName()}
"; // string|null Not in use. + echo "Status: {$fixedAsset->getStatus()}
"; // Status|null Status of the fixed asset. + echo "Touched: {$fixedAsset->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($fixedAsset->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of fixed assets is AST. + echo "Type (string): " . Util::objectToStr($fixedAsset->getType()) . "
"; // string|null + echo "UID: {$fixedAsset->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + + echo "FixedAssetFinancials
"; + $fixedAssetFinancials = $fixedAsset->getFinancials(); // FixedAssetFinancials|null FixedAssetFinancials object. + + echo "AccountType: {$fixedAssetFinancials->getAccountType()}
"; // AccountType|null Fixed value inherit. Read-only attribute. + echo "Level: {$fixedAssetFinancials->getLevel()}
"; // int|null Specifies the dimension level. Normally the level of fixed assets is level 3. Read-only attribute. + echo "MatchType: {$fixedAssetFinancials->getMatchType()}
"; // MatchType|null The matchable value of the balance account. Read-only attribute. + + if ($fixedAssetFinancials->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($fixedAssetFinancials->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$fixedAssetFinancials->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SubAnalyse: {$fixedAssetFinancials->getSubAnalyse()}
"; // SubAnalyse|null Is subanalyses needed. Read-only attribute. + echo "SubstituteWith (\\PhpTwinfield\\CostCenter):
" . print_r($fixedAssetFinancials->getSubstituteWith(), true) . "

"; // CostCenter|null Dimension code of the cost center. + echo "SubstituteWith (string): " . Util::objectToStr($fixedAssetFinancials->getSubstituteWith()) . "
"; // string|null + echo "SubstituteWithID: {$fixedAssetFinancials->getSubstituteWithID()}
"; // string|null + echo "SubstitutionLevel: {$fixedAssetFinancials->getSubstitutionLevel()}
"; // int|null Dimension level of the cost center. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($fixedAssetFinancials->getVatCode(), true) . "

"; // VatCode|null Default VAT code. + echo "VatCode (string): " . Util::objectToStr($fixedAssetFinancials->getVatCode()) . "
"; // string|null + echo "VatCode Fixed (bool): {$fixedAssetFinancials->getVatCodeFixed()}
"; // bool|null + echo "VatCode Fixed (string): " . Util::formatBoolean($fixedAssetFinancials->getVatCodeFixed()) . "
"; // string|null + + $fixedAssetFixedAssets = $fixedAsset->getFixedAssets(); // array|null Array of FixedAssetFixedAssets objects. + + echo "FixedAssetFixedAssets {$key}
"; + + echo "BeginPeriod: {$fixedAssetFixedAssets->getBeginPeriod()}
"; // string|null Period in YYYY/PP format. The period from which the depreciation to begin. + echo "BeginPeriod Locked (bool): {$fixedAssetFixedAssets->getBeginPeriodLocked()}
"; // bool|null + echo "BeginPeriod Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getBeginPeriodLocked()) . "
"; // string|null + echo "FreeText1: {$fixedAssetFixedAssets->getFreeText1()}
"; // string|null Free text field 1 as set on the asset method. + echo "FreeText1 Locked (bool): {$fixedAssetFixedAssets->getFreeText1Locked()}
"; // bool|null + echo "FreeText1 Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getFreeText1Locked()) . "
"; // string|null + echo "FreeText2: {$fixedAssetFixedAssets->getFreeText2()}
"; // string|null Free text field 2 as set on the asset method. + echo "FreeText2 Locked (bool): {$fixedAssetFixedAssets->getFreeText2Locked()}
"; // bool|null + echo "FreeText2 Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getFreeText2Locked()) . "
"; // string|null + echo "FreeText3: {$fixedAssetFixedAssets->getFreeText3()}
"; // string|null Free text field 3 as set on the asset method. + echo "FreeText3 Locked (bool): {$fixedAssetFixedAssets->getFreeText3Locked()}
"; // bool|null + echo "FreeText3 Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getFreeText3Locked()) . "
"; // string|null + echo "FreeText4: {$fixedAssetFixedAssets->getFreeText4()}
"; // string|null Free text field 4 as set on the asset method. + echo "FreeText4 Locked (bool): {$fixedAssetFixedAssets->getFreeText4Locked()}
"; // bool|null + echo "FreeText4 Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getFreeText4Locked()) . "
"; // string|null + echo "FreeText5: {$fixedAssetFixedAssets->getFreeText5()}
"; // string|null Free text field 5 as set on the asset method. + echo "FreeText5 Locked (bool): {$fixedAssetFixedAssets->getFreeText5Locked()}
"; // bool|null + echo "FreeText5 Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getFreeText5Locked()) . "
"; // string|null + echo "LastDepreciation: {$fixedAssetFixedAssets->getLastDepreciation()}
"; // string|null Period in YYYY/PP format. The period of the last depreciation of the asset. + echo "LastDepreciation Locked (bool): {$fixedAssetFixedAssets->getLastDepreciationLocked()}
"; // bool|null + echo "LastDepreciation Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getLastDepreciationLocked()) . "
"; // string|null + + if ($fixedAssetFixedAssets->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($fixedAssetFixedAssets->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Method (\\PhpTwinfield\\AssetMethod):
" . print_r($fixedAssetFixedAssets->getMethod(), true) . "

"; // AssetMethod|null The asset method. See Asset methods. + echo "Method (string): " . Util::objectToStr($fixedAssetFixedAssets->getMethod()) . "
"; // string|null + echo "Method Locked (bool): {$fixedAssetFixedAssets->getMethodLocked()}
"; // bool|null + echo "Method Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getMethodLocked()) . "
"; // string|null + echo "NrOfPeriods: {$fixedAssetFixedAssets->getNrOfPeriods()}
"; // int|null The number of periods over which the asset should be depreciated. + echo "NrOfPeriods Inherited (bool): {$fixedAssetFixedAssets->getNrOfPeriodsInherited()}
"; // bool|null + echo "NrOfPeriods Inherited (string): " . Util::formatBoolean($fixedAssetFixedAssets->getNrOfPeriodsInherited()) . "
"; // string|null + echo "NrOfPeriods Locked (bool): {$fixedAssetFixedAssets->getNrOfPeriodsLocked()}
"; // bool|null + echo "NrOfPeriods Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getNrOfPeriodsLocked()) . "
"; // string|null + echo "Percentage: {$fixedAssetFixedAssets->getPercentage()}
"; // int|null The depreciation percentage. + echo "Percentage Locked (bool): {$fixedAssetFixedAssets->getPercentageLocked()}
"; // bool|null + echo "Percentage Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getPercentageLocked()) . "
"; // string|null + echo "PurchaseDate (\\DateTimeInterface):
" . print_r($fixedAssetFixedAssets->getPurchaseDate(), true) . "

"; // DateTimeInterface|null The purchase date of the asset. + echo "PurchaseDate (string): " . Util::formatDate($fixedAssetFixedAssets->getPurchaseDate()) . "
"; // string|null + echo "PurchaseDate Locked (bool): {$fixedAssetFixedAssets->getPurchaseDateLocked()}
"; // bool|null + echo "PurchaseDate Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getPurchaseDateLocked()) . "
"; // string|null + echo "ResidualValue (\\Money\\Money):
" . print_r($fixedAssetFixedAssets->getResidualValue(), true) . "

"; // Money|null The residual value of the asset at the end of the depreciation duration. + echo "ResidualValue (string): " . Util::formatMoney($fixedAssetFixedAssets->getResidualValue()) . "
"; // string|null + echo "ResidualValue Locked (bool): {$fixedAssetFixedAssets->getResidualValueLocked()}
"; // bool|null + echo "ResidualValue Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getResidualValueLocked()) . "
"; // string|null + echo "Result: {$fixedAssetFixedAssets->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SellDate (\\DateTimeInterface):
" . print_r($fixedAssetFixedAssets->getSellDate(), true) . "

"; // DateTimeInterface|null The date the asset is sold. + echo "SellDate (string): " . Util::formatDate($fixedAssetFixedAssets->getSellDate()) . "
"; // string|null + echo "SellDate Locked (bool): {$fixedAssetFixedAssets->getSellDateLocked()}
"; // bool|null + echo "SellDate Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getSellDateLocked()) . "
"; // string|null + echo "Status: {$fixedAssetFixedAssets->getStatus()}
"; // FixedAssetsStatus|null The status of the asset. + echo "Status Locked (bool): {$fixedAssetFixedAssets->getStatusLocked()}
"; // bool|null The value future depreciation should stop at. + echo "Status Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getStatusLocked()) . "
"; // string|null + echo "StopValue (\\Money\\Money):
" . print_r($fixedAssetFixedAssets->getStopValue(), true) . "

"; // Money|null Transaction line amount. + echo "StopValue (string): " . Util::formatMoney($fixedAssetFixedAssets->getStopValue()) . "
"; // string|null + echo "StopValue Locked (bool): {$fixedAssetFixedAssets->getStopValueLocked()}
"; // bool|null + echo "StopValue Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getStopValueLocked()) . "
"; // string|null + echo "TransactionLines Locked (bool): {$fixedAssetFixedAssets->getTransactionLinesLocked()}
"; // bool|null + echo "TransactionLines Locked (string): " . Util::formatBoolean($fixedAssetFixedAssets->getTransactionLinesLocked()) . "
"; // string|null + + $fixedAssetTransactionLines = $fixedAssetFixedAssets->getTransactionLines(); // array|null Array of FixedAssetTransactionLine objects. + + foreach ($fixedAssetTransactionLines as $key => $fixedAssetTransactionLine) { + echo "FixedAssetTransactionLine {$key}
"; + + echo "Amount (\\Money\\Money):
" . print_r($fixedAssetTransactionLine->getAmount(), true) . "

"; // Money|null Transaction line amount. + echo "Amount (string): " . Util::formatMoney($fixedAssetTransactionLine->getAmount()) . "
"; // string|null + echo "Amount Locked (bool): {$fixedAssetTransactionLine->getAmountLocked()}
"; // bool|null + echo "Amount Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getAmountLocked()) . "
"; // string|null + echo "Code (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getCode(), true) . "

"; // HasCodeInterface|null Transaction type code. + echo "Code (string): " . Util::objectToStr($fixedAssetTransactionLine->getCode()) . "
"; // string|null + echo "Code Locked (bool): {$fixedAssetTransactionLine->getCodeLocked()}
"; // bool|null + echo "Code Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getCodeLocked()) . "
"; // string|null + echo "Dim1 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim1(), true) . "

"; // HasCodeInterface|null Dimension 1 of the tranaction line. + echo "Dim1 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim1()) . "
"; // string|null + echo "Dim1 Locked (bool): {$fixedAssetTransactionLine->getDim1Locked()}
"; // bool|null + echo "Dim1 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim1Locked()) . "
"; // string|null + echo "Dim2 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim2(), true) . "

"; // HasCodeInterface|null Dimension 2 of the tranaction line. + echo "Dim2 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim2()) . "
"; // string|null + echo "Dim2 Locked (bool): {$fixedAssetTransactionLine->getDim2Locked()}
"; // bool|null + echo "Dim2 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim2Locked()) . "
"; // string|null + echo "Dim3 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim3(), true) . "

"; // HasCodeInterface|null Dimension 3 of the tranaction line. + echo "Dim3 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim3()) . "
"; // string|null + echo "Dim3 Locked (bool): {$fixedAssetTransactionLine->getDim3Locked()}
"; // bool|null + echo "Dim3 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim3Locked()) . "
"; // string|null + echo "Dim4 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim4(), true) . "

"; // HasCodeInterface|null Dimension 4 of the tranaction line. + echo "Dim4 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim4()) . "
"; // string|null + echo "Dim4 Locked (bool): {$fixedAssetTransactionLine->getDim4Locked()}
"; // bool|null + echo "Dim4 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim4Locked()) . "
"; // string|null + echo "Dim5 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim5(), true) . "

"; // HasCodeInterface|null Dimension 5 of the tranaction line. + echo "Dim5 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim5()) . "
"; // string|null + echo "Dim5 Locked (bool): {$fixedAssetTransactionLine->getDim5Locked()}
"; // bool|null + echo "Dim5 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim5Locked()) . "
"; // string|null + echo "Dim6 (\\PhpTwinfield\\HasCodeInterface):
" . print_r($fixedAssetTransactionLine->getDim6(), true) . "

"; // HasCodeInterface|null Dimension 6 of the tranaction line. + echo "Dim6 (string): " . Util::objectToStr($fixedAssetTransactionLine->getDim6()) . "
"; // string|null + echo "Dim6 Locked (bool): {$fixedAssetTransactionLine->getDim6Locked()}
"; // bool|null + echo "Dim6 Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getDim6Locked()) . "
"; // string|null + echo "Line: {$fixedAssetTransactionLine->getLine()}
"; // int|null Transaction line number. + echo "Line Locked (bool): {$fixedAssetTransactionLine->getLineLocked()}
"; // bool|null + echo "Line Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getLineLocked()) . "
"; // string|null + + if ($fixedAssetTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($fixedAssetTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Number: {$fixedAssetTransactionLine->getNumber()}
"; // int|null Transaction number. + echo "Number Locked (bool): {$fixedAssetTransactionLine->getNumberLocked()}
"; // bool|null + echo "Number Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getNumberLocked()) . "
"; // string|null + echo "Period: {$fixedAssetTransactionLine->getPeriod()}
"; // string|null Period in YYYY/PP format. Period of the transaction. + echo "Period Locked (bool): {$fixedAssetTransactionLine->getPeriodLocked()}
"; // bool|null + echo "Period Locked (string): " . Util::formatBoolean($fixedAssetTransactionLine->getPeriodLocked()) . "
"; // string|null + echo "Result: {$fixedAssetTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + } +} + +// Copy an existing FixedAsset to a new entity +if ($executeCopy) { + try { + $fixedAsset = $fixedAssetApiConnector->get("60001", $office); + } catch (ResponseException $e) { + $fixedAsset = $e->getReturnedObject(); + } + + $fixedAsset->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$fixedAsset->setCode('60002'); // string|null Dimension code, must be compliant with the mask of the AST Dimension type. + + try { + $fixedAssetCopy = $fixedAssetApiConnector->send($fixedAsset); + } catch (ResponseException $e) { + $fixedAssetCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAssetCopy);
+    echo "
"; + + echo "Result of copy process: {$fixedAssetCopy->getResult()}
"; + echo "Code of copied FixedAsset: {$fixedAssetCopy->getCode()}
"; + echo "Status of copied FixedAsset: {$fixedAssetCopy->getStatus()}
"; +} + +// Create a new FixedAsset from scratch, alternatively read an existing FixedAsset as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $fixedAsset = new \PhpTwinfield\FixedAsset; + + // Required values for creating a new FixedAsset + $fixedAsset->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$fixedAsset->setCode('60002'); // string|null Dimension code, must be compliant with the mask of the AST Dimension type. + $fixedAsset->setName("Example FixedAsset"); // string|null Name of the dimension. + $fixedAsset->setOffice($office); // Office|null Office code. + $fixedAsset->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new FixedAsset + //$fixedAsset->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$fixedAsset->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case a dimension that is used in a transaction is deleted, its status has been changed into hide. Hidden dimensions can be activated by using active. + + $dimensionGroup = new \PhpTwinfield\DimensionGroup; + $dimensionGroup->setCode('DIMGROUP'); + //$fixedAsset->setGroup($dimensionGroup); // DimensionGroup|null Sets the dimension group. See Dimension group. + //$fixedAsset->setGroup(\PhpTwinfield\DimensionGroup::fromCode("DIMGROUP")); // string|null + + $fixedAssetFinancials = new \PhpTwinfield\FixedAssetFinancials; + $substituteWith = new \PhpTwinfield\CostCenter; + $substituteWith->getCode('00001'); + $fixedAssetFinancials->setSubstituteWith($substituteWith); // CostCenter|null Dimension code of the cost center. + $fixedAssetFinancials->setSubstituteWith(\PhpTwinfield\CostCenter::fromCode('00001')); // string|null + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $fixedAssetFinancials->setVatCode($vatCode); // VatCode|null Default VAT code. + $fixedAssetFinancials->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + $fixedAsset->setFinancials($fixedAssetFinancials); // FixedAssetFinancials Set the FixedAssetFinancials object tot the FixedAsset object + + $fixedAssetFixedAssets = new \PhpTwinfield\FixedAssetFixedAssets; + $fixedAssetFixedAssets->setBeginPeriod('2019/01'); // string|null Period in YYYY/PP format. The period from which the depreciation to begin. + $fixedAssetFixedAssets->setFreeText1('1'); // string|null Free text field 1 as set on the asset method. + $fixedAssetFixedAssets->setFreeText2('3'); // string|null Free text field 2 as set on the asset method. + $fixedAssetFixedAssets->setFreeText3('3'); // string|null Free text field 3 as set on the asset method. + $fixedAssetFixedAssets->setFreeText4('4'); // string|null Free text field 4 as set on the asset method. + $fixedAssetFixedAssets->setFreeText5('5'); // string|null Free text field 5 as set on the asset method. + $fixedAssetFixedAssets->setLastDepreciation('2019/12'); // string|null Period in YYYY/PP format. The period of the last depreciation of the asset. + $method = new \PhpTwinfield\AssetMethod; + $method->setCode('101'); + $fixedAssetFixedAssets->setMethod($currency); // AssetMethod|null The asset method. See Asset methods. + $fixedAssetFixedAssets->setMethod(\PhpTwinfield\AssetMethod::fromCode('101')); // string|null + $fixedAssetFixedAssets->setNrOfPeriods(12); // int|null The number of periods over which the asset should be depreciated. + //$fixedAssetFixedAssets->setPercentage(8); // int|null The depreciation percentage. + $purchaseDate = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $fixedAssetFixedAssets->setPurchaseDate($purchaseDate); // DateTimeInterface|null The purchase date of the asset. + $fixedAssetFixedAssets->setPurchaseDate(Util::parseDate('20190101')); // string|null + $fixedAssetFixedAssets->setResidualValue(\Money\Money::EUR(50000)); // Money|null The residual value of the asset at the end of the depreciation duration. (Equals 500.00 EUR) + $sellDate = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + //$fixedAssetFixedAssets->setSellDate($sellDate); // DateTimeInterface|null The date the asset is sold. + //$fixedAssetFixedAssets->setSellDate(Util::parseDate('20190101')); // string|null + $fixedAssetFixedAssets->setStopValue(\Money\Money::EUR(0)); // Money|null The value future depreciation should stop at. (Equals 0.00 EUR) + + $fixedAsset->setFixedAssets($fixedAssetFixedAssets); // FixedAssetFixedAssets Set the FixedAssetFixedAssets object tot the FixedAsset object + + try { + $fixedAssetNew = $fixedAssetApiConnector->send($fixedAsset); + } catch (ResponseException $e) { + $fixedAssetNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAssetNew);
+    echo "
"; + + echo "Result of creation process: {$fixedAssetNew->getResult()}
"; + echo "Code of new FixedAsset: {$fixedAssetNew->getCode()}
"; + echo "Status of new FixedAsset: {$fixedAssetNew->getStatus()}
"; +} + +// Delete a FixedAsset based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $fixedAssetDeleted = $fixedAssetApiConnector->delete("60002", $office); + } catch (ResponseException $e) { + $fixedAssetDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($fixedAssetDeleted);
+    echo "
"; + + echo "Result of deletion process: {$fixedAssetDeleted->getResult()}
"; + echo "Code of deleted FixedAsset: {$fixedAssetDeleted->getCode()}
"; + echo "Status of deleted FixedAsset: {$fixedAssetDeleted->getStatus()}
"; +} diff --git a/examples/GeneralLedger.php b/examples/GeneralLedger.php new file mode 100644 index 00000000..aa6bc19a --- /dev/null +++ b/examples/GeneralLedger.php @@ -0,0 +1,304 @@ + dimtype = 'BAS' +if ($executeListAllWithFilter) { + $options = array('dimtype' => 'BAS'); + + try { + $generalLedgers = $generalLedgerApiConnector->listAll("1*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $generalLedgers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedgers);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $generalLedgers = $generalLedgerApiConnector->listAll(); + } catch (ResponseException $e) { + $generalLedgers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedgers);
+    echo "
"; +} + +/* GeneralLedger + * \PhpTwinfield\GeneralLedger + * Available getters: getBeginPeriod, getBeginYear, getBehaviour, getCode, getEndPeriod, getEndYear, getGroup, getInUse, getMessages, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getWebsite, hasMessages, getFinancials + * Available setters: fromCode, setBeginPeriod, setBeginYear, setBehaviour, setCode, setEndPeriod, setEndYear, setGroup, setName, setOffice, setShortName, setStatus, setType, setFinancials + */ + +/* GeneralLedgerFinancials + * \PhpTwinfield\GeneralLedgerFinancials + * Available getters: getAccountType, getLevel, getMatchType, getMessages, getResult, getSubAnalyse, getVatCode, getVatCodeFixed, getChildValidations, hasMessages + * Available setters: setAccountType, setLevel, setMatchType, setSubAnalyse, setVatCode, setVatCodeFixed, addChildValidation, removeChildValidation + */ + +/* GeneralLedgerChildValidation + * \PhpTwinfield\GeneralLedgerChildValidation + * Available getters: getElementValue, getLevel, getMessages, getResult, getType, hasMessages + * Available setters: setElementValue, setLevel, setType + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($generalLedgers as $key => $generalLedger) { + echo "GeneralLedger {$key}
"; + echo "Code: {$generalLedger->getCode()}
"; + echo "Name: {$generalLedger->getName()}

"; + } +} + +// Read a GeneralLedger based off the passed in code, dimension type and optionally the office. +if ($executeRead) { + try { + $generalLedger = $generalLedgerApiConnector->get("1000", "BAS", $office); + } catch (ResponseException $e) { + $generalLedger = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedger);
+    echo "
"; + + echo "GeneralLedger
"; + echo "BeginPeriod: {$generalLedger->getBeginPeriod()}
"; // int|null Determines together with beginyear the period from which the dimension may be used. + echo "BeginYear: {$generalLedger->getBeginYear()}
"; // int|null Determines together with beginperiod the period from which the dimension may be used. + echo "Behaviour: {$generalLedger->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$generalLedger->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the BAS or PNL Dimension type. + echo "EndPeriod: {$generalLedger->getEndPeriod()}
"; // int|null Determines together with endyear the period till which the dimension may be used. + echo "EndYear: {$generalLedger->getEndYear()}
"; // int|null Determines together with endperiod the period till which the dimension may be used. + echo "Group (\\PhpTwinfield\\DimensionGroup):
" . print_r($generalLedger->getGroup(), true) . "

"; // DimensionGroup|null Sets the dimension group. See Dimension group. + echo "Group (string): " . Util::objectToStr($generalLedger->getGroup()) . "
"; // string|null + echo "InUse (bool): {$generalLedger->getInUse()}
"; // bool|null Indicates if the balance or profit and loss account is used in a financial transaction or linked to a VAT code or linked to an article or not in use at all. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($generalLedger->getInUse()) . "
"; // string|null + + if ($generalLedger->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($generalLedger->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$generalLedger->getName()}
"; // string|null Name of the dimension. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($generalLedger->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($generalLedger->getOffice()) . "
"; // string|null + echo "Result: {$generalLedger->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$generalLedger->getShortName()}
"; // string|null Short name of the dimension. + echo "Status: {$generalLedger->getStatus()}
"; // Status|null Status of the generalLedger. + echo "Touched: {$generalLedger->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($generalLedger->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of balance accounts is BAS and type of profit and loss is PNL. + echo "Type (string): " . Util::objectToStr($generalLedger->getType()) . "
"; // string|null + echo "UID: {$generalLedger->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + + echo "GeneralLedgerFinancials
"; + $generalLedgerFinancials = $generalLedger->getFinancials(); // GeneralLedgerFinancials|null GeneralLedgerFinancials object. + + echo "AccountType: {$generalLedgerFinancials->getAccountType()}
"; // AccountType|null Fixed value balance. + echo "Level: {$generalLedgerFinancials->getLevel()}
"; // int|null Specifies the dimension level. Normally the level of balance accounts is level 1. Read-only attribute. + echo "MatchType: {$generalLedgerFinancials->getMatchType()}
"; // MatchType|null Sets the matchable value of the balance account. + + if ($generalLedgerFinancials->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($generalLedgerFinancials->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$generalLedgerFinancials->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SubAnalyse: {$generalLedgerFinancials->getSubAnalyse()}
"; // SubAnalyse|null Is subanalyses needed. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($generalLedgerFinancials->getVatCode(), true) . "

"; // VatCode|null Default VAT code. + echo "VatCode (string): " . Util::objectToStr($generalLedgerFinancials->getVatCode()) . "
"; // string|null + echo "VatCode Fixed (bool): {$generalLedgerFinancials->getVatCodeFixed()}
"; // bool|null + echo "VatCode Fixed (string): " . Util::formatBoolean($generalLedgerFinancials->getVatCodeFixed()) . "
"; // string|null + + $generalLedgerChildValidations = $generalLedgerFinancials->getChildValidations(); // array|null Array of GeneralLedgerChildValidations objects. Validation rule when subanalyses is needed. + + foreach ($generalLedgerChildValidations as $key => $generalLedgerChildValidation) { + echo "GeneralLedgerChildValidation {$key}
"; + + echo "ElementValue: {$generalLedgerChildValidation->getElementValue()}
"; // string|null + echo "Level: {$generalLedgerChildValidation->getLevel()}
"; // int|null + + if ($generalLedgerChildValidation->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($generalLedgerChildValidation->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$generalLedgerChildValidation->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Type: {$generalLedgerChildValidation->getType()}
"; // ChildValidationType|null + } +} + +// Copy an existing GeneralLedger to a new entity +if ($executeCopy) { + try { + $generalLedger = $generalLedgerApiConnector->get("1000", "BAS", $office); + } catch (ResponseException $e) { + $generalLedger = $e->getReturnedObject(); + } + + $generalLedger->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$generalLedger->setCode('1100'); // string|null Dimension code, must be compliant with the mask of the BAS or PNL Dimension type. + + try { + $generalLedgerCopy = $generalLedgerApiConnector->send($generalLedger); + } catch (ResponseException $e) { + $generalLedgerCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedgerCopy);
+    echo "
"; + + echo "Result of copy process: {$generalLedgerCopy->getResult()}
"; + echo "Code of copied GeneralLedger: {$generalLedgerCopy->getCode()}
"; + echo "Status of copied GeneralLedger: {$generalLedgerCopy->getStatus()}
"; +} + +// Create a new GeneralLedger from scratch, alternatively read an existing GeneralLedger as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $generalLedger = new \PhpTwinfield\GeneralLedger; + + // Required values for creating a new GeneralLedger + $generalLedger->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$generalLedger->setCode('1100'); // string|null Dimension code, must be compliant with the mask of the BAS or PNL Dimension type. + $generalLedger->setName("Example GeneralLedger"); // string|null Name of the dimension. + $dimensionType = new \PhpTwinfield\DimensionType; + $dimensionType->setCode('BAS'); + //$dimensionType->setCode('PNL'); + $generalLedger->setType($dimensionType); // DimensionType|null + $generalLedger->setType(\PhpTwinfield\DimensionType::fromCode('BAS')); // string|null + //$generalLedger->setType(\PhpTwinfield\DimensionType::fromCode('PNL')); // string|null + $generalLedger->setOffice($office); // Office|null Office code. + $generalLedger->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new GeneralLedger + $generalLedger->setBeginPeriod(0); // int|null Determines together with beginyear the period from which the dimension may be used. + $generalLedger->setBeginYear(0); // int|null Determines together with beginperiod the period from which the dimension may be used. + $generalLedger->setEndPeriod(0); // int|null Determines together with endyear the period till which the dimension may be used. + $generalLedger->setEndYear(0); // int|null Determines together with endperiod the period till which the dimension may be used. + $generalLedger->setShortName("ExmplCust"); // string|null Short name of the dimension. + //$generalLedger->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$generalLedger->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case a dimension that is used in a transaction is deleted, its status has been changed into hide. Hidden dimensions can be activated by using active. + + $dimensionGroup = new \PhpTwinfield\DimensionGroup; + $dimensionGroup->setCode('DIMGROUP'); + //$generalLedger->setGroup($dimensionGroup); // DimensionGroup|null Sets the dimension group. See Dimension group. + //$generalLedger->setGroup(\PhpTwinfield\DimensionGroup::fromCode("DIMGROUP")); // string|null + + $generalLedgerFinancials = new \PhpTwinfield\GeneralLedgerFinancials; + $generalLedgerFinancials->setAccountType(\PhpTwinfield\Enums\AccountType::BALANCE()); // AccountType|null + //$generalLedgerFinancials->setAccountType(\PhpTwinfield\Enums\AccountType::PROFITANDLOSS()); // AccountType|null + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $generalLedgerFinancials->setVatCode($vatCode); // VatCode|null Default VAT code. + $generalLedgerFinancials->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + $generalLedger->setFinancials($generalLedgerFinancials); // GeneralLedgerFinancials Set the GeneralLedgerFinancials object tot the GeneralLedger object + + try { + $generalLedgerNew = $generalLedgerApiConnector->send($generalLedger); + } catch (ResponseException $e) { + $generalLedgerNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedgerNew);
+    echo "
"; + + echo "Result of creation process: {$generalLedgerNew->getResult()}
"; + echo "Code of new GeneralLedger: {$generalLedgerNew->getCode()}
"; + echo "Status of new GeneralLedger: {$generalLedgerNew->getStatus()}
"; +} + +// Delete a GeneralLedger based off the passed in code, dimension type and optionally the office. +if ($executeDelete) { + try { + $generalLedgerDeleted = $generalLedgerApiConnector->delete("0000", "BAS", $office); + } catch (ResponseException $e) { + $generalLedgerDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($generalLedgerDeleted);
+    echo "
"; + + echo "Result of deletion process: {$generalLedgerDeleted->getResult()}
"; + echo "Code of deleted GeneralLedger: {$generalLedgerDeleted->getCode()}
"; + echo "Status of deleted GeneralLedger: {$generalLedgerDeleted->getStatus()}
"; +} diff --git a/examples/Invoice.php b/examples/Invoice.php new file mode 100644 index 00000000..89e7b0ad --- /dev/null +++ b/examples/Invoice.php @@ -0,0 +1,392 @@ + openvalue = 50.25 +if ($executeListAllWithFilter) { + $options = array('openvalue' => 50.25); + + try { + $invoices = $invoiceApiConnector->listAll("2019*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $invoices = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoices);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $invoices = $invoiceApiConnector->listAll(); + } catch (ResponseException $e) { + $invoices = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoices);
+    echo "
"; +} + +/* Invoice + * \PhpTwinfield\Invoice + * Available getters: getBank, getCalculateOnly, getCurrency, getCustomer, getCustomerToString, getCustomerName, getDebitCredit, getDeliverAddressNumber, getDueDate, getFinancialCode, getFinancialNumber, getFooterText, getHeaderText, getInvoiceAddressNumber, getInvoiceAmount, getInvoiceAmountToFloat, getInvoiceDate, getInvoiceNumber, getInvoiceType, getMessages, getOffice, getPaymentMethod, + * getPerformanceDate, getPeriod, getPeriodRaiseWarning, getRaiseWarning, getResult, getStatus, hasMessages, getLines, getMatchReference, getTotals, getVatLines + * + * Available setters: fromCode, setBank, setCalculateOnly, setCurrency, setCustomer, setCustomerName, setDebitCredit, setDeliverAddressNumber, setDueDate, setFinancialCode, setFinancialNumber, setFooterText, setHeaderText, setInvoiceAddressNumber, setInvoiceAmount, setInvoiceDate, setInvoiceNumber, setInvoiceType, setOffice, + * setPaymentMethod, setPerformanceDate, setPeriod, setPeriodRaiseWarning, setRaiseWarning, setStatus, setTotals, addLine, addVatLine, removeLine, removeVatLine + * + */ + +/* InvoiceTotals + * \PhpTwinfield\InvoiceTotals + * Available getters: getMessages, getResult, getValueExcl, getValueInc, hasMessages + * Available setters: setValueExcl, setValueInc + */ + +/* InvoiceLine + * \PhpTwinfield\InvoiceLine + * Available getters: getAllowDiscountOrPremium, getArticle, getDescription, getDim1, getFreeText1, getFreeText2, getFreeText3, getID, getMessages, getPerformanceDate, getPerformanceType, getQuantity, getResult, getSubArticle, getSubArticleToString, getUnits, getUnitsPriceExcl, getUnitsPriceInc, getValueExcl, getValueInc, getVatCode, getVatValue, hasMessages + * Available setters: setAllowDiscountOrPremium, setArticle, setDescription, setDim1, setFreeText1, setFreeText2, setFreeText3, setID, setPerformanceDate, setPerformanceType, setQuantity, setSubArticle, setUnits, setUnitsPriceExcl, setUnitsPriceInc, setValueExcl, setValueInc, setVatCode, setVatValue + */ + +/* InvoiceVatLine + * \PhpTwinfield\InvoiceVatLine + * Available getters: getMessages, getPerformanceDate, getPerformanceType, getResult, getVatCode, getVatValue, hasMessages + * Available setters: setPerformanceDate, setPerformanceType, setVatCode, setVatValue + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($invoices as $key => $invoice) { + echo "Invoice {$key}
"; + echo "InvoiceNumber: {$invoice->getInvoiceNumber()}
"; + echo "InvoiceAmount (\\Money\\Money):
" . print_r($invoice->getInvoiceAmount(), true) . "

"; + echo "InvoiceAmount (string): " . Util::formatMoney($invoice->getInvoiceAmount()) . "
"; + echo "Customer (\\PhpTwinfield\\Customer):
" . print_r($invoice->getCustomer(), true) . "

"; + echo "Customer (string): " . Util::objectToStr($invoice->getCustomer()) . "
"; + echo "CustomerName: {$invoice->getCustomerName()}
"; + echo "Debit/Credit: {$invoice->getDebitCredit()}

"; + } +} + +// Read an Invoice based off the passed in code and optionally the office. +if ($executeRead) { + try { + $invoice = $invoiceApiConnector->get("FACTUUR", "1", $office); + } catch (ResponseException $e) { + $invoice = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoice);
+    echo "
"; + + echo "Invoice
"; + echo "Bank (\\PhpTwinfield\\CashBankBook):
" . print_r($invoice->getBank(), true) . "

"; // CashBankBook|null Bank code. + echo "Bank (string): " . Util::objectToStr($invoice->getBank()) . "
"; // string|null + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($invoice->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($invoice->getCurrency()) . "
"; // string|null + echo "Customer (\\PhpTwinfield\\Customer):
" . print_r($invoice->getCustomer(), true) . "

"; // Customer|null Customer code. + echo "Customer (string): " . Util::objectToStr($invoice->getCustomer()) . "
"; // string|null + echo "DeliverAddressNumber: {$invoice->getDeliverAddressNumber()}
"; // int|null + echo "DueDate (\\DateTimeInterface):
" . print_r($invoice->getDueDate(), true) . "

"; // DateTimeInterface|null Due date. + echo "DueDate (string): " . Util::formatDate($invoice->getDueDate()) . "
"; // string|null + echo "FinancialCode: {$invoice->getFinancialCode()}
"; // string|null The transaction type code. Read-only attribute. + echo "FinancialNumber: {$invoice->getFinancialNumber()}
"; // string|null The transaction number. Read-only attribute. + echo "FooterText: {$invoice->getFooterText()}
"; // string|null Footer text on the invoice. + echo "HeaderText: {$invoice->getHeaderText()}
"; // string|null Header text on the invoice. + echo "InvoiceAddressNumber: {$invoice->getInvoiceAddressNumber()}
"; // int|null + echo "InvoiceDate (\\DateTimeInterface):
" . print_r($invoice->getInvoiceDate(), true) . "

"; // DateTimeInterface|null Invoice date. + echo "InvoiceDate (string): " . Util::formatDate($invoice->getInvoiceDate()) . "
"; // string|null + echo "InvoiceNumber: {$invoice->getInvoiceNumber()}
"; // string|null Invoice Number. + echo "InvoiceType (\\PhpTwinfield\\InvoiceType):
" . print_r($invoice->getInvoiceType(), true) . "

"; // InvoiceType|null Invoice type code. + echo "InvoiceType (string): " . Util::objectToStr($invoice->getInvoiceType()) . "
"; // string|null + + if ($invoice->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($invoice->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Office (\\PhpTwinfield\\Office):
" . print_r($invoice->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($invoice->getOffice()) . "
"; // string|null + echo "PaymentMethod: {$invoice->getPaymentMethod()}
"; // PaymentMethod|null The payment method. + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($invoice->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Performance date, when set-up on the invoice header. + echo "PerformanceDate (string): " . Util::formatDate($invoice->getPerformanceDate()) . "
"; // string|null + echo "Period: {$invoice->getPeriod()}
"; // string|null Period in YYYY/PP format. + echo "Result: {$invoice->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Status: {$invoice->getStatus()}
"; // Status|null Status of the invoice. + + $invoiceTotals = $invoice->getTotals(); + + echo "InvoiceTotals
"; + + if ($invoiceTotals->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($invoiceTotals->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$invoiceTotals->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ValueExcl (\\Money\\Money):
" . print_r($invoiceTotals->getValueExcl(), true) . "

"; // Money|null Value without VAT. Read-only attribute. + echo "ValueExcl (string): " . Util::formatMoney($invoiceTotals->getValueExcl()) . "
"; // string|null + echo "ValueInc (\\Money\\Money):
" . print_r($invoiceTotals->getValueInc(), true) . "

"; // Money|null Value with VAT. Read-only attribute. + echo "ValueInc (string): " . Util::formatMoney($invoiceTotals->getValueInc()) . "
"; // string|null + + if ($invoice->getFinancialCode() != null && $invoice->getFinancialNumber != null) { + $match = $invoice->getMatchReference(); + echo "Match (\\PhpTwinfield\\MatchReference):
" . print_r($match, true) . "

"; // MatchReference|null + } + + $invoiceLines = $invoice->getLines(); // array|null Array of InvoiceLine objects. + + foreach ($invoiceLines as $key => $invoiceLine) { + echo "InvoiceLine {$key}
"; + + echo "AllowDiscountOrPremium (bool): {$invoiceLine->getAllowDiscountOrPremium()}
"; // bool|null Calculate discount on this line. + echo "AllowDiscountOrPremium (string): " . Util::formatBoolean($invoiceLine->getAllowDiscountOrPremium()) . "
"; // string|null + echo "Article (\\PhpTwinfield\\Article):
" . print_r($invoiceLine->getArticle(), true) . "

"; // Article|null Article code. + echo "Article (string): " . Util::objectToStr($invoiceLine->getArticle()) . "
"; // string|null + echo "Description: {$invoiceLine->getDescription()}
"; // string|null Invoice line description, only on the lines with article ‘0’ or ‘-‘. + echo "Dim1 (\\PhpTwinfield\\GeneralLedger):
" . print_r($invoiceLine->getDim1(), true) . "

"; // GeneralLedger|null Balance account. + echo "Dim1 (string): " . Util::objectToStr($invoiceLine->getDim1()) . "
"; // string|null + echo "FreeText1: {$invoiceLine->getFreeText1()}
"; // string|null Free text field 1 as entered on the invoice type. + echo "FreeText2: {$invoiceLine->getFreeText2()}
"; // string|null Free text field 2 as entered on the invoice type. + echo "FreeText3: {$invoiceLine->getFreeText3()}
"; // string|null Free text field 3 as entered on the invoice type. + echo "ID: {$invoiceLine->getID()}
"; // int|null Line ID + + if ($invoiceLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($invoiceLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($invoiceLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Performance date, when set-up on invoice lines. + echo "PerformanceDate (string): " . Util::formatDate($invoiceLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$invoiceLine->getPerformanceType()}
"; // PerformanceType|null The performance type in case of an ICT sales invoice. + echo "Quantity: {$invoiceLine->getQuantity()}
"; // int|null The quantity on the sales invoice line. + echo "Result: {$invoiceLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SubArticle (\\PhpTwinfield\\ArticleLine):
" . print_r($invoiceLine->getSubArticle(), true) . "

"; // ArticleLine|null Sub-article code. + echo "SubArticle (string): {$invoiceLine->getSubArticleToString()}
"; // string|null + echo "Units: {$invoiceLine->getUnits()}
"; // int|null The number of units per quantity. + echo "UnitsPriceExcl (\\Money\\Money):
" . print_r($invoiceLine->getUnitsPriceExcl(), true) . "

"; // Money|null Only valid for invoice types with VAT exclusive units prices. + echo "UnitsPriceExcl (string): " . Util::formatMoney($invoiceLine->getUnitsPriceExcl()) . "
"; // string|null Only add this tag to an XML request if the setting Prices can be changed on an item is set to true. Otherwise, the price will be determined by the system. + echo "UnitsPriceInc (\\Money\\Money):
" . print_r($invoiceLine->getUnitsPriceInc(), true) . "

"; // Money|null Only valid for invoice types with VAT inclusive units prices. + echo "UnitsPriceInc (string): " . Util::formatMoney($invoiceLine->getUnitsPriceInc()) . "
"; // string|null Only add this tag to an XML request if the setting Prices can be changed on an item is set to true. Otherwise, the price will be determined by the system. + echo "ValueExcl (\\Money\\Money):
" . print_r($invoiceLine->getValueExcl(), true) . "

"; // Money|null Calculated element. Read-only attribute. + echo "ValueExcl (string): " . Util::formatMoney($invoiceLine->getValueExcl()) . "
"; // string|null + echo "ValueInc (\\Money\\Money):
" . print_r($invoiceLine->getValueInc(), true) . "

"; // Money|null Calculated element. Read-only attribute. + echo "ValueInc (string): " . Util::formatMoney($invoiceLine->getValueInc()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($invoiceLine->getVatCode(), true) . "

"; // VatCode|null VAT code. + echo "VatCode (string): " . Util::objectToStr($invoiceLine->getVatCode()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($invoiceLine->getVatValue(), true) . "

"; // Money|null Calculated element. Read-only attribute. + echo "VatValue (string): " . Util::formatMoney($invoiceLine->getVatValue()) . "
"; // string|null + } + + $invoiceVatLines = $invoice->getVatLines(); // array|null Array of InvoiceVatLine objects. + + foreach ($invoiceVatLines as $key => $invoiceVatLine) { + echo "InvoiceVatLine {$key}
"; + + if ($invoiceVatLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($invoiceVatLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($invoiceVatLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null The performance date. Only in case performancetype = services. Read-only attribute. + echo "PerformanceDate (string): " . Util::formatDate($invoiceVatLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$invoiceVatLine->getPerformanceType()}
"; // PerformanceType|null The performance type. Read-only attribute. + echo "Result: {$invoiceVatLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($invoiceVatLine->getVatCode(), true) . "

"; // VatCode|null VAT code. Read-only attribute. + echo "VatCode (string): " . Util::objectToStr($invoiceVatLine->getVatCode()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($invoiceVatLine->getVatValue(), true) . "

"; // Money|null VAT amount. Read-only attribute. + echo "VatValue (string): " . Util::formatMoney($invoiceVatLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing Invoice to a new entity +if ($executeCopy) { + try { + $invoice = $invoiceApiConnector->get("FACTUUR", "1", $office); + } catch (ResponseException $e) { + $invoice = $e->getReturnedObject(); + } + + $invoice->setInvoiceNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $invoice->setStatus(\PhpTwinfield\Enums\InvoiceStatus::CONCEPT()); + + try { + $invoiceCopy = $invoiceApiConnector->send($invoice); + } catch (ResponseException $e) { + $invoiceCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoiceCopy);
+    echo "
"; + + echo "Result of copy process: {$invoiceCopy->getResult()}
"; + echo "Number of copied Invoice: {$invoiceCopy->getInvoiceNumber()}
"; + echo "Status of copied Invoice: {$invoiceCopy->getStatus()}
"; +} + +// Create a new Invoice from scratch, alternatively read an existing Invoice as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $invoice = new \PhpTwinfield\Invoice; + + // Required values for creating a new Invoice + $customer = new \PhpTwinfield\Customer; + $customer->setCode('1000'); + $invoice->setCustomer($customer); // Customer|null Customer code. + $invoice->setCustomer(\PhpTwinfield\Customer::fromCode("1000")); // string|null + $invoiceType = new \PhpTwinfield\InvoiceType; + $invoiceType->setCode('FACTUUR'); + $invoice->setInvoiceType($invoiceType); // InvoiceType|null Invoice type code. + $invoice->setInvoiceType(\PhpTwinfield\InvoiceType::fromCode("FACTUUR")); // string|null + $invoice->setOffice($office); // Office|null Office code. + $invoice->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Invoice + $invoice->setCalculateOnly(false); // bool|null Attribute to indicate that invoice should not be saved but only checked and calculated. @calculateonly must be true for that. + $invoice->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + $bank = new \PhpTwinfield\CashBankBook; + $bank->setCode('BNK'); + $invoice->setBank($bank); // CashBankBook|null Customer code. + $invoice->setBank(\PhpTwinfield\CashBankBook::fromCode("BNK")); // string|null + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $invoice->setCurrency($currency); // Currency|null Currency code. + $invoice->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $invoice->setDeliverAddressNumber(1); // int|null If you want the default address, omit the tag or leave it empty. + $dueDate = \DateTime::createFromFormat('d-m-Y', '01-07-2019'); + $invoice->setDueDate($dueDate); // DateTimeInterface|null Due date. + $invoice->setDueDate(Util::parseDate("20190701")); // string|null + $invoice->setFooterText("Example Footer"); // string|null Footer text on the invoice. + $invoice->setHeaderText("Example Header"); // string|null Header text on the invoice. + $invoice->setInvoiceAddressNumber(1); // int|null If you want the default address, omit the tag or leave it empty. + $invoiceDate = \DateTime::createFromFormat('d-m-Y', '01-07-2019'); + $invoice->setInvoiceDate($invoiceDate); // DateTimeInterface|null Optional; when the invoicedate is not supplied Twinfield uses the system date as the invoice date. + $invoice->setInvoiceDate(Util::parseDate("20190701")); // string|null + $invoice->setPaymentMethod(\PhpTwinfield\Enums\PaymentMethod::BANK()); // PaymentMethod|null The payment method. + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-07-2019'); + $invoice->setPerformanceDate($performanceDate); // DateTimeInterface|null Performance date, when set-up on the invoice header. + $invoice->setPerformanceDate(Util::parseDate("20190701")); // string|null + $invoice->setPeriod("2019/07"); // string|null Period in YYYY/PP format. + $invoice->setPeriodRaiseWarning(false); // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. This overwrites the value of the raisewarning attribute as set on the root element. + //$invoice->setStatus(\PhpTwinfield\Enums\InvoiceStatus::CONCEPT()); // InvoiceStatus|null default can only be returned when retrieving a sales invoice. You cannot use this status when creating or updating an invoice. + //$invoice->setStatus(\PhpTwinfield\Enums\InvoiceStatus::FINAL()); // InvoiceStatus|null concept saves the invoice as provisional. After saving as final, no changes can be made anymore. When posting an invoice final, a financial transaction is generated and posted automatically. + + // The minimum amount of InvoiceLines linked to an Invoice object is 1 + $invoiceLine = new \PhpTwinfield\InvoiceLine; + + $invoiceLine->setAllowDiscountOrPremium(true); // bool|null Calculate discount on this line. + $article = new \PhpTwinfield\Article; + $article->setCode('9060'); + $invoiceLine->setArticle($article); // Article|null Article code. + $invoiceLine->setArticle(\PhpTwinfield\Article::fromCode('9060')); // string|null + //$invoiceLine->setDescription('Example Description'); // string|null Invoice line description, only on the lines with article ‘0’ or ‘-‘. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('9060'); + $invoiceLine->setDim1($dim1); // GeneralLedger|null Balance account. + $invoiceLine->setDim1(\PhpTwinfield\GeneralLedger::fromCode('9060')); // string|null + //$invoiceLine->setFreeText1('Example Free Text 1'); // string|null Free text field 1 as entered on the invoice type. + //$invoiceLine->setFreeText2('Example Free Text 2'); // string|null Free text field 2 as entered on the invoice type. + //$invoiceLine->setFreeText3("Example Free Text 3"); // string|null Free text field 3 as entered on the invoice type. + $invoiceLine->setID(1); // int|null Line ID. + //$invoiceLine->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null The performance type in case of an ICT sales invoice. + //$invoiceLine->setPerformanceDate($performanceDate); // DateTimeInterface|null Performance date, when set-up on invoice lines. + //$invoiceLine->setPerformanceDate(Util::parseDate("20190701")); // string|null + $invoiceLine->setQuantity(1); // int|null The quantity on the sales invoice line. + $subArticle = new \PhpTwinfield\ArticleLine; + $subArticle->setSubCode('9060'); + $invoiceLine->setSubArticle($subArticle); // ArticleLine|null Sub-article code. + $invoiceLine->setSubArticle(\PhpTwinfield\ArticleLine::fromCode('9060')); // string|null + $invoiceLine->setUnits(1); // int|null The number of units per quantity. + $invoiceLine->setUnitsPriceExcl(\Money\Money::EUR(1000)); // Money|null Only valid for invoice types with VAT exclusive units prices. Only add this tag to an XML request if the setting Prices can be changed on an item is set to true. Otherwise, the price will be determined by the system. (Equals 10.00 EUR) + //$invoiceLine->setUnitsPriceInc(\Money\Money::EUR(1210)); // Money|null Only valid for invoice types with VAT inclusive units prices. Only add this tag to an XML request if the setting Prices can be changed on an item is set to true. Otherwise, the price will be determined by the system. (Equals 12.10 EUR) + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + //$invoiceLine->setVatCode($vatCode); // VatCode|null VAT code. + //$invoiceLine->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null + + $invoice->addLine($invoiceLine); // InvoiceLine Add an InvoiceLine object to the Invoice object + //$invoice->removeLine(0); // int Remove an invoice line based on the index of the invoice line + + try { + $invoiceNew = $invoiceApiConnector->send($invoice); + } catch (ResponseException $e) { + $invoiceNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoiceNew);
+    echo "
"; + + echo "Result of creation process: {$invoiceNew->getResult()}
"; + echo "Number of new Invoice: {$invoiceNew->getInvoiceNumber()}
"; + echo "Status of new Invoice: {$invoiceNew->getStatus()}
"; +} diff --git a/examples/InvoiceType.php b/examples/InvoiceType.php new file mode 100644 index 00000000..964c3d71 --- /dev/null +++ b/examples/InvoiceType.php @@ -0,0 +1,94 @@ + vat = 'exclusive' +if ($executeListAllWithFilter) { + $options = array('vat' => 'exclusive'); + + try { + $invoiceTypes = $invoiceTypeApiConnector->listAll("INV*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $invoiceTypes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoiceTypes);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $invoiceTypes = $invoiceTypeApiConnector->listAll(); + } catch (ResponseException $e) { + $invoiceTypes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($invoiceTypes);
+    echo "
"; +} + +/* InvoiceType + * \PhpTwinfield\InvoiceType + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($invoiceTypes as $key => $invoiceType) { + echo "InvoiceType {$key}
"; + echo "Code: {$invoiceType->getCode()}
"; + echo "Name: {$invoiceType->getName()}
"; + echo "VAT: {$invoiceTypeApiConnector->getInvoiceTypeVatType($invoiceType->getCode())}

"; + } +} diff --git a/examples/JournalTransaction.php b/examples/JournalTransaction.php new file mode 100644 index 00000000..863fea75 --- /dev/null +++ b/examples/JournalTransaction.php @@ -0,0 +1,336 @@ +get(\PhpTwinfield\JournalTransaction::class, "MEMO", 201900003, $office); + } catch (ResponseException $e) { + $journalTransaction = $e->getReturnedObject(); + } + + echo "
";
+    print_r($journalTransaction);
+    echo "
"; + + echo "JournalTransaction
"; + echo "AutoBalanceVat (bool): {$journalTransaction->getAutoBalanceVat()}
"; // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + echo "AutoBalanceVat (string): " . Util::formatBoolean($journalTransaction->getAutoBalanceVat()) . "
"; // string|null + echo "BookingReference (\\PhpTwinfield\\BookingReference):
" . print_r($journalTransaction->getBookingReference(), true) . "

"; // BookingReference|null The Booking reference + echo "Code: {$journalTransaction->getCode()}
"; // string|null Transaction type code. + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($journalTransaction->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($journalTransaction->getCurrency()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($journalTransaction->getDate(), true) . "

"; // DateTimeInterface|null Transaction date. + echo "Date (string): " . Util::formatDate($journalTransaction->getDate()) . "
"; // string|null + echo "DateRaiseWarning (bool): {$journalTransaction->getDateRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + echo "DateRaiseWarning (string): {$journalTransaction->getDateRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + echo "Destiny: {$journalTransaction->getDestiny()}
"; // Destiny|null Attribute to indicate the destiny of the journal transaction. Only used in the request XML. temporary = journal transaction will be saved as provisional. final = journal transaction will be saved as final. + echo "FreeText1: {$journalTransaction->getFreeText1()}
"; // string|null Free text field 1 as entered on the transaction type. + echo "FreeText2: {$journalTransaction->getFreeText2()}
"; // string|null Free text field 2 as entered on the transaction type. + echo "FreeText3: {$journalTransaction->getFreeText3()}
"; // string|null Free text field 3 as entered on the transaction type. + echo "InputDate (\\DateTimeInterface):
" . print_r($journalTransaction->getInputDate(), true) . "

"; // DateTimeInterface|null The date/time on which the transaction was created. Read-only attribute. + echo "InputDate (string): " . Util::formatDate($journalTransaction->getInputDate()) . "
"; // string|null + + if ($journalTransaction->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($journalTransaction->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ModificationDate (\\DateTimeInterface):
" . print_r($journalTransaction->getModificationDate(), true) . "

"; // DateTimeInterface|null The date/time on which the journal transaction was modified the last time. Read-only attribute. + echo "ModificationDate (string): " . Util::formatDate($journalTransaction->getModificationDate()) . "
"; // string|null + echo "Number: {$journalTransaction->getNumber()}
"; // int|null Transaction number. When creating a new journal transaction, don't include this tag as the transaction number is determined by the system. When updating a journal transaction, the related transaction number should be provided. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($journalTransaction->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($journalTransaction->getOffice()) . "
"; // string|null + echo "Origin: {$journalTransaction->getOrigin()}
"; // string|null The journal transaction origin. Read-only attribute. + echo "Period: {$journalTransaction->getPeriod()}
"; // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + echo "RaiseWarning (bool): {$journalTransaction->getRaiseWarning()}
"; // bool|null Should warnings be given true or not false? Default true. + echo "RaiseWarning (string): " . Util::formatBoolean($journalTransaction->getRaiseWarning()) . "
"; // string|null + echo "Regime: {$journalTransaction->getRegime()}
"; // Regime|null Type of regime. You can post transactions as 'Fiscal', 'Commercial', 'Economic' or 'Generic'. The default regime is 'Generic'. 'Generic' means that the transaction is visible for all regimes. + echo "Result: {$journalTransaction->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + + $journalTransactionLines = $journalTransaction->getLines(); // array|null Array of JournalTransactionLine objects. + + foreach ($journalTransactionLines as $key => $journalTransactionLine) { + echo "JournalTransactionLine {$key}
"; + + echo "Baseline: {$journalTransactionLine->getBaseline()}
"; // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + echo "BaseValue (\\Money\\Money):
" . print_r($journalTransactionLine->getBaseValue(), true) . "

"; // Money|null Amount in the base currency. + echo "BaseValue (string): " . Util::formatMoney($journalTransactionLine->getBaseValue()) . "
"; // string|null + echo "BaseValueOpen (\\Money\\Money):
" . print_r($journalTransactionLine->getBaseValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in base currency. Read-only attribute. + echo "BaseValueOpen (string): " . Util::formatMoney($journalTransactionLine->getBaseValueOpen()) . "
"; // string|null + echo "Comment: {$journalTransactionLine->getComment()}
"; // string|null Comment set on the transaction line. + echo "CurrencyDate (\\DateTimeInterface):
" . print_r($journalTransactionLine->getCurrencyDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the journal book is set to Allowed or Mandatory. + echo "CurrencyDate (string): " . Util::formatDate($journalTransactionLine->getCurrencyDate()) . "
"; // string|null + echo "DebitCredit: {$journalTransactionLine->getDebitCredit()}
"; // DebitCredit|null The debit/credit indicator of the journal transaction line. + echo "Description: {$journalTransactionLine->getDescription()}
"; // string|null Description of the transaction line. + echo "DestOffice (\\PhpTwinfield\\Office):
" . print_r($journalTransactionLine->getDestOffice(), true) . "

"; // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + echo "DestOffice (string): " . Util::objectToStr($journalTransactionLine->getDestOffice()) . "
"; // string|null + echo "Dim1:
" . print_r($journalTransactionLine->getDim1(), true) . "

"; // object|null If line type = detail the journal balance account or profit and loss account. + echo "Dim1 (string): " . Util::objectToStr($journalTransactionLine->getDim1()) . "
"; // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + echo "Dim2:
" . print_r($journalTransactionLine->getDim2(), true) . "

"; // object|null If line type = detail the customer or supplier or the cost center or empty. + echo "Dim2 (string): " . Util::objectToStr($journalTransactionLine->getDim2()) . "
"; // string|null If line type = vat empty. + echo "Dim3:
" . print_r($journalTransactionLine->getDim2(), true) . "

"; // object|null If line type = detail the project or asset or empty. + echo "Dim3 (string): " . Util::objectToStr($journalTransactionLine->getDim3()) . "
"; // string|null If line type = vat empty. + echo "FreeChar: {$journalTransactionLine->getFreeChar()}
"; // string|null Free character field. + echo "ID: {$journalTransactionLine->getID()}
"; // int|null Line ID. + echo "InvoiceNumber: {$journalTransactionLine->getInvoiceNumber()}
"; // string|null Invoice number. Only if line type is detail. + echo "LineType: {$journalTransactionLine->getLineType()}
"; // LineType|null Line type. + echo "MatchLevel: {$journalTransactionLine->getMatchLevel()}
"; // int|null Only if line type is detail. The level of the matchable dimension. Read-only attribute. + echo "MatchStatus: {$journalTransactionLine->getMatchStatus()}
"; // MatchStatus|null Payment status of the journal transaction. If line type vat always notmatchable. Read-only attribute. + + if ($journalTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($journalTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceCountry (\\PhpTwinfield\\Country):
" . print_r($journalTransactionLine->getPerformanceCountry(), true) . "

"; // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + echo "PerformanceCountry (string): " . Util::objectToStr($journalTransactionLine->getPerformanceCountry()) . "
"; // string|null + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($journalTransactionLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + echo "PerformanceDate (string): " . Util::formatDate($journalTransactionLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$journalTransactionLine->getPerformanceType()}
"; // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + echo "PerformanceVatNumber: {$journalTransactionLine->getPerformanceVatNumber()}
"; // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + echo "Rate: {$journalTransactionLine->getRate()}
"; // float|null The exchange rate used for the calculation of the base amount. + echo "Reference (\\PhpTwinfield\\MatchReference):
" . print_r($journalTransactionLine->getReference(), true) . "

"; // MatchReference|null Match reference + echo "Relation: {$journalTransactionLine->getRelation()}
"; // int|null Only if line type is detail. Read-only attribute. + echo "RepRate: {$journalTransactionLine->getRepRate()}
"; // float|null The exchange rate used for the calculation of the reporting amount. + echo "RepValue (\\Money\\Money):
" . print_r($journalTransactionLine->getRepValue(), true) . "

"; // Money|null Amount in the reporting currency. + echo "RepValue (string): " . Util::formatMoney($journalTransactionLine->getRepValue()) . "
"; // string|null + echo "RepValueOpen (\\Money\\Money):
" . print_r($journalTransactionLine->getRepValueOpen(), true) . "

"; // Money|null Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + echo "RepValueOpen (string): " . Util::formatMoney($journalTransactionLine->getRepValueOpen()) . "
"; // string|null + echo "Result: {$journalTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SignedValue (\\Money\\Money):
" . print_r($journalTransactionLine->getSignedValue(), true) . "

"; // Money|null + echo "SignedValue (string): " . Util::formatMoney($journalTransactionLine->getSignedValue()) . "
"; // string|null + echo "Value (\\Money\\Money):
" . print_r($journalTransactionLine->getValue(), true) . "

"; // Money|null If line type = detail amount without VAT. If line type = vat VAT amount. + echo "Value (string): " . Util::formatMoney($journalTransactionLine->getValue()) . "
"; // string|null + echo "VatBaseTurnover (\\Money\\Money):
" . print_r($journalTransactionLine->getVatBaseTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + echo "VatBaseTurnover (string): " . Util::formatMoney($journalTransactionLine->getVatBaseTurnover()) . "
"; // string|null + echo "VatBaseValue (\\Money\\Money):
" . print_r($journalTransactionLine->getVatBaseValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in base currency. + echo "VatBaseValue (string): " . Util::formatMoney($journalTransactionLine->getVatBaseValue()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($journalTransactionLine->getVatCode(), true) . "

"; // VatCode|null Only if line type is detail or vat. VAT code. + echo "VatCode (string): " . Util::objectToStr($journalTransactionLine->getVatCode()) . "
"; // string|null + echo "VatRepTurnover (\\Money\\Money):
" . print_r($journalTransactionLine->getVatRepTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + echo "VatRepTurnover (string): " . Util::formatMoney($journalTransactionLine->getVatRepTurnover()) . "
"; // string|null + echo "VatRepValue (\\Money\\Money):
" . print_r($journalTransactionLine->getVatRepValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepValue (string): " . Util::formatMoney($journalTransactionLine->getVatRepValue()) . "
"; // string|null + echo "VatTurnover (\\Money\\Money):
" . print_r($journalTransactionLine->getVatTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the journal transaction. + echo "VatTurnover (string): " . Util::formatMoney($journalTransactionLine->getVatTurnover()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($journalTransactionLine->getVatValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in the currency of the journal transaction. + echo "VatValue (string): " . Util::formatMoney($journalTransactionLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing JournalTransaction to a new entity +if ($executeCopy) { + try { + $journalTransaction = $transactionApiConnector->get(\PhpTwinfield\JournalTransaction::class, "MEMO", 201900003, $office); + } catch (ResponseException $e) { + $journalTransaction = $e->getReturnedObject(); + } + + $journalTransaction->setNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $journalTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); + + try { + $journalTransactionCopy = $transactionApiConnector->send($journalTransaction); + } catch (ResponseException $e) { + $journalTransactionCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($journalTransactionCopy);
+    echo "
"; + + echo "Result of copy process: {$journalTransactionCopy->getResult()}
"; + echo "Number of copied JournalTransaction: {$journalTransactionCopy->getNumber()}
"; +} + +// Create a new JournalTransaction from scratch, alternatively read an existing JournalTransaction as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $journalTransaction = new \PhpTwinfield\JournalTransaction; + + // Required values for creating a new JournalTransaction + $journalTransaction->setCode('MEMO'); // string|null Transaction type code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $journalTransaction->setCurrency($currency); // Currency|null Currency code. + //$journalTransaction->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $journalTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); // Destiny|null Attribute to indicate the destiny of the journal transaction. Only used in the request XML. temporary = journal transaction will be saved as provisional. + //$journalTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::FINAL()); // Destiny|null final = journal transaction will be saved as final. + $journalTransaction->setOffice($office); // Office|null Office code. + $journalTransaction->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new JournalTransaction + $journalTransaction->setAutoBalanceVat(true); // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + $date = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + $journalTransaction->setDate($date); // DateTimeInterface|null Transaction date. Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + $journalTransaction->setDate(Util::parseDate("20190901")); // string|null This overwrites the value of the raisewarning attribute as set on the root element. + $journalTransaction->setDateRaiseWarning(false); // bool|null + //$journalTransaction->setFreeText1('Example FreeText 1'); // string|null Free text field 1 as entered on the transaction type. + //$journalTransaction->setFreeText2('Example FreeText 2'); // string|null Free text field 2 as entered on the transaction type. + //$journalTransaction->setFreeText3('Example FreeText 3'); // string|null Free text field 3 as entered on the transaction type. + //$journalTransaction->setNumber(201900011); // int|null Transaction number. When creating a new journal transaction, don't include this tag as the transaction number is determined by the system. When updating a journal transaction, the related transaction number should be provided. + //$journalTransaction->setPeriod("2019/07"); // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + $journalTransaction->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + //$journalTransaction->setRegime(\PhpTwinfield\Enums\Regime::GENERIC()); // Regime|null Type of regime. You can post transactions as 'Fiscal', 'Commercial', 'Economic' or 'Generic'. The default regime is 'Generic'. 'Generic' means that the transaction is visible for all regimes. + + // The minimum amount of JournalTransactionLines linked to an JournalTransaction object is 2 + $journalTransactionLine1 = new \PhpTwinfield\JournalTransactionLine; + $journalTransactionLine1->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $journalTransactionLine1->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $journalTransactionLine1->setDescription("Example Description on line with ID 1"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $journalTransactionLine1->setDim1($dim1); // object|null If line type = detail the journal balance account or profit and loss account. + $journalTransactionLine1->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $journalTransactionLine1->setID(1); // int|null Line ID. + $journalTransactionLine1->setValue(\Money\Money::EUR(10000)); // Money|null If line type = detail amount without VAT. If line type = vat VAT amount. + + $journalTransaction->addLine($journalTransactionLine1); // JournalTransactionLine Add a JournalTransactionLine object to the JournalTransaction object + + $journalTransactionLine2 = new \PhpTwinfield\JournalTransactionLine; + $journalTransactionLine2->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $journalTransactionLine2->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $journalTransactionLine2->setDescription("Example Description on line with ID 2"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $journalTransactionLine2->setDim1($dim1); // object|null If line type = detail the journal balance account or profit and loss account. + $journalTransactionLine2->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $journalTransactionLine2->setID(2); // int|null Line ID. + $journalTransactionLine2->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = detail amount without VAT. If line type = vat VAT amount. + + //$journalTransactionLine2->setInvoiceNumber(201900001); // string|null Invoice number. Only if line type is detail. + //$journalTransactionLine2->setComment('Example Comments'); // string|null Comment set on the transaction line. + $currencyDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$journalTransaction->setCurrencyDate($currencyDate); // DateTimeInterface|null Only if line type is detail. The line date. Only allowed if the line date in the journal book is set to Allowed or Mandatory. + //$journalTransaction->setCurrencyDate(Util::parseDate("20190901")); // string|null + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('1234'); + //$journalTransaction->setDestOffice($destOffice); // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + //$journalTransaction->setDestOffice(\PhpTwinfield\Office::fromCode('1234')); // string|null + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1001'); + //$journalTransactionLine2->setDim2($dim2); // object|null If line type = detail the customer or supplier or the cost center or empty. If line type = vat empty. + //$journalTransactionLine2->setDim2(\PhpTwinfield\Customer::fromCode('1001')); // string|null + $dim3 = new \PhpTwinfield\Project; + $dim3->setCode('P0000'); + //$journalTransactionLine2->setDim3($dim3); // object|null If line type = detail the project or asset or empty. If line type = vat empty. + //$journalTransactionLine2->setDim3(\PhpTwinfield\Project::fromCode('P0000')); // string|null + //$journalTransactionLine2->setFreeChar('A'); // string|null Free character field. + $performanceCountry = new \PhpTwinfield\Country; + $performanceCountry->setCode('NL'); + //$journalTransactionLine2->setPerformanceCountry($performanceCountry); // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + //$journalTransactionLine2->setPerformanceCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$journalTransactionLine2->setPerformanceDate($performanceDate); // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + //$journalTransactionLine2->setPerformanceDate(Util::parseDate("20190901")); // string|null + //$journalTransactionLine2->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + //$journalTransactionLine2->setPerformanceVatNumber('NL1234567890B01'); // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + //$journalTransactionLine2->setRepValue(\Money\Money::EUR(-10000)); // Money|null Amount in the reporting currency. + //$journalTransactionLine2->setRate(1); // float|null The exchange rate used for the calculation of the base amount. + //$journalTransactionLine2->setRepRate(1); // float|null The exchange rate used for the calculation of the reporting amount. + //$journalTransactionLine2->setVatBaseValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in base currency. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VN'); + //$journalTransactionLine2->setVatCode($vatCode); // VatCode|null Only if line type is detail or vat. VAT code. + //$journalTransactionLine2->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); // string|null + //$journalTransactionLine2->setVatRepValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in reporting currency. + //$journalTransactionLine2->setVatValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in the currency of the journal transaction. + + $journalTransaction->addLine($journalTransactionLine2); + + //$journalTransactionLine3 = new \PhpTwinfield\JournalTransactionLine; + //$journalTransactionLine3->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Line type. + //$journalTransactionLine3->setBaseline(1); // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + //$journalTransactionLine3->setVatBaseTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + //$journalTransactionLine3->setVatRepTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + //$journalTransactionLine3->setVatTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the journal transaction. + + try { + $journalTransactionNew = $transactionApiConnector->send($journalTransaction); + } catch (ResponseException $e) { + $journalTransactionNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($journalTransactionNew);
+    echo "
"; + + echo "Result of creation process: {$journalTransactionNew->getResult()}
"; + echo "Number of new JournalTransaction: {$journalTransactionNew->getNumber()}
"; +} + +// Delete a BrankTransaction based off the passed in office, code, number and given reason +if ($executeDelete) { + $bookingReference = new \PhpTwinfield\BookingReference($office, 'MEMO', 201900005); + + try { + $journalTransactionDeleted = $transactionApiConnector->delete($bookingReference, 'Example reason'); + } catch (ResponseException $e) { + $journalTransactionDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($journalTransactionDeleted);
+    echo "
"; +} \ No newline at end of file diff --git a/examples/Office.php b/examples/Office.php new file mode 100644 index 00000000..e7cc7704 --- /dev/null +++ b/examples/Office.php @@ -0,0 +1,166 @@ +listAllWithoutOfficeCode(); + } catch (ResponseException $e) { + $offices = $e->getReturnedObject(); + } + + echo "
";
+    print_r($offices);
+    echo "
"; +} + +//List all with pattern "NL*", field 0 (= search code or name), firstRow 1, maxRows 10, options -> consolidate = 0 +if ($executeListAllWithFilter) { + $options = array('consolidate' => 0); + + try { + $offices = $officeApiConnector->listAll("NL*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $offices = $e->getReturnedObject(); + } + + echo "
";
+    print_r($offices);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $offices = $officeApiConnector->listAll(); + } catch (ResponseException $e) { + $offices = $e->getReturnedObject(); + } + + echo "
";
+    print_r($offices);
+    echo "
"; +} + +/* Office + * \PhpTwinfield\Office + * Available getters: __toString, getBaseCurrency, getCode, getCountryCode, getCreated, getMessages, getModified, getName, getReportingCurrency, getResult, getShortName, getStatus, getTouched, getUser, getVatFirstQuarterStartsIn, getVatPeriod, hasMessages + * Available setters: fromCode, setBaseCurrency, setCode, setCountryCode, setName, setReportingCurrency, setShortName, setStatus, setVatFirstQuarterStartsIn,setVatPeriod + */ + +if ($executeListAllWithoutOfficeCode || $executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($offices as $key => $office) { + echo "Office {$key}
"; + echo "Code: {$office->getCode()}
"; + echo "Name: {$office->getName()}

"; + echo "CountryCode (\\PhpTwinfield\\Country):
" . print_r($office->getCountryCode(), true) . "

"; + echo "CountryCode (string): " . Util::objectToStr($office->getCountryCode()) . "
"; + echo "VatFirstQuarterStartsIn: {$office->getVatFirstQuarterStartsIn()}
"; + echo "VatPeriod: {$office->getVatPeriod()}
"; + } +} + +// Read an Office based off the passed in code and optionally the office. +if ($executeRead) { + try { + $office = $officeApiConnector->get("NLA000001", $defaultOffice); + } catch (ResponseException $e) { + $office = $e->getReturnedObject(); + } + + echo "
";
+    print_r($office);
+    echo "
"; + + echo "Office
"; + echo "BaseCurrency (\\PhpTwinfield\\Currency):
" . print_r($office->getBaseCurrency(), true) . "

"; // Currency|null The base currency + echo "BaseCurrency (string): " . Util::objectToStr($office->getBaseCurrency()) . "
"; // string|null + echo "Code: {$office}
"; // string|null + echo "Code: {$office->getCode()}
"; // string|null + //echo "CountryCode (\\PhpTwinfield\\Country):
" . print_r($office->getCountryCode(), true) . "

"; // Country|null + //echo "CountryCode (string): " . Util::objectToStr($office->getCountryCode()) . "
"; // string|null + echo "Created (\\DateTimeInterface):
" . print_r($office->getCreated(), true) . "

"; // DateTimeInterface|null The date/time the office was created. + echo "Created (string): " . Util::formatDateTime($office->getCreated()) . "
"; // string|null + + if ($office->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($office->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Modified (\\DateTimeInterface):
" . print_r($office->getModified(), true) . "

"; // DateTimeInterface|null The date/time the office was modified. + echo "Modified (string): " . Util::formatDateTime($office->getModified()) . "
"; // string|null + echo "Name: {$office->getName()}
"; // string|null + echo "ReportingCurrency (\\PhpTwinfield\\Currency):
" . print_r($office->getReportingCurrency(), true) . "

"; // Currency|null The reporting currency + echo "ReportingCurrency (string): " . Util::objectToStr($office->getReportingCurrency()) . "
"; // string|null + echo "Result: {$office->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$office->getShortName()}
"; // string|null + echo "Status: {$office->getStatus()}
"; // Status|null + echo "Touched: {$office->getTouched()}
"; // int|null The number of times the office is modified. + echo "User (\\PhpTwinfield\\User):
" . print_r($office->getUser(), true) . "

"; // User|null The code of the user who created or modified the Office. + echo "User (string): " . Util::objectToStr($office->getUser()) . "
"; // string|null + //echo "VatFirstQuarterStartsIn: {$office->getVatFirstQuarterStartsIn()}
"; // string|null + //echo "VatPeriod: {$office->getVatPeriod()}
"; // string|null +} diff --git a/examples/PayCode.php b/examples/PayCode.php new file mode 100644 index 00000000..ebe687d0 --- /dev/null +++ b/examples/PayCode.php @@ -0,0 +1,93 @@ + paytype = pay +if ($executeListAllWithFilter) { + $options = array('paytype' => 'pay'); + + try { + $payCodes = $payCodeApiConnector->listAll("SEPA*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $payCodes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($payCodes);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $payCodes = $payCodeApiConnector->listAll(); + } catch (ResponseException $e) { + $payCodes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($payCodes);
+    echo "
"; +} + +/* PayCode + * \PhpTwinfield\PayCode + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($payCodes as $key => $payCode) { + echo "PayCode {$key}
"; + echo "Code: {$payCode->getCode()}
"; + echo "Name: {$payCode->getName()}

"; + } +} diff --git a/examples/Project.php b/examples/Project.php new file mode 100644 index 00000000..6989ee92 --- /dev/null +++ b/examples/Project.php @@ -0,0 +1,358 @@ + accessrules = 0 +if ($executeListAllWithFilter) { + $options = array('accessrules' => 0); + + try { + $projects = $projectApiConnector->listAll("P*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $projects = $e->getReturnedObject(); + } + + echo "
";
+    print_r($projects);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $projects = $projectApiConnector->listAll(); + } catch (ResponseException $e) { + $projects = $e->getReturnedObject(); + } + + echo "
";
+    print_r($projects);
+    echo "
"; +} + +/* Project + * \PhpTwinfield\Project + * Available getters: getBehaviour, getCode, getInUse, getMessages, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUID, getVatCode, hasMessages, getProjects + * Available setters: fromCode, setBehaviour, setCode, setName, setOffice, setShortName, setStatus, setType, setVatCode, setProjects + */ + +/* ProjectProjects + * \PhpTwinfield\ProjectProjects + * Available getters: getAuthoriser, getAuthoriserToString, getAuthoriserInherit, getAuthoriserInheritToString, getAuthoriserLocked, getAuthoriserLockedToString, getBillable, getBillableToString, getBillableForRatio, getBillableForRatioToString, + * getBillableInherit, getBillableInheritToString, getBillableLocked, getBillableLockedToString, getCustomer, getCustomerToString, getCustomerInherit, getCustomerInheritToString, getCustomerLocked, getCustomerLockedToString, getInvoiceDescription, getMessages, + * getRate, getRateToString, getRateInherit, getRateInheritToString, getRateLocked, getRateLockedToString, getResult, getValidFrom, getValidTill, hasMessages, getQuantities + * + * Available setters: setAuthoriser, setAuthoriserInherit, setAuthoriserLocked, setBillable, setBillableForRatio, setBillableInherit, setBillableLocked, setCustomer, setCustomerInherit, setCustomerLocked, setInvoiceDescription, setRate, setRateInherit, + * setRateLocked, setValidFrom, setValidTill, addQuantity, removeQuantity + * + */ + +/* ProjectQuantity + * \PhpTwinfield\ProjectQuantity + * Available getters: getBillable, getBillableToString, getBillableLocked, getBillableLockedToString, getLabel, getMandatory, getMessages, getRate, getRateToString, getResult, hasMessages + * Available setters: setBillable, setBillableLocked, setLabel, setMandatory, setRate + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($projects as $key => $project) { + echo "Project {$key}
"; + echo "Code: {$project->getCode()}
"; + echo "Name: {$project->getName()}

"; + } +} + +// Read an Project based off the passed in code and optionally the office. +if ($executeRead) { + try { + $project = $projectApiConnector->get("P0000", $office); + } catch (ResponseException $e) { + $project = $e->getReturnedObject(); + } + + echo "
";
+    print_r($project);
+    echo "
"; + + echo "Project
"; + echo "Behaviour: {$project->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$project->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + echo "InUse (bool): {$project->getInUse()}
"; // bool|null Indicates whether the project is used in a transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($project->getInUse()) . "
"; // string|null + + if ($project->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($project->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$project->getName()}
"; // string|null Project description. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($project->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($project->getOffice()) . "
"; // string|null + echo "Result: {$project->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$project->getShortName()}
"; // string|null Short project description. + echo "Status: {$project->getStatus()}
"; // Status|null Status of the project. + echo "Touched: {$project->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($project->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of projects is ACT. + echo "Type (string): " . Util::objectToStr($project->getType()) . "
"; // string|null + echo "UID: {$project->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($project->getVatCode(), true) . "

"; // VatCode|null The VAT code if one code will apply for all projects within the project. Note that if any VAT codes are + echo "VatCode (string): " . Util::objectToStr($project->getVatCode()) . "
"; // string|null defined on project level, these will apply regardless of what is defined on project level. + + $projectProjects = $project->getProjects(); // ProjectProjects|null ProjectProjects object. + + echo "Authoriser (\\PhpTwinfield\\User):
" . print_r($projectProjects->getAuthoriser(), true) . "

"; // User|null A specific authoriser for an project. + echo "Authoriser (string): " . Util::objectToStr($projectProjects->getAuthoriser()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Authoriser Inherit (bool): {$projectProjects->getAuthoriserInherit()}
"; // bool|null + echo "Authoriser Inherit (string): " . Util::formatBoolean($projectProjects->getAuthoriserInherit()) . "
"; // string|null If "change" = disallow then locked = true and inherit = false + echo "Authoriser Locked (bool): {$projectProjects->getAuthoriserLocked()}
"; // bool|null + echo "Authoriser Locked (string): " . Util::formatBoolean($projectProjects->getAuthoriserLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Billable (bool): {$projectProjects->getBillable()}
"; // bool|null Choose to make an project billable (true) or not (false) and whether or not it should be included when calculating the "productivity" ratio (@forratio). + echo "Billable (string): " . Util::formatBoolean($projectProjects->getBillable()) . "
"; // string|null You could also decide that these settings should be inherited from project or user level (@inherit). + echo "Billable ForRatio (bool): {$projectProjects->getBillableForRatio()}
"; // bool|null You can also set whether a change of these settings is allowed or disallowed when a user is entering their timesheet (@locked). + echo "Billable ForRatio (string): " . Util::formatBoolean($projectProjects->getBillableForRatio()) . "
"; // string|null If "change" = allow then locked = false and inherit = false. + echo "Billable Inherit (bool): {$projectProjects->getBillableInherit()}
"; // bool|null + echo "Billable Inherit (string): " . Util::formatBoolean($projectProjects->getBillableInherit()) . "
"; // string|null If "change" = disallow then locked = true and inherit = false. + echo "Billable Locked (bool): {$projectProjects->getBillableLocked()}
"; // bool|null + echo "Billable Locked (string): " . Util::formatBoolean($projectProjects->getBillableLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Customer (\\PhpTwinfield\\Customer):
" . print_r($projectProjects->getCustomer(), true) . "

"; // Customer|null An project always needs to be linked to a customer. + echo "Customer (string): " . Util::objectToStr($projectProjects->getCustomer()) . "
"; // string|null Choose to have the customer ‘inherited’ (from a project) or you can specify the customer here. + echo "Customer Inherit (bool): {$projectProjects->getCustomerInherit()}
"; // bool|null + echo "Customer Inherit (string): " . Util::formatBoolean($projectProjects->getCustomerInherit()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Customer Locked (bool): {$projectProjects->getCustomerLocked()}
"; // bool|null If "change" = disallow then locked = true and inherit = false + echo "Customer Locked (string): " . Util::formatBoolean($projectProjects->getCustomerLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Invoice Description: {$projectProjects->getInvoiceDescription()}
"; // string|null This field can be used to enter a longer project description which will be available on the invoice template. + + if ($projectProjects->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($projectProjects->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Rate (\\PhpTwinfield\\Rate):
" . print_r($projectProjects->getRate(), true) . "

"; // Rate|null Choose to define a specific rate code here or you could also decide that these settings should be inherited from project or user level (@inherit). + echo "Rate (string): " . Util::objectToStr($projectProjects->getRate()) . "
"; // string|null You can also set whether a change of the rate code is allowed or disallowed when a user is entering their timesheet (@locked). + echo "Rate Inherit (bool): {$projectProjects->getRateInherit()}
"; // bool|null + echo "Rate Inherit (string): " . Util::formatBoolean($projectProjects->getRateInherit()) . "
"; // string|null If "change" = allow then locked = false and inherit = false + echo "Rate Locked (bool): {$projectProjects->getRateLocked()}
"; // bool|null If "change" = disallow then locked = true and inherit = false + echo "Rate Locked (string): " . Util::formatBoolean($projectProjects->getRateLocked()) . "
"; // string|null If "change" = inherit then locked = true and inherit = true + echo "Result: {$projectProjects->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Valid From (\\DateTimeInterface):
" . print_r($projectProjects->getValidFrom(), true) . "

"; // DateTimeInterface|null An project can be set to only be valid for certain dates. Users will then only be able to book hours to the project during these dates. + echo "Valid From (string): " . Util::formatDate($projectProjects->getValidFrom()) . "
"; // string|null + echo "Valid Till (\\DateTimeInterface):
" . print_r($projectProjects->getValidTill(), true) . "

"; // DateTimeInterface|null An project can be set to only be valid for certain dates. Users will then only be able to book hours to the project during these dates. + echo "Valid Till (string): " . Util::formatDate($projectProjects->getValidTill()) . "
"; // string|null + + $projectQuantities = $projectProjects->getQuantities(); // array|null Array of ProjectQuantity objects. + + foreach ($projectQuantities as $key => $projectQuantity) { + echo "ProjectQuantity {$key}
"; + + echo "Billable (bool): {$projectQuantity->getBillable()}
"; // bool|null Is the quantity line billable or not. + echo "Billable (string): " . Util::formatBoolean($projectQuantity->getBillable()) . "
"; // string|null If "billable" = true and "change is not allowed" then locked = true + echo "Billable Locked (bool): {$projectQuantity->getBillableLocked()}
"; // bool|null If "billable" = true and "change is allowed" then locked = false + echo "Billable Locked (string): " . Util::formatBoolean($projectQuantity->getBillableLocked()) . "
"; // string|null + + if ($projectQuantity->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($projectQuantity->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Label: {$projectQuantity->getLabel()}
"; // string|null The label of the quantity. + echo "Mandatory (bool): {$projectQuantity->getMandatory()}
"; // bool|null Is the quantity line mandatory or not. + echo "Mandatory (string): " . Util::formatBoolean($projectQuantity->getMandatory()) . "
"; // string|null + echo "Rate (\\PhpTwinfield\\Rate):
" . print_r($projectQuantity->getRate(), true) . "

"; // Rate|null The rate. + echo "Rate (string): " . Util::objectToStr($projectQuantity->getRate()) . "
"; // string|null + echo "Result: {$projectQuantity->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + } +} + +// Copy an existing Project to a new entity +if ($executeCopy) { + try { + $project = $projectApiConnector->get("P0000", $office); + } catch (ResponseException $e) { + $project = $e->getReturnedObject(); + } + + $project->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$project->setCode('P0100'); // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + + try { + $projectCopy = $projectApiConnector->send($project); + } catch (ResponseException $e) { + $projectCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($projectCopy);
+    echo "
"; + + echo "Result of copy process: {$projectCopy->getResult()}
"; + echo "Code of copied Project: {$projectCopy->getCode()}
"; + echo "Status of copied Project: {$projectCopy->getStatus()}
"; +} + +// Create a new Project from scratch, alternatively read an existing Project as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $project = new \PhpTwinfield\Project; + + // Required values for creating a new Project + $project->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$project->setCode('P0100'); // string|null Dimension code, must be compliant with the mask of the ACT Dimension type. + $project->setName("Example Project"); // string|null Project description. + $project->setOffice($office); // Office|null Office code. + $project->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Project + $project->setShortName("ExmplAct"); // string|null Short project description. + //$project->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$project->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case an project is in use, its status has been changed into hide. Hidden projects can be activated by using active. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VH'); + $project->setVatCode($vatCode); // VatCode|null The VAT code if one code will apply for all projects within the project. Note that if any VAT codes are + $project->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); // string|null defined on project level, these will apply regardless of what is defined on project level. + + $projectProjects = new \PhpTwinfield\ProjectProjects; + + $authoriser = new \PhpTwinfield\User; + $authoriser->setCode('TWINAPPS'); + $projectProjects->setAuthoriser($authoriser); // User|null A specific authoriser for an project. + $projectProjects->setAuthoriser(\PhpTwinfield\User::fromCode('TWINAPPS')); // string|null If "change" = allow then locked = false and inherit = false + $projectProjects->setAuthoriserInherit(false); // bool|null + $projectProjects->setAuthoriserLocked(false); // bool|null + $projectProjects->setBillable(false); // bool|null Choose to make an project billable (true) or not (false) and whether or not it should be included when calculating the "productivity" ratio (@forratio). + $projectProjects->setBillableForRatio(false); // bool|null You can also set whether a change of these settings is allowed or disallowed when a user is entering their timesheet (@locked). + $projectProjects->setBillableInherit(false); // bool|null + $projectProjects->setBillableLocked(false); // bool|null + $customer = new \PhpTwinfield\Customer; + $customer->setCode('1000'); + //$projectProjects->setCustomer($customer); // Customer|null An project always needs to be linked to a customer. + //$projectProjects->setCustomer(\PhpTwinfield\Customer::fromCode('1000')); // string|null Choose to have the customer ‘inherited’ (from a project) or you can specify the customer here. + $projectProjects->setCustomerInherit(true); // bool|null + $projectProjects->setCustomerLocked(true); // bool|null If "change" = disallow then locked = true and inherit = false + $projectProjects->setInvoiceDescription('Example Invoice Description'); // string|null This field can be used to enter a longer project description which will be available on the invoice template. + $rate = new \PhpTwinfield\Rate; + $rate->setCode('DIRECT'); + $projectProjects->setRate($rate); // Rate|null Choose to define a specific rate code here or you could also decide that these settings should be inherited from project or user level (@inherit). + $projectProjects->setRate(\PhpTwinfield\Rate::fromCode('DIRECT')); // string|null You can also set whether a change of the rate code is allowed or disallowed when a user is entering their timesheet (@locked). + $projectProjects->setRateInherit(false); // bool|null + $projectProjects->setRateLocked(true); // bool|null If "change" = disallow then locked = true and inherit = false + $validFrom = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $projectProjects->setValidFrom($validFrom); // DateTimeInterface|null An project can be set to only be valid for certain dates. Users will then only be able to book hours to the project during these dates. + $projectProjects->setValidFrom(Util::parseDate('20190101')); // string|null + $validTill = \DateTime::createFromFormat('d-m-Y', '31-12-2019'); + $projectProjects->setValidTill($validTill); // DateTimeInterface|null An project can be set to only be valid for certain dates. Users will then only be able to book hours to the project during these dates. + $projectProjects->setValidTill(Util::parseDate('20191231')); // string|null + + // The minimum amount of ProjectQuantities linked to a ProjectProjects object is 0, the maximum amount is 4 + $projectQuantity = new \PhpTwinfield\ProjectQuantity; + $projectQuantity->setBillable(false); // bool|null Is the quantity line billable or not. + $projectQuantity->setBillableLocked(false); // bool|null + $projectQuantity->setLabel('Example Quantity'); // string|null + $projectQuantity->setMandatory(false); // bool|null Is the quantity line mandatory or not. + $rate = new \PhpTwinfield\Rate; + $rate->setCode('KILOMETERS'); + $projectQuantity->setRate($rate); // Rate|null The rate. + $projectQuantity->setRate(\PhpTwinfield\Rate::fromCode('KILOMETERS')); // string|null + + $projectProjects->addQuantity($projectQuantity); // ProjectQuantity Add an ProjectQuantity object to the ProjectProjects object + //$projectProjects->removeQuantity(0); // int Remove a quantity based on the index of the quantity within the array + + $project->setProjects($projectProjects); // ProjectProjects Set the ProjectProjects object tot the Project object + + try { + $projectNew = $projectApiConnector->send($project); + } catch (ResponseException $e) { + $projectNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($projectNew);
+    echo "
"; + + echo "Result of creation process: {$projectNew->getResult()}
"; + echo "Code of new Project: {$projectNew->getCode()}
"; + echo "Status of new Project: {$projectNew->getStatus()}
"; +} + +// Delete a Project based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $projectDeleted = $projectApiConnector->delete("P0100", $office); + } catch (ResponseException $e) { + $projectDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($projectDeleted);
+    echo "
"; + + echo "Result of deletion process: {$projectDeleted->getResult()}
"; + echo "Code of deleted Project: {$projectDeleted->getCode()}
"; + echo "Status of deleted Project: {$projectDeleted->getStatus()}
"; +} diff --git a/examples/PurchaseTransaction.php b/examples/PurchaseTransaction.php new file mode 100644 index 00000000..0186475d --- /dev/null +++ b/examples/PurchaseTransaction.php @@ -0,0 +1,347 @@ +get(\PhpTwinfield\PurchaseTransaction::class, "INK", 201900003, $office); + } catch (ResponseException $e) { + $purchaseTransaction = $e->getReturnedObject(); + } + + echo "
";
+    print_r($purchaseTransaction);
+    echo "
"; + + echo "PurchaseTransaction
"; + echo "AutoBalanceVat (bool): {$purchaseTransaction->getAutoBalanceVat()}
"; // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + echo "AutoBalanceVat (string): " . Util::formatBoolean($purchaseTransaction->getAutoBalanceVat()) . "
"; // string|null + echo "BookingReference (\\PhpTwinfield\\BookingReference):
" . print_r($purchaseTransaction->getBookingReference(), true) . "

"; // BookingReference|null The Booking reference + echo "Code: {$purchaseTransaction->getCode()}
"; // string|null Transaction type code. + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($purchaseTransaction->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($purchaseTransaction->getCurrency()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($purchaseTransaction->getDate(), true) . "

"; // DateTimeInterface|null Transaction date. + echo "Date (string): " . Util::formatDate($purchaseTransaction->getDate()) . "
"; // string|null + echo "DateRaiseWarning (bool): {$purchaseTransaction->getDateRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + echo "DateRaiseWarning (string): {$purchaseTransaction->getDateRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + echo "Destiny: {$purchaseTransaction->getDestiny()}
"; // Destiny|null Attribute to indicate the destiny of the purchase transaction. Only used in the request XML. temporary = purchase transaction will be saved as provisional. final = purchase transaction will be saved as final + echo "DueDate (\\DateTimeInterface):
" . print_r($purchaseTransaction->getDueDate(), true) . "

"; // DateTimeInterface|null Due date. + echo "DueDate (string): " . Util::formatDate($purchaseTransaction->getDueDate()) . "
"; // string|null + echo "FreeText1: {$purchaseTransaction->getFreeText1()}
"; // string|null Free text field 1 as entered on the transaction type. + echo "FreeText2: {$purchaseTransaction->getFreeText2()}
"; // string|null Free text field 2 as entered on the transaction type. + echo "FreeText3: {$purchaseTransaction->getFreeText3()}
"; // string|null Free text field 3 as entered on the transaction type. + echo "InputDate (\\DateTimeInterface):
" . print_r($purchaseTransaction->getInputDate(), true) . "

"; // DateTimeInterface|null The date/time on which the transaction was created. Read-only attribute. + echo "InputDate (string): " . Util::formatDate($purchaseTransaction->getInputDate()) . "
"; // string|null + echo "InvoiceNumber: {$purchaseTransaction->getInvoiceNumber()}
"; // string|null Invoice number. + echo "InvoiceNumberRaiseWarning (bool): {$purchaseTransaction->getInvoiceNumberRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'double invoice numbers' by adding the raisewarning attribute and set its value to false. + echo "InvoiceNumberRaiseWarning (string): {$purchaseTransaction->getInvoiceNumberRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + + if ($purchaseTransaction->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($purchaseTransaction->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ModificationDate (\\DateTimeInterface):
" . print_r($purchaseTransaction->getModificationDate(), true) . "

"; // DateTimeInterface|null The date/time on which the purchase transaction was modified the last time. Read-only attribute. + echo "ModificationDate (string): " . Util::formatDate($purchaseTransaction->getModificationDate()) . "
"; // string|null + echo "Number: {$purchaseTransaction->getNumber()}
"; // int|null Transaction number. When creating a new purchase transaction, don't include this tag as the transaction number is determined by the system. When updating a purchase transaction, the related transaction number should be provided. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($purchaseTransaction->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($purchaseTransaction->getOffice()) . "
"; // string|null + echo "Origin: {$purchaseTransaction->getOrigin()}
"; // string|null The purchase transaction origin. Read-only attribute. + echo "PaymentReference: {$purchaseTransaction->getPaymentReference()}
"; // string|null Payment reference of the transaction. If payment reference is not specified, the paymentreference section must be omitted + echo "Period: {$purchaseTransaction->getPeriod()}
"; // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + echo "RaiseWarning (bool): {$purchaseTransaction->getRaiseWarning()}
"; // bool|null Should warnings be given true or not false? Default true. + echo "RaiseWarning (string): " . Util::formatBoolean($purchaseTransaction->getRaiseWarning()) . "
"; // string|null + echo "Result: {$purchaseTransaction->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + + $purchaseTransactionLines = $purchaseTransaction->getLines(); // array|null Array of PurchaseTransactionLine objects. + + foreach ($purchaseTransactionLines as $key => $purchaseTransactionLine) { + echo "PurchaseTransactionLine {$key}
"; + + echo "Baseline: {$purchaseTransactionLine->getBaseline()}
"; // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + echo "BaseValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getBaseValue(), true) . "

"; // Money|null Amount in the base currency. + echo "BaseValue (string): " . Util::formatMoney($purchaseTransactionLine->getBaseValue()) . "
"; // string|null + echo "BaseValueOpen (\\Money\\Money):
" . print_r($purchaseTransactionLine->getBaseValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still to be paid in base currency. Read-only attribute. + echo "BaseValueOpen (string): " . Util::formatMoney($purchaseTransactionLine->getBaseValueOpen()) . "
"; // string|null + echo "Comment: {$purchaseTransactionLine->getComment()}
"; // string|null Comment set on the transaction line. + echo "DebitCredit: {$purchaseTransactionLine->getDebitCredit()}
"; // DebitCredit|null If line type = total. In case of a 'normal' purchase transaction credit. In case of a credit purchase transaction debit. If line type = detail or vat. In case of a 'normal' purchase transaction debit. In case of a credit purchase transaction credit. + echo "Description: {$purchaseTransactionLine->getDescription()}
"; // string|null Description of the transaction line. + echo "DestOffice (\\PhpTwinfield\\Office):
" . print_r($purchaseTransactionLine->getDestOffice(), true) . "

"; // Office|null Only if line type is detail. Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + echo "DestOffice (string): " . Util::objectToStr($purchaseTransactionLine->getDestOffice()) . "
"; // string|null + echo "Dim1:
" . print_r($purchaseTransactionLine->getDim1(), true) . "

"; // object|null If line type = total the accounts payable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the supplier in Twinfield. If line type = detail the profit and loss account. + echo "Dim1 (string): " . Util::objectToStr($purchaseTransactionLine->getDim1()) . "
"; // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + echo "Dim2:
" . print_r($purchaseTransactionLine->getDim2(), true) . "

"; // object|null If line type = total the account payable. If line type = detail the cost center or empty. + echo "Dim2 (string): " . Util::objectToStr($purchaseTransactionLine->getDim2()) . "
"; // string|null If line type = vat the cost center or empty. + echo "Dim3:
" . print_r($purchaseTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the project or asset or empty. + echo "Dim3 (string): " . Util::objectToStr($purchaseTransactionLine->getDim3()) . "
"; // string|null If line type = vat the project or asset or empty. + echo "FreeChar: {$purchaseTransactionLine->getFreeChar()}
"; // string|null Free character field. If line type is total and filled with N the purchase invoice is excluded from payment runs done in Twinfield. + echo "ID: {$purchaseTransactionLine->getID()}
"; // int|null Line ID. + echo "LineType: {$purchaseTransactionLine->getLineType()}
"; // LineType|null Line type. + echo "MatchDate (\\DateTimeInterface):
" . print_r($purchaseTransactionLine->getMatchDate(), true) . "

"; // DateTimeInterface|null Only if line type is total. The date on which the purchase invoice is matched. Read-only attribute. + echo "MatchDate (string): " . Util::formatDate($purchaseTransactionLine->getMatchDate()) . "
"; // string|null + echo "MatchLevel: {$purchaseTransactionLine->getMatchLevel()}
"; // int|null Only if line type is total. The level of the matchable dimension. Read-only attribute. + echo "MatchStatus: {$purchaseTransactionLine->getMatchStatus()}
"; // MatchStatus|null Payment status of the purchase transaction. If line type detail or vat always notmatchable. Read-only attribute. + + if ($purchaseTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($purchaseTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Rate: {$purchaseTransactionLine->getRate()}
"; // float|null The exchange rate used for the calculation of the base amount. + echo "Reference (\\PhpTwinfield\\MatchReference):
" . print_r($purchaseTransactionLine->getReference(), true) . "

"; // MatchReference|null Match reference + echo "Relation: {$purchaseTransactionLine->getRelation()}
"; // int|null Only if line type is total. Read-only attribute. + echo "RepRate: {$purchaseTransactionLine->getRepRate()}
"; // float|null The exchange rate used for the calculation of the reporting amount. + echo "RepValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getRepValue(), true) . "

"; // Money|null Amount in the reporting currency. + echo "RepValue (string): " . Util::formatMoney($purchaseTransactionLine->getRepValue()) . "
"; // string|null + echo "RepValueOpen (\\Money\\Money):
" . print_r($purchaseTransactionLine->getRepValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still to be paid in reporting currency. Read-only attribute. + echo "RepValueOpen (string): " . Util::formatMoney($purchaseTransactionLine->getRepValueOpen()) . "
"; // string|null + echo "Result: {$purchaseTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SignedValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getSignedValue(), true) . "

"; // Money|null + echo "SignedValue (string): " . Util::formatMoney($purchaseTransactionLine->getSignedValue()) . "
"; // string|null + echo "Value (\\Money\\Money):
" . print_r($purchaseTransactionLine->getValue(), true) . "

"; // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + echo "Value (string): " . Util::formatMoney($purchaseTransactionLine->getValue()) . "
"; // string|null + echo "ValueOpen (\\Money\\Money):
" . print_r($purchaseTransactionLine->getValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still to be paid in the currency of the purchase transaction. Read-only attribute. + echo "ValueOpen (string): " . Util::formatMoney($purchaseTransactionLine->getValueOpen()) . "
"; // string|null + echo "VatBaseTotal (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatBaseTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in base currency. + echo "VatBaseTotal (string): " . Util::formatMoney($purchaseTransactionLine->getVatBaseTotal()) . "
"; // string|null + echo "VatBaseTurnover (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatBaseTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + echo "VatBaseTurnover (string): " . Util::formatMoney($purchaseTransactionLine->getVatBaseTurnover()) . "
"; // string|null + echo "VatBaseValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatBaseValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in base currency. + echo "VatBaseValue (string): " . Util::formatMoney($purchaseTransactionLine->getVatBaseValue()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($purchaseTransactionLine->getVatCode(), true) . "

"; // VatCode|null Only if line type is detail or vat. VAT code. + echo "VatCode (string): " . Util::objectToStr($purchaseTransactionLine->getVatCode()) . "
"; // string|null + echo "VatRepTotal (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatRepTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in reporting currency. + echo "VatRepTotal (string): " . Util::formatMoney($purchaseTransactionLine->getVatRepTotal()) . "
"; // string|null + echo "VatRepTurnover (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatRepTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + echo "VatRepTurnover (string): " . Util::formatMoney($purchaseTransactionLine->getVatRepTurnover()) . "
"; // string|null + echo "VatRepValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatRepValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepValue (string): " . Util::formatMoney($purchaseTransactionLine->getVatRepValue()) . "
"; // string|null + echo "VatTotal (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in the currency of the purchase transaction. + echo "VatTotal (string): " . Util::formatMoney($purchaseTransactionLine->getVatTotal()) . "
"; // string|null + echo "VatTurnover (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the purchase transaction. + echo "VatTurnover (string): " . Util::formatMoney($purchaseTransactionLine->getVatTurnover()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($purchaseTransactionLine->getVatValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in the currency of the purchase transaction. + echo "VatValue (string): " . Util::formatMoney($purchaseTransactionLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing PurchaseTransaction to a new entity +if ($executeCopy) { + try { + $purchaseTransaction = $transactionApiConnector->get(\PhpTwinfield\PurchaseTransaction::class, "INK", 201900003, $office); + } catch (ResponseException $e) { + $purchaseTransaction = $e->getReturnedObject(); + } + + $purchaseTransaction->setNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $purchaseTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); + + try { + $purchaseTransactionCopy = $transactionApiConnector->send($purchaseTransaction); + } catch (ResponseException $e) { + $purchaseTransactionCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($purchaseTransactionCopy);
+    echo "
"; + + echo "Result of copy process: {$purchaseTransactionCopy->getResult()}
"; + echo "Number of copied PurchaseTransaction: {$purchaseTransactionCopy->getNumber()}
"; +} + +// Create a new PurchaseTransaction from scratch, alternatively read an existing PurchaseTransaction as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $purchaseTransaction = new \PhpTwinfield\PurchaseTransaction; + + // Required values for creating a new PurchaseTransaction + $purchaseTransaction->setCode('INK'); // string|null Transaction type code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $purchaseTransaction->setCurrency($currency); // Currency|null Currency code. + //$purchaseTransaction->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $purchaseTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); // Destiny|null Attribute to indicate the destiny of the purchase transaction. Only used in the request XML. + //$purchaseTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::FINAL()); // Destiny|null temporary = purchase transaction will be saved as provisional. final = purchase transaction will be saved as final. + $purchaseTransaction->setInvoiceNumber(201900011); // string|null Invoice number. + $purchaseTransaction->setOffice($office); // Office|null Office code. + $purchaseTransaction->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new PurchaseTransaction + $purchaseTransaction->setAutoBalanceVat(true); // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + $date = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + $purchaseTransaction->setDate($date); // DateTimeInterface|null Transaction date. Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + $purchaseTransaction->setDate(Util::parseDate("20190901")); // string|null This overwrites the value of the raisewarning attribute as set on the root element. + $purchaseTransaction->setDateRaiseWarning(false); // bool|null + $dueDate = \DateTime::createFromFormat('d-m-Y', '01-10-2019'); + $purchaseTransaction->setDueDate($dueDate); // DateTimeInterface|null Due date. + $purchaseTransaction->setDueDate(Util::parseDate("20191001")); // string|null + //$purchaseTransaction->setFreeText1('Example FreeText 1'); // string|null Free text field 1 as entered on the transaction type. + //$purchaseTransaction->setFreeText2('Example FreeText 2'); // string|null Free text field 2 as entered on the transaction type. + //$purchaseTransaction->setFreeText3('Example FreeText 3'); // string|null Free text field 3 as entered on the transaction type. + $purchaseTransaction->setInvoiceNumberRaiseWarning(false); // bool|null Optionally, it is possible to suppress warnings about 'double invoice numbers' by adding the raisewarning attribute and set its value to false. This overwrites the value of the raisewarning attribute as set on the root element. + //$purchaseTransaction->setNumber(201900011); // int|null Transaction number. When creating a new purchase transaction, don't include this tag as the transaction number is determined by the system. When updating a purchase transaction, the related transaction number should be provided. + //$purchaseTransaction->setPeriod("2019/07"); // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + $purchaseTransaction->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + + // The minimum amount of PurchaseTransactionLines linked to an PurchaseTransaction object is 2 (1 total, 1 detail) + $purchaseTransactionLine1 = new \PhpTwinfield\PurchaseTransactionLine; + $purchaseTransactionLine1->setLineType(\PhpTwinfield\Enums\LineType::TOTAL()); // LineType|null Line type. + + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('1600'); + $purchaseTransactionLine1->setDim1($dim1); // object|null If line type = total the accounts payable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the supplier in Twinfield. If line type = detail the profit and loss account. + $purchaseTransactionLine1->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1600')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $dim2 = new \PhpTwinfield\Supplier; + $dim2->setCode('2000'); + $purchaseTransactionLine1->setDim2($dim2); // object|null If line type = total the account payable. If line type = detail the cost center or empty. If line type = vat the cost center or empty. + $purchaseTransactionLine1->setDim2(\PhpTwinfield\Supplier::fromCode('2000')); // string|null + $purchaseTransactionLine1->setID(1); // int|null Line ID. + $purchaseTransactionLine1->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + //$purchaseTransactionLine1->setVatBaseTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in base currency. + //$purchaseTransactionLine1->setVatRepTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in reporting currency. + //$purchaseTransactionLine1->setVatTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in the currency of the purchase transaction. + + $purchaseTransaction->addLine($purchaseTransactionLine1); // PurchaseTransactionLine Add a PurchaseTransactionLine object to the PurchaseTransaction object + + $purchaseTransactionLine2 = new \PhpTwinfield\PurchaseTransactionLine; + $purchaseTransactionLine2->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $purchaseTransactionLine2->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $purchaseTransactionLine2->setDescription("Example Description on line with ID 2"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $purchaseTransactionLine2->setDim1($dim1); // object|null If line type = total the accounts payable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the supplier in Twinfield. If line type = detail the profit and loss account. + $purchaseTransactionLine2->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $purchaseTransactionLine2->setID(2); // int|null Line ID. + $purchaseTransactionLine2->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + + //$purchaseTransactionLine2->setComment('Example Comments'); // string|null Comment set on the transaction line. + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('1234'); + //$purchaseTransaction->setDestOffice($destOffice); // Office|null Only if line type is detail. Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + //$purchaseTransaction->setDestOffice(\PhpTwinfield\Office::fromCode('1234')); // string|null + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1001'); + //$purchaseTransactionLine2->setDim2($dim2); // object|null If line type = total the account payable. If line type = detail the cost center or empty. If line type = vat the cost center or empty. + //$purchaseTransactionLine2->setDim2(\PhpTwinfield\Customer::fromCode('1001')); // string|null + $dim3 = new \PhpTwinfield\Project; + $dim3->setCode('P0000'); + //$purchaseTransactionLine2->setDim3($dim3); // object|null If line type = total empty. If line type = detail the project or asset or empty. If line type = vat the project or asset or empty. + //$purchaseTransactionLine2->setDim3(\PhpTwinfield\Project::fromCode('P0000')); // string|null + //$purchaseTransactionLine2->setFreeChar('A'); // string|null Free character field. If line type is total and filled with N the purchase invoice is excluded from payment runs done in Twinfield. + $performanceCountry = new \PhpTwinfield\Country; + $performanceCountry->setCode('NL'); + //$purchaseTransactionLine2->setPerformanceCountry($performanceCountry); // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + //$purchaseTransactionLine2->setPerformanceCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$purchaseTransactionLine2->setPerformanceDate($performanceDate); // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + //$purchaseTransactionLine2->setPerformanceDate(Util::parseDate("20190901")); // string|null + //$purchaseTransactionLine2->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + //$purchaseTransactionLine2->setPerformanceVatNumber('NL1234567890B01'); // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + //$purchaseTransactionLine2->setRepValue(\Money\Money::EUR(-10000)); // Money|null Amount in the reporting currency. + //$purchaseTransactionLine2->setRate(1); // float|null The exchange rate used for the calculation of the base amount. + //$purchaseTransactionLine2->setRepRate(1); // float|null The exchange rate used for the calculation of the reporting amount. + //$purchaseTransactionLine2->setVatBaseValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in base currency. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VN'); + //$purchaseTransactionLine2->setVatCode($vatCode); // VatCode|null Only if line type is detail or vat. VAT code. + //$purchaseTransactionLine2->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); // string|null + //$purchaseTransactionLine2->setVatRepValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in reporting currency. + //$purchaseTransactionLine2->setVatValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in the currency of the purchase transaction. + + $purchaseTransaction->addLine($purchaseTransactionLine2); + + //$purchaseTransactionLine3 = new \PhpTwinfield\PurchaseTransactionLine; + //$purchaseTransactionLine3->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Line type. + //$purchaseTransactionLine3->setBaseline(1); // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + //$purchaseTransactionLine3->setVatBaseTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + //$purchaseTransactionLine3->setVatRepTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + //$purchaseTransactionLine3->setVatTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the purchase transaction. + + try { + $purchaseTransactionNew = $transactionApiConnector->send($purchaseTransaction); + } catch (ResponseException $e) { + $purchaseTransactionNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($purchaseTransactionNew);
+    echo "
"; + + echo "Result of creation process: {$purchaseTransactionNew->getResult()}
"; + echo "Number of new PurchaseTransaction: {$purchaseTransactionNew->getNumber()}
"; +} + +// Delete a BrankTransaction based off the passed in office, code, number and given reason +if ($executeDelete) { + $bookingReference = new \PhpTwinfield\BookingReference($office, 'INK', 201900004); + + try { + $purchaseTransactionDeleted = $transactionApiConnector->delete($bookingReference, 'Example reason'); + } catch (ResponseException $e) { + $purchaseTransactionDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($purchaseTransactionDeleted);
+    echo "
"; +} \ No newline at end of file diff --git a/examples/Rate.php b/examples/Rate.php new file mode 100644 index 00000000..a3dfdfde --- /dev/null +++ b/examples/Rate.php @@ -0,0 +1,268 @@ + ratetype = 'quantity' +if ($executeListAllWithFilter) { + $options = array('ratetype' => 'time'); + + try { + $rates = $rateApiConnector->listAll("DIR*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $rates = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rates);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $rates = $rateApiConnector->listAll(); + } catch (ResponseException $e) { + $rates = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rates);
+    echo "
"; +} + +/* Rate + * \PhpTwinfield\Rate + * Available getters: getCode, getCreated, getCurrency, getMessages, getModified, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUnit, getUser, hasMessages, getRateChanges + * Available setters: fromCode, setCode, setCurrency, setName, setOffice, setShortName, setStatus, setType, setUnit, addRateChange, removeRateChange + */ + +/* RateRateChange + * \PhpTwinfield\RateRateChange + * Available getters: getBeginDate, getEndDate, getExternalRate, getID, getInternalRate, getMessages, getResult, getStatus, hasMessages + * Available setters: setBeginDate, setEndDate, setExternalRate, setID, setInternalRate, setStatus + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($rates as $key => $rate) { + echo "Rate {$key}
"; + echo "Code: {$rate->getCode()}
"; + echo "Name: {$rate->getName()}

"; + } +} + +// Read a Rate based off the passed in code and optionally the office. +if ($executeRead) { + try { + $rate = $rateApiConnector->get("DIRECT", $office); + } catch (ResponseException $e) { + $rate = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rate);
+    echo "
"; + + echo "Rate
"; + echo "Code: {$rate->getCode()}
"; // string|null Rate code. + echo "Created (\\DateTimeInterface):
" . print_r($rate->getCreated(), true) . "

"; // DateTimeInterface|null The date/time the rate was created. Read-only attribute. + echo "Created (string): " . Util::formatDateTime($rate->getCreated()) . "
"; // string|null + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($rate->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($rate->getCurrency()) . "
"; // string|null + + if ($rate->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($rate->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Modified (\\DateTimeInterface):
" . print_r($rate->getModified(), true) . "

"; // DateTimeInterface|null The date/time the rate was modified. Read-only attribute. + echo "Modified (string): " . Util::formatDateTime($rate->getModified()) . "
"; // string|null + echo "Name: {$rate->getName()}
"; // string|null Rate description. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($rate->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($rate->getOffice()) . "
"; // string|null + echo "Result: {$rate->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$rate->getShortName()}
"; // string|null Short rate description. + echo "Status: {$rate->getStatus()}
"; // Status|null Status of the rate. + echo "Touched: {$rate->getTouched()}
"; // int|null The number of times the rate is modified. Read-only attribute. + echo "Type: {$rate->getType()}
"; // RateType|null The rate type. + echo "Unit: {$rate->getUnit()}
"; // int|null How will be charged e.g. if charged per hour Time, set it to 60. If charged per 8 hours, set it to 8 * 60 = 460. + // Quantities refers to items such as kilometers. If charged per kilometer set it to 1. + echo "User (\\PhpTwinfield\\User):
" . print_r($rate->getUser(), true) . "

"; // User|null The code of the user who created or modified the Rate. Read-only attribute. + echo "User (string): " . Util::objectToStr($rate->getUser()) . "
"; // string|null + + $rateRateChanges = $rate->getRateChanges(); // Array|null Array of RateRateChange objects. + + foreach ($rateRateChanges as $key => $rateRateChange) { + echo "RateRateChange {$key}
"; + + echo "BeginDate (\\DateTimeInterface):
" . print_r($rateRateChange->getBeginDate(), true) . "

"; // DateTimeInterface|null Begin date of the rate. + echo "BeginDate (string): " . Util::formatDate($rateRateChange->getBeginDate()) . "
"; // string|null + echo "EndDate (\\DateTimeInterface):
" . print_r($rateRateChange->getEndDate(), true) . "

"; // DateTimeInterface|null End date of the rate. + echo "EndDate (string): " . Util::formatDate($rateRateChange->getEndDate()) . "
"; // string|null + echo "ExternalRate: {$rateRateChange->getExternalRate()}
"; // int|null The external rate e.g. the selling price per unit. + echo "ID: {$rateRateChange->getID()}
"; // int|null Line ID. + echo "InternalRate: {$rateRateChange->getInternalRate()}
"; // int|null The internal rate e.g. the cost price per unit. + + if ($rateRateChange->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($rateRateChange->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$rateRateChange->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Status: {$rateRateChange->getStatus()}
"; // Status|null Status of the rate change. + } +} + +// Copy an existing Rate to a new entity +if ($executeCopy) { + try { + $rate = $rateApiConnector->get("DIRECT", $office); + } catch (ResponseException $e) { + $rate = $e->getReturnedObject(); + } + + $rate->setCode("DIRECT2"); + + try { + $rateCopy = $rateApiConnector->send($rate); + } catch (ResponseException $e) { + $rateCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rateCopy);
+    echo "
"; + + echo "Result of copy process: {$rateCopy->getResult()}
"; + echo "Code of copied Rate: {$rateCopy->getCode()}
"; + echo "Status of copied Rate: {$rateCopy->getStatus()}
"; +} + +// Create a new Rate from scratch, alternatively read an existing Rate as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $rate = new \PhpTwinfield\Rate; + + // Required values for creating a new Rate + $rate->setCode('DIRECT2'); // string|null Rate code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $rate->setCurrency($currency); // Currency|null Currency code. + $rate->setCurrency(\PhpTwinfield\Currency::fromCode('EUR')); // string|null + $rate->setName("Example Rate"); // string|null Rate description. + $rate->setOffice($office); // Office|null Office code. + $rate->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + $rate->setType(\PhpTwinfield\Enums\RateType::TIME()); // RateType|null The rate type. + $rate->setUnit(60); // int|null How will be charged e.g. if charged per hour Time, set it to 60. If charged per 8 hours, set it to 8 * 60 = 460. + // Quantities refers to items such as kilometers. If charged per kilometer set it to 1. + // Optional values for creating a new Rate + $rate->setShortName("ExmpleRate"); // string|null Short rate description. + $rate->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. + //$rate->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // For deleting deleted should be used. In case a rate that is in use, its status has been changed into hide. + // Hidden rates can be activated by using active. + + // The minimum amount of RateRateChanges linked to a Rate object is 0 + $rateRateChange = new \PhpTwinfield\RateRateChange; + $beginDate = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $rateRateChange->setBeginDate($beginDate); // DateTimeInterface|null Begin date of the rate. + $rateRateChange->setBeginDate(Util::parseDate('20190101')); // string|null + $endDate = \DateTime::createFromFormat('d-m-Y', '31-12-2019'); + $rateRateChange->setEndDate($endDate); // DateTimeInterface|null Begin date of the rate. + $rateRateChange->setEndDate(Util::parseDate('20191231')); // string|null + $rateRateChange->setExternalRate(60); // float|null The internal rate e.g. the cost price per unit. + $rateRateChange->setID(2); // int|null Line ID. + $rateRateChange->setInternalRate(120); // float|null The internal rate e.g. the cost price per unit. + //$rateRateChange->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null Status of the rate line. For creating and updating status may be left empty. NOTE: Do not use $rateRateChange->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); + // For deleting deleted should be used. NOTE: Do not use $rateRateChange->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); + + $rate->addRateChange($rateRateChange); // RateRateChange Add a RateRateChange object to the Rate object + //$rate->removeRateChange(0); // int Remove a rate change based on the index of the rate change + + try { + $rateNew = $rateApiConnector->send($rate); + } catch (ResponseException $e) { + $rateNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rateNew);
+    echo "
"; + + echo "Result of creation process: {$rateNew->getResult()}
"; + echo "Code of new Rate: {$rateNew->getCode()}
"; + echo "Status of new Rate: {$rateNew->getStatus()}
"; +} + +// Delete a Rate based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $rateDeleted = $rateApiConnector->delete("DIRECT2", $office); + } catch (ResponseException $e) { + $rateDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($rateDeleted);
+    echo "
"; + + echo "Result of deletion process: {$rateDeleted->getResult()}
"; + echo "Code of deleted Rate: {$rateDeleted->getCode()}
"; + echo "Status of deleted Rate: {$rateDeleted->getStatus()}
"; +} diff --git a/examples/RenewAccessToken.php b/examples/RenewAccessToken.php new file mode 100644 index 00000000..d7a44d9e --- /dev/null +++ b/examples/RenewAccessToken.php @@ -0,0 +1,94 @@ + (time() - 60 * 45)) { + return true; + } + + return false; +} + +// Only allow the script to run from the command line interface e.g. Cron +if (php_sapi_name() !='cli') exit; + +// Only allow the script to run if last successful run time is more than 45 minutes ago +if (!LastRunThreeQuartersAgo()) exit; + +require_once('vendor/autoload.php'); + +// The client ID assigned to you by Twinfield. +$twin_client_id = 'SomeClientId'; + +// The client secret assigned to you by Twinfield. +$twin_client_secret = 'SomeClientSecret'; + +// The FQDN URI of the script used for initial authorization, must be filled out on the form (Redirect URL) when requesting the client ID/Secret from Twinfield. +$twin_redirect_uri = 'https://example.org/twinfield/Authorization.php'; + +// Retrieve a stored Refresh token from storage. +$refreshTokenStorage = retrieveRefreshTokenFromStore(); + +$provider = new \PhpTwinfield\Secure\Provider\OAuthProvider([ + 'clientId' => $twin_client_id, + 'clientSecret' => $twin_client_secret, + 'redirectUri' => $twin_redirect_uri, +]); + +// Get a new access token using the stored refresh token +$accessToken = $provider->getAccessToken('refresh_token', [ + 'refresh_token' => $refreshTokenStorage['refresh_token'] +]); + +// Validate the access token and retrieve the access cluster +$validationUrl = "https://login.twinfield.com/auth/authentication/connect/accesstokenvalidation?token="; +$validationResult = @file_get_contents($validationUrl . urlencode($accessToken->getToken())); + +if ($validationResult !== false) { + $resultDecoded = \json_decode($validationResult, true); + + $tokenStorage = array(); + $tokenStorage['access_token'] = $accessToken->getToken(); + $tokenStorage['access_expiry'] = $accessToken->getExpires(); + $tokenStorage['access_cluster'] = $resultDecoded["twf.clusterUrl"]; + + // Save the new access token, expiry time and cluster to storage + SaveAccessTokenToStore($tokenStorage); + + // Update the last renewal successful run time to right now + touch('renewaccesstoken.timestamp'); +} diff --git a/examples/RenewAuthorization.php b/examples/RenewAuthorization.php new file mode 100644 index 00000000..3f7a9a2e --- /dev/null +++ b/examples/RenewAuthorization.php @@ -0,0 +1,54 @@ +
+ +The Twinfield authorization for domain/application is about to expire.
+Please renew the authorization as soon as possible.
+Renew the authorization by clicking here and logging in with Twinfield.

+ +You will receive this email once a week until the authorization is renewed."; + +if ($refreshTokenStorage['refresh_expiry'] < (time() + ($daysLeftAfterWhichRequestRenewal * 60 * 60 * 24))) { + SendEmail($accountingAdminEmail, $fromEmail, $subject, $body); +} +?> diff --git a/examples/SalesTransaction.php b/examples/SalesTransaction.php new file mode 100644 index 00000000..5d11b2d3 --- /dev/null +++ b/examples/SalesTransaction.php @@ -0,0 +1,352 @@ +get(\PhpTwinfield\SalesTransaction::class, "VRK", 201900011, $office); + } catch (ResponseException $e) { + $salesTransaction = $e->getReturnedObject(); + } + + echo "
";
+    print_r($salesTransaction);
+    echo "
"; + + echo "SalesTransaction
"; + echo "AutoBalanceVat (bool): {$salesTransaction->getAutoBalanceVat()}
"; // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + echo "AutoBalanceVat (string): " . Util::formatBoolean($salesTransaction->getAutoBalanceVat()) . "
"; // string|null + echo "BookingReference (\\PhpTwinfield\\BookingReference):
" . print_r($salesTransaction->getBookingReference(), true) . "

"; // BookingReference|null The Booking reference + echo "Code: {$salesTransaction->getCode()}
"; // string|null Transaction type code. + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($salesTransaction->getCurrency(), true) . "

"; // Currency|null Currency code. + echo "Currency (string): " . Util::objectToStr($salesTransaction->getCurrency()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($salesTransaction->getDate(), true) . "

"; // DateTimeInterface|null Transaction date. + echo "Date (string): " . Util::formatDate($salesTransaction->getDate()) . "
"; // string|null + echo "DateRaiseWarning (bool): {$salesTransaction->getDateRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + echo "DateRaiseWarning (string): {$salesTransaction->getDateRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + echo "Destiny: {$salesTransaction->getDestiny()}
"; // Destiny|null Attribute to indicate the destiny of the sales transaction. Only used in the request XML. temporary = sales transaction will be saved as provisional. final = sales transaction will be saved as final + echo "DueDate (\\DateTimeInterface):
" . print_r($salesTransaction->getDueDate(), true) . "

"; // DateTimeInterface|null Due date. + echo "DueDate (string): " . Util::formatDate($salesTransaction->getDueDate()) . "
"; // string|null + echo "FreeText1: {$salesTransaction->getFreeText1()}
"; // string|null Free text field 1 as entered on the transaction type. + echo "FreeText2: {$salesTransaction->getFreeText2()}
"; // string|null Free text field 2 as entered on the transaction type. + echo "FreeText3: {$salesTransaction->getFreeText3()}
"; // string|null Free text field 3 as entered on the transaction type. + echo "InputDate (\\DateTimeInterface):
" . print_r($salesTransaction->getInputDate(), true) . "

"; // DateTimeInterface|null The date/time on which the transaction was created. Read-only attribute. + echo "InputDate (string): " . Util::formatDate($salesTransaction->getInputDate()) . "
"; // string|null + echo "InvoiceNumber: {$salesTransaction->getInvoiceNumber()}
"; // string|null Invoice number. + echo "InvoiceNumberRaiseWarning (bool): {$salesTransaction->getInvoiceNumberRaiseWarning()}
"; // bool|null Optionally, it is possible to suppress warnings about 'double invoice numbers' by adding the raisewarning attribute and set its value to false. + echo "InvoiceNumberRaiseWarning (string): {$salesTransaction->getInvoiceNumberRaiseWarningToString()}
"; // string|null This overwrites the value of the raisewarning attribute as set on the root element. + + if ($salesTransaction->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($salesTransaction->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "ModificationDate (\\DateTimeInterface):
" . print_r($salesTransaction->getModificationDate(), true) . "

"; // DateTimeInterface|null The date/time on which the sales transaction was modified the last time. Read-only attribute. + echo "ModificationDate (string): " . Util::formatDate($salesTransaction->getModificationDate()) . "
"; // string|null + echo "Number: {$salesTransaction->getNumber()}
"; // int|null Transaction number. When creating a new sales transaction, don't include this tag as the transaction number is determined by the system. When updating a sales transaction, the related transaction number should be provided. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($salesTransaction->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($salesTransaction->getOffice()) . "
"; // string|null + echo "Origin: {$salesTransaction->getOrigin()}
"; // string|null The sales transaction origin. Read-only attribute. + echo "OriginReference: {$salesTransaction->getOriginReference()}
"; // string|null The sales transaction origin reference (id). Provided in form of Guid. Read-only attribute. + echo "PaymentReference: {$salesTransaction->getPaymentReference()}
"; // string|null Payment reference of the transaction. If payment reference is not specified, the paymentreference section must be omitted + echo "Period: {$salesTransaction->getPeriod()}
"; // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + echo "RaiseWarning (bool): {$salesTransaction->getRaiseWarning()}
"; // bool|null Should warnings be given true or not false? Default true. + echo "RaiseWarning (string): " . Util::formatBoolean($salesTransaction->getRaiseWarning()) . "
"; // string|null + echo "Result: {$salesTransaction->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + + $salesTransactionLines = $salesTransaction->getLines(); // array|null Array of SalesTransactionLine objects. + + foreach ($salesTransactionLines as $key => $salesTransactionLine) { + echo "SalesTransactionLine {$key}
"; + + echo "Baseline: {$salesTransactionLine->getBaseline()}
"; // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + echo "BaseValue (\\Money\\Money):
" . print_r($salesTransactionLine->getBaseValue(), true) . "

"; // Money|null Amount in the base currency. + echo "BaseValue (string): " . Util::formatMoney($salesTransactionLine->getBaseValue()) . "
"; // string|null + echo "BaseValueOpen (\\Money\\Money):
" . print_r($salesTransactionLine->getBaseValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still owed in base currency. Read-only attribute. + echo "BaseValueOpen (string): " . Util::formatMoney($salesTransactionLine->getBaseValueOpen()) . "
"; // string|null + echo "Comment: {$salesTransactionLine->getComment()}
"; // string|null Comment set on the transaction line. + echo "DebitCredit: {$salesTransactionLine->getDebitCredit()}
"; // DebitCredit|null If line type = total. In case of a 'normal' sales transaction debit. In case of a credit sales transaction credit. If line type = detail or vat. In case of a 'normal' sales transaction credit. In case of a credit sales transaction debit. + echo "Description: {$salesTransactionLine->getDescription()}
"; // string|null Description of the transaction line. + echo "DestOffice (\\PhpTwinfield\\Office):
" . print_r($salesTransactionLine->getDestOffice(), true) . "

"; // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + echo "DestOffice (string): " . Util::objectToStr($salesTransactionLine->getDestOffice()) . "
"; // string|null + echo "Dim1:
" . print_r($salesTransactionLine->getDim1(), true) . "

"; // object|null If line type = total the accounts receivable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the customer in Twinfield. If line type = detail the profit and loss account. + echo "Dim1 (string): " . Util::objectToStr($salesTransactionLine->getDim1()) . "
"; // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + echo "Dim2:
" . print_r($salesTransactionLine->getDim2(), true) . "

"; // object|null If line type = total the account receivable. If line type = detail the cost center or empty. + echo "Dim2 (string): " . Util::objectToStr($salesTransactionLine->getDim2()) . "
"; // string|null If line type = vat empty. + echo "Dim3:
" . print_r($salesTransactionLine->getDim2(), true) . "

"; // object|null If line type = total empty. If line type = detail the project or asset or empty. + echo "Dim3 (string): " . Util::objectToStr($salesTransactionLine->getDim3()) . "
"; // string|null If line type = vat empty. + echo "FreeChar: {$salesTransactionLine->getFreeChar()}
"; // string|null Free character field. If line type is total and filled with N the sales invoice is excluded from direct debit runs done in Twinfield. + echo "ID: {$salesTransactionLine->getID()}
"; // int|null Line ID. + echo "LineType: {$salesTransactionLine->getLineType()}
"; // LineType|null Line type. + echo "MatchLevel: {$salesTransactionLine->getMatchLevel()}
"; // int|null Only if line type is total. The level of the matchable dimension. Read-only attribute. + echo "MatchStatus: {$salesTransactionLine->getMatchStatus()}
"; // MatchStatus|null Payment status of the sales transaction. If line type detail or vat always notmatchable. Read-only attribute. + + if ($salesTransactionLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($salesTransactionLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PerformanceCountry (\\PhpTwinfield\\Country):
" . print_r($salesTransactionLine->getPerformanceCountry(), true) . "

"; // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + echo "PerformanceCountry (string): " . Util::objectToStr($salesTransactionLine->getPerformanceCountry()) . "
"; // string|null + echo "PerformanceDate (\\DateTimeInterface):
" . print_r($salesTransactionLine->getPerformanceDate(), true) . "

"; // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + echo "PerformanceDate (string): " . Util::formatDate($salesTransactionLine->getPerformanceDate()) . "
"; // string|null + echo "PerformanceType: {$salesTransactionLine->getPerformanceType()}
"; // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + echo "PerformanceVatNumber: {$salesTransactionLine->getPerformanceVatNumber()}
"; // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + echo "Rate: {$salesTransactionLine->getRate()}
"; // float|null The exchange rate used for the calculation of the base amount. + echo "Reference (\\PhpTwinfield\\MatchReference):
" . print_r($salesTransactionLine->getReference(), true) . "

"; // MatchReference|null Match reference + echo "Relation: {$salesTransactionLine->getRelation()}
"; // int|null Only if line type is total. Read-only attribute. + echo "RepRate: {$salesTransactionLine->getRepRate()}
"; // float|null The exchange rate used for the calculation of the reporting amount. + echo "RepValue (\\Money\\Money):
" . print_r($salesTransactionLine->getRepValue(), true) . "

"; // Money|null Amount in the reporting currency. + echo "RepValue (string): " . Util::formatMoney($salesTransactionLine->getRepValue()) . "
"; // string|null + echo "RepValueOpen (\\Money\\Money):
" . print_r($salesTransactionLine->getRepValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still owed in reporting currency. Read-only attribute. + echo "RepValueOpen (string): " . Util::formatMoney($salesTransactionLine->getRepValueOpen()) . "
"; // string|null + echo "Result: {$salesTransactionLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SignedValue (\\Money\\Money):
" . print_r($salesTransactionLine->getSignedValue(), true) . "

"; // Money|null + echo "SignedValue (string): " . Util::formatMoney($salesTransactionLine->getSignedValue()) . "
"; // string|null + echo "Value (\\Money\\Money):
" . print_r($salesTransactionLine->getValue(), true) . "

"; // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + echo "Value (string): " . Util::formatMoney($salesTransactionLine->getValue()) . "
"; // string|null + echo "ValueOpen (\\Money\\Money):
" . print_r($salesTransactionLine->getValueOpen(), true) . "

"; // Money|null Only if line type is total. The amount still owed in the currency of the sales transaction. Read-only attribute. + echo "ValueOpen (string): " . Util::formatMoney($salesTransactionLine->getValueOpen()) . "
"; // string|null + echo "VatBaseTotal (\\Money\\Money):
" . print_r($salesTransactionLine->getVatBaseTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in base currency. + echo "VatBaseTotal (string): " . Util::formatMoney($salesTransactionLine->getVatBaseTotal()) . "
"; // string|null + echo "VatBaseTurnover (\\Money\\Money):
" . print_r($salesTransactionLine->getVatBaseTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + echo "VatBaseTurnover (string): " . Util::formatMoney($salesTransactionLine->getVatBaseTurnover()) . "
"; // string|null + echo "VatBaseValue (\\Money\\Money):
" . print_r($salesTransactionLine->getVatBaseValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in base currency. + echo "VatBaseValue (string): " . Util::formatMoney($salesTransactionLine->getVatBaseValue()) . "
"; // string|null + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($salesTransactionLine->getVatCode(), true) . "

"; // VatCode|null Only if line type is detail or vat. VAT code. + echo "VatCode (string): " . Util::objectToStr($salesTransactionLine->getVatCode()) . "
"; // string|null + echo "VatRepTotal (\\Money\\Money):
" . print_r($salesTransactionLine->getVatRepTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in reporting currency. + echo "VatRepTotal (string): " . Util::formatMoney($salesTransactionLine->getVatRepTotal()) . "
"; // string|null + echo "VatRepTurnover (\\Money\\Money):
" . print_r($salesTransactionLine->getVatRepTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + echo "VatRepTurnover (string): " . Util::formatMoney($salesTransactionLine->getVatRepTurnover()) . "
"; // string|null + echo "VatRepValue (\\Money\\Money):
" . print_r($salesTransactionLine->getVatRepValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in reporting currency. + echo "VatRepValue (string): " . Util::formatMoney($salesTransactionLine->getVatRepValue()) . "
"; // string|null + echo "VatTotal (\\Money\\Money):
" . print_r($salesTransactionLine->getVatTotal(), true) . "

"; // Money|null Only if line type is total. The total VAT amount in the currency of the sales transaction. + echo "VatTotal (string): " . Util::formatMoney($salesTransactionLine->getVatTotal()) . "
"; // string|null + echo "VatTurnover (\\Money\\Money):
" . print_r($salesTransactionLine->getVatTurnover(), true) . "

"; // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the sales transaction. + echo "VatTurnover (string): " . Util::formatMoney($salesTransactionLine->getVatTurnover()) . "
"; // string|null + echo "VatValue (\\Money\\Money):
" . print_r($salesTransactionLine->getVatValue(), true) . "

"; // Money|null Only if line type is detail. VAT amount in the currency of the sales transaction. + echo "VatValue (string): " . Util::formatMoney($salesTransactionLine->getVatValue()) . "
"; // string|null + } +} + +// Copy an existing SalesTransaction to a new entity +if ($executeCopy) { + try { + $salesTransaction = $transactionApiConnector->get(\PhpTwinfield\SalesTransaction::class, "VRK", 201900011, $office); + } catch (ResponseException $e) { + $salesTransaction = $e->getReturnedObject(); + } + + $salesTransaction->setNumber(null); + + //Optional, but recommended so your copy is not posted to final immediately + $salesTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); + + try { + $salesTransactionCopy = $transactionApiConnector->send($salesTransaction); + } catch (ResponseException $e) { + $salesTransactionCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($salesTransactionCopy);
+    echo "
"; + + echo "Result of copy process: {$salesTransactionCopy->getResult()}
"; + echo "Number of copied SalesTransaction: {$salesTransactionCopy->getNumber()}
"; +} + +// Create a new SalesTransaction from scratch, alternatively read an existing SalesTransaction as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $salesTransaction = new \PhpTwinfield\SalesTransaction; + + // Required values for creating a new SalesTransaction + $salesTransaction->setCode('VRK'); // string|null Transaction type code. + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $salesTransaction->setCurrency($currency); // Currency|null Currency code. + //$salesTransaction->setCurrency(\PhpTwinfield\Currency::fromCode("EUR")); // string|null + $salesTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::TEMPORARY()); // Destiny|null Attribute to indicate the destiny of the sales transaction. Only used in the request XML. + //$salesTransaction->setDestiny(\PhpTwinfield\Enums\Destiny::FINAL()); // Destiny|null temporary = sales transaction will be saved as provisional. final = sales transaction will be saved as final. + $salesTransaction->setInvoiceNumber(201900011); // string|null Invoice number. + $salesTransaction->setOffice($office); // Office|null Office code. + $salesTransaction->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new SalesTransaction + $salesTransaction->setAutoBalanceVat(true); // bool|null Should VAT be rounded true or not false? Rounding will only be done with a maximum of two cents. + $date = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + $salesTransaction->setDate($date); // DateTimeInterface|null Transaction date. Optionally, it is possible to suppress warnings about 'date out of range for the given period' by adding the raisewarning attribute and set its value to false. + $salesTransaction->setDate(Util::parseDate("20190901")); // string|null This overwrites the value of the raisewarning attribute as set on the root element. + $salesTransaction->setDateRaiseWarning(false); // bool|null + $dueDate = \DateTime::createFromFormat('d-m-Y', '01-10-2019'); + $salesTransaction->setDueDate($dueDate); // DateTimeInterface|null Due date. + $salesTransaction->setDueDate(Util::parseDate("20191001")); // string|null + //$salesTransaction->setFreeText1('Example FreeText 1'); // string|null Free text field 1 as entered on the transaction type. + //$salesTransaction->setFreeText2('Example FreeText 2'); // string|null Free text field 2 as entered on the transaction type. + //$salesTransaction->setFreeText3('Example FreeText 3'); // string|null Free text field 3 as entered on the transaction type. + $salesTransaction->setInvoiceNumberRaiseWarning(false); // bool|null Optionally, it is possible to suppress warnings about 'double invoice numbers' by adding the raisewarning attribute and set its value to false. This overwrites the value of the raisewarning attribute as set on the root element. + //$salesTransaction->setNumber(201900011); // int|null Transaction number. When creating a new sales transaction, don't include this tag as the transaction number is determined by the system. When updating a sales transaction, the related transaction number should be provided. + //$salesTransaction->setPeriod("2019/07"); // string|null Period in YYYY/PP format. If this tag is not included or if it is left empty, the period is determined by the system based on the provided transaction date. + $salesTransaction->setRaiseWarning(true); // bool|null Should warnings be given true or not false? Default true. + + // The minimum amount of SalesTransactionLines linked to an SalesTransaction object is 2 (1 total, 1 detail) + $salesTransactionLine1 = new \PhpTwinfield\SalesTransactionLine; + $salesTransactionLine1->setLineType(\PhpTwinfield\Enums\LineType::TOTAL()); // LineType|null Line type. + + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('1300'); + $salesTransactionLine1->setDim1($dim1); // object|null If line type = total the accounts receivable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the customer in Twinfield. If line type = detail the profit and loss account. + $salesTransactionLine1->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1300')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1000'); + $salesTransactionLine1->setDim2($dim2); // object|null If line type = total the account receivable. If line type = detail the cost center or empty. If line type = vat empty. + $salesTransactionLine1->setDim2(\PhpTwinfield\Customer::fromCode('1000')); // string|null + $salesTransactionLine1->setID(1); // int|null Line ID. + $salesTransactionLine1->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + //$salesTransactionLine1->setVatBaseTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in base currency. + //$salesTransactionLine1->setVatRepTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in reporting currency. + //$salesTransactionLine1->setVatTotal(\Money\Money::EUR(-10000)); // Money|null Only if line type is total. The total VAT amount in the currency of the sales transaction. + + $salesTransaction->addLine($salesTransactionLine1); // SalesTransactionLine Add a SalesTransactionLine object to the SalesTransaction object + + $salesTransactionLine2 = new \PhpTwinfield\SalesTransactionLine; + $salesTransactionLine2->setLineType(\PhpTwinfield\Enums\LineType::DETAIL()); // LineType|null Line type. + + $salesTransactionLine2->setBaseValue(\Money\Money::EUR(10000)); // Money|null Amount in the base currency. + $salesTransactionLine2->setDescription("Example Description on line with ID 2"); // string|null Description of the transaction line. + $dim1 = new \PhpTwinfield\GeneralLedger; + $dim1->setCode('2500'); + $salesTransactionLine2->setDim1($dim1); // object|null If line type = total the accounts receivable balance account. When dim1 is omitted, by default the general ledger account will be taken as entered at the customer in Twinfield. If line type = detail the profit and loss account. + $salesTransactionLine2->setDim1(\PhpTwinfield\GeneralLedger::fromCode('2500')); // string|null If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken as entered at the VAT code in Twinfield. + $salesTransactionLine2->setID(2); // int|null Line ID. + $salesTransactionLine2->setValue(\Money\Money::EUR(-10000)); // Money|null If line type = total amount including VAT. If line type = detail amount without VAT. If line type = vat VAT amount. + + //$salesTransactionLine2->setComment('Example Comments'); // string|null Comment set on the transaction line. + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('1234'); + //$salesTransaction->setDestOffice($destOffice); // Office|null Office code. Used for inter company transactions – here you define in which company the transaction line should be posted. + //$salesTransaction->setDestOffice(\PhpTwinfield\Office::fromCode('1234')); // string|null + $dim2 = new \PhpTwinfield\Customer; + $dim2->setCode('1001'); + //$salesTransactionLine2->setDim2($dim2); // object|null If line type = total the account receivable. If line type = detail the cost center or empty. If line type = vat empty. + //$salesTransactionLine2->setDim2(\PhpTwinfield\Customer::fromCode('1001')); // string|null + $dim3 = new \PhpTwinfield\Project; + $dim3->setCode('P0000'); + //$salesTransactionLine2->setDim3($dim3); // object|null If line type = total empty. If line type = detail the project or asset or empty. If line type = vat empty. + //$salesTransactionLine2->setDim3(\PhpTwinfield\Project::fromCode('P0000')); // string|null + //$salesTransactionLine2->setFreeChar('A'); // string|null Free character field. If line type is total and filled with N the sales invoice is excluded from direct debit runs done in Twinfield. + $performanceCountry = new \PhpTwinfield\Country; + $performanceCountry->setCode('NL'); + //$salesTransactionLine2->setPerformanceCountry($performanceCountry); // Country|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + //$salesTransactionLine2->setPerformanceCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $performanceDate = \DateTime::createFromFormat('d-m-Y', '01-09-2019'); + //$salesTransactionLine2->setPerformanceDate($performanceDate); // DateTimeInterface|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + //$salesTransactionLine2->setPerformanceDate(Util::parseDate("20190901")); // string|null + //$salesTransactionLine2->setPerformanceType(\PhpTwinfield\Enums\PerformanceType::SERVICES()); // PerformanceType|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + //$salesTransactionLine2->setPerformanceVatNumber('NL1234567890B01'); // string|null Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + //$salesTransactionLine2->setRepValue(\Money\Money::EUR(-10000)); // Money|null Amount in the reporting currency. + //$salesTransactionLine2->setRate(1); // float|null The exchange rate used for the calculation of the base amount. + //$salesTransactionLine2->setRepRate(1); // float|null The exchange rate used for the calculation of the reporting amount. + //$salesTransactionLine2->setVatBaseValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in base currency. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('VN'); + //$salesTransactionLine2->setVatCode($vatCode); // VatCode|null Only if line type is detail or vat. VAT code. + //$salesTransactionLine2->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); // string|null + //$salesTransactionLine2->setVatRepValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in reporting currency. + //$salesTransactionLine2->setVatValue(\Money\Money::EUR(-10000)); // Money|null Only if line type is detail. VAT amount in the currency of the sales transaction. + + $salesTransaction->addLine($salesTransactionLine2); + + //$salesTransactionLine3 = new \PhpTwinfield\SalesTransactionLine; + //$salesTransactionLine3->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Line type. + //$salesTransactionLine3->setBaseline(1); // int|null Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + //$salesTransactionLine3->setVatBaseTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in base currency. + //$salesTransactionLine3->setVatRepTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in reporting currency. + //$salesTransactionLine3->setVatTurnover(\Money\Money::EUR(-10000)); // Money|null Only if line type is vat. Amount on which VAT was calculated in the currency of the sales transaction. + + try { + $salesTransactionNew = $transactionApiConnector->send($salesTransaction); + } catch (ResponseException $e) { + $salesTransactionNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($salesTransactionNew);
+    echo "
"; + + echo "Result of creation process: {$salesTransactionNew->getResult()}
"; + echo "Number of new SalesTransaction: {$salesTransactionNew->getNumber()}
"; +} + +// Delete a BrankTransaction based off the passed in office, code, number and given reason +if ($executeDelete) { + $bookingReference = new \PhpTwinfield\BookingReference($office, 'VRK', 201900012); + + try { + $salesTransactionDeleted = $transactionApiConnector->delete($bookingReference, 'Example reason'); + } catch (ResponseException $e) { + $salesTransactionDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($salesTransactionDeleted);
+    echo "
"; +} \ No newline at end of file diff --git a/examples/Supplier.php b/examples/Supplier.php new file mode 100644 index 00000000..b31e093a --- /dev/null +++ b/examples/Supplier.php @@ -0,0 +1,575 @@ + matchtype = 'relation' +if ($executeListAllWithFilter) { + $options = array('matchtype' => 'relation'); + + try { + $suppliers = $supplierApiConnector->listAll("2*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $suppliers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($suppliers);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $suppliers = $supplierApiConnector->listAll(); + } catch (ResponseException $e) { + $suppliers = $e->getReturnedObject(); + } + + echo "
";
+    print_r($suppliers);
+    echo "
"; +} + +/* Supplier + * \PhpTwinfield\Supplier + * Available getters: getBeginPeriod, getBeginYear, getBehaviour, getBlockedAccountPaymentConditionsIncludeVat, getBlockedAccountPaymentConditionsPercentage, getCode, getEndPeriod, getEndYear, getGroup, getInUse, getMessages, getName, getOffice, + * getPaymentConditionDiscountDays, getPaymentConditionDiscountPercentage, getRemittanceAdviceSendMail, getRemittanceAdviceSendType, getResult, getShortName, getStatus, getTouched, getType, getUID, getWebsite, hasMessages, getAddresses, getBanks, getFinancials, getPostingRules + * + * Available setters: fromCode, setBeginPeriod, setBeginYear, setBehaviour, setBlockedAccountPaymentConditionsIncludeVat, setBlockedAccountPaymentConditionsPercentage, setCode, setEndPeriod, setEndYear, setGroup, setName, setOffice, + * setPaymentConditionDiscountDays, setPaymentConditionDiscountPercentage, setRemittanceAdviceSendMail, setRemittanceAdviceSendType, setShortName, setStatus, setType, setWebsite, setFinancials, addAddress, removeAddress, addBank, removeBank, addPostingRule, removePostingRule + * + */ + +/* SupplierFinancials + * \PhpTwinfield\SupplierFinancials + * Available getters: getAccountType, getDueDays, getLevel, getMatchType, getMeansOfPayment, getMessages, getPayAvailable, getPayCode, getPayCodeID, getRelationsReference, getResult, getSubAnalyse, getSubstituteWith, getSubstituteWithID, getSubstitutionLevel, getVatCode, getVatCodeFixed, getChildValidations, hasMessages + * + * Available setters: setAccountType, setDueDays, setLevel, setMatchType, setMeansOfPayment, setPayAvailable, setPayCode, setPayCodeID, setRelationsReference, setSubAnalyse, setSubstituteWith, setSubstituteWithID, setSubstitutionLevel, setVatCode, setVatCodeFixed, addChildValidation, removeChildValidation + * + */ + +/* SupplierChildValidation + * \PhpTwinfield\SupplierChildValidation + * Available getters: getElementValue, getLevel, getMessages, getResult, getType, hasMessages + * Available setters: setElementValue, setLevel, setType + */ + +/* SupplierAddress + * \PhpTwinfield\SupplierAddress + * Available getters: getCity, getCountry, getDefault, getEmail, getField1, getField2, getField3, getField4, getField5, getField6, getID, getMessages, getName, getPostcode, getResult, getTelefax, getTelephone, getType, hasMessages + * Available setters: setCity, setCountry, setDefault, setEmail, setField1, setField2, setField3, setField4, setField5, setField6, setID, setName, setPostcode, setTelefax, setTelephone, setType + */ + +/* SupplierBank + * \PhpTwinfield\SupplierBank + * Available getters: getAccountNumber, getAddressField2, getAddressField3, getAscription, getBankName, getBicCode, getBlocked, getCity, getCountry, getDefault, getID, getIban, getMessages, getNatBicCode, getPostcode, getResult, getState, hasMessages + * Available setters: setAccountNumber, setAddressField2, setAddressField3, setAscription, setBankName, setBicCode, setBlocked, setCity, setCountry, setDefault, setID, setIban, setNatBicCode, setPostcode, setState + */ + +/* SupplierPostingRule + * \PhpTwinfield\SupplierPostingRule + * Available getters: getAmount, getCurrency, getDescription, getID, getMessages, getResult, getStatus, getLines, hasMessages + * Available setters: setAmount, setCurrency, setDescription, setID, setStatus, addLine, removeLine + */ + +/* SupplierLine + * \PhpTwinfield\SupplierLine + * Available getters: getDescription, getDimension1, getDimension1ID, getDimension2, getDimension2ID, getDimension3, getDimension3ID, getMessages, getOffice, getRatio, getResult, getVatCode, hasMessages + * Available setters: setDescription, setDimension1, setDimension1ID, setDimension2, setDimension2ID, setDimension3, setDimension3ID, setOffice, setRatio, setVatCode + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($suppliers as $key => $supplier) { + echo "Supplier {$key}
"; + echo "Code: {$supplier->getCode()}
"; + echo "Name: {$supplier->getName()}

"; + } +} + +// Read a Supplier based off the passed in code and optionally the office. +if ($executeRead) { + try { + $supplier = $supplierApiConnector->get("2000", $office); + } catch (ResponseException $e) { + $supplier = $e->getReturnedObject(); + } + + echo "
";
+    print_r($supplier);
+    echo "
"; + + echo "Supplier
"; + echo "BeginPeriod: {$supplier->getBeginPeriod()}
"; // int|null Determines together with beginyear the period from which the dimension may be used. + echo "BeginYear: {$supplier->getBeginYear()}
"; // int|null Determines together with beginperiod the period from which the dimension may be used. + echo "Behaviour: {$supplier->getBehaviour()}
"; // Behaviour|null Determines the behaviour of dimensions. Read-only attribute. + echo "Code: {$supplier->getCode()}
"; // string|null Dimension code, must be compliant with the mask of the CRD Dimension type. + echo "EndPeriod: {$supplier->getEndPeriod()}
"; // int|null Determines together with endyear the period till which the dimension may be used. + echo "EndYear: {$supplier->getEndYear()}
"; // int|null Determines together with endperiod the period till which the dimension may be used. + echo "Group (\\PhpTwinfield\\DimensionGroup):
" . print_r($supplier->getGroup(), true) . "

"; // DimensionGroup|null Sets the dimension group. See Dimension group. + echo "Group (string): " . Util::objectToStr($supplier->getGroup()) . "
"; // string|null + echo "InUse (bool): {$supplier->getInUse()}
"; // bool|null Indicates whether the dimension is used in a financial transaction or not. Read-only attribute. + echo "InUse (string): " . Util::formatBoolean($supplier->getInUse()) . "
"; // string|null + + if ($supplier->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplier->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$supplier->getName()}
"; // string|null Name of the dimension. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($supplier->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($supplier->getOffice()) . "
"; // string|null + echo "PaymentCondition:
"; // Sets the payment condition of a dimension. + echo "PaymentCondition DiscountDays: {$supplier->getPaymentConditionDiscountDays()}
"; // int|null Number of discount days. + echo "PaymentCondition DiscountPercentage: {$supplier->getPaymentConditionDiscountPercentage()}
"; // float|null Discount percentage. + echo "RemittanceAdvice:
"; // + echo "RemittanceAdvice SendMail: {$supplier->getRemittanceAdviceSendMail()}
"; // string|null Mandatory if sendtype = ByEmail, remittance advice will be sent using this e-mail address. + echo "RemittanceAdvice SendType: {$supplier->getRemittanceAdviceSendType()}
"; // RemittanceAdviceSendType|null To file manager, By e-mail + echo "Result: {$supplier->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$supplier->getShortName()}
"; // string|null Short name of the dimension. + echo "Status: {$supplier->getStatus()}
"; // Status|null Status of the supplier. + echo "Touched: {$supplier->getTouched()}
"; // int|null Count of the number of times the dimension settings are changed. Read-only attribute. + echo "Type (\\PhpTwinfield\\DimensionType):
" . print_r($supplier->getType(), true) . "

"; // DimensionType|null Dimension type. See Dimension type. Dimension type of suppliers is CRD. + echo "Type (string): " . Util::objectToStr($supplier->getType()) . "
"; // string|null + echo "UID: {$supplier->getUID()}
"; // string|null Unique identification of the dimension. Read-only attribute. + echo "Website: {$supplier->getWebsite()}
"; // string|null Website of the dimension. + + $supplierAddresses = $supplier->getAddresses(); // array|null Array of SupplierAddress objects. + + foreach ($supplierAddresses as $key => $supplierAddress) { + echo "SupplierAddress {$key}
"; + + echo "City: {$supplierAddress->getCity()}
"; // string|null City. + echo "Country (\\PhpTwinfield\\Country):
" . print_r($supplierAddress->getCountry(), true) . "

"; // Country|null Country code. The ISO country codes are used. + echo "Country (string): " . Util::objectToStr($supplierAddress->getCountry()) . "
"; // string|null + echo "Default (bool): {$supplierAddress->getDefault()}
"; // bool|null Is this the default address, only one default address is possible. + echo "Default (string): " . Util::formatBoolean($supplierAddress->getDefault()) . "
"; // string|null + echo "Email: {$supplierAddress->getEmail()}
"; // string|null + echo "Field1: {$supplierAddress->getField1()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field2: {$supplierAddress->getField2()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field3: {$supplierAddress->getField3()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field4: {$supplierAddress->getField4()}
"; // string|null User defined fields, the labels are configured in the Dimension type. Currently, field4 is reserved for VAT numbers. So only valid VAT numbers may be filled in. + echo "Field5: {$supplierAddress->getField5()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "Field6: {$supplierAddress->getField6()}
"; // string|null User defined fields, the labels are configured in the Dimension type. + echo "ID: {$supplierAddress->getID()}
"; // int|null Sequence number of the address line. + + if ($supplierAddress->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierAddress->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Name: {$supplierAddress->getName()}
"; // string|null Company name. + echo "Postcode: {$supplierAddress->getPostcode()}
"; // string|null Postcode. + echo "Result: {$supplierAddress->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Telefax: {$supplierAddress->getTelefax()}
"; // string|null Fax number. + echo "Telephone: {$supplierAddress->getTelephone()}
"; // string|null Telephone number. + echo "Type: {$supplierAddress->getType()}
"; // AddressType|null The type of the address. + } + + $supplierBanks = $supplier->getBanks(); + + foreach ($supplierBanks as $key => $supplierBank) { + echo "SupplierBank {$key}
"; + + echo "AccountNumber: {$supplierBank->getAccountNumber()}
"; // string|null Account number. + echo "AddressField2: {$supplierBank->getAddressField2()}
"; // string|null Bank address. + echo "AddressField3: {$supplierBank->getAddressField3()}
"; // string|null Bank address number. + echo "Ascription: {$supplierBank->getAscription()}
"; // string|null Account holder. + echo "BankName: {$supplierBank->getBankName()}
"; // string|null Bank name. + echo "BicCode: {$supplierBank->getBicCode()}
"; // string|null BIC code. + + echo "Blocked (bool): {$supplierBank->getBlocked()}
"; // bool|null + echo "Blocked (string): " . Util::formatBoolean($supplierBank->getBlocked()) . "
"; // string|null + echo "City: {$supplierBank->getCity()}
"; // string|null City. + echo "Country (\\PhpTwinfield\\Country):
" . print_r($supplierBank->getCountry(), true) . "

"; // Country|null Bank country code. The ISO country codes are used. + echo "Country (string): " . Util::objectToStr($supplierBank->getCountry()) . "
"; // string|null + echo "Default (bool): {$supplierBank->getDefault()}
"; // bool|null Is this the default bank account, only one default bank account is possible. + echo "Default (string): " . Util::formatBoolean($supplierBank->getDefault()) . "
"; // string|null + echo "ID: {$supplierBank->getID()}
"; // int|null Sequence number of the bank account line. When adding a new bank, do not supply the @id. When changing a bank account, supply the corresponding @id. + echo "IBAN: {$supplierBank->getIban()}
"; // string|null IBAN account number. + + if ($supplierBank->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierBank->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "NatBicCode: {$supplierBank->getNatBicCode()}
"; // string|null National bank code. + echo "Postcode: {$supplierBank->getPostcode()}
"; // string|null Postcode. + echo "Result: {$supplierBank->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "State: {$supplierBank->getState()}
"; // string|null State. + } + + echo "SupplierFinancials
"; + $supplierFinancials = $supplier->getFinancials(); // SupplierFinancials|null SupplierFinancials object. + + echo "AccountType: {$supplierFinancials->getAccountType()}
"; // AccountType|null Fixed value inherit. + echo "DueDays: {$supplierFinancials->getDueDays()}
"; // int|null The number of due days. + echo "Level: {$supplierFinancials->getLevel()}
"; // int|null Specifies the dimension level. Normally the level of suppliers is level 2. Read-only attribute. + echo "MatchType: {$supplierFinancials->getMatchType()}
"; // MatchType|null Fixed value customersupplier. + echo "MeansOfPayment: {$supplierFinancials->getMeansOfPayment()}
"; // MeansOfPayment|null The option none is only allowed in case payavailable is set to false. The option paymentfile is only allowed in case payavailable is set to true. + + if ($supplierFinancials->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierFinancials->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "PayAvailable (bool): {$supplierFinancials->getPayAvailable()}
"; // bool|null Determines if direct debit is possible. + echo "PayAvailable (string): " . Util::formatBoolean($supplierFinancials->getPayAvailable()) . "
"; // string|null + echo "PayCode (\\PhpTwinfield\\PayCode):
" . print_r($supplierFinancials->getPayCode(), true) . "

"; // PayCode|null The code of the payment type in case direct debit is possible. + echo "PayCode (string): " . Util::objectToStr($supplierFinancials->getPayCode()) . "
"; // string|null + echo "PayCodeID: {$supplierFinancials->getPayCodeID()}
"; // string|null + echo "RelationsReference: {$supplierFinancials->getRelationsReference()}
"; // string|null External supplier number. + echo "Result: {$supplierFinancials->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "SubAnalyse: {$supplierFinancials->getSubAnalyse()}
"; // SubAnalyse|null Fixed value false. + echo "SubstituteWith (\\PhpTwinfield\\GeneralLedger):
" . print_r($supplierFinancials->getSubstituteWith(), true) . "

"; // GeneralLedger|null Default supplier balancesheet account. + echo "SubstituteWith (string): " . Util::objectToStr($supplierFinancials->getSubstituteWith()) . "
"; // string|null + echo "SubstituteWithID: {$supplierFinancials->getSubstituteWithID()}
"; // string|null + echo "SubstitutionLevel: {$supplierFinancials->getSubstitutionLevel()}
"; // int|null Level of the balancesheet account. Fixed value 1. + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($supplierFinancials->getVatCode(), true) . "

"; // VatCode|null Default VAT code. + echo "VatCode (string): " . Util::objectToStr($supplierFinancials->getVatCode()) . "
"; // string|null + echo "VatCode Fixed (bool): {$supplierFinancials->getVatCodeFixed()}
"; // bool|null + echo "VatCode Fixed (string): " . Util::formatBoolean($supplierFinancials->getVatCodeFixed()) . "
"; // string|null + + $supplierChildValidations = $supplierFinancials->getChildValidations(); // array|null Array of SupplierChildValidations objects. + + foreach ($supplierChildValidations as $key => $supplierChildValidation) { + echo "SupplierChildValidation {$key}
"; + + echo "ElementValue: {$supplierChildValidation->getElementValue()}
"; // string|null + echo "Level: {$supplierChildValidation->getLevel()}
"; // int|null + + if ($supplierChildValidation->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierChildValidation->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$supplierChildValidation->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Type: {$supplierChildValidation->getType()}
"; // ChildValidationType|null + } + + $supplierPostingRules = $supplier->getPostingRules(); // array|null Array of SupplierPostingRule objects. + + foreach ($supplierPostingRules as $key => $supplierPostingRule) { + echo "SupplierPostingRule {$key}
"; + + echo "Amount (\\Money\\Money):
" . print_r($supplierPostingRule->getAmount(), true) . "

"; // Money|null Amount. + echo "Amount (string): " . Util::formatMoney($supplierPostingRule->getAmount()) . "
"; // string|null + echo "Currency (\\PhpTwinfield\\Currency):
" . print_r($supplierPostingRule->getCurrency(), true) . "

"; // Currency|null Currency. + echo "Currency (string): " . Util::objectToStr($supplierPostingRule->getCurrency()) . "
"; // string|null + echo "Description: {$supplierPostingRule->getDescription()}
"; // string|null Description. + echo "ID: {$supplierPostingRule->getID()}
"; // int|null Sequence number of the posting rule. Fixed value 1. + + if ($supplierPostingRule->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierPostingRule->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Result: {$supplierPostingRule->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Status: {$supplierPostingRule->getStatus()}
"; // Status|null Status of the posting rule. + + $supplierLines = $supplierPostingRule->getLines(); // array|null Array of SupplierLine objects. + + foreach ($supplierLines as $key => $supplierLine) { + echo "SupplierLine {$key}
"; + + echo "Description: {$supplierLine->getDescription()}
"; // string|null Description. + echo "Dimension1 (\\PhpTwinfield\\GeneralLedger):
" . print_r($supplierLine->getDimension1(), true) . "

"; // GeneralLedger|null General ledger. + echo "Dimension1 (string): " . Util::objectToStr($supplierLine->getDimension1()) . "
"; // string|null + echo "Dimension1ID: {$supplierLine->getDimension1ID()}
"; // string|null + echo "Dimension2 (\\PhpTwinfield\\CostCenter):
" . print_r($supplierLine->getDimension2(), true) . "

"; // CostCenter|null Cost center. + echo "Dimension2 (string): " . Util::objectToStr($supplierLine->getDimension2()) . "
"; // string|null + echo "Dimension2ID: {$supplierLine->getDimension2ID()}
"; // string|null + echo "Dimension3:
" . print_r($supplierLine->getDimension3(), true) . "

"; // Project|Activity|null Project or asset. + echo "Dimension3 (string): " . Util::objectToStr($supplierLine->getDimension3()) . "
"; // string|null + echo "Dimension3ID: {$supplierLine->getDimension3ID()}
"; // string|null + + if ($supplierLine->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($supplierLine->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Office (\\PhpTwinfield\\Office):
" . print_r($supplierLine->getOffice(), true) . "

"; // Office|null Destination company. + echo "Office (string): " . Util::objectToStr($supplierLine->getOffice()) . "
"; // string|null + echo "Ratio: {$supplierLine->getRatio()}
"; // float|null The ratio of the posting rule line. + echo "Result: {$supplierLine->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "VatCode (\\PhpTwinfield\\VatCode):
" . print_r($supplierLine->getVatCode(), true) . "

"; // VatCode|null VAT code. + echo "VatCode (string): " . Util::objectToStr($supplierLine->getVatCode()) . "
"; // string|null + } + } +} + +// Copy an existing Supplier to a new entity +if ($executeCopy) { + try { + $supplier = $supplierApiConnector->get("2000", $office); + } catch (ResponseException $e) { + $supplier = $e->getReturnedObject(); + } + + $supplier->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$supplier->setCode('2100'); // string|null Dimension code, must be compliant with the mask of the CRD Dimension type. + + //Twinfield does not accept BankID's on new entities + $supplierBanks = $supplier->getBanks(); + + foreach ($supplierBanks as $supplierBank) { + $supplierBank->setID(null); + } + + try { + $supplierCopy = $supplierApiConnector->send($supplier); + } catch (ResponseException $e) { + $supplierCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($supplierCopy);
+    echo "
"; + + echo "Result of copy process: {$supplierCopy->getResult()}
"; + echo "Code of copied Supplier: {$supplierCopy->getCode()}
"; + echo "Status of copied Supplier: {$supplierCopy->getStatus()}
"; +} + +// Create a new Supplier from scratch, alternatively read an existing Supplier as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $supplier = new \PhpTwinfield\Supplier; + + // Required values for creating a new Supplier + $supplier->setCode(null); // string|null Set to null to let Twinfield assign a Dimension code based on the Dimension type mask + //$supplier->setCode('2100'); // string|null Dimension code, must be compliant with the mask of the CRD Dimension type. + $supplier->setName("Example Supplier"); // string|null Name of the dimension. + $supplier->setOffice($office); // Office|null Office code. + $supplier->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + + // Optional values for creating a new Supplier + $supplier->setBeginPeriod(0); // int|null Determines together with beginyear the period from which the dimension may be used. + $supplier->setBeginYear(0); // int|null Determines together with beginperiod the period from which the dimension may be used. + $supplier->setEndPeriod(0); // int|null Determines together with endyear the period till which the dimension may be used. + $supplier->setEndYear(0); // int|null Determines together with endperiod the period till which the dimension may be used. + $supplier->setShortName("ExmplCust"); // string|null Short name of the dimension. + //$supplier->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating status may be left empty. For deleting deleted should be used. + //$supplier->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null In case a dimension that is used in a transaction is deleted, its status has been changed into hide. Hidden dimensions can be activated by using active. + $supplier->setWebsite("www.example.com"); // string|null Website of the dimension. + + $dimensionGroup = new \PhpTwinfield\DimensionGroup; + $dimensionGroup->setCode('DIMGROUP'); + //$supplier->setGroup($dimensionGroup); // DimensionGroup|null Sets the dimension group. See Dimension group. + //$supplier->setGroup(\PhpTwinfield\DimensionGroup::fromCode("DIMGROUP")); // string|null + + $supplier->setPaymentConditionDiscountDays(3); // int|null Number of discount days. + $supplier->setPaymentConditionDiscountPercentage(25); // int|null Discount percentage. + + $supplier->setRemittanceAdviceSendMail("test@example.com"); // string|null Mandatory if sendtype = ByEmail, remittance advice will be sent using this e-mail address. + $supplier->setRemittanceAdviceSendType(\PhpTwinfield\Enums\RemittanceAdviceSendType::BYEMAIL()); // RemittanceAdviceSendMail|null To file manager, By e-mail + + $supplierFinancials = new \PhpTwinfield\SupplierFinancials; + $supplierFinancials->setDueDays(14); // int|null The number of due days. + $supplierFinancials->setMeansOfPayment(\PhpTwinfield\Enums\MeansOfPayment::PAYMENTFILE()); // MeansOfPayment|null The option none is only allowed in case payavailable is set to false. The option paymentfile is only allowed in case payavailable is set to true. + $supplierFinancials->setPayAvailable(true); // bool|null Determines if direct debit is possible. + $payCode = new \PhpTwinfield\PayCode; + $payCode->setCode('SEPANLCT'); + $supplierFinancials->setPayCode($payCode); // PayCode|null The code of the payment type in case direct debit is possible. + $supplierFinancials->setPayCode(\PhpTwinfield\PayCode::fromCode('SEPANLCT')); // string|null + $substituteWith = new \PhpTwinfield\GeneralLedger; + $substituteWith->getCode('1535'); + $supplierFinancials->setSubstituteWith($substituteWith); // GeneralLedger|null Default supplier balancesheet account. + $supplierFinancials->setSubstituteWith(\PhpTwinfield\GeneralLedger::fromCode('1535')); // string|null + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('IH'); + $supplierFinancials->setVatCode($vatCode); // VatCode|null Default VAT code. + $supplierFinancials->setVatCode(\PhpTwinfield\VatCode::fromCode('IH')); // string|null + + $supplier->setFinancials($supplierFinancials); // SupplierFinancials Set the SupplierFinancials object tot the Supplier object + + $supplierAddress = new \PhpTwinfield\SupplierAddress; + $supplierAddress->setCity('Amsterdam'); // string|null City. + $country = new \PhpTwinfield\Country; + $country->setCode('NL'); + $supplierAddress->setCountry($country); // Country|null Country code. The ISO country codes are used. + $supplierAddress->setCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $supplierAddress->setDefault(true); // bool|null Is this the default address, only one default address is possible. + $supplierAddress->setEmail('test@example.com'); // string|null + $supplierAddress->setField1(''); // string|null User defined fields, the labels are configured in the Dimension type. + $supplierAddress->setField2(''); // string|null User defined fields, the labels are configured in the Dimension type. + $supplierAddress->setField3(''); // string|null User defined fields, the labels are configured in the Dimension type. + $supplierAddress->setField4(null); // string|null User defined fields, the labels are configured in the Dimension type. Currently, field4 is reserved for VAT numbers. So only valid VAT numbers may be filled in. + $supplierAddress->setField5(''); // string|null User defined fields, the labels are configured in the Dimension type. + $supplierAddress->setField6(''); // string|null User defined fields, the labels are configured in the Dimension type. + $supplierAddress->setID(1); // string|null Sequence number of the address line. + $supplierAddress->setName('Example Supplier'); // string|null Company name. + $supplierAddress->setPostcode('9876YZ'); // string|null Postcode. + $supplierAddress->setTelefax('012-3456789'); // string|null Fax number. + $supplierAddress->setTelephone('987-654321'); // string|null Telephone number. + $supplierAddress->setType(\PhpTwinfield\Enums\AddressType::INVOICE()); // AddressType|null The type of the address. + + $supplier->addAddress($supplierAddress); // SupplierAddress Add a SupplierAddress object to the Supplier object + //$supplier->removeAddress(0); // int Remove an address based on the index of the address within the array + + $supplierBank = new \PhpTwinfield\SupplierBank; + $supplierBank->setAccountNumber('123456789'); // string|null Account number. + $supplierBank->setAddressField2('Example Street'); // string|null Bank address. + $supplierBank->setAddressField3('12'); // string|null Bank address number. + $supplierBank->setAscription('Example Supplier'); // string|null Account holder. + $supplierBank->setBankName('Example Bank'); // string|null Bank name. + $supplierBank->setBicCode('ABNANL2A'); // string|null BIC code. + $supplierBank->setBlocked(false); // bool|null + $supplierBank->setCity('Amsterdam'); // string|null City. + $country = new \PhpTwinfield\Country; + $country->setCode('NL'); + $supplierBank->setCountry($country); // Country|null Bank country code. The ISO country codes are used. + $supplierBank->setCountry(\PhpTwinfield\Country::fromCode('NL')); // string|null + $supplierBank->setDefault(true); // bool|null Is this the default bank account, only one default bank account is possible. + $supplierBank->setID(null); // int|null Sequence number of the bank account line. When adding a new bank, do not supply the @id. When changing a bank account, supply the corresponding @id. + $supplierBank->setIban(null); // string|null IBAN account number. + $supplierBank->setNatBicCode('NL'); // string|null National bank code. + $supplierBank->setPostcode('1234AB'); // string|null Postcode. + $supplierBank->setState('Noord-Holland'); // string|null State. + + $supplier->addBank($supplierBank); // SupplierBank Add a SupplierBank object to the Supplier object + //$supplier->removeBank(0); // int Remove a bank based on the index of the bank within the array + + $supplierPostingRule = new \PhpTwinfield\SupplierPostingRule; + $supplierPostingRule->setAmount(\Money\Money::EUR(10000)); // Money|null Amount. (Equals 100.00 EUR) + $currency = new \PhpTwinfield\Currency; + $currency->setCode('EUR'); + $supplierPostingRule->setCurrency($currency); // Currency|null Currency. + $supplierPostingRule->setCurrency(\PhpTwinfield\Currency::fromCode('EUR')); // string|null + $supplierPostingRule->setDescription('Example PostingRule'); // string|null Description. + $supplierPostingRule->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating active should be used. For deleting deleted should be used. + //$supplierPostingRule->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + + $supplierLine = new \PhpTwinfield\SupplierLine; + $supplierLine->setDescription('Example Line'); // string|null Description. + $dimension1 = new \PhpTwinfield\GeneralLedger; + $dimension1->setCode('1535'); + $supplierLine->setDimension1($dimension1); // GeneralLedger|null General ledger. + $supplierLine->setDimension1(\PhpTwinfield\GeneralLedger::fromCode('1535')); // string|null + $costCenter = new \PhpTwinfield\CostCenter; + $costCenter->setCode('00000'); + $supplierLine->setDimension2($costCenter); // CostCenter|null Cost center. + $supplierLine->setDimension2(\PhpTwinfield\CostCenter::fromCode('00000')); // string|null + $activity = new \PhpTwinfield\Activity; + $activity->setCode('P0000'); + $supplierLine->setDimension3($activity); // Project|Activity|null Project or asset. + $supplierLine->setDimension3(\PhpTwinfield\Activity::fromCode('P0000')); // string|null + $destOffice = new \PhpTwinfield\Office; + $destOffice->setCode('NLA0000001'); + //$supplierLine->setOffice($destOffice); // Office|null Destination company. + //$supplierLine->setOffice(\PhpTwinfield\Office::fromCode('NLA0000001')); // string|null + $supplierLine->setRatio(1); // float|null The ratio of the posting rule line. + $vatCode = new \PhpTwinfield\VatCode; + $vatCode->setCode('IH'); + $supplierLine->setVatCode($vatCode); // VatCode|null Default VAT code. + $supplierLine->setVatCode(\PhpTwinfield\VatCode::fromCode('IH')); // string|null + + $supplierPostingRule->addLine($supplierLine); // SupplierLine Add a SupplierLine object to the SupplierPostingRule object + //$supplierPostingRule->removeLine(0); // int Remove a line based on the index of the line within the array + + $supplier->addPostingRule($supplierPostingRule); // SupplierPostingRule Add a SupplierPostingRule object to the Supplier object + //$supplier->removePostingRule(0); // int Remove a posting rule based on the index of the posting rule within the array + + try { + $supplierNew = $supplierApiConnector->send($supplier); + } catch (ResponseException $e) { + $supplierNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($supplierNew);
+    echo "
"; + + echo "Result of creation process: {$supplierNew->getResult()}
"; + echo "Code of new Supplier: {$supplierNew->getCode()}
"; + echo "Status of new Supplier: {$supplierNew->getStatus()}
"; +} + +// Delete a Supplier based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $supplierDeleted = $supplierApiConnector->delete("2004", $office); + } catch (ResponseException $e) { + $supplierDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($supplierDeleted);
+    echo "
"; + + echo "Result of deletion process: {$supplierDeleted->getResult()}
"; + echo "Code of deleted Supplier: {$supplierDeleted->getCode()}
"; + echo "Status of deleted Supplier: {$supplierDeleted->getStatus()}
"; +} diff --git a/examples/User.php b/examples/User.php new file mode 100644 index 00000000..a60b1519 --- /dev/null +++ b/examples/User.php @@ -0,0 +1,168 @@ + mutualoffices = 0 +if ($executeListAllWithFilter) { + $options = array('mutualoffices' => 0); + + try { + $users = $userApiConnector->listAll("API*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $users = $e->getReturnedObject(); + } + + echo "
";
+    print_r($users);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $users = $userApiConnector->listAll(); + } catch (ResponseException $e) { + $users = $e->getReturnedObject(); + } + + echo "
";
+    print_r($users);
+    echo "
"; +} + +/* User + * \PhpTwinfield\User + * Available getters: getAcceptExtraCost, getCode, getCreated, getCulture, getCultureName, getCultureNativeName, getDemo, getDemoLocked, getEmail, getExchangeQuota, getExchangeQuotaLocked, getFileManagerQuota, + * getFileManagerQuotaLocked, getIsCurrentUser, getLevel, getMessages, getModified, getName, getPassword, getResult, getRole, getRoleLocked, getShortName, getStatus, getTouched, getType, getTypeLocked, hasMessages + * + * Available setters: fromCode, setAcceptExtraCost, setCode, setCulture, setCultureName, setCultureNativeName, setDemo, setDemoLocked, setEmail, setExchangeQuota, setExchangeQuotaLocked, setFileManagerQuota, + * setFileManagerQuotaLocked, setIsCurrentUser, setLevel, setName, setPassword, setRole, setRoleLocked, setShortName, setStatus, setType, setTypeLocked + * + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($users as $key => $user) { + echo "User {$key}
"; + echo "Code: {$user->getCode()}
"; + echo "Name: {$user->getName()}

"; + } +} + +// Read a User based off the passed in code and optionally the office. +if ($executeRead) { + try { + $user = $userApiConnector->get("API000001", $office); + } catch (ResponseException $e) { + $user = $e->getReturnedObject(); + } + + echo "
";
+    print_r($user);
+    echo "
"; + + echo "User
"; + echo "AcceptExtraCost (bool): {$user->getAcceptExtraCost()}
"; // bool|null Are extra costs accepted when changing the role (subscription) of the user. + echo "AcceptExtraCost (string): " . Util::formatBoolean($user->getAcceptExtraCost()) . "
"; // string|null + echo "Code: {$user->getCode()}
"; // string|null Code of the user. + echo "Created (\\DateTimeInterface):
" . print_r($user->getCreated(), true) . "

"; // DateTimeInterface|null The date/time the user was created. Read-only attribute. + echo "Created (string): " . Util::formatDateTime($user->getCreated()) . "
"; // string|null + echo "Culture: {$user->getCulture()}
"; // Culture|null The culture in which Twinfield is shown. + echo "CultureName: {$user->getCultureName()}
"; // string|null + echo "CultureNativeName: {$user->getCultureNativeName()}
"; // string|null + echo "Demo (bool): {$user->getDemo()}
"; // bool|null Indicates whether the user will be used only for training purposes. Only available when type is equal to Client of accountant. + echo "Demo (string): " . Util::formatBoolean($user->getDemo()) . "
"; // string|null + echo "DemoLocked (bool): {$user->getDemoLocked()}
"; // bool|null + echo "DemoLocked (string): " . Util::formatBoolean($user->getDemoLocked()) . "
"; // string|null + echo "Email: {$user->getEmail()}
"; // string|null The user’s email address. + echo "ExchangeQuota: {$user->getExchangeQuota()}
"; // int|null Twinfield Analysis quota. + echo "ExchangeQuotaLocked (bool): {$user->getExchangeQuotaLocked()}
"; // bool|null + echo "ExchangeQuotaLocked (string): " . Util::formatBoolean($user->getExchangeQuotaLocked()) . "
"; // string|null + echo "FileManagerQuota: {$user->getFileManagerQuota()}
"; // int|null File Manager quota. + echo "FileManagerQuotaLocked (bool): {$user->getFileManagerQuotaLocked()}
"; // bool|null + echo "FileManagerQuotaLocked (string): " . Util::formatBoolean($user->getFileManagerQuotaLocked()) . "
"; // string|null + echo "IsCurrentUser (bool): {$user->getIsCurrentUser()}
"; // bool|null + echo "IsCurrentUser (string): " . Util::formatBoolean($user->getIsCurrentUser()) . "
"; // string|null + echo "Level: {$user->getLevel()}
"; // int|null + + if ($user->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($user->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Modified (\\DateTimeInterface):
" . print_r($user->getModified(), true) . "

"; // DateTimeInterface|null The last date/time the user was modified. Read-only attribute. + echo "Modified (string): " . Util::formatDateTime($user->getModified()) . "
"; // string|null + echo "Name: {$user->getName()}
"; // string|null The name of the user. + echo "Password: {$user->getPassword()}
"; // string|null The password for the user. + echo "Result: {$user->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "Role (\\PhpTwinfield\\UserRole):
" . print_r($user->getRole(), true) . "

"; // UserRole|null The role the user is linked to. + echo "Role (string): " . Util::objectToStr($user->getRole()) . "
"; // string|null + echo "RoleLocked (bool): {$user->getRoleLocked()}
"; // bool|null + echo "RoleLocked (string): " . Util::formatBoolean($user->getRoleLocked()) . "
"; // string|null + echo "ShortName: {$user->getShortName()}
"; // string|null The short name of the user. + echo "Status: {$user->getStatus()}
"; // Status|null For creating and updating status may be left empty. For deleting deleted should be used. In case a user that is used in a transaction is deleted, its status has been changed into hide. Hidden users can be activated by using active. + echo "Touched: {$user->getTouched()}
"; // int|null Count of the number of times the user settings are changed. Read-only attribute. + echo "Type: {$user->getType()}
"; // UserType|null User type, will be validated with the office type. Use regular in case of a non-accountancy organisation. + echo "TypeLocked (bool): {$user->getTypeLocked()}
"; // bool|null + echo "TypeLocked (string): " . Util::formatBoolean($user->getTypeLocked()) . "
"; // string|null +} diff --git a/examples/UserRole.php b/examples/UserRole.php new file mode 100644 index 00000000..a97d63a0 --- /dev/null +++ b/examples/UserRole.php @@ -0,0 +1,87 @@ +listAll("LVL1*", 0, 1, 10); + } catch (ResponseException $e) { + $userRoles = $e->getReturnedObject(); + } + + echo "
";
+    print_r($userRoles);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $userRoles = $userRoleApiConnector->listAll(); + } catch (ResponseException $e) { + $userRoles = $e->getReturnedObject(); + } + + echo "
";
+    print_r($userRoles);
+    echo "
"; +} + +/* UserRole + * \PhpTwinfield\UserRole + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($userRoles as $key => $userRole) { + echo "UserRole {$key}
"; + echo "Code: {$userRole->getCode()}
"; + echo "Name: {$userRole->getName()}

"; + } +} diff --git a/examples/VatCode.php b/examples/VatCode.php new file mode 100644 index 00000000..a39e03a2 --- /dev/null +++ b/examples/VatCode.php @@ -0,0 +1,311 @@ + vattype = 'sales' +if ($executeListAllWithFilter) { + $options = array('vattype' => 'sales'); + + try { + $vatCodes = $vatCodeApiConnector->listAll("V*", 0, 1, 10, $options); + } catch (ResponseException $e) { + $vatCodes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCodes);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $vatCodes = $vatCodeApiConnector->listAll(); + } catch (ResponseException $e) { + $vatCodes = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCodes);
+    echo "
"; +} + +/* VatCode + * \PhpTwinfield\VatCode + * Available getters: getCode, getCreated, getMessages, getModified, getName, getOffice, getResult, getShortName, getStatus, getTouched, getType, getUID, getUser, hasMessages, getPercentages + * Available setters: fromCode, setCode, setName, setOffice, setShortName, setStatus, setType, addPercentage, removePercentage + */ + +/* VatCodePercentage + * \PhpTwinfield\VatCodePercentage + * Available getters: getCreated, getDate, getInUse, getMessages, getName, getPercentage, getResult, getShortName, getStatus, getUser, hasMessages, getAccounts + * Available setters: setDate, setName, setPercentage, setShortName, setStatus, addAccount, removeAccount + */ + +/* VatCodeAccount + * \PhpTwinfield\VatCodeAccount + * Available getters: getDim1, getGroup, getGroupCountry, getID, getLineType, getMessages, getPercentage, getResult, hasMessages + * Available setters: setDim1, setGroup, setGroupCountry, setID, setLineType, setPercentage + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($vatCodes as $key => $vatCode) { + echo "VatCode {$key}
"; + echo "Code: {$vatCode->getCode()}
"; + echo "Name: {$vatCode->getName()}

"; + } +} + +// Read a VatCode based off the passed in code and optionally the office. +if ($executeRead) { + try { + $vatCode = $vatCodeApiConnector->get("VH", $office); + } catch (ResponseException $e) { + $vatCode = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCode);
+    echo "
"; + + echo "VatCode
"; + echo "Code: {$vatCode->getCode()}
"; // string|null VAT code. + echo "Created (\\DateTimeInterface):
" . print_r($vatCode->getCreated(), true) . "

"; // \DateTimeInterface|null The date/time the VAT code was created. Read-only attribute. + echo "Created (string): " . Util::formatDate($vatCode->getCreated()) . "
"; // string|null + + if ($vatCode->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($vatCode->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Modified (\\DateTimeInterface):
" . print_r($vatCode->getModified(), true) . "

"; // \DateTimeInterface|null The most recent date/time the VAT code was modified. Read-only attribute. + echo "Modified (string): " . Util::formatDate($vatCode->getModified()) . "
"; // string|null + echo "Name: {$vatCode->getName()}
"; // string|null Name of the VAT. + echo "Office (\\PhpTwinfield\\Office):
" . print_r($vatCode->getOffice(), true) . "

"; // Office|null Office code. + echo "Office (string): " . Util::objectToStr($vatCode->getOffice()) . "
"; // string|null + echo "Result: {$vatCode->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$vatCode->getShortName()}
"; // string|null Short name of the VAT. + echo "Status: {$vatCode->getStatus()}
"; // Status|null Status of the VAT. + echo "Touched: {$vatCode->getTouched()}
"; // int|null The number of times the VAT code is modified. Read-only attribute. + echo "Type: {$vatCode->getType()}
"; // VatType|null The VAT type. + echo "UID: {$vatCode->getUID()}
"; // string|null Unique identification of the VAT code. Read-only attribute. + echo "User (\\PhpTwinfield\\User):
" . print_r($vatCode->getUser(), true) . "

"; // User|null The code of the user who created or modified the VAT code. Read-only attribute. + echo "User (string): " . Util::objectToStr($vatCode->getUser()) . "
"; // string|null + + $vatCodePercentages = $vatCode->getPercentages(); // Array|null Array of VatCodePercentage objects. + + foreach ($vatCodePercentages as $key => $vatCodePercentage) { + echo "VatCodePercentage {$key}
"; + + if ($vatCodePercentage->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($vatCodePercentage->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Created (\\DateTimeInterface):
" . print_r($vatCodePercentage->getCreated(), true) . "

"; // \DateTimeInterface|null The date/time the VAT line was created. Read-only attribute. + echo "Created (string): " . Util::formatDate($vatCodePercentage->getCreated()) . "
"; // string|null + echo "Date (\\DateTimeInterface):
" . print_r($vatCodePercentage->getDate(), true) . "

"; // \DateTimeInterface|null Effective date. + echo "Date (string): " . Util::formatDate($vatCodePercentage->getDate()) . "
"; // string|null + echo "InUse (bool):
" . print_r($vatCodePercentage->getInUse(), true) . "

"; // bool|null + echo "InUse (string): " . Util::formatBoolean($vatCodePercentage->getInUse() . "
"; // string|null + echo "Name: {$vatCodePercentage->getName()}
"; // string|null Name of the VAT line. + echo "Percentage: {$vatCodePercentage->getPercentage()}
"; // float|null Percentage of the VAT line. + echo "Result: {$vatCodePercentage->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + echo "ShortName: {$vatCodePercentage->getShortName()}
"; // string|null Short name of the VAT line. + echo "Status: {$vatCodePercentage->getStatus()}
"; // Status|null Status of the percentage. + echo "User (\\PhpTwinfield\\User):
" . print_r($vatCodePercentage->getUser(), true) . "

"; // User|null The code of the user who created or modified the VAT line. Read-only attribute. + echo "User (string): " . Util::objectToStr($vatCodePercentage->getUser()) . "
"; // string|null + + $vatCodeAccounts = $vatCodePercentage->getAccounts(); // Array|null Array of VatCodeAccount objects. + + foreach ($vatCodeAccounts as $key => $vatCodeAccount) { + echo "VatCodeAccount {$key}
"; + + if ($vatCodeAccount->hasMessages()) { // bool Object contains (error) messages true/false. + echo "Messages: " . print_r($vatCodeAccount->getMessages(), true) . "
"; // Array|null (Error) messages. + } + + echo "Dim1 (\\PhpTwinfield\\GeneralLedger):
" . print_r($vatCodeAccount->getDim1(), true) . "

"; // GeneralLedger|null General ledger account on which the VAT amount will be posted. + echo "Dim1 (string): " . Util::objectToStr($vatCodeAccount->getDim1()) . "
"; // string|null + echo "Group (\\PhpTwinfield\\VatGroup):
" . print_r($vatCodeAccount->getGroup(), true) . "

"; // VatGroup|null The VAT group. + echo "Group (string): " . Util::objectToStr($vatCodeAccount->getGroup()) . "
"; // string|null + echo "GroupCountry (\\PhpTwinfield\\VatGroupCountry):
" . print_r($vatCodeAccount->getGroupCountry(), true) . "

"; // VatGroupCountry|null Country code of the VAT group. + echo "GroupCountry (string): " . Util::objectToStr($vatCodeAccount->getGroupCountry()) . "
"; // string|null + echo "ID: {$vatCodeAccount->getID()}
"; // int|null Line ID. + echo "LineType: {$vatCodeAccount->getLineType()}
"; // LineType|null Is it a vat line or not detail. Use detail in case a part of the calculated vat value should be posted on a different general ledger account. + echo "Percentage: {$vatCodeAccount->getPercentage()}
"; // float|null The VAT percentage. + echo "Result: {$vatCodeAccount->getResult()}
"; // int|null Result (0 = error, 1 or empty = success). + } + } +} + +// Copy an existing VatCode to a new entity +if ($executeCopy) { + try { + $vatCode = $vatCodeApiConnector->get("VH", $office); + } catch (ResponseException $e) { + $vatCode = $e->getReturnedObject(); + } + + $vatCode->setCode("VH2"); + + try { + $vatCodeCopy = $vatCodeApiConnector->send($vatCode); + } catch (ResponseException $e) { + $vatCodeCopy = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCodeCopy);
+    echo "
"; + + echo "Result of copy process: {$vatCodeCopy->getResult()}
"; + echo "Code of copied VatCode: {$vatCodeCopy->getCode()}
"; + echo "Status of copied VatCode: {$vatCodeCopy->getStatus()}
"; +} + +// Create a new VatCode from scratch, alternatively read an existing VatCode as shown above and than modify the values in the same way as shown below +if ($executeNew) { + $vatCode = new \PhpTwinfield\VatCode; + + // Required values for creating a new VatCode + // + $vatCode->setCode('VH2'); // string|null VAT code. + $vatCode->setName("BTW 21%"); // string|null Name of the VAT. + $vatCode->setOffice($office); // Office|null Office code. + $vatCode->setOffice(\PhpTwinfield\Office::fromCode($officeCode)); // string|null + $vatCode->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating active should be used. For deleting deleted should be used. + //$vatCode->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + $vatCode->setType(\PhpTwinfield\Enums\VatType::SALES()); // VatType|null + + // Optional values for creating a new VatCode + $vatCode->setShortName("VH 21%"); // string|null Short name of the VAT. + + // The minimum amount of VatCodePercentages linked to a VatCode object is 0 + $vatCodePercentage = new \PhpTwinfield\VatCodePercentage; + $date = \DateTime::createFromFormat('d-m-Y', '01-01-2019'); + $vatCodePercentage->setDate($date); // DateTimeInterface|null Effective date. + $vatCodePercentage->setDate(Util::parseDate('20190101')); // string|null + $vatCodePercentage->setName("BTW 21%"); // string|null Name of the VAT line. + $vatCodePercentage->setPercentage(21); // float|null Percentage of the VAT line. + $vatCodePercentage->setShortName("VH 21%"); // string|null Short name of the VAT line. + $vatCodePercentage->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); // Status|null For creating and updating active should be used. For deleting deleted should be used. + //$vatCodePercentage->setStatus(\PhpTwinfield\Enums\Status::DELETED()); // Status|null + + // The minimum amount of VatCodeAccounts linked to a VatCodePercentage object is 1 + $vatCodeAccount = new \PhpTwinfield\VatCodeAccount; + $generalLedger = new \PhpTwinfield\GeneralLedger; + $generalLedger->setCode('1530'); + $vatCodeAccount->setDim1($generalLedger); // GeneralLedger|null General ledger account on which the VAT amount will be posted. + $vatCodeAccount->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1530')); // string|null + $vatGroup = new \PhpTwinfield\VatGroup; + $vatGroup->setCode('NL1A'); + $vatCodeAccount->setGroup($vatGroup); // VatGroup|null The VAT group. + $vatCodeAccount->setGroup(\PhpTwinfield\VatGroup::fromCode('NL1A')); // string|null + $vatGroupCountry = new \PhpTwinfield\VatGroupCountry; + $vatGroupCountry->setCode('NL'); + $vatCodeAccount->setGroupCountry($vatGroupCountry); // VatGroupCountry|null Country code of the VAT group. + $vatCodeAccount->setGroupCountry(\PhpTwinfield\VatGroupCountry::fromCode('NL')); // string|null + + $vatCodeAccount->setID(1); // int|null Line ID. + $vatCodeAccount->setLineType(\PhpTwinfield\Enums\LineType::VAT()); // LineType|null Is it a vat line or not detail. Use detail in case a part of the calculated vat value should be posted on a different general ledger account. + + $vatCodeAccount->setPercentage(100); // float|null Percentage of the VAT line. + + $vatCodePercentage->addAccount($vatCodeAccount); // VatCodeAccount Add a VatCodeAccount object to the VatCodePercentage object + //$vatCodePercentage->removeAccount(0); // int Remove an account based on the index of the account + + $vatCode->addPercentage($vatCodePercentage); // VatCodePercentage Add a VatCodePercentage object to the VatCode object + //$vatCode->removePercentage(0); // int Remove a percentage based on the index of the percentage within the array + + try { + $vatCodeNew = $vatCodeApiConnector->send($vatCode); + } catch (ResponseException $e) { + $vatCodeNew = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCodeNew);
+    echo "
"; + + echo "Result of creation process: {$vatCodeNew->getResult()}
"; + echo "Code of new VatCode: {$vatCodeNew->getCode()}
"; + echo "Status of new VatCode: {$vatCodeNew->getStatus()}
"; +} + +// Delete a VatCode based off the passed in code and optionally the office. +if ($executeDelete) { + try { + $vatCodeDeleted = $vatCodeApiConnector->delete("VH2", $office); + } catch (ResponseException $e) { + $vatCodeDeleted = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatCodeDeleted);
+    echo "
"; + + echo "Result of deletion process: {$vatCodeDeleted->getResult()}
"; + echo "Code of deleted VatCode: {$vatCodeDeleted->getCode()}
"; + echo "Status of deleted VatCode: {$vatCodeDeleted->getStatus()}
"; +} diff --git a/examples/VatGroup.php b/examples/VatGroup.php new file mode 100644 index 00000000..02fb937f --- /dev/null +++ b/examples/VatGroup.php @@ -0,0 +1,87 @@ +listAll("1*", 0, 1, 10); + } catch (ResponseException $e) { + $vatGroups = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatGroups);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $vatGroups = $vatGroupApiConnector->listAll(); + } catch (ResponseException $e) { + $vatGroups = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatGroups);
+    echo "
"; +} + +/* VatGroup + * \PhpTwinfield\VatGroup + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($vatGroups as $key => $vatGroup) { + echo "VatGroup {$key}
"; + echo "Code: {$vatGroup->getCode()}
"; + echo "Name: {$vatGroup->getName()}

"; + } +} diff --git a/examples/VatGroupCountry.php b/examples/VatGroupCountry.php new file mode 100644 index 00000000..8eac9648 --- /dev/null +++ b/examples/VatGroupCountry.php @@ -0,0 +1,92 @@ + country = NL +if ($executeListAllWithFilter) { + $options = array('country' => 'NL'); + + try { + $vatGroupCountries = $vatGroupCountryApiConnector->listAll('*', 0, 1, 10, $options); + } catch (ResponseException $e) { + $vatGroupCountries = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatGroupCountries);
+    echo "
"; +} + +//List all with default settings (pattern '*', field 0, firstRow 1, maxRows 100, options []) +if ($executeListAllWithoutFilter) { + try { + $vatGroupCountries = $vatGroupCountryApiConnector->listAll(); + } catch (ResponseException $e) { + $vatGroupCountries = $e->getReturnedObject(); + } + + echo "
";
+    print_r($vatGroupCountries);
+    echo "
"; +} + +/* VatGroupCountry + * \PhpTwinfield\VatGroupCountry + * Available getters: getCode, getName, getShortName + * Available setters: fromCode, setCode, setName, setShortName + */ + +if ($executeListAllWithFilter || $executeListAllWithoutFilter) { + foreach ($vatGroupCountries as $key => $vatGroupCountry) { + echo "VatGroupCountry {$key}
"; + echo "Code: {$vatGroupCountry->getCode()}
"; + echo "Name: {$vatGroupCountry->getName()}

"; + } +} diff --git a/readme.md b/readme.md index 5b402290..6eb1c97d 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ A PHP library for Twinfield Integration. Use the Twinfield SOAP Services to have your PHP application communicate directly with your Twinfield account. -**:warning: Note that this libary is *not* created or mainained by Twinfield. You can only get support on the code in this library here. For any questions related to your Twinfield administration or how to do certain things with the Twinfield API, contact your Twinfield account manager.** +**:warning: Note that this libary is *not* created or maintained by Twinfield. You can only get support on the code in this library here. For any questions related to your Twinfield administration or how to do certain things with the Twinfield API, contact your Twinfield account manager.** ## Installation @@ -12,269 +12,59 @@ Install this Twinfield PHP library with Composer: composer require 'php-twinfield/twinfield:^2.0' ``` +Considering session login is deprecated and OAuth 2 is the preferred login method you should also install PHP League's OAuth 2.0 Client -## Usage - -### Authentication -You need to set up a `\PhpTwinfield\Secure\AuthenticatedConnection` class with your credentials. When using basic -username and password authentication, the `\PhpTwinfield\Secure\WebservicesAuthentication` class should be used, as follows: - -```php -$connection = new Secure\WebservicesAuthentication("username", "password", "organization"); -``` - -In order to use OAuth2 to authenticate with Twinfield, one should use the `\PhpTwinfield\Secure\Provider\OAuthProvider` to retrieve an `\League\OAuth2\Client\Token\AccessToken` object, and extract the refresh token from this object. Furthermore, it is required to set up a default `\PhpTwinfield\Office`, that will be used during requests to Twinfield. **Please note:** when a different office is specified when sending a request through one of the `ApiConnectors`, this Office will override the default. - -Using this information, we can create an instance of the `\PhpTwinfield\Secure\OpenIdConnectAuthentication` class, as follows: - -```php -$provider = new OAuthProvider([ - 'clientId' => 'someClientId', - 'clientSecret' => 'someClientSecret', - 'redirectUri' => 'https://example.org/' -]); -$accessToken = $provider->getAccessToken("authorization_code", ["code" => ...]); -$refreshToken = $accessToken->getRefreshToken(); -$office = \PhpTwinfield\Office::fromCode("someOfficeCode"); - -$connection = new \PhpTwinfield\Secure\OpenIdConnectAuthentication($provider, $refreshToken, $office); -``` -For more information about retrieving the initial `AccessToken`, please refer to: https://github.com/thephpleague/oauth2-client#usage - -### Getting data from the API -In order to communicate with the Twinfield API, you need to create an `ApiConnector` instance for the corresponding -resource and use the `get()` or `list()` method. - -The `ApiConnector` takes a `Secure\AuthenticatedConnection` object: - -An example: - -```php - -$connection = new Secure\WebservicesAuthentication("username", "password", "organization"); -$customerApiConnector = new ApiConnectors\CustomerApiConnector($connection); - -// Get one customer. -$office = Office::fromCode('office code'); -$customer = $customerApiConnector->get('1001', $office); - -// Get a list of all customers. -$customer = $customerApiConnector->listAll($office); -``` - -### Creating or updating objects -If you want to create or update a customer or any other object, it's just as easy: - -```php -$customer_factory = new ApiConnectors\CustomerApiConnector($connection); - -// First, create the objects you want to send. -$customer = new Customer(); -$customer - ->setCode('1001') - ->setName('John Doe') - ->setOffice($office) - ->setEBilling(false); - -$customer_address = new CustomerAddress(); -$customer_address - ->setType('invoice') - ->setDefault(false) - ->setPostcode('1212 AB') - ->setCity('TestCity') - ->setCountry('NL') - ->setTelephone('010-12345') - ->setFax('010-1234') - ->setEmail('johndoe@example.com'); -$customer->addAddress($customer_address); - -// And secondly, send it to Twinfield. -$customer_factory->send($customer); -``` - -You can also send multiple objects in one batch, chunking is handled automatically. - -### Browse data -In order to get financial data out of Twinfield like general ledger transactions, sales invoices, and so on, you can use the the browse data functionality. -More information about the browse data functionality in Twinfield can be found in the [documentation](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Request/BrowseData). - -#### Browse definition - -You can retrieve the browse definition of a browse code as follows. -You don't need to retrieve the browse definition for getting the browse data. It's only for viewing the browse definition of a browse code to know exactly which columns are available. - -```php -$connector = new BrowseDataApiConnector($connection); -$browseDefinition = $connector->getBrowseDefinition('000'); -``` - -#### Browse fields - -You can retrieve the browse fields as follows. -You don't need to retrieve the browse fields for getting the browse data. It's only for viewing the definitions of all browse fields so you now what you can expect when retrieving browse data. - -```php -$connector = new BrowseDataApiConnector($connection); -$browseFields = $connector->getBrowseFields(); -``` - -#### Browse data - -You can retrieve browse data of a browse code as follows. - -```php -$connector = new BrowseDataApiConnector($connection); - -// First, create the columns that you want to retrieve (see the browse definition for which columns are available) -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.head.yearperiod') - ->setLabel('Period') - ->setVisible(true) - ->setAsk(true) - ->setOperator(Enums\BrowseColumnOperator::BETWEEN()) - ->setFrom('2013/01') - ->setTo('2013/12'); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.head.code') - ->setLabel('Transaction type') - ->setVisible(true); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.head.shortname') - ->setLabel('Name') - ->setVisible(true); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.head.number') - ->setLabel('Trans. no.') - ->setVisible(true); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.line.dim1') - ->setLabel('General ledger') - ->setVisible(true) - ->setAsk(true) - ->setOperator(Enums\BrowseColumnOperator::BETWEEN()) - ->setFrom('1300') - ->setTo('1300'); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.head.curcode') - ->setLabel('Currency') - ->setVisible(true); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.line.valuesigned') - ->setLabel('Value') - ->setVisible(true); - -$columns[] = (new BrowseColumn()) - ->setField('fin.trs.line.description') - ->setLabel('Description') - ->setVisible(true); - -// Second, create sort fields -$sortFields[] = new BrowseSortField('fin.trs.head.code'); - -// Get the browse data -$browseData = $connector->getBrowseData('000', $columns, $sortFields); -``` - -### ApiConnector Configuration - -The ApiConnector has a constructor second parameter that can be used to configure some aspects of its operation. - -The ApiOptions has the following methods signature: - -```php -/** - * This will allow you to enfornce the messages or the number of max retries. - * Passing null you will use the default values. - */ -public function __construct(?array $messages = null, ?int $maxRetries = null); -/** - * This will allow you to get all the exception messages - */ -public function getRetriableExceptionMessages(): array -/** - * This will allow you to replace the exception messages that should be retried - */ -public function setRetriableExceptionMessages(array $retriableExceptionMessages): ApiOptions -/** - * This will allow you to add new messages to the array of exception messages - */ -public function addMessages(array $messages): ApiOptions -/** - * This will allow you to get the number of max retries - */ -public function getMaxRetries(): int -/** - * This will allow you to set the number of max retries - */ -public function setMaxRetries(int $maxRetries): ApiOptions -``` - - - -:exclamation: All the *get* methods will return a new instance with the configuration you changed. - -#### Configuration Examples - -Below are some examples on how to use the configuration object - -```php -$connector = new BrowseDataApiConnector( - $connection, - new ApiOptions( - [ - "SSL: Connection reset by peer", - "Bad Gateway" - ], - 3 - ) -); -``` - -The example below will look for the defaul messages plus the "Bad Gateway" message. - -```php -$options = new ApiOptions( - null, - 3 -); -$connector = new BrowseDataApiConnector( - $connection, - $options->addMessages(["Bad Gateway"]) -); +```bash +composer require 'league/oauth2-client' ``` -#### Configuration default values +## Usage -| Attribute | Default Value | Description | -| ---------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| Max retries | 3 | The number of retries that should happen before throwing an error. | -| Retriable exception messages | [
"SSL: Connection reset by peer",
"Your logon credentials are not valid anymore. Try to log on again."
] | The exception messages that should be match in order to retry automatically. | +See [Usage](usage.md). +For breaking changes since 2.7.0 see [Breaking Changes since 2.7.0](breaking270.md). ### Supported resources Not all resources from the Twinfield API are currently implemented. Feel free to create a pull request when you need support for another resource. -| Component | get() | listAll() | send() | delete() | Mapper | -| --------------------------------------------------------------------------------------------------------------- | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | -| [Articles](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Articles) | :white_check_mark: | | :white_check_mark: | | :white_check_mark: | -| [BankTransaction](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/BankTransactions)| | | :white_check_mark: | :white_check_mark: | | -| [Customer](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Customers) | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | -| [Electronic Bank Statements](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/BankStatements)| | | :white_check_mark: | | | -| [Sales Invoices](https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesInvoices) | :white_check_mark: | | :white_check_mark: | | :white_check_mark: | -| [Matching](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Miscellaneous/Matching) | | | :white_check_mark: | | :white_check_mark: | | -| [Offices](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Offices) | | :white_check_mark: | | | :white_check_mark: | -| [Suppliers](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Suppliers) | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | -| Transactions:
[Purchase](https://c3.twinfield.com/webservices/documentation/#/ApiReference/PurchaseTransactions), [Sale](https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesTransactions), [Journal](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/JournalTransactions), [Cash](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/CashTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| [Users](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Users) | | :white_check_mark: | | | | -| [Vat types](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/VAT) | | :white_check_mark: | | | | -| [Browse Data](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Request/BrowseData) | :white_check_mark: | | | | :white_check_mark: | +| Component | get() | listAll() | send() | delete() | Mapper | Example | +| ----------------------------------------------------------------------------------------------------------------------------------| :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | +| [Activities](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Activities) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Activity](examples/Activity.php) | +| [Articles](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Articles) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Article](examples/Article.php) | +| [Asset Methods](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/AssetMethods) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Asset Method](examples/AssetMethod.php) | +| [Browse Data](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Request/BrowseData) | :white_check_mark: | | | | :white_check_mark: | [Browse Data](examples/BrowseData.php) | +| Cash and Bank Books | | :white_check_mark: | | | :white_check_mark: | [Cash and Bank Book](examples/CashBankBook.php) | +| [Cost Centers](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/CostCenters) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Cost Center](examples/CostCenter.php) | +| Countries | | :white_check_mark: | | | :white_check_mark: | [Country](examples/Country.php) | +| [Currencies](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Currencies) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Currency](examples/Currency.php) | +| [Customers](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Customers) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Customer](examples/Customer.php) | +| [Dimension Groups](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/DimensionGroups) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Dimension Group](examples/DimensionGroup.php) | +| [Dimension Types](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/DimensionTypes) | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | [Dimension Type](examples/DimensionType.php) | +| [Electronic Bank Statements](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/BankStatements) | | | :white_check_mark: | | | | +| [Fixed Assets](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/FixedAssets) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Fixed Asset](examples/FixedAsset.php) | +| [General Ledger Accounts](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/BalanceSheets) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [General Ledger Account](examples/GeneralLedger.php) | +| [Matching](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Miscellaneous/Matching) | | | :white_check_mark: | | :white_check_mark: | | +| [Offices](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Offices) | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | [Office](examples/Office.php) | +| Paycodes | | :white_check_mark: | | | :white_check_mark: | [Paycode](examples/PayCode.php) | +| [Projects](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Projects) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Project](examples/Project.php) | +| [Rates](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Rates) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Rate](examples/Rate.php) | +| [Sales Invoices](https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesInvoices) | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: | [Sales Invoice](examples/Invoice.php) | +| Sales Invoice Types | | :white_check_mark: | | | :white_check_mark: | [Sales Invoice Type](examples/InvoiceType.php) | +| [Suppliers](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Suppliers) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Supplier](examples/Supplier.php) | +| | | | | | | | +| Transactions | | | | | | | +[Bank Transactions](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/BankTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Bank Transaction](examples/BankTransaction.php) | +[Cash Transactions](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/CashTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Cash Transaction](examples/CashTransaction.php) | +[Journal Transactions](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/JournalTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Journal Transaction](examples/JournalTransaction.php) | +[Purchase Transactions](https://c3.twinfield.com/webservices/documentation/#/ApiReference/PurchaseTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Purchase Transaction](examples/PurchaseTransaction.php) | +[Sales Transactions](https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesTransactions) | :white_check_mark: | | :white_check_mark: | :white_check_mark: | :white_check_mark: | [Sales Transaction](examples/SalesTransaction.php) | +| | | | | | | | +| [Users](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Users) | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | [User](examples/User.php) | +| User Roles | | :white_check_mark: | | | :white_check_mark: | [User Role](examples/UserRole.php) | +| [VAT](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/VAT) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | [VAT](examples/VatCode.php) | +| VAT Groups | | :white_check_mark: | | | :white_check_mark: | [VAT Group](examples/VatGroup.php) | +| VAT Group Countries | | :white_check_mark: | | | :white_check_mark: | [VAT Group Country](examples/VatGroupCountry.php) | ## Links diff --git a/src/Activity.php b/src/Activity.php new file mode 100644 index 00000000..59ca84f8 --- /dev/null +++ b/src/Activity.php @@ -0,0 +1,62 @@ + + */ +class Activity extends BaseObject implements HasCodeInterface +{ + use BehaviourField; + use CodeField; + use InUseField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + use VatCodeField; + + private $projects; + + public function __construct() + { + $this->setType(\PhpTwinfield\DimensionType::fromCode('ACT')); + + $this->setProjects(new ActivityProjects); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getProjects(): ActivityProjects + { + return $this->projects; + } + + public function setProjects(ActivityProjects $projects) + { + $this->projects = $projects; + return $this; + } +} diff --git a/src/ActivityProjects.php b/src/ActivityProjects.php new file mode 100644 index 00000000..f9eb8c1d --- /dev/null +++ b/src/ActivityProjects.php @@ -0,0 +1,79 @@ +setAuthoriserInherit(true); + $this->setAuthoriserLocked(true); + $this->setBillableInherit(true); + $this->setBillableLocked(true); + $this->setCustomerInherit(true); + $this->setCustomerLocked(true); + $this->setRateInherit(true); + $this->setRateLocked(true); + } + + public function getQuantities() + { + return $this->quantities; + } + + public function addQuantity(ActivityQuantity $quantity) + { + $this->quantities[] = $quantity; + return $this; + } + + public function removeQuantity($index) + { + if (array_key_exists($index, $this->quantities)) { + unset($this->quantities[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/ActivityQuantity.php b/src/ActivityQuantity.php new file mode 100644 index 00000000..be3c7887 --- /dev/null +++ b/src/ActivityQuantity.php @@ -0,0 +1,22 @@ + + */ +class ActivityApiConnector extends BaseApiConnector +{ + /** + * Requests a specific Activity based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Activity The requested Activity or Activity object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): Activity + { + // Make a request to read a single Activity. Set the required values + $request_activity = new Request\Read\Activity(); + $request_activity + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_activity); + + return ActivityMapper::map($response); + } + + /** + * Sends an Activity instance to Twinfield to update or add. + * + * @param Activity $activity + * @return Activity + * @throws Exception + */ + public function send(Activity $activity): Activity + { + foreach($this->sendAll([$activity]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param Activity[] $activities + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $activities): MappedResponseCollection + { + Assert::allIsInstanceOf($activities, Activity::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($activities) as $chunk) { + + $activitiesDocument = new ActivitiesDocument(); + + foreach ($chunk as $activity) { + $activitiesDocument->addActivity($activity); + } + + $responses[] = $this->sendXmlDocument($activitiesDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): Activity { + return ActivityMapper::map($response); + }); + } + + /** + * List all activities. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Activity[] The activities found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "ACT"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_PROJECTS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $activityArrayListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Activity::class, $response->data, $activityArrayListAllTags); + } + + /** + * Deletes a specific Activity based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Activity The deleted Activity or Activity object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Activity + { + $activity = self::get($code, $office); + + if ($activity->getResult() == 1) { + $activity->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $activityDeleted = self::send($activity); + } catch (ResponseException $e) { + $activityDeleted = $e->getReturnedObject(); + } + + return $activityDeleted; + } else { + return $activity; + } + } +} diff --git a/src/ApiConnectors/ArticleApiConnector.php b/src/ApiConnectors/ArticleApiConnector.php index b825dbaa..b397edfb 100644 --- a/src/ApiConnectors/ArticleApiConnector.php +++ b/src/ApiConnectors/ArticleApiConnector.php @@ -5,11 +5,14 @@ use PhpTwinfield\Article; use PhpTwinfield\DomDocuments\ArticlesDocument; use PhpTwinfield\Exception; +use PhpTwinfield\HasMessageInterface; use PhpTwinfield\Mappers\ArticleMapper; use PhpTwinfield\Office; use PhpTwinfield\Request as Request; use PhpTwinfield\Response\MappedResponseCollection; use PhpTwinfield\Response\Response; +use PhpTwinfield\Response\ResponseException; +use PhpTwinfield\Services\FinderService; use Webmozart\Assert\Assert; /** @@ -19,9 +22,9 @@ * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Willem van de Sande + * @author Willem van de Sande , extended by Yannick Aerssens */ -class ArticleApiConnector extends BaseApiConnector +class ArticleApiConnector extends BaseApiConnector implements HasEqualInterface { /** * Requests a specific Article based off the passed in code and optionally the office. @@ -29,7 +32,7 @@ class ArticleApiConnector extends BaseApiConnector * @param string $code * @param Office $office If no office has been passed it will instead take the default office from the * passed in config class. - * @return Article|bool The requested article or false if it can't be found. + * @return Article The requested Article or Article object with error message if it can't be found. * @throws Exception */ public function get(string $code, Office $office): Article @@ -37,13 +40,13 @@ public function get(string $code, Office $office): Article // Make a request to read a single Article. Set the required values $request_article = new Request\Read\Article(); $request_article - ->setOffice($office->getCode()) + ->setOffice($office) ->setCode($code); // Send the Request document and set the response to this instance. $response = $this->sendXmlDocument($request_article); - return ArticleMapper::map($response); + return ArticleMapper::map($response, $this->getConnection()); } /** @@ -55,21 +58,18 @@ public function get(string $code, Office $office): Article */ public function send(Article $article): Article { - $articleResponses = $this->sendAll([$article]); - - Assert::count($articleResponses, 1); - - foreach ($articleResponses as $articleResponse) { - return $articleResponse->unwrap(); + foreach($this->sendAll([$article]) as $each) { + return $each->unwrap(); } } /** * @param Article[] $articles + * @param bool|null $reSend * @return MappedResponseCollection * @throws Exception */ - public function sendAll(array $articles): MappedResponseCollection + public function sendAll(array $articles, bool $reSend = false): MappedResponseCollection { Assert::allIsInstanceOf($articles, Article::class); @@ -77,7 +77,6 @@ public function sendAll(array $articles): MappedResponseCollection $responses = []; foreach ($this->getProcessXmlService()->chunk($articles) as $chunk) { - $articlesDocument = new ArticlesDocument(); foreach ($chunk as $article) { @@ -87,8 +86,108 @@ public function sendAll(array $articles): MappedResponseCollection $responses[] = $this->sendXmlDocument($articlesDocument); } - return $this->getProcessXmlService()->mapAll($responses, "article", function(Response $response): Article { - return ArticleMapper::map($response); + $mappedResponseCollection = $this->getProcessXmlService()->mapAll($responses, "article", function(Response $response): Article { + return ArticleMapper::map($response, $this->getConnection()); }); + + if ($reSend) { + return $mappedResponseCollection; + } + + return self::testSentEqualsResponse($this, $articles, $mappedResponseCollection); + } + + /** + * @param HasMessageInterface $returnedObject + * @param HasMessageInterface $sentObject + * @return array + */ + public function testEqual(HasMessageInterface $returnedObject, HasMessageInterface $sentObject): array + { + Assert::IsInstanceOf($returnedObject, Article::class); + Assert::IsInstanceOf($sentObject, Article::class); + + $equal = true; + $idArray = []; + + $returnedLines = $returnedObject->getLines(); + $sentLines = $sentObject->getLines(); + + foreach ($sentLines as $key => $sentLine) { + $idArray[] = $sentLine->getID(); + } + + foreach ($returnedLines as $key => $returnedLine) { + $id = $returnedLine->getID(); + + if (!in_array($id, $idArray) && $returnedLine->getStatus() != 'deleted') { + $returnedLine->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + $equal = false; + } + } + + return [$equal, $returnedObject]; + } + + /** + * List all articles. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Article[] The articles found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_ITEMS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $articleArrayListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Article::class, $response->data, $articleArrayListAllTags); + } + + /** + * Deletes a specific Article based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Article The deleted Article or Article object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Article + { + $article = self::get($code, $office); + + if ($article->getResult() == 1) { + $article->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $articleDeleted = self::send($article); + } catch (ResponseException $e) { + $articleDeleted = $e->getReturnedObject(); + } + + return $articleDeleted; + } else { + return $article; + } } } diff --git a/src/ApiConnectors/AssetMethodApiConnector.php b/src/ApiConnectors/AssetMethodApiConnector.php new file mode 100644 index 00000000..cba801be --- /dev/null +++ b/src/ApiConnectors/AssetMethodApiConnector.php @@ -0,0 +1,196 @@ + + */ +class AssetMethodApiConnector extends BaseApiConnector implements HasEqualInterface +{ + /** + * Requests a specific AssetMethod based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return AssetMethod The requested AssetMethod or AssetMethod object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): AssetMethod + { + // Make a request to read a single AssetMethod. Set the required values + $request_assetMethod = new Request\AssetMethod(); + $request_assetMethod + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_assetMethod); + + return AssetMethodMapper::map($response); + } + + /** + * Sends an AssetMethod instance to Twinfield to update or add. + * + * @param AssetMethod $assetMethod + * @return AssetMethod + * @throws Exception + */ + public function send(AssetMethod $assetMethod): AssetMethod + { + foreach($this->sendAll([$assetMethod]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param AssetMethod[] $assetMethods + * @param bool|null $reSend + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $assetMethods, bool $reSend = false): MappedResponseCollection + { + Assert::allIsInstanceOf($assetMethods, AssetMethod::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($assetMethods) as $chunk) { + + $assetMethodsDocument = new AssetMethodsDocument(); + + foreach ($chunk as $assetMethod) { + $assetMethodsDocument->addAssetMethod($assetMethod); + } + + $responses[] = $this->sendXmlDocument($assetMethodsDocument); + } + + $mappedResponseCollection = $this->getProcessXmlService()->mapAll($responses, "assetmethod", function(Response $response): AssetMethod { + return AssetMethodMapper::map($response); + }); + + if ($reSend) { + return $mappedResponseCollection; + } + + return self::testSentEqualsResponse($this, $assetMethods, $mappedResponseCollection); + } + + /** + * @param HasMessageInterface $returnedObject + * @param HasMessageInterface $sentObject + * @return array + */ + public function testEqual(HasMessageInterface $returnedObject, HasMessageInterface $sentObject): array + { + Assert::IsInstanceOf($returnedObject, AssetMethod::class); + Assert::IsInstanceOf($sentObject, AssetMethod::class); + + $equal = true; + + $idArray = []; + + $returnedFreeTexts = $returnedObject->getFreeTexts(); + $sentFreeTexts = $sentObject->getFreeTexts(); + + foreach ($sentFreeTexts as $key => $sentFreeText) { + $idArray[] = $sentFreeText->getID(); + } + + foreach ($returnedFreeTexts as $key => $returnedFreeText) { + $id = $returnedFreeText->getID(); + + if (!in_array($id, $idArray) && (!empty($returnedFreeText->getElementValue()) || $returnedFreeText->getType() != 'text')) { + $returnedFreeText->setType(\PhpTwinfield\Enums\FreeTextType::TEXT()); + $returnedFreeText->setElementValue(''); + $equal = false; + } + } + + return [$equal, $returnedObject]; + } + + /** + * List all asset methods. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return AssetMethod[] The asset methods found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_ASSET_METHODS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $assetMethodArrayListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(AssetMethod::class, $response->data, $assetMethodArrayListAllTags); + } + + /** + * Deletes a specific AssetMethod based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return AssetMethod The deleted AssetMethod or AssetMethod object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): AssetMethod + { + $assetMethod = self::get($code, $office); + + if ($assetMethod->getResult() == 1) { + $assetMethod->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $assetMethodDeleted = self::send($assetMethod); + } catch (ResponseException $e) { + $assetMethodDeleted = $e->getReturnedObject(); + } + + return $assetMethodDeleted; + } else { + return $assetMethod; + } + } +} diff --git a/src/ApiConnectors/BankTransactionApiConnector.php b/src/ApiConnectors/BankTransactionApiConnector.php deleted file mode 100644 index 3a704632..00000000 --- a/src/ApiConnectors/BankTransactionApiConnector.php +++ /dev/null @@ -1,66 +0,0 @@ -sendAll([$bankTransaction]); - - Assert::count($bankTransactionResponses, 1); - - foreach ($bankTransactionResponses as $bankTransactionResponse) { - return $bankTransactionResponse->unwrap(); - } - } - - /** - * @param BankTransaction[] $bankTransactions - * @return MappedResponseCollection|IndividualMappedResponse[] - * @throws Exception - */ - public function sendAll(array $bankTransactions): MappedResponseCollection - { - Assert::allIsInstanceOf($bankTransactions, BankTransaction::class); - - /* - * We can have multiple documents sent, so we need to collect all documents. - */ - /** @var Response[] $responses */ - $responses = []; - - foreach ($this->getProcessXmlService()->chunk($bankTransactions) as $chunk) { - - $bankTransactionDocument = new BankTransactionDocument(); - - foreach ($chunk as $bankTransaction) { - $bankTransactionDocument->addBankTransaction($bankTransaction); - } - - $responses[] = $this->sendXmlDocument($bankTransactionDocument); - } - - return $this->getProcessXmlService()->mapAll($responses, "transaction", function(Response $subresponse): BankTransaction { - return BankTransactionMapper::map($subresponse->getResponseDocument()); - }); - } -} diff --git a/src/ApiConnectors/BaseApiConnector.php b/src/ApiConnectors/BaseApiConnector.php index 6f75bc66..4d0c3fd6 100644 --- a/src/ApiConnectors/BaseApiConnector.php +++ b/src/ApiConnectors/BaseApiConnector.php @@ -4,7 +4,9 @@ use PhpTwinfield\Enums\Services; use PhpTwinfield\Exception; +use PhpTwinfield\Response\MappedResponseCollection; use PhpTwinfield\Response\Response; +use PhpTwinfield\Response\ResponseException; use PhpTwinfield\Secure\AuthenticatedConnection; use PhpTwinfield\Services\FinderService; use PhpTwinfield\Services\ProcessXmlService; @@ -37,6 +39,7 @@ abstract class BaseApiConnector implements LoggerAwareInterface public function __construct(AuthenticatedConnection $connection, ?ApiOptions $options = null) { $this->connection = $connection; + if ($options === null) { $this->options = new ApiOptions(); } else { @@ -44,6 +47,17 @@ public function __construct(AuthenticatedConnection $connection, ?ApiOptions $op } } + /** + * Will return the current connection + * + * @return \PhpTwinfield\Secure\AuthenticatedConnection + * @throws Exception + */ + public function getConnection(): AuthenticatedConnection + { + return $this->connection; + } + public function getOptions(): ApiOptions { return $this->options; @@ -164,4 +178,104 @@ protected function getFinderService(): FinderService { return $this->connection->getAuthenticatedClient(Services::FINDER()); } + + /** + * Convert options array to an ArrayOfString which is accepted by Twinfield. + * + * In some cases you are not allowed to change certain options (such as the dimtype, which should always be DEB when using CustomerApiConnector->ListAll()), + * in which case the $forcedOptions parameter will be set by the ApiConnector for this option, which will override any user settings in $options + * + * @param array $options + * @param array $forcedOptions + * @return array + * @throws Exception + */ + public function convertOptionsToArrayOfString(array $options, array $forcedOptions = []): array { + if (isset($options['ArrayOfString'])) { + return $options; + } + + $optionsArrayOfString = ['ArrayOfString' => []]; + + foreach ($forcedOptions as $key => $value) { + unset($options[$key]); + $optionsArrayOfString['ArrayOfString'][] = array($key, $value); + } + + foreach ($options as $key => $value) { + $optionsArrayOfString['ArrayOfString'][] = array($key, $value); + } + + return $optionsArrayOfString; + } + + /** + * Map the response of a listAll to an array of the requested class + * + * Is used by child ApiConnectors to map a $data object received by the FinderService to one or more new entities of $objectClass + * using the methods and attributes in $methodToAttributeMap. Returns an array of $objectClass objects + * + * @param string $objectClass + * @param $data + * @param array $methodToAttributeMap + * @return array + * @throws Exception + */ + public function mapListAll(string $objectClass, $data, array $methodToAttributeMap): array { + if ($data->TotalRows == 0) { + return []; + } + + $objects = []; + + foreach ($data->Items->ArrayOfString as $responseArrayElement) { + $object = new $objectClass(); + + if (isset($responseArrayElement->string[0])) { + $elementArray = $responseArrayElement->string; + } else { + $elementArray = $responseArrayElement; + } + + foreach ($methodToAttributeMap as $key => $method) { + $object->$method($elementArray[$key]); + } + + $objects[] = $object; + } + + return $objects; + } + + /** + * @param HasEqualInterface $apiConnector + * @param array $sentObjects + * @param MappedResponseCollection $mappedResponseCollection + * @return MappedResponseCollection + */ + public function testSentEqualsResponse(HasEqualInterface $apiConnector, array $sentObjects, MappedResponseCollection $mappedResponseCollection): MappedResponseCollection + { + $checkedMappedResponseCollection = new MappedResponseCollection(); + + foreach($mappedResponseCollection as $key => $individualMappedResponse) { + $returnedObject = $individualMappedResponse->unwrap(); + + if ($returnedObject->getResult() == 1) { + $testResult = $apiConnector->testEqual($returnedObject, $sentObjects[$key]); + $equal = $testResult[0]; + $returnedObject = $testResult[1]; + + if (!$equal) { + $apiConnector->sendAll([$returnedObject], true)[0]; + sleep(2); + $sentObjects[$key]->setCode($returnedObject->getCode()); + $individualMappedResponse = $apiConnector->sendAll([$sentObjects[$key]], true)[0]; + } + } + + $checkedMappedResponseCollection->append($individualMappedResponse); + } + + return $checkedMappedResponseCollection; + } } diff --git a/src/ApiConnectors/BookingReferenceDeletionTrait.php b/src/ApiConnectors/BookingReferenceDeletionTrait.php index 87d9ca1c..016bfd9f 100644 --- a/src/ApiConnectors/BookingReferenceDeletionTrait.php +++ b/src/ApiConnectors/BookingReferenceDeletionTrait.php @@ -25,4 +25,4 @@ public function delete(BookingReference $bookingReference, string $reason): void $response = $this->getProcessXmlService()->sendDocument($document); $response->assertSuccessful(); } -} \ No newline at end of file +} diff --git a/src/ApiConnectors/BrowseDataApiConnector.php b/src/ApiConnectors/BrowseDataApiConnector.php index 2fa2d9b0..d1f1ba7f 100644 --- a/src/ApiConnectors/BrowseDataApiConnector.php +++ b/src/ApiConnectors/BrowseDataApiConnector.php @@ -2,13 +2,13 @@ namespace PhpTwinfield\ApiConnectors; -use PhpTwinfield\Exception; use PhpTwinfield\BrowseColumn; use PhpTwinfield\BrowseSortField; +use PhpTwinfield\Exception; use PhpTwinfield\Mappers\BrowseDataMapper; use PhpTwinfield\Mappers\BrowseDefinitionMapper; -use PhpTwinfield\Request\BrowseData; use PhpTwinfield\Mappers\BrowseFieldMapper; +use PhpTwinfield\Request\BrowseData; use PhpTwinfield\Request\Catalog\BrowseField; use PhpTwinfield\Request\Read\BrowseDefinition; use Webmozart\Assert\Assert; diff --git a/src/ApiConnectors/CashBankBookApiConnector.php b/src/ApiConnectors/CashBankBookApiConnector.php new file mode 100644 index 00000000..5693d6db --- /dev/null +++ b/src/ApiConnectors/CashBankBookApiConnector.php @@ -0,0 +1,53 @@ + + */ +class CashBankBookApiConnector extends BaseApiConnector +{ + /** + * List all cash and bank books. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return CashBankBook[] The cash and bank books found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_CASHBOOKS_AND_BANKS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $cashBankBookListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(CashBankBook::class, $response->data, $cashBankBookListAllTags); + } +} diff --git a/src/ApiConnectors/CostCenterApiConnector.php b/src/ApiConnectors/CostCenterApiConnector.php new file mode 100644 index 00000000..795be882 --- /dev/null +++ b/src/ApiConnectors/CostCenterApiConnector.php @@ -0,0 +1,155 @@ + + */ +class CostCenterApiConnector extends BaseApiConnector +{ + /** + * Requests a specific CostCenter based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return CostCenter The requested CostCenter or CostCenter object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): CostCenter + { + // Make a request to read a single CostCenter. Set the required values + $request_costCenter = new Request\Read\CostCenter(); + $request_costCenter + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_costCenter); + + return CostCenterMapper::map($response); + } + + /** + * Sends a CostCenter instance to Twinfield to update or add. + * + * @param CostCenter $costCenter + * @return CostCenter + * @throws Exception + */ + public function send(CostCenter $costCenter): CostCenter + { + foreach($this->sendAll([$costCenter]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param CostCenter[] $costCenters + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $costCenters): MappedResponseCollection + { + Assert::allIsInstanceOf($costCenters, CostCenter::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($costCenters) as $chunk) { + + $costCentersDocument = new CostCentersDocument(); + + foreach ($chunk as $costCenter) { + $costCentersDocument->addCostCenter($costCenter); + } + + $responses[] = $this->sendXmlDocument($costCentersDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): CostCenter { + return CostCenterMapper::map($response); + }); + } + + /** + * List all cost centers. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return CostCenter[] The cost centers found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "KPL"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_FINANCIALS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $costCenterArrayListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(CostCenter::class, $response->data, $costCenterArrayListAllTags); + } + + /** + * Deletes a specific CostCenter based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return CostCenter The deleted CostCenter or CostCenter object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): CostCenter + { + $costCenter = self::get($code, $office); + + if ($costCenter->getResult() == 1) { + $costCenter->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $costCenterDeleted = self::send($costCenter); + } catch (ResponseException $e) { + $costCenterDeleted = $e->getReturnedObject(); + } + + return $costCenterDeleted; + } else { + return $costCenter; + } + } +} diff --git a/src/ApiConnectors/CountryApiConnector.php b/src/ApiConnectors/CountryApiConnector.php new file mode 100644 index 00000000..ab5ee1ac --- /dev/null +++ b/src/ApiConnectors/CountryApiConnector.php @@ -0,0 +1,53 @@ + + */ +class CountryApiConnector extends BaseApiConnector +{ + /** + * List all countries. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Country[] The countries found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_COUNTRIES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $countryListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Country::class, $response->data, $countryListAllTags); + } +} diff --git a/src/ApiConnectors/CurrencyApiConnector.php b/src/ApiConnectors/CurrencyApiConnector.php new file mode 100644 index 00000000..acbe5bf3 --- /dev/null +++ b/src/ApiConnectors/CurrencyApiConnector.php @@ -0,0 +1,233 @@ + + */ +class CurrencyApiConnector extends BaseApiConnector implements HasEqualInterface +{ + /** + * Requests a specific Currency based off the passed in code and optionally the office. + * NOTE: The Twinfield API does not currently officially support reading currencies + * This function uses the fact that the API will return part of an existing object when sending a known code with an explicit error (no name) + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Currency The requested Currency or Currency object with error message if it can't be found. + * @throws Exception + */ + + public function get(string $code, Office $office): Currency + { + $currency = new Currency; + $currency->setCode($code); + $currency->setOffice($office); + $currencyName = ''; + + $currencies = self::listAll($code, 1, 1, 100, array('office' => $office->getCode())); + + if (count($currencies) == 0) { + $currency->setResult(0); + return $currency; + } + + foreach ($currencies as $currencyListing) { + if ($currencyListing->getCode() == $code) { + $currencyName = $currencyListing->getName(); + break; + } + } + + if (empty($currencyName)) { + $currency->setResult(0); + return $currency; + } + + try { + $currencyResponse = $this->send($currency); + } catch (ResponseException $e) { + $currencyResponse = $e->getReturnedObject(); + $currencyResponse->setMessages(null); + $currencyResponse->setName($currencyName); + $currencyResponse->setResult(1); + } + + return $currencyResponse; + } + + /** + * Sends a Currency instance to Twinfield to update or add. + * + * @param Currency $currency + * @return Currency + * @throws Exception + */ + public function send(Currency $currency): Currency + { + foreach($this->sendAll([$currency]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param Currency[] $currencies + * @param bool|null $reSend + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $currencies, bool $reSend = false): MappedResponseCollection + { + Assert::allIsInstanceOf($currencies, Currency::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($currencies) as $chunk) { + + $currenciesDocument = new CurrenciesDocument(); + + foreach ($chunk as $currency) { + $currenciesDocument->addCurrency($currency); + } + + $responses[] = $this->sendXmlDocument($currenciesDocument); + } + + $mappedResponseCollection = $this->getProcessXmlService()->mapAll($responses, "currency", function(Response $response): Currency { + return CurrencyMapper::map($response); + }); + + if ($reSend) { + return $mappedResponseCollection; + } + + return self::testSentEqualsResponse($this, $currencies, $mappedResponseCollection); + } + + /** + * @param HasMessageInterface $returnedObject + * @param HasMessageInterface $sentObject + * @return array + */ + public function testEqual(HasMessageInterface $returnedObject, HasMessageInterface $sentObject): array + { + Assert::IsInstanceOf($returnedObject, Currency::class); + Assert::IsInstanceOf($sentObject, Currency::class); + + $currencyResponse = $this->get($returnedObject->getCode(), $returnedObject->getOffice()); + + foreach ($returnedObject->getRates() as $key => $rate) { + $returnedObject->removeRate($key); + } + + foreach ($currencyResponse->getRates() as $key => $rate) { + $returnedObject->addRate($rate); + } + + $equal = true; + + $dateArray = []; + + $returnedRates = $returnedObject->getRates(); + $sentRates = $sentObject->getRates(); + + foreach ($sentRates as $sentRate) { + $dateArray[] = Util::formatDate($sentRate->getStartDate()); + } + + foreach ($returnedRates as $returnedRate) { + $date = Util::formatDate($returnedRate->getStartDate()); + + if (!in_array($date, $dateArray) && $returnedRate->getStatus() != 'deleted') { + $returnedRate->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + $equal = false; + } + } + + return [$equal, $returnedObject]; + } + + /** + * List all currencies. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Currency[] The currencies found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_CURRENCIES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $currencyArrayListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Currency::class, $response->data, $currencyArrayListAllTags); + } + + /** + * Deletes a specific Currency based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Currency The deleted Currency or Currency object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Currency + { + $currency = self::get($code, $office); + + if ($currency->getResult() == 1) { + $currency->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $currencyDeleted = self::send($currency); + } catch (ResponseException $e) { + $currencyDeleted = $e->getReturnedObject(); + } + + return $currencyDeleted; + } else { + return $currency; + } + } +} diff --git a/src/ApiConnectors/CustomerApiConnector.php b/src/ApiConnectors/CustomerApiConnector.php index 0f42276d..243d7bcd 100644 --- a/src/ApiConnectors/CustomerApiConnector.php +++ b/src/ApiConnectors/CustomerApiConnector.php @@ -10,6 +10,8 @@ use PhpTwinfield\Request as Request; use PhpTwinfield\Response\MappedResponseCollection; use PhpTwinfield\Response\Response; +use PhpTwinfield\Response\ResponseException; +use PhpTwinfield\Services\FinderService; use Webmozart\Assert\Assert; /** @@ -19,17 +21,18 @@ * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ class CustomerApiConnector extends BaseApiConnector { /** - * Requests a specific customer based off the passed in code and the office. + * Requests a specific Customer based off the passed in code and optionally the office. * * @param string $code - * @param Office $office - * @return Customer The requested customer + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Customer The requested Customer or Customer object with error message if it can't be found. * @throws Exception */ public function get(string $code, Office $office): Customer @@ -37,57 +40,17 @@ public function get(string $code, Office $office): Customer // Make a request to read a single customer. Set the required values $request_customer = new Request\Read\Customer(); $request_customer - ->setOffice($office->getCode()) + ->setOffice($office) ->setCode($code); // Send the Request document and set the response to this instance. $response = $this->sendXmlDocument($request_customer); - return CustomerMapper::map($response); - } - - /** - * Requests all customers from the List Dimension Type. - * - * @param Office $office - * @return array A multidimensional array in the following form: - * [$customerId => ['name' => $name, 'shortName' => $shortName], ...] - * - * @throws Exception - */ - public function listAll(Office $office): array - { - // Make a request to a list of all customers - $request_customers = new Request\Catalog\Dimension($office, "DEB"); - - // Send the Request document and set the response to this instance. - $response = $this->sendXmlDocument($request_customers); - // Get the raw response document - $responseDOM = $response->getResponseDocument(); - - // Prepared empty customer array - $customers = []; - - // Store in an array by customer id - /** @var \DOMElement $customer */ - foreach ($responseDOM->getElementsByTagName('dimension') as $customer) { - $customer_id = $customer->textContent; - - if ($customer_id == "DEB") { - continue; - } - - $customers[$customer->textContent] = array( - 'name' => $customer->getAttribute('name'), - 'shortName' => $customer->getAttribute('shortname'), - ); - } - - return $customers; + return CustomerMapper::map($response, $this->getConnection()); } /** - * Sends a \PhpTwinfield\Customer\Customer instance to Twinfield to update or add. + * Sends a Customer instance to Twinfield to update or add. * * @param Customer $customer * @return Customer @@ -95,12 +58,8 @@ public function listAll(Office $office): array */ public function send(Customer $customer): Customer { - $customerResponses = $this->sendAll([$customer]); - - Assert::count($customerResponses, 1); - - foreach ($customerResponses as $customerResponse) { - return $customerResponse->unwrap(); + foreach($this->sendAll([$customer]) as $each) { + return $each->unwrap(); } } @@ -113,10 +72,10 @@ public function sendAll(array $customers): MappedResponseCollection { Assert::allIsInstanceOf($customers, Customer::class); + /** @var Response[] $responses */ $responses = []; foreach ($this->getProcessXmlService()->chunk($customers) as $chunk) { - $customersDocument = new CustomersDocument(); foreach ($chunk as $customer) { @@ -127,7 +86,70 @@ public function sendAll(array $customers): MappedResponseCollection } return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): Customer { - return CustomerMapper::map($response); + return CustomerMapper::map($response, $this->getConnection()); }); } + + /** + * List all customers. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Customer[] The customers found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "DEB"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_FINANCIALS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $customerListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Customer::class, $response->data, $customerListAllTags); + } + + /** + * Deletes a specific Customer based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Customer The deleted Customer or Customer object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Customer + { + $customer = self::get($code, $office); + + if ($customer->getResult() == 1) { + $customer->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $customerDeleted = self::send($customer); + } catch (ResponseException $e) { + $customerDeleted = $e->getReturnedObject(); + } + + return $customerDeleted; + } else { + return $customer; + } + } } diff --git a/src/ApiConnectors/DimensionGroupApiConnector.php b/src/ApiConnectors/DimensionGroupApiConnector.php new file mode 100644 index 00000000..d12c9a80 --- /dev/null +++ b/src/ApiConnectors/DimensionGroupApiConnector.php @@ -0,0 +1,154 @@ + + */ +class DimensionGroupApiConnector extends BaseApiConnector +{ + /** + * Requests a specific DimensionGroup based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return DimensionGroup The requested DimensionGroup or DimensionGroup object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): DimensionGroup + { + // Make a request to read a single DimensionGroup. Set the required values + $request_dimensionGroup = new Request\DimensionGroup(); + $request_dimensionGroup + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_dimensionGroup); + + return DimensionGroupMapper::map($response); + } + + /** + * Sends an DimensionGroup instance to Twinfield to update or add. + * + * @param DimensionGroup $dimensionGroup + * @return DimensionGroup + * @throws Exception + */ + public function send(DimensionGroup $dimensionGroup): DimensionGroup + { + foreach($this->sendAll([$dimensionGroup]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param DimensionGroup[] $dimensionGroups + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $dimensionGroups): MappedResponseCollection + { + Assert::allIsInstanceOf($dimensionGroups, DimensionGroup::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($dimensionGroups) as $chunk) { + + $dimensionGroupsDocument = new DimensionGroupsDocument(); + + foreach ($chunk as $dimensionGroup) { + $dimensionGroupsDocument->addDimensionGroup($dimensionGroup); + } + + $responses[] = $this->sendXmlDocument($dimensionGroupsDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimensiongroup", function(Response $response): DimensionGroup { + return DimensionGroupMapper::map($response); + }); + } + + /** + * List all dimension groups. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return DimensionGroup[] The dimension groups found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSION_GROUPS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $dimensionGroupListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(DimensionGroup::class, $response->data, $dimensionGroupListAllTags); + } + + /** + * Deletes a specific DimensionGroup based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return DimensionGroup The deleted DimensionGroup or DimensionGroup object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): DimensionGroup + { + $dimensionGroup = self::get($code, $office); + + if ($dimensionGroup->getResult() == 1) { + $dimensionGroup->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $dimensionGroupDeleted = self::send($dimensionGroup); + } catch (ResponseException $e) { + $dimensionGroupDeleted = $e->getReturnedObject(); + } + + return $dimensionGroupDeleted; + } else { + return $dimensionGroup; + } + } +} diff --git a/src/ApiConnectors/DimensionTypeApiConnector.php b/src/ApiConnectors/DimensionTypeApiConnector.php new file mode 100644 index 00000000..b7bea89d --- /dev/null +++ b/src/ApiConnectors/DimensionTypeApiConnector.php @@ -0,0 +1,125 @@ + + */ +class DimensionTypeApiConnector extends BaseApiConnector +{ + /** + * Requests a specific DimensionType based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return DimensionType The requested DimensionType or DimensionType object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): DimensionType + { + // Make a request to read a single DimensionType. Set the required values + $request_dimensionType = new Request\DimensionType(); + $request_dimensionType + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_dimensionType); + + return DimensionTypeMapper::map($response); + } + + /** + * Sends an DimensionType instance to Twinfield to update or add. + * + * @param DimensionType $dimensionType + * @return DimensionType + * @throws Exception + */ + public function send(DimensionType $dimensionType): DimensionType + { + foreach($this->sendAll([$dimensionType]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param DimensionType[] $dimensionTypes + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $dimensionTypes): MappedResponseCollection + { + Assert::allIsInstanceOf($dimensionTypes, DimensionType::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($dimensionTypes) as $chunk) { + + $dimensionTypesDocument = new DimensionTypesDocument(); + + foreach ($chunk as $dimensionType) { + $dimensionTypesDocument->addDimensionType($dimensionType); + } + + $responses[] = $this->sendXmlDocument($dimensionTypesDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimensiontype", function(Response $response): DimensionType { + return DimensionTypeMapper::map($response); + }); + } + + /** + * List all dimension types. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return DimensionType[] The dimension types found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSION_TYPES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $dimensionTypeListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(DimensionType::class, $response->data, $dimensionTypeListAllTags); + } +} diff --git a/src/ApiConnectors/ElectronicBankStatementApiConnector.php b/src/ApiConnectors/ElectronicBankStatementApiConnector.php index 7f9a1c5e..b7ce37d0 100644 --- a/src/ApiConnectors/ElectronicBankStatementApiConnector.php +++ b/src/ApiConnectors/ElectronicBankStatementApiConnector.php @@ -35,7 +35,6 @@ public function sendAll(array $statements): void $responses = []; foreach ($this->getProcessXmlService()->chunk($statements) as $chunk) { - $document = new ElectronicBankStatementDocument(); foreach ($chunk as $statement) { diff --git a/src/ApiConnectors/FixedAssetApiConnector.php b/src/ApiConnectors/FixedAssetApiConnector.php new file mode 100644 index 00000000..3dc1107f --- /dev/null +++ b/src/ApiConnectors/FixedAssetApiConnector.php @@ -0,0 +1,154 @@ + + */ +class FixedAssetApiConnector extends BaseApiConnector +{ + /** + * Requests a specific FixedAsset based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return FixedAsset The requested FixedAsset or FixedAsset object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): FixedAsset + { + // Make a request to read a single FixedAsset. Set the required values + $request_fixedAsset = new Request\Read\FixedAsset(); + $request_fixedAsset + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_fixedAsset); + + return FixedAssetMapper::map($response, $this->getConnection()); + } + + /** + * Sends a FixedAsset instance to Twinfield to update or add. + * + * @param FixedAsset $fixedAsset + * @return FixedAsset + * @throws Exception + */ + public function send(FixedAsset $fixedAsset): FixedAsset + { + foreach($this->sendAll([$fixedAsset]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param FixedAsset[] $fixedAssets + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $fixedAssets): MappedResponseCollection + { + Assert::allIsInstanceOf($fixedAssets, FixedAsset::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($fixedAssets) as $chunk) { + $fixedAssetsDocument = new FixedAssetsDocument(); + + foreach ($chunk as $fixedAsset) { + $fixedAssetsDocument->addFixedAsset($fixedAsset); + } + + $responses[] = $this->sendXmlDocument($fixedAssetsDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): FixedAsset { + return FixedAssetMapper::map($response, $this->getConnection()); + }); + } + + /** + * List all fixed assets. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return FixedAsset[] The fixed assets found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "AST"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_FINANCIALS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $fixedAssetListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(FixedAsset::class, $response->data, $fixedAssetListAllTags); + } + + /** + * Deletes a specific FixedAsset based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return FixedAsset The deleted FixedAsset or FixedAsset object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): FixedAsset + { + $fixedAsset = self::get($code, $office); + + if ($fixedAsset->getResult() == 1) { + $fixedAsset->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $fixedAssetDeleted = self::send($fixedAsset); + } catch (ResponseException $e) { + $fixedAssetDeleted = $e->getReturnedObject(); + } + + return $fixedAssetDeleted; + } else { + return $fixedAsset; + } + } +} diff --git a/src/ApiConnectors/GeneralLedgerApiConnector.php b/src/ApiConnectors/GeneralLedgerApiConnector.php new file mode 100644 index 00000000..ceec9c4e --- /dev/null +++ b/src/ApiConnectors/GeneralLedgerApiConnector.php @@ -0,0 +1,157 @@ + + */ +class GeneralLedgerApiConnector extends BaseApiConnector +{ + /** + * Requests a specific GeneralLedger based off the passed in code, dimension type and optionally the office. + * + * @param string $code + * @param string $dimType + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return GeneralLedger The requested GeneralLedger or GeneralLedger object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, string $dimType, Office $office): GeneralLedger + { + // Make a request to read a single GeneralLedger. Set the required values + $request_generalLedger = new Request\Read\GeneralLedger(); + $request_generalLedger + ->setOffice($office) + ->setDimType($dimType) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_generalLedger); + + return GeneralLedgerMapper::map($response); + } + + /** + * Sends a GeneralLedger instance to Twinfield to update or add. + * + * @param GeneralLedger $generalLedger + * @return GeneralLedger + * @throws Exception + */ + public function send(GeneralLedger $generalLedger): GeneralLedger + { + foreach($this->sendAll([$generalLedger]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param GeneralLedger[] $generalLedgers + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $generalLedgers): MappedResponseCollection + { + Assert::allIsInstanceOf($generalLedgers, GeneralLedger::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($generalLedgers) as $chunk) { + $generalLedgersDocument = new GeneralLedgersDocument(); + + foreach ($chunk as $generalLedger) { + $generalLedgersDocument->addGeneralLedger($generalLedger); + } + + $responses[] = $this->sendXmlDocument($generalLedgersDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): GeneralLedger { + return GeneralLedgerMapper::map($response); + }); + } + + /** + * List all fixed assets. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return GeneralLedger[] The fixed assets found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['level'] = 1; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_FINANCIALS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $generalLedgerListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(GeneralLedger::class, $response->data, $generalLedgerListAllTags); + } + + /** + * Deletes a specific GeneralLedger based off the passed in code and optionally the office. + * + * @param string $code + * @param string $dimType + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return GeneralLedger The deleted GeneralLedger or GeneralLedger object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, string $dimType, Office $office): GeneralLedger + { + $generalLedger = self::get($code, $dimType, $office); + + if ($generalLedger->getResult() == 1) { + $generalLedger->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $generalLedgerDeleted = self::send($generalLedger); + } catch (ResponseException $e) { + $generalLedgerDeleted = $e->getReturnedObject(); + } + + return $generalLedgerDeleted; + } else { + return $generalLedger; + } + } +} diff --git a/src/ApiConnectors/HasEqualInterface.php b/src/ApiConnectors/HasEqualInterface.php new file mode 100644 index 00000000..08fb75d9 --- /dev/null +++ b/src/ApiConnectors/HasEqualInterface.php @@ -0,0 +1,17 @@ +setCode($code) - ->setNumber($invoiceNumber) - ->setOffice($office->getCode()); + ->setInvoiceNumber($invoiceNumber) + ->setOffice($office); // Send the Request document and set the response to this instance $response = $this->sendXmlDocument($request_invoice); @@ -57,12 +58,8 @@ public function get(string $code, string $invoiceNumber, Office $office) */ public function send(Invoice $invoice): Invoice { - $invoiceResponses = $this->sendAll([$invoice]); - - Assert::count($invoiceResponses, 1); - - foreach ($invoiceResponses as $invoiceResponse) { - return $invoiceResponse->unwrap(); + foreach($this->sendAll([$invoice]) as $each) { + return $each->unwrap(); } } @@ -79,11 +76,10 @@ public function sendAll(array $invoices): MappedResponseCollection $responses = []; foreach ($this->getProcessXmlService()->chunk($invoices) as $chunk) { - $invoicesDocument = new InvoicesDocument(); foreach ($chunk as $invoice) { - $invoicesDocument->addInvoice($invoice); + $invoicesDocument->addInvoice($invoice, $this->getConnection()); } $responses[] = $this->sendXmlDocument($invoicesDocument); @@ -93,4 +89,41 @@ public function sendAll(array $invoices): MappedResponseCollection return InvoiceMapper::map($response); }); } + + /** + * List all sales invoices. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Invoice[] The sales invoices found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_LIST_OF_AVAILABLE_INVOICES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $invoiceListAllTags = array( + 0 => 'setInvoiceNumber', + 1 => 'setInvoiceAmountFromFloat', + 2 => 'setCustomerFromString', + 3 => 'setCustomerName', + 4 => 'setDebitCreditFromString', + ); + + return $this->mapListAll(Invoice::class, $response->data, $invoiceListAllTags); + } } diff --git a/src/ApiConnectors/InvoiceTypeApiConnector.php b/src/ApiConnectors/InvoiceTypeApiConnector.php new file mode 100644 index 00000000..71f448e1 --- /dev/null +++ b/src/ApiConnectors/InvoiceTypeApiConnector.php @@ -0,0 +1,87 @@ + + */ +class InvoiceTypeApiConnector extends BaseApiConnector +{ + /** + * List all Invoice types. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return InvoiceType[] The Invoice types found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_INVOICE_TYPES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $invoiceTypeListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(InvoiceType::class, $response->data, $invoiceTypeListAllTags); + } + + /** + * Determine if a specified invoice type is of the inclusive or exclusive VAT type. + * + * @param string $pattern The search pattern. May contain wildcards * and ?, but should be the full code of the invoice type + * + * @return string Is the invoice type of the inclusive or exclusive VAT type. + */ + public function getInvoiceTypeVatType( + string $pattern + ): ?string { + $options = array('vat' => 'inclusive'); + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_INVOICE_TYPES, $pattern, 1, 1, 1, $optionsArrayOfString); + + if ($response->data->TotalRows == 0) { + return 'exclusive'; + } + + foreach ($response->data->Items->ArrayOfString as $invoiceTypeArray) { + if (isset($invoiceTypeArray->string[0])) { + if ($pattern === $invoiceTypeArray->string[0]) { + return 'inclusive'; + } + } else { + if ($pattern === $invoiceTypeArray[0]) { + return 'inclusive'; + } + } + } + + return 'exclusive'; + } +} diff --git a/src/ApiConnectors/MatchesApiConnector.php b/src/ApiConnectors/MatchesApiConnector.php index c0f87984..8c03384f 100644 --- a/src/ApiConnectors/MatchesApiConnector.php +++ b/src/ApiConnectors/MatchesApiConnector.php @@ -22,7 +22,9 @@ class MatchesApiConnector extends BaseApiConnector */ public function send(MatchSet $matchSet): MatchSet { - return $this->sendAll([$matchSet])[0]->unwrap(); + foreach($this->sendAll([$matchSet]) as $each) { + return $each->unwrap(); + } } /** @@ -38,7 +40,6 @@ public function sendAll(array $matchSets): MappedResponseCollection $responses = []; foreach ($this->getProcessXmlService()->chunk($matchSets) as $chunk) { - $document = new MatchDocument(); foreach ($chunk as $matchSet) { diff --git a/src/ApiConnectors/OfficeApiConnector.php b/src/ApiConnectors/OfficeApiConnector.php index 2d826d05..bc0d9968 100644 --- a/src/ApiConnectors/OfficeApiConnector.php +++ b/src/ApiConnectors/OfficeApiConnector.php @@ -3,8 +3,10 @@ namespace PhpTwinfield\ApiConnectors; use PhpTwinfield\Mappers\OfficeMapper; +use PhpTwinfield\Exception; use PhpTwinfield\Office; use PhpTwinfield\Services\FinderService; +use PhpTwinfield\Request as Request; use PhpTwinfield\Request\Catalog\Office as OfficeRequestDocument; /** @@ -14,10 +16,29 @@ * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Emile Bons + * @author Emile Bons , extended by Yannick Aerssens */ class OfficeApiConnector extends BaseApiConnector { + /** + * Requests a specific Office based off the passed in code. + * + * @param string $code + * @return Office The requested Office or Office object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code): Office + { + // Make a request to read a single Office. Set the required values + $request_office = new Request\Read\Office(); + $request_office->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_office); + + return OfficeMapper::map($response); + } + /** * List the available offices when you are using the OAuth based authentication and don't have an office code yet. * For more information following see. @@ -64,27 +85,18 @@ public function listAll( int $maxRows = 100, array $options = [] ): array { - $response = $this->getFinderService()->searchFinder(FinderService::TYPE_OFFICES, $pattern, $field, $firstRow, $maxRows, $options); + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); - if ($response->data->TotalRows == 0) { - return []; - } + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_OFFICES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); - $offices = []; - foreach ($response->data->Items->ArrayOfString as $officeArray) { - $office = new Office(); - if(is_array($officeArray)) { - $office->setCode($officeArray[0]); - $office->setCountryCode($officeArray[2]); - $office->setName($officeArray[1]); - } else { - $office->setCode($officeArray->string[0]); - $office->setCountryCode($officeArray->string[2]); - $office->setName($officeArray->string[1]); - } - $offices[] = $office; - } + $officeListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + 2 => 'setCountryCodeFromString', + 3 => 'setVatPeriod', + 4 => 'setVatFirstQuarterStartsIn', + ); - return $offices; + return $this->mapListAll(Office::class, $response->data, $officeListAllTags); } } diff --git a/src/ApiConnectors/PayCodeApiConnector.php b/src/ApiConnectors/PayCodeApiConnector.php new file mode 100644 index 00000000..0837b9cd --- /dev/null +++ b/src/ApiConnectors/PayCodeApiConnector.php @@ -0,0 +1,53 @@ + + */ +class PayCodeApiConnector extends BaseApiConnector +{ + /** + * List all pay codes. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return PayCode[] The pay codes found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_PAYMENT_TYPES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $payCodeListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(PayCode::class, $response->data, $payCodeListAllTags); + } +} diff --git a/src/ApiConnectors/ProjectApiConnector.php b/src/ApiConnectors/ProjectApiConnector.php new file mode 100644 index 00000000..5a9b2639 --- /dev/null +++ b/src/ApiConnectors/ProjectApiConnector.php @@ -0,0 +1,155 @@ + + */ +class ProjectApiConnector extends BaseApiConnector +{ + /** + * Requests a specific Project based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Project The requested Project or Project object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): Project + { + // Make a request to read a single Project. Set the required values + $request_project = new Request\Read\Project(); + $request_project + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_project); + + return ProjectMapper::map($response); + } + + /** + * Sends a Project instance to Twinfield to update or add. + * + * @param Project $project + * @return Project + * @throws Exception + */ + public function send(Project $project): Project + { + foreach($this->sendAll([$project]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param Project[] $projects + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $projects): MappedResponseCollection + { + Assert::allIsInstanceOf($projects, Project::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($projects) as $chunk) { + + $projectsDocument = new ProjectsDocument(); + + foreach ($chunk as $project) { + $projectsDocument->addProject($project); + } + + $responses[] = $this->sendXmlDocument($projectsDocument); + } + + return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): Project { + return ProjectMapper::map($response); + }); + } + + /** + * List all projects. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Project[] The projects found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "PRJ"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_PROJECTS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $projectListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Project::class, $response->data, $projectListAllTags); + } + + /** + * Deletes a specific Project based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Project The deleted Project or Project object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Project + { + $project = self::get($code, $office); + + if ($project->getResult() == 1) { + $project->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $projectDeleted = self::send($project); + } catch (ResponseException $e) { + $projectDeleted = $e->getReturnedObject(); + } + + return $projectDeleted; + } else { + return $project; + } + } +} diff --git a/src/ApiConnectors/RateApiConnector.php b/src/ApiConnectors/RateApiConnector.php new file mode 100644 index 00000000..c4895c2c --- /dev/null +++ b/src/ApiConnectors/RateApiConnector.php @@ -0,0 +1,194 @@ + + */ +class RateApiConnector extends BaseApiConnector implements HasEqualInterface +{ + /** + * Requests a specific Rate based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Rate The requested Rate or Rate object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): Rate + { + // Make a request to read a single Rate. Set the required values + $request_rate = new Request\Read\Rate(); + $request_rate + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_rate); + + return RateMapper::map($response); + } + + /** + * Sends a Rate instance to Twinfield to update or add. + * + * @param Rate $rate + * @return Rate + * @throws Exception + */ + public function send(Rate $rate): Rate + { + foreach($this->sendAll([$rate]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param Rate[] $rates + * @param bool|null $reSend + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $rates, bool $reSend = false): MappedResponseCollection + { + Assert::allIsInstanceOf($rates, Rate::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($rates) as $chunk) { + + $ratesDocument = new RatesDocument(); + + foreach ($chunk as $rate) { + $ratesDocument->addRate($rate); + } + + $responses[] = $this->sendXmlDocument($ratesDocument); + } + + $mappedResponseCollection = $this->getProcessXmlService()->mapAll($responses, "projectrate", function(Response $response): Rate { + return RateMapper::map($response); + }); + + if ($reSend) { + return $mappedResponseCollection; + } + + return self::testSentEqualsResponse($this, $rates, $mappedResponseCollection); + } + + /** + * @param HasMessageInterface $returnedObject + * @param HasMessageInterface $sentObject + * @return array + */ + public function testEqual(HasMessageInterface $returnedObject, HasMessageInterface $sentObject): array + { + Assert::IsInstanceOf($returnedObject, Rate::class); + Assert::IsInstanceOf($sentObject, Rate::class); + + $equal = true; + $idArray = []; + + $returnedRateChanges = $returnedObject->getRateChanges(); + $sentRateChanges = $sentObject->getRateChanges(); + + foreach ($sentRateChanges as $key => $sentRateChange) { + $idArray[] = $sentRateChange->getID(); + } + + foreach ($returnedRateChanges as $key => $returnedRateChange) { + $id = $returnedRateChange->getID(); + + if (!in_array($id, $idArray) && $returnedRateChange->getStatus() != 'deleted') { + $returnedRateChange->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + $equal = false; + } + } + + return [$equal, $returnedObject]; + } + + /** + * List all rates. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Rate[] The rates found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_TIME_PROJECT_RATES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $rateListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Rate::class, $response->data, $rateListAllTags); + } + + /** + * Deletes a specific Rate based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Rate The deleted Rate or Rate object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Rate + { + $rate = self::get($code, $office); + + if ($rate->getResult() == 1) { + $rate->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $rateDeleted = self::send($rate); + } catch (ResponseException $e) { + $rateDeleted = $e->getReturnedObject(); + } + + return $rateDeleted; + } else { + return $rate; + } + } +} diff --git a/src/ApiConnectors/SupplierApiConnector.php b/src/ApiConnectors/SupplierApiConnector.php index f6e692ee..d25f5a22 100644 --- a/src/ApiConnectors/SupplierApiConnector.php +++ b/src/ApiConnectors/SupplierApiConnector.php @@ -9,6 +9,8 @@ use PhpTwinfield\Request as Request; use PhpTwinfield\Response\MappedResponseCollection; use PhpTwinfield\Response\Response; +use PhpTwinfield\Response\ResponseException; +use PhpTwinfield\Services\FinderService; use PhpTwinfield\Supplier; use Webmozart\Assert\Assert; @@ -19,78 +21,36 @@ * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ class SupplierApiConnector extends BaseApiConnector { /** - * Requests a specific supplier based off the passed in code and optionally the office. + * Requests a specific Supplier based off the passed in code and optionally the office. * * @param string $code - * @param Office $office - * @return Supplier The requested supplier + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Supplier The requested Supplier or Supplier object with error message if it can't be found. * @throws Exception */ - public function get($code, Office $office): Supplier + public function get(string $code, Office $office): Supplier { - // Make a request to read a single customer. Set the required values - $request_customer = new Request\Read\Supplier(); - $request_customer - ->setOffice($office->getCode()) + // Make a request to read a single supplier. Set the required values + $request_supplier = new Request\Read\Supplier(); + $request_supplier + ->setOffice($office) ->setCode($code); - $response = $this->sendXmlDocument($request_customer); - - return SupplierMapper::map($response); - } - - /** - * Requests all customers from the List Dimension Type. - * - * @param Office $office - * @param string $dimType - * @return array A multidimensional array in the following form: - * [$supplierId => ['name' => $name, 'shortName' => $shortName], ...] - * @throws Exception - */ - public function listAll(Office $office, string $dimType = 'CRD'): array - { - - // Make a request to a list of all customers - $request_customers = new Request\Catalog\Dimension($office, $dimType); - // Send the Request document and set the response to this instance. - $response = $this->sendXmlDocument($request_customers); + $response = $this->sendXmlDocument($request_supplier); - // Get the raw response document - $responseDOM = $response->getResponseDocument(); - - // Prepared empty customer array - $suppliers = []; - - // Store in an array by customer id - foreach ($responseDOM->getElementsByTagName('dimension') as $supplier) { - $supplier_id = $supplier->textContent; - - if (!is_numeric($supplier_id)) { - continue; - } - - $suppliers[$supplier->textContent] = array( - 'name' => $supplier->getAttribute('name'), - 'shortName' => $supplier->getAttribute('shortname'), - ); - } - - return $suppliers; + return SupplierMapper::map($response); } /** - * Sends a \PhpTwinfield\Supplier\Supplier instance to Twinfield to update or add. - * - * If you want to map the response back into a customer use getResponse()->getResponseDocument()->asXML() into the - * SupplierMapper::map() method. + * Sends a Supplier instance to Twinfield to update or add. * * @param Supplier $supplier * @return Supplier @@ -98,19 +58,12 @@ public function listAll(Office $office, string $dimType = 'CRD'): array */ public function send(Supplier $supplier): Supplier { - $supplierResponses = $this->sendAll([$supplier]); - - Assert::count($supplierResponses, 1); - - foreach ($supplierResponses as $supplierResponse) { - return $supplierResponse->unwrap(); + foreach($this->sendAll([$supplier]) as $each) { + return $each->unwrap(); } } - /** - * Sends a list of Transaction instances to Twinfield to add or update. - * * @param Supplier[] $suppliers * @return MappedResponseCollection * @throws Exception @@ -123,7 +76,6 @@ public function sendAll(array $suppliers): MappedResponseCollection $responses = []; foreach ($this->getProcessXmlService()->chunk($suppliers) as $chunk) { - $suppliersDocument = new SuppliersDocument(); foreach ($chunk as $supplier) { @@ -134,7 +86,70 @@ public function sendAll(array $suppliers): MappedResponseCollection } return $this->getProcessXmlService()->mapAll($responses, "dimension", function(Response $response): Supplier { - return SupplierMapper::map($response); + return SupplierMapper::map($response); }); } + + /** + * List all suppliers. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return Supplier[] The suppliers found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $forcedOptions['dimtype'] = "CRD"; + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options, $forcedOptions); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_DIMENSIONS_FINANCIALS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $supplierListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(Supplier::class, $response->data, $supplierListAllTags); + } + + /** + * Deletes a specific Supplier based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return Supplier The deleted Supplier or Supplier object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): Supplier + { + $supplier = self::get($code, $office); + + if ($supplier->getResult() == 1) { + $supplier->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $supplierDeleted = self::send($supplier); + } catch (ResponseException $e) { + $supplierDeleted = $e->getReturnedObject(); + } + + return $supplierDeleted; + } else { + return $supplier; + } + } } diff --git a/src/ApiConnectors/TransactionApiConnector.php b/src/ApiConnectors/TransactionApiConnector.php index 6ca39c34..1678d2c7 100644 --- a/src/ApiConnectors/TransactionApiConnector.php +++ b/src/ApiConnectors/TransactionApiConnector.php @@ -32,12 +32,8 @@ class TransactionApiConnector extends BaseApiConnector * @throws Exception * @return BaseTransaction */ - public function get( - string $transactionClassName, - string $code, - string $transactionNumber, - Office $office - ): BaseTransaction { + public function get(string $transactionClassName, string $code, string $transactionNumber, Office $office): BaseTransaction + { // Make a request to read a single transaction $request_transaction = new Request\Read\Transaction(); $request_transaction @@ -48,7 +44,7 @@ public function get( // Send the Request document and set the response to this instance $response = $this->sendXmlDocument($request_transaction); - return TransactionMapper::map($transactionClassName, $response); + return TransactionMapper::map($transactionClassName, $response, $this->getConnection()); } /** @@ -76,14 +72,10 @@ public function sendAll(array $transactions): MappedResponseCollection $classname = get_class(reset($transactions)); - /* - * We can have multiple documents sent, so we need to collect all documents. - */ /** @var Response[] $responses */ $responses = []; foreach ($this->getProcessXmlService()->chunk($transactions) as $chunk) { - $transactionsDocument = new TransactionsDocument(); foreach ($chunk as $transaction) { @@ -93,12 +85,8 @@ public function sendAll(array $transactions): MappedResponseCollection $responses[] = $this->sendXmlDocument($transactionsDocument); } - return $this->getProcessXmlService()->mapAll( - $responses, - "transaction", - function (Response $subresponse) use ($classname): BaseTransaction { - return TransactionMapper::map($classname, $subresponse); - } - ); + return $this->getProcessXmlService()->mapAll($responses, "transaction", function (Response $subresponse) use ($classname): BaseTransaction { + return TransactionMapper::map($classname, $subresponse, $this->getConnection()); + }); } } diff --git a/src/ApiConnectors/UserApiConnector.php b/src/ApiConnectors/UserApiConnector.php index 255803c7..5f56be0a 100644 --- a/src/ApiConnectors/UserApiConnector.php +++ b/src/ApiConnectors/UserApiConnector.php @@ -2,8 +2,15 @@ namespace PhpTwinfield\ApiConnectors; +use PhpTwinfield\Exception; +use PhpTwinfield\Mappers\UserMapper; +use PhpTwinfield\Office; +use PhpTwinfield\Request as Request; +use PhpTwinfield\Response\MappedResponseCollection; +use PhpTwinfield\Response\Response; use PhpTwinfield\Services\FinderService; use PhpTwinfield\User; +use Webmozart\Assert\Assert; /** * A facade to make interaction with the the Twinfield service easier when trying to retrieve or send information about @@ -12,22 +19,36 @@ * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Emile Bons + * @author Emile Bons , extended by Yannick Aerssens */ class UserApiConnector extends BaseApiConnector { - const ACCESS_RULES_DISABLED = 0; - const ACCESS_RULES_ENABLED = 1; + /** + * Requests a specific User based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return User The requested User or User object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): User + { + // Make a request to read a single User. Set the required values + $request_user = new Request\Read\User(); + $request_user + ->setOffice($office) + ->setCode($code); - const MUTUAL_OFFICES_DISABLED = 0; - const MUTUAL_OFFICES_ENABLED = 1; + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_user); + + return UserMapper::map($response); + } /** * List all users. * - * @param string|null $officeCode The office code, if only users from one office should be listed - * @param integer|null $accessRules One of the self::ACCESS_RULES_* constants. - * @param integer|null $mutualOffices One of the self::MUTUAL_OFFICES_* constants. * @param string $pattern The search pattern. May contain wildcards * and ? * @param int $field The search field determines which field or fields will be searched. The * available fields depends on the finder type. Passing a value outside the @@ -41,39 +62,21 @@ class UserApiConnector extends BaseApiConnector * @return User[] The users found. */ public function listAll( - $officeCode = null, - $accessRules = null, - $mutualOffices = null, $pattern = '*', $field = 0, $firstRow = 1, $maxRows = 100, $options = array() ): array { - if (!is_null($officeCode)) { - $options['office'] = $officeCode; - } - if (!is_null($accessRules)) { - $options['accessRules'] = $accessRules; - } - if (!is_null($mutualOffices)) { - $options['mutualOffices'] = $mutualOffices; - } - - $response = $this->getFinderService()->searchFinder(FinderService::TYPE_USERS, $pattern, $field, $firstRow, $maxRows, $options); + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); - if ($response->data->TotalRows == 0) { - return []; - } + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_USERS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); - $users = []; - foreach ($response->data->Items->ArrayOfString as $userArray) { - $user = new User(); - $user->setCode($userArray->string[0]); - $user->setName($userArray->string[1]); - $users[] = $user; - } + $userListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); - return $users; + return $this->mapListAll(User::class, $response->data, $userListAllTags); } } diff --git a/src/ApiConnectors/UserRoleApiConnector.php b/src/ApiConnectors/UserRoleApiConnector.php new file mode 100644 index 00000000..dab89984 --- /dev/null +++ b/src/ApiConnectors/UserRoleApiConnector.php @@ -0,0 +1,53 @@ + + */ +class UserRoleApiConnector extends BaseApiConnector +{ + /** + * List all user roles. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return UserRole[] The user roles found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_USER_ROLES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $userRoleListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(UserRole::class, $response->data, $userRoleListAllTags); + } +} diff --git a/src/ApiConnectors/VatCodeApiConnector.php b/src/ApiConnectors/VatCodeApiConnector.php index 17b69251..5bf33578 100644 --- a/src/ApiConnectors/VatCodeApiConnector.php +++ b/src/ApiConnectors/VatCodeApiConnector.php @@ -2,20 +2,135 @@ namespace PhpTwinfield\ApiConnectors; +use PhpTwinfield\DomDocuments\VatCodesDocument; +use PhpTwinfield\Exception; +use PhpTwinfield\HasMessageInterface; +use PhpTwinfield\Mappers\VatCodeMapper; +use PhpTwinfield\Office; +use PhpTwinfield\Request as Request; +use PhpTwinfield\Response\MappedResponseCollection; +use PhpTwinfield\Response\Response; +use PhpTwinfield\Response\ResponseException; use PhpTwinfield\Services\FinderService; +use PhpTwinfield\Util; use PhpTwinfield\VatCode; +use Webmozart\Assert\Assert; /** * A facade to make interaction with the the Twinfield service easier when trying to retrieve or send information about - * VAT codes. + * VatCodes. * * If you require more complex interactions or a heavier amount of control over the requests to/from then look inside * the methods or see the advanced guide detailing the required usages. * - * @author Emile Bons + * @author Emile Bons , extended by Yannick Aerssens */ -class VatCodeApiConnector extends BaseApiConnector +class VatCodeApiConnector extends BaseApiConnector implements HasEqualInterface { + /** + * Requests a specific VatCode based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return VatCode The requested VatCode or VatCode object with error message if it can't be found. + * @throws Exception + */ + public function get(string $code, Office $office): VatCode + { + // Make a request to read a single VatCode. Set the required values + $request_vatCode = new Request\Read\VatCode(); + $request_vatCode + ->setOffice($office) + ->setCode($code); + + // Send the Request document and set the response to this instance. + $response = $this->sendXmlDocument($request_vatCode); + + return VatCodeMapper::map($response); + } + + /** + * Sends a VatCode instance to Twinfield to update or add. + * + * @param VatCode $vatCode + * @return VatCode + * @throws Exception + */ + public function send(VatCode $vatCode): VatCode + { + foreach($this->sendAll([$vatCode]) as $each) { + return $each->unwrap(); + } + } + + /** + * @param VatCode[] $vatCodes + * @param bool|null $reSend + * @return MappedResponseCollection + * @throws Exception + */ + public function sendAll(array $vatCodes, bool $reSend = false): MappedResponseCollection + { + Assert::allIsInstanceOf($vatCodes, VatCode::class); + + /** @var Response[] $responses */ + $responses = []; + + foreach ($this->getProcessXmlService()->chunk($vatCodes) as $chunk) { + + $vatCodesDocument = new VatCodesDocument(); + + foreach ($chunk as $vatCode) { + $vatCodesDocument->addVatCode($vatCode); + } + + $responses[] = $this->sendXmlDocument($vatCodesDocument); + } + + $mappedResponseCollection = $this->getProcessXmlService()->mapAll($responses, "vat", function(Response $response): VatCode { + return VatCodeMapper::map($response); + }); + + if ($reSend) { + return $mappedResponseCollection; + } + + return self::testSentEqualsResponse($this, $vatCodes, $mappedResponseCollection); + } + + /** + * @param HasMessageInterface $returnedObject + * @param HasMessageInterface $sentObject + * @return array + */ + public function testEqual(HasMessageInterface $returnedObject, HasMessageInterface $sentObject): array + { + Assert::IsInstanceOf($returnedObject, VatCode::class); + Assert::IsInstanceOf($sentObject, VatCode::class); + + $equal = true; + $dateArray = []; + + $returnedPercentages = $returnedObject->getPercentages(); + $sentPercentages = $sentObject->getPercentages(); + + foreach ($sentPercentages as $key => $sentPercentage) { + $dateArray[] = Util::formatDate($sentPercentage->getDate()); + } + + foreach ($returnedPercentages as $key => $returnedPercentage) { + $date = Util::formatDate($returnedPercentage->getDate()); + + if (!in_array($date, $dateArray) && $returnedPercentage->getStatus() != 'deleted') { + $returnedPercentage->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + $equal = false; + } + } + + return [$equal, $returnedObject]; + } + /** * List all VAT codes. * @@ -38,20 +153,43 @@ public function listAll( int $maxRows = 100, array $options = [] ): array { - $response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_CODES, $pattern, $field, $firstRow, $maxRows, $options); + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); - if ($response->data->TotalRows == 0) { - return []; - } + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_CODES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); - $vatCodes = []; - foreach ($response->data->Items->ArrayOfString as $vatCodeArray) { - $vatCode = new VatCode(); - $vatCode->setCode($vatCodeArray->string[0]); - $vatCode->setName($vatCodeArray->string[1]); - $vatCodes[] = $vatCode; - } + $vatCodeListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(VatCode::class, $response->data, $vatCodeListAllTags); + } + + /** + * Deletes a specific VatCode based off the passed in code and optionally the office. + * + * @param string $code + * @param Office $office If no office has been passed it will instead take the default office from the + * passed in config class. + * @return VatCode The deleted VatCode or VatCode object with error message if it can't be found. + * @throws Exception + */ + public function delete(string $code, Office $office): VatCode + { + $vatCode = self::get($code, $office); - return $vatCodes; + if ($vatCode->getResult() == 1) { + $vatCode->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + try { + $vatCodeDeleted = self::send($vatCode); + } catch (ResponseException $e) { + $vatCodeDeleted = $e->getReturnedObject(); + } + + return $vatCodeDeleted; + } else { + return $vatCode; + } } } diff --git a/src/ApiConnectors/VatGroupApiConnector.php b/src/ApiConnectors/VatGroupApiConnector.php new file mode 100644 index 00000000..e9373f33 --- /dev/null +++ b/src/ApiConnectors/VatGroupApiConnector.php @@ -0,0 +1,53 @@ + + */ +class VatGroupApiConnector extends BaseApiConnector +{ + /** + * List all VAT groups. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return VatGroup[] The VAT groups found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_GROUPS, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $vatGroupListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(VatGroup::class, $response->data, $vatGroupListAllTags); + } +} diff --git a/src/ApiConnectors/VatGroupCountryApiConnector.php b/src/ApiConnectors/VatGroupCountryApiConnector.php new file mode 100644 index 00000000..059ba088 --- /dev/null +++ b/src/ApiConnectors/VatGroupCountryApiConnector.php @@ -0,0 +1,53 @@ + + */ +class VatGroupCountryApiConnector extends BaseApiConnector +{ + /** + * List all VAT group countries. + * + * @param string $pattern The search pattern. May contain wildcards * and ? + * @param int $field The search field determines which field or fields will be searched. The available fields + * depends on the finder type. Passing a value outside the specified values will cause an + * error. + * @param int $firstRow First row to return, useful for paging + * @param int $maxRows Maximum number of rows to return, useful for paging + * @param array $options The Finder options. Passing an unsupported name or value causes an error. It's possible + * to add multiple options. An option name may be used once, specifying an option multiple + * times will cause an error. + * + * @return VatGroupCountry[] The VAT group countries found. + */ + public function listAll( + string $pattern = '*', + int $field = 0, + int $firstRow = 1, + int $maxRows = 100, + array $options = [] + ): array { + $optionsArrayOfString = $this->convertOptionsToArrayOfString($options); + + $response = $this->getFinderService()->searchFinder(FinderService::TYPE_VAT_GROUPS_COUNTRIES, $pattern, $field, $firstRow, $maxRows, $optionsArrayOfString); + + $vatGroupCountryListAllTags = array( + 0 => 'setCode', + 1 => 'setName', + ); + + return $this->mapListAll(VatGroupCountry::class, $response->data, $vatGroupCountryListAllTags); + } +} diff --git a/src/Article.php b/src/Article.php index cc659ef8..66abf84c 100644 --- a/src/Article.php +++ b/src/Article.php @@ -2,187 +2,64 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionFields\OfficeField; -use PhpTwinfield\Transactions\TransactionLineFields\VatCodeField; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\Invoice\AllowDiscountOrPremiumField; +use PhpTwinfield\Fields\Invoice\Article\AllowChangePerformanceTypeField; +use PhpTwinfield\Fields\Invoice\Article\AllowChangeUnitsPriceField; +use PhpTwinfield\Fields\Invoice\Article\AllowChangeVatCodeField; +use PhpTwinfield\Fields\Invoice\Article\AllowDecimalQuantityField; +use PhpTwinfield\Fields\Invoice\Article\PercentageField; +use PhpTwinfield\Fields\Invoice\Article\TypeField; +use PhpTwinfield\Fields\Invoice\Article\UnitNamePluralField; +use PhpTwinfield\Fields\Invoice\Article\UnitNameSingularField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; +use PhpTwinfield\Fields\VatCodeField; /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Articles * @todo Add documentation and typehints to all properties. */ -class Article +class Article extends BaseObject implements HasCodeInterface { - use VatCodeField; + use AllowChangePerformanceTypeField; + use AllowChangeUnitsPriceField; + use AllowChangeVatCodeField; + use AllowDecimalQuantityField; + use AllowDiscountOrPremiumField; + use CodeField; + use NameField; use OfficeField; + use PercentageField; + use PerformanceTypeField; + use ShortNameField; + use StatusField; + use TypeField; + use UnitNamePluralField; + use UnitNameSingularField; + use VatCodeField; - private $code; - private $status; - private $type; - private $name; - private $shortName; - private $unitNameSingular; - private $unitNamePlural; - private $allowChangeVatCode = false; - private $performanceType; - private $allowChangePerformanceType; - private $percentage; - private $allowDiscountorPremium = true; - private $allowChangeUnitsPrice = false; - private $allowDecimalQuantity = false; private $lines = []; - public function getCode() - { - return $this->code; - } - - public function setCode($code) - { - $this->code = $code; - return $this; - } - - public function getStatus() - { - return $this->status; - } - - public function setStatus($status) - { - $this->status = $status; - return $this; - } - - public function getType() - { - return $this->type; - } - - public function setType($type) - { - $this->type = $type; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) + public function __construct() { - $this->name = $name; - return $this; - } - - public function getShortName() - { - return $this->shortName; - } - - public function setShortName($shortName) - { - $this->shortName = $shortName; - return $this; - } - - public function getUnitNameSingular() - { - return $this->unitNameSingular; - } - - public function setUnitNameSingular($unitNameSingular) - { - $this->unitNameSingular = $unitNameSingular; - return $this; + $this->setAllowChangePerformanceType(true); + $this->setAllowChangeUnitsPrice(false); + $this->setAllowChangeVatCode(false); + $this->setAllowDecimalQuantity(false); + $this->setAllowDiscountorPremium(true); + $this->setPercentage(false); + $this->setType(\PhpTwinfield\Enums\ArticleType::NORMAL()); } - public function getUnitNamePlural() - { - return $this->unitNamePlural; - } + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); - public function setUnitNamePlural($unitNamePlural) - { - $this->unitNamePlural = $unitNamePlural; - return $this; - } - - public function getAllowChangeVatCode(): bool - { - return $this->allowChangeVatCode; - } - - public function setAllowChangeVatCode(bool $allowChangeVatCode): self - { - $this->allowChangeVatCode = $allowChangeVatCode; - return $this; - } - - public function getPerformanceType() - { - return $this->performanceType; - } - - public function setPerformanceType($performanceType) - { - $this->performanceType = $performanceType; - return $this; - } - - public function getAllowChangePerformanceType() - { - return $this->allowChangePerformanceType; - } - - public function setAllowChangePerformanceType($allowChangePerformanceType) - { - $this->allowChangePerformanceType - = $allowChangePerformanceType; - return $this; - } - - public function getPercentage() - { - return $this->percentage; - } - - public function setPercentage($percentage) - { - $this->percentage = $percentage; - return $this; - } - - public function getAllowDiscountorPremium(): bool - { - return $this->allowDiscountorPremium; - } - - public function setAllowDiscountorPremium(bool $allowDiscountorPremium): self - { - $this->allowDiscountorPremium = $allowDiscountorPremium; - return $this; - } - - public function getAllowChangeUnitsPrice(): bool - { - return $this->allowChangeUnitsPrice; - } - - public function setAllowChangeUnitsPrice(bool $allowChangeUnitsPrice): self - { - $this->allowChangeUnitsPrice = $allowChangeUnitsPrice; - return $this; - } - - public function getAllowDecimalQuantity(): bool - { - return $this->allowDecimalQuantity; - } - - public function setAllowDecimalQuantity(bool $allowDecimalQuantity): self - { - $this->allowDecimalQuantity = $allowDecimalQuantity; - return $this; + return $instance; } public function getLines() @@ -192,7 +69,7 @@ public function getLines() public function addLine(ArticleLine $line) { - $this->lines[$line->getID()] = $line; + $this->lines[] = $line; return $this; } @@ -205,4 +82,22 @@ public function removeLine($index) return false; } } + + public function removeLineByID($id) + { + $found = false; + + foreach ($this->lines as $index => $line) { + if ($id == $line->getID()) { + unset($this->lines[$index]); + $found = true; + } + } + + if ($found) { + return true; + } + + return false; + } } diff --git a/src/ArticleLine.php b/src/ArticleLine.php index b8ec6d2f..fd166dc7 100644 --- a/src/ArticleLine.php +++ b/src/ArticleLine.php @@ -2,135 +2,42 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\FreeText3Field; +use PhpTwinfield\Fields\IDField; +use PhpTwinfield\Fields\InUseField; +use PhpTwinfield\Fields\Invoice\Article\FreeText1Field; +use PhpTwinfield\Fields\Invoice\Article\FreeText2Field; +use PhpTwinfield\Fields\Invoice\Article\SubCodeField; +use PhpTwinfield\Fields\Invoice\UnitsField; +use PhpTwinfield\Fields\Invoice\UnitsPriceExclField; +use PhpTwinfield\Fields\Invoice\UnitsPriceIncField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; + /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Articles * @todo Add documentation and typehints to all properties. */ -class ArticleLine +class ArticleLine extends BaseObject { - private $ID; - private $status; - private $inUse; - private $unitsPriceExcl; - private $unitsPriceInc; - private $units; - private $name; - private $shortName; - private $subCode; - private $freeText1; - - public function __construct() - { - $this->ID = uniqid(); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - public function getStatus() - { - return $this->status; - } - - public function setStatus($status) - { - $this->status = $status; - return $this; - } - - public function getInUse() - { - return $this->inUse; - } - - public function setInUse($inUse) - { - $this->inUse = $inUse; - return $this; - } - - public function getUnitsPriceInc() - { - return $this->unitsPriceInc; - } - - public function setUnitsPriceInc($unitsPriceInc) - { - $this->unitsPriceInc = $unitsPriceInc; - return $this; - } - - public function getUnitsPriceExcl () - { - return $this->unitsPriceExcl; - } - - public function setUnitsPriceExcl($unitsPriceExcl) - { - $this->unitsPriceExcl = $unitsPriceExcl; - return $this; - } - - public function getUnits() - { - return $this->units; - } - - public function setUnits($units) - { - $this->units = $units; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - return $this; - } - - public function getShortName() - { - return $this->shortName; - } - - public function setShortName($shortName) - { - $this->shortName = $shortName; - return $this; - } - - public function getSubCode() - { - return $this->subCode; - } - - public function setSubCode($subCode) - { - $this->subCode = $subCode; - return $this; - } - - public function getFreeText1() - { - return $this->freeText1; - } - - public function setFreeText1($freeText1) - { - $this->freeText1 = $freeText1; - return $this; + use FreeText1Field; + use FreeText2Field; + use FreeText3Field; + use IDField; + use InUseField; + use NameField; + use ShortNameField; + use StatusField; + use SubCodeField; + use UnitsField; + use UnitsPriceExclField; + use UnitsPriceIncField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setSubCode($code); + + return $instance; } } diff --git a/src/AssetMethod.php b/src/AssetMethod.php new file mode 100644 index 00000000..01870a6d --- /dev/null +++ b/src/AssetMethod.php @@ -0,0 +1,119 @@ +setBalanceAccounts(new AssetMethodBalanceAccounts); + $this->setProfitLossAccounts(new AssetMethodProfitLossAccounts); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getBalanceAccounts(): AssetMethodBalanceAccounts + { + return $this->balanceAccounts; + } + + public function setBalanceAccounts(AssetMethodBalanceAccounts $balanceAccounts) + { + $this->balanceAccounts = $balanceAccounts; + return $this; + } + + public function getProfitLossAccounts(): AssetMethodProfitLossAccounts + { + return $this->profitLossAccounts; + } + + public function setProfitLossAccounts(AssetMethodProfitLossAccounts $profitLossAccounts) + { + $this->profitLossAccounts = $profitLossAccounts; + return $this; + } + + public function getFreeTexts() + { + return $this->freeTexts; + } + + public function addFreeText(AssetMethodFreeText $freeText) + { + $this->freeTexts[] = $freeText; + return $this; + } + + public function removeFreeText($index) + { + if (array_key_exists($index, $this->freeTexts)) { + unset($this->freeTexts[$index]); + return true; + } else { + return false; + } + } + + public function removeFreeTextByID($id) + { + $found = false; + + foreach ($this->freeTexts as $index => $freeText) { + if ($id == $freeText->getID()) { + unset($this->freeTexts[$index]); + $found = true; + } + } + + if ($found) { + return true; + } + + return false; + } +} diff --git a/src/AssetMethodBalanceAccounts.php b/src/AssetMethodBalanceAccounts.php new file mode 100644 index 00000000..4ab5dd50 --- /dev/null +++ b/src/AssetMethodBalanceAccounts.php @@ -0,0 +1,26 @@ +currency = new Currency("EUR"); - $this->startvalue = new Money(0, $this->getCurrency()); + $this->startValue = new \Money\Money(0, new \Money\Currency('XXX')); } + /* + * @return string + */ public function getLineClassName(): string { - return Transactions\BankTransactionLine\Base::class; + return BankTransactionLine::class; } - /** - * The bank transaction origin. - * Read-only attribute. + /* + * Set the currency. Can only be done when the start value is still 0. * - * @return mixed + * @param Currency $currency + * @return $this */ - public function getOrigin() + public function setCurrency(?Currency $currency): parent { - return $this->origin; - } + $this->traitSetCurrency($currency); - public function getInputDate(): \DateTimeInterface - { - return $this->inputDate; + return $this; } - public function addLine(Transactions\BankTransactionLine\Base $line): void + /* + * @param $line + * @return $this + */ + public function addLine($line) { - Assert::notEmpty($this->startvalue); - - /* - * Max is 500 lines. - */ - Assert::lessThan($this->getLineCount(), 500); - - /* - * Calls the addLine() method on the LinesField trait. Uses an alias in the `use` statement at top of this - * class, because parent::addLine() doesn't work for traits. - */ - $this->traitAddLine($line); + parent::addLine($line); + /* @var BankTransactionLine $line */ if (!$line->getLineType()->equals(LineType::TOTAL())) { /* - * Don't add total lines to the closevalue, they are summaries of the details and vat lines. - * - * @link https://github.com/php-twinfield/twinfield/issues/39 + * Don't add total lines to the close value, they are summaries of the details and vat lines. */ if ($line->getDebitCredit()->equals(DebitCredit::CREDIT())) { - $this->closevalue = $this->getClosevalue()->add($line->getValue()); + $this->closeValue = $this->getCloseValue()->add($line->getValue()); } else { - $this->closevalue = $this->getClosevalue()->subtract($line->getValue()); + $this->closeValue = $this->getCloseValue()->subtract($line->getValue()); } } + + return $this; } } diff --git a/src/BankTransactionLine.php b/src/BankTransactionLine.php new file mode 100644 index 00000000..d0e387fa --- /dev/null +++ b/src/BankTransactionLine.php @@ -0,0 +1,332 @@ +transaction, 'Attempting to set a transaction while the transaction is already set.'); + Assert::isInstanceOf($object, BankTransaction::class); + $this->transaction = $object; + } + + /* + * References the transaction this line belongs too. + * + * @return BankTransaction + */ + public function getTransaction(): BankTransaction + { + return $this->transaction; + } + + /* + * Only if line type is detail. The amount still owed in base currency. Read-only attribute. + * + * @param Money|null $baseValueOpen + * @return $this + * @throws Exception + */ + public function setBaseValueOpen(?Money $baseValueOpen): parent + { + if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('basevalueopen', $this); + } + + return parent::setBaseValueOpen($baseValueOpen); + } + + /* + * Only if line type is detail. The line date. Only allowed if the line date in the bank book is set to Allowed or Mandatory. + * + * @param \DateTimeInterface|null $currencyDate + * @return $this + * @throws Exception + */ + public function setCurrencyDate(?\DateTimeInterface $currencyDate): self + { + if ($currencyDate !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('currencydate', $this); + } + + $this->currencyDate = $currencyDate; + + return $this; + } + + /* + * If line type = total empty. + * + * If line type = detail the customer or supplier or the cost center or empty. + * + * If line type = vat empty. + * + * @param $dim2 + * @return $this + * @throws Exception + */ + public function setDim2($dim2): parent + { + if ($dim2 !== null && ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidDimensionForLineType(2, $this); + } + + return parent::setDim2($dim2); + } + + /* + * If line type = total empty. + * + * If line type = detail the project or asset or empty. + * + * If line type = vat empty. + * + * @param $dim3 + * @return $this + * @throws Exception + */ + public function setDim3($dim3): parent + { + if ($dim3 !== null && ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidDimensionForLineType(3, $this); + } + + return parent::setDim3($dim3); + } + + /* + * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction + * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. + * + * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing + * transaction type is a Purchase Transaction. + * + * @return bool + */ + protected function isIncomingTransactionType(): bool + { + return true; + } + + /* + * Only if line type is detail. The level of the matchable dimension. Read-only attribute. + * + * @param int|null $matchLevel + * @return $this + * @throws Exception + */ + public function setMatchLevel(?int $matchLevel): parent + { + if ($matchLevel !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('matchlevel', $this); + } + + return parent::setMatchLevel($matchLevel); + } + + /* + * Payment status of the transaction. If line type total or vat always notmatchable. Read-only attribute. + * + * @param MatchStatus|null $matchStatus + * @return $this + * @throws Exception + */ + public function setMatchStatus(?MatchStatus $matchStatus): parent + { + if ($matchStatus !== null && in_array($this->getLineType(), [LineType::TOTAL(), LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { + throw Exception::invalidMatchStatusForLineType($matchStatus, $this); + } + + return parent::setMatchStatus($matchStatus); + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. + * + * @param PerformanceType|null $performanceType + * @return $this + * @throws Exception + */ + public function setPerformanceType(?PerformanceType $performanceType): self + { + if ($performanceType !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancetype', $this); + } + + $this->performanceType = $performanceType; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. + * + * @param Country|null $performanceCountry + * @return $this + * @throws Exception + */ + public function setPerformanceCountry(?Country $performanceCountry): self + { + if ($performanceCountry !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancecountry', $this); + } + + $this->performanceCountry = $performanceCountry; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + * + * @param string|null $performanceVatNumber + * @return $this + * @throws Exception + */ + public function setPerformanceVatNumber(?string $performanceVatNumber): self + { + if ($performanceVatNumber !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancevatnumber', $this); + } + + $this->performanceVatNumber = $performanceVatNumber; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + * + * @param \DateTimeInterface|null $performanceDate + * @return $this + * @throws Exception + */ + public function setPerformanceDate(?\DateTimeInterface $performanceDate): self + { + if ($performanceDate !== null && (!$this->getPerformanceType()->equals(PerformanceType::SERVICES()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidFieldForLineType('performancedate', $this); + } + + $this->performanceDate = $performanceDate; + + return $this; + } + + /* + * Relation of the transaction. Only if line type is detail. Read-only attribute. + * + * @param int|null $relation + * @return $this + * @throws Exception + */ + public function setRelation(?int $relation): parent + { + if ($relation !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('relation', $this); + } + + return parent::setRelation($relation); + } + + /* + * Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + * + * @param Money|null $repValueOpen + * @return $this + * @throws Exception + */ + public function setRepValueOpen(?Money $repValueOpen): parent + { + if ($repValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('repvalueopen', $this); + } + + return parent::setRepValueOpen($repValueOpen); + } + + /* + * Only if line type is total. The total VAT amount in the currency of the bank transaction + * + * @param Money|null $vatTotal + * @return $this + * @throws Exception + */ + public function setVatTotal(?Money $vatTotal): self + { + if ($vatTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vattotal', $this); + } + + $this->vatTotal = $vatTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in base currency. + * + * @param Money|null $vatBaseTotal + * @return $this + * @throws Exception + */ + public function setVatBaseTotal(?Money $vatBaseTotal): self + { + if ($vatBaseTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatbasetotal', $this); + } + + $this->vatBaseTotal = $vatBaseTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in reporting currency. + * + * @param Money|null $vatRepTotal + * @return $this + * @throws Exception + */ + public function setVatRepTotal(?Money $vatRepTotal): self + { + if ($vatRepTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatreptotal', $this); + } + + $this->vatRepTotal = $vatRepTotal; + + return $this; + } +} diff --git a/src/BaseObject.php b/src/BaseObject.php index d7db7e72..1123a602 100644 --- a/src/BaseObject.php +++ b/src/BaseObject.php @@ -9,7 +9,7 @@ * * @author Jop peters */ -abstract class BaseObject +abstract class BaseObject implements HasMessageInterface { private $result; private $messages; @@ -31,12 +31,11 @@ public function getMessages() return $this->messages; } - public function addMessage(Message $message) + public function addMessage(Message $message): void { $this->messages[] = $message; - - return $this; } + public function setMessages($messages) { $this->messages = $messages; @@ -46,6 +45,10 @@ public function setMessages($messages) public function hasMessages() { + if (empty($this->messages)) { + return false; + } + return count($this->messages) > 0; } } diff --git a/src/BaseTransaction.php b/src/BaseTransaction.php index bbdc4dc2..541af34b 100644 --- a/src/BaseTransaction.php +++ b/src/BaseTransaction.php @@ -2,78 +2,49 @@ namespace PhpTwinfield; -use Money\Currency; -use PhpTwinfield\Transactions\Transaction; -use PhpTwinfield\Transactions\TransactionFields\AutoBalanceVatField; -use PhpTwinfield\Transactions\TransactionFields\CodeNumberOfficeFields; -use PhpTwinfield\Transactions\TransactionFields\DestinyField; -use PhpTwinfield\Transactions\TransactionFields\FreeTextFields; -use PhpTwinfield\Transactions\TransactionFields\LinesField; -use PhpTwinfield\Transactions\TransactionFields\RaiseWarningField; -use PhpTwinfield\Transactions\TransactionLineFields\DateField; -use PhpTwinfield\Transactions\TransactionLineFields\PeriodField; - -/** - * @todo $modificationDate The date/time on which the sales transaction was modified the last time. Read-only attribute. - * @todo $user The user who created the sales transaction. Read-only attribute. - * @todo $inputDate The date/time on which the transaction was created. Read-only attribute. - */ -abstract class BaseTransaction extends BaseObject implements Transaction +use PhpTwinfield\BookingReference; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\CurrencyField; +use PhpTwinfield\Fields\DateField; +use PhpTwinfield\Fields\FreeText1Field; +use PhpTwinfield\Fields\FreeText2Field; +use PhpTwinfield\Fields\FreeText3Field; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\PeriodField; +use PhpTwinfield\Fields\Transaction\AutoBalanceVatField; +use PhpTwinfield\Fields\Transaction\DateRaiseWarningField; +use PhpTwinfield\Fields\Transaction\DestinyField; +use PhpTwinfield\Fields\Transaction\InputDateField; +use PhpTwinfield\Fields\Transaction\LinesField; +use PhpTwinfield\Fields\Transaction\ModificationDateField; +use PhpTwinfield\Fields\Transaction\NumberField; +use PhpTwinfield\Fields\Transaction\OriginField; +use PhpTwinfield\Fields\Transaction\RaiseWarningField; +use PhpTwinfield\Fields\UserField; +use PhpTwinfield\MatchReferenceInterface; + +abstract class BaseTransaction extends BaseObject implements HasCodeInterface { - use DestinyField; use AutoBalanceVatField; - use CodeNumberOfficeFields; - use PeriodField; - use FreeTextFields; + use CodeField; + use CurrencyField; use DateField; - use RaiseWarningField; + use DateRaiseWarningField; + use DestinyField; + use FreeText1Field; + use FreeText2Field; + use FreeText3Field; + use InputDateField; use LinesField; + use ModificationDateField; + use NumberField; + use OfficeField; + use OriginField; + use PeriodField; + use RaiseWarningField; - /** - * @var Currency|null The currency. - */ - private $currency; - - /** - * @var string|null The sales transaction origin. Read-only attribute. - */ - private $origin; - - /** - * @return Currency|null - */ - public function getCurrency(): ?Currency - { - return $this->currency; - } - - /** - * @param Currency|null $currency - * @return $this - */ - public function setCurrency(?Currency $currency): BaseTransaction - { - $this->currency = $currency; - - return $this; - } - - /** - * @return string|null - */ - public function getOrigin(): ?string - { - return $this->origin; - } - - /** - * @param string|null $origin - * @return $this - */ - public function setOrigin(?string $origin): BaseTransaction + public function getBookingReference(): BookingReference { - $this->origin = $origin; - - return $this; + return new BookingReference($this->office, $this->code, $this->number); } } diff --git a/src/BaseTransactionLine.php b/src/BaseTransactionLine.php index 85c6092a..f8dbcb6f 100644 --- a/src/BaseTransactionLine.php +++ b/src/BaseTransactionLine.php @@ -4,384 +4,198 @@ use Money\Money; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionLine; -use PhpTwinfield\Transactions\TransactionLineFields\CommentField; -use PhpTwinfield\Transactions\TransactionLineFields\FreeCharField; -use PhpTwinfield\Transactions\TransactionLineFields\ThreeDimFields; -use PhpTwinfield\Transactions\TransactionLineFields\ValueFields; -use PhpTwinfield\Transactions\TransactionLineFields\VatTurnoverFields; - -/** - * @todo $relation Only if line type is total (or detail for Journal and Cash transactions). Read-only attribute. - * @todo $repValueOpen Meaning differs per transaction type. Read-only attribute. - * @todo $vatBaseValue Only if line type is detail. VAT amount in base currency. - * @todo $vatRepValue Only if line type is detail. VAT amount in reporting currency. - * @todo $destOffice Office code. Used for inter company transactions. - * @todo $comment Comment set on the transaction line. - * @todo $matches Contains matching information. Read-only attribute. - * - * @link https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/BankTransactions - */ -abstract class BaseTransactionLine implements TransactionLine +use PhpTwinfield\Enums\MatchStatus; +use PhpTwinfield\Fields\CommentField; +use PhpTwinfield\Fields\DescriptionField; +use PhpTwinfield\Fields\Dim2Field; +use PhpTwinfield\Fields\Dim3Field; +use PhpTwinfield\Fields\IDField; +use PhpTwinfield\Fields\LineTypeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaseValueField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaseValueOpenField; +use PhpTwinfield\Fields\Transaction\TransactionLine\DestOfficeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\Dim1Field; +use PhpTwinfield\Fields\Transaction\TransactionLine\FreeCharField; +use PhpTwinfield\Fields\Transaction\TransactionLine\MatchLevelField; +use PhpTwinfield\Fields\Transaction\TransactionLine\MatchStatusField; +use PhpTwinfield\Fields\Transaction\TransactionLine\RateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\RelationField; +use PhpTwinfield\Fields\Transaction\TransactionLine\RepRateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\RepValueField; +use PhpTwinfield\Fields\Transaction\TransactionLine\RepValueOpenField; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueFields; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseTurnoverField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseValueField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepTurnoverField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepValueField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatTurnoverField; +use PhpTwinfield\Fields\VatCodeField; +use PhpTwinfield\Fields\VatValueField; + +abstract class BaseTransactionLine extends BaseObject implements TransactionLineInterface { - use ValueFields; - use ThreeDimFields; - use VatTurnoverFields; + use BaseValueField; + use BaseValueOpenField; use CommentField; + use DescriptionField; + use DestOfficeField; + use Dim1Field; + use Dim2Field; + use Dim3Field; use FreeCharField; - - public const MATCHSTATUS_AVAILABLE = 'available'; - public const MATCHSTATUS_MATCHED = 'matched'; - public const MATCHSTATUS_PROPOSED = 'proposed'; - public const MATCHSTATUS_NOTMATCHABLE = 'notmatchable'; - - // Used in PerformanceFields trait. - const PERFORMANCETYPE_SERVICES = 'services'; - const PERFORMANCETYPE_GOODS = 'goods'; - - /** - * @var LineType - */ - protected $lineType; - - /** - * @var int|null The line ID. - */ - protected $id; - - /** - * @var Money|null Amount in the base currency. - * @todo This field is currently read-only in this library. - */ - protected $baseValue; - - /** - * @var int|null - */ - private $baseline; - - /** - * @var float|null The exchange rate used for the calculation of the base amount. - * @todo This field is currently read-only in this library. - */ - protected $rate; - - /** - * @var Money|null Amount in the reporting currency. - * @todo This field is currently read-only in this library. - */ - protected $repValue; - - /** - * @var float|null The exchange rate used for the calculation of the reporting amount. - * @todo This field is currently read-only in this library. - */ - protected $repRate; - - /** - * @var string|null Description of the transaction line. Max length is 40 characters. - */ - protected $description; - - /** - * @var string|null Payment status of the transaction. One of the self::MATCHSTATUS_* constants. Read-only - * attribute. There are some restrictions for possible values depending on the sub class. See - * explanation in the sub classes. - */ - protected $matchStatus; - - /** - * @var int|null The level of the matchable dimension. Read-only attribute. Only available for some line types, - * depending on the sub class. See the explanation in sub classes. - */ - protected $matchLevel; - - /** - * @var Money|null Meaning differs per transaction type. Read-only attribute. See explanatio in the sub classes. - */ - protected $baseValueOpen; - - /** - * @var string|null Only if line type is detail or vat. VAT code. - */ - protected $vatCode; - - /** - * @var Money|null Only if line type is detail. VAT amount in the currency of the transaction. - */ - protected $vatValue; - - public function getLineType(): LineType - { - return $this->lineType; - } - - /** - * @param LineType $lineType - * @return $this + use IDField; + use LineTypeField; + use MatchLevelField; + use MatchStatusField; + use RateField; + use RelationField; + use RepRateField; + use RepValueField; + use RepValueOpenField; + use ValueFields; + use VatBaseTurnoverField; + use VatBaseValueField; + use VatCodeField; + use VatRepTurnoverField; + use VatRepValueField; + use VatTurnoverField; + use VatValueField; + + /* + * This will get you a unique reference to the object in Twinfield. + * + * With this reference, you can perform matching. + * + * @return MatchReferenceInterface */ - public function setLineType(LineType $lineType): BaseTransactionLine + public function getReference(): MatchReferenceInterface { - $this->lineType = $lineType; - - return $this; - } + /* @var BankTransaction|CashTransaction|JournalTransaction|PurchaseTransaction|SalesTransaction $transaction */ + $transaction = $this->getTransaction(); - /** - * @return int|null - */ - public function getId(): ?int - { - return $this->id; + return new MatchReference( + $transaction->getOffice(), + $transaction->getCode(), + $transaction->getNumber(), + $this->getId() + ); } - /** - * @param int|null $id + /* + * Only if line type is vat. Amount on which VAT was calculated in base currency. + * + * @param Money|null $vatBaseTurnover * @return $this + * @throws Exception */ - public function setId(?int $id): BaseTransactionLine - { - $this->id = $id; - - return $this; - } - - /** - * @return Money|null - */ - public function getBaseValue(): ?Money + public function setVatBaseTurnover(?Money $vatBaseTurnover): self { - return $this->baseValue; - } + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType('vatbaseturnover', $this); + } - /** - * @param Money|null $baseValue - * @return $this - */ - public function setBaseValue(?Money $baseValue): BaseTransactionLine - { - $this->baseValue = $baseValue; + $this->vatBaseTurnover = $vatBaseTurnover; return $this; } - /** - * @return float|null - */ - public function getRate(): ?float - { - return $this->rate; - } - - /** - * @param float|null $rate + /* + * @param Money|null $vatBaseValue * @return $this + * @throws Exception */ - public function setRate(?float $rate): BaseTransactionLine - { - $this->rate = $rate; - - return $this; - } - - /** - * @return Money|null - */ - public function getRepValue(): ?Money + public function setVatBaseValue(?Money $vatBaseValue): self { - return $this->repValue; - } + if ($vatBaseValue !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('vatbasevalue', $this); + } - /** - * @param Money|null $repValue - * @return $this - */ - public function setRepValue(?Money $repValue): BaseTransactionLine - { - $this->repValue = $repValue; + $this->vatBaseValue = $vatBaseValue; return $this; } - /** - * @return float|null - */ - public function getRepRate(): ?float - { - return $this->repRate; - } - - /** - * @param float|null $repRate + /* + * @param VatCode|null $vatCode * @return $this + * @throws Exception */ - public function setRepRate(?float $repRate): BaseTransactionLine - { - $this->repRate = $repRate; - - return $this; - } - - /** - * @return string|null - */ - public function getDescription(): ?string + public function setVatCode(?VatCode $vatCode): self { - return $this->description; - } + if ($vatCode !== null && !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()])) { + throw Exception::invalidFieldForLineType('vatcode', $this); + } - /** - * @param string|null $description - * @return $this - */ - public function setDescription(?string $description): BaseTransactionLine - { - $this->description = $description; + $this->vatCode = $vatCode; return $this; } - /** - * @return string|null - */ - public function getMatchStatus(): ?string - { - return $this->matchStatus; - } - - /** - * @param string|null $matchStatus + /* + * Only if line type is vat. Amount on which VAT was calculated in reporting currency. + * + * @param Money|null $vatRepTurnover * @return $this + * @throws Exception */ - public function setMatchStatus(?string $matchStatus): BaseTransactionLine - { - $this->matchStatus = $matchStatus; - - return $this; - } - - /** - * @return int|null - */ - public function getMatchLevel(): ?int + public function setVatRepTurnover(?Money $vatRepTurnover): self { - return $this->matchLevel; - } + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType('vatrepturnover', $this); + } - /** - * @param int|null $matchLevel - * @return $this - */ - public function setMatchLevel(?int $matchLevel): BaseTransactionLine - { - $this->matchLevel = $matchLevel; + $this->vatRepTurnover = $vatRepTurnover; return $this; } - /** - * @return Money|null - */ - public function getBaseValueOpen(): ?Money - { - return $this->baseValueOpen; - } - - /** - * @param Money|null $baseValueOpen + /* + * @param Money|null $vatRepValue * @return $this + * @throws Exception */ - public function setBaseValueOpen(?Money $baseValueOpen): BaseTransactionLine + public function setVatRepValue(?Money $vatRepValue): self { - $this->baseValueOpen = $baseValueOpen; + if ($vatRepValue !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('vatrepvalue', $this); + } - return $this; - } + $this->vatRepValue = $vatRepValue; - /** - * @return string|null - */ - public function getVatCode(): ?string - { - return $this->vatCode; + return $this; } - /** - * @param string|null $vatCode + /* + * Only if line type is vat. Amount on which VAT was calculated in the currency of the sales transaction. + * + * @param Money|null $vatTurnover * @return $this * @throws Exception */ - public function setVatCode(?string $vatCode): BaseTransactionLine + public function setVatTurnover(?Money $vatTurnover): self { - if ($vatCode !== null && !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()])) { - throw Exception::invalidFieldForLineType('vatCode', $this); + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType('vatturnover', $this); } - $this->vatCode = $vatCode; + $this->vatTurnover = $vatTurnover; return $this; } - /** - * @return Money|null - */ - public function getVatValue(): ?Money - { - return !empty($this->vatValue) ? $this->vatValue->absolute() : null; - } - - /** + /* * @param Money|null $vatValue * @return $this * @throws Exception */ - public function setVatValue(?Money $vatValue): BaseTransactionLine + public function setVatValue(?Money $vatValue): self { if ($vatValue !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('vatValue', $this); + throw Exception::invalidFieldForLineType('vatvalue', $this); } $this->vatValue = $vatValue; return $this; } - - /** - * @return int|null - */ - public function getBaseline(): ?int - { - return $this->baseline; - } - - /** - * @param int|null $baseline - * @return $this - */ - public function setBaseline(?int $baseline) - { - $this->baseline = $baseline; - - return $this; - } - - /** - * This will get you a unique reference to the object in Twinfield. - * - * With this reference, you can perform matching. - * - * @return MatchReferenceInterface - */ - public function getReference(): MatchReferenceInterface - { - /** @var JournalTransaction|PurchaseTransaction|SalesTransaction $transaction */ - $transaction = $this->getTransaction(); - - return new MatchReference( - $transaction->getOffice(), - $transaction->getCode(), - $transaction->getNumber(), - $this->getId() - ); - } } diff --git a/src/BookingReference.php b/src/BookingReference.php index 4a37bcfa..fd6c910b 100644 --- a/src/BookingReference.php +++ b/src/BookingReference.php @@ -57,4 +57,4 @@ public function getNumber(): int { return $this->number; } -} \ No newline at end of file +} diff --git a/src/BookingReferenceInterface.php b/src/BookingReferenceInterface.php index 0a8cb7df..26a54c75 100644 --- a/src/BookingReferenceInterface.php +++ b/src/BookingReferenceInterface.php @@ -27,4 +27,4 @@ public function getCode(): string; * References the transaction. */ public function getNumber(): int; -} \ No newline at end of file +} diff --git a/src/BrowseColumn.php b/src/BrowseColumn.php index e8ed6a8a..0b757e3e 100644 --- a/src/BrowseColumn.php +++ b/src/BrowseColumn.php @@ -4,7 +4,7 @@ use PhpTwinfield\Enums\BrowseColumnOperator; -class BrowseColumn +class BrowseColumn extends BaseObject { /** @var int */ private $id; diff --git a/src/BrowseData.php b/src/BrowseData.php index 9329ba1d..e11364af 100644 --- a/src/BrowseData.php +++ b/src/BrowseData.php @@ -2,7 +2,7 @@ namespace PhpTwinfield; -class BrowseData +class BrowseData extends BaseObject { /** @var int */ private $first; diff --git a/src/BrowseDataCell.php b/src/BrowseDataCell.php index 91cdb9d0..f28baff5 100644 --- a/src/BrowseDataCell.php +++ b/src/BrowseDataCell.php @@ -2,7 +2,7 @@ namespace PhpTwinfield; -class BrowseDataCell +class BrowseDataCell extends BaseObject { /** @var string */ private $field; diff --git a/src/BrowseDataHeader.php b/src/BrowseDataHeader.php index 48472db4..2444280f 100644 --- a/src/BrowseDataHeader.php +++ b/src/BrowseDataHeader.php @@ -2,10 +2,11 @@ namespace PhpTwinfield; -class BrowseDataHeader +use PhpTwinfield\Fields\CodeField; + +class BrowseDataHeader extends BaseObject implements HasCodeInterface { - /** @var string */ - private $code; + use CodeField; /** @var string */ private $label; @@ -16,24 +17,6 @@ class BrowseDataHeader /** @var string */ private $type; - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @param string $code - * @return BrowseDataHeader - */ - public function setCode(string $code): BrowseDataHeader - { - $this->code = $code; - return $this; - } - /** * @return string */ diff --git a/src/BrowseDataRow.php b/src/BrowseDataRow.php index 4ae7f1b8..985218c4 100644 --- a/src/BrowseDataRow.php +++ b/src/BrowseDataRow.php @@ -2,13 +2,13 @@ namespace PhpTwinfield; -class BrowseDataRow -{ - /** @var Office */ - private $office; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\OfficeField; - /** @var string */ - private $code; +class BrowseDataRow extends BaseObject implements HasCodeInterface +{ + use CodeField; + use OfficeField; /** @var int */ private $number; @@ -27,42 +27,6 @@ public function __construct() $this->cells = []; } - /** - * @return Office - */ - public function getOffice(): Office - { - return $this->office; - } - - /** - * @param Office $office - * @return BrowseDataRow - */ - public function setOffice(Office $office): BrowseDataRow - { - $this->office = $office; - return $this; - } - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @param string $code - * @return BrowseDataRow - */ - public function setCode(string $code): BrowseDataRow - { - $this->code = $code; - return $this; - } - /** * @return int */ diff --git a/src/BrowseDefinition.php b/src/BrowseDefinition.php index e63d3fcc..9bb2b4b0 100644 --- a/src/BrowseDefinition.php +++ b/src/BrowseDefinition.php @@ -2,20 +2,17 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionFields\OfficeField; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\ShortNameField; -class BrowseDefinition +class BrowseDefinition extends BaseObject implements HasCodeInterface { + use CodeField; + use NameField; use OfficeField; - - /** @var string */ - private $code; - - /** @var string */ - private $name; - - /** @var string */ - private $shortName; + use ShortNameField; /** @var bool */ private $visible; @@ -31,60 +28,6 @@ public function __construct() $this->columns = []; } - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @param string $code - * @return BrowseDefinition - */ - public function setCode(string $code): BrowseDefinition - { - $this->code = $code; - return $this; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @param string $name - * @return BrowseDefinition - */ - public function setName(string $name): BrowseDefinition - { - $this->name = $name; - return $this; - } - - /** - * @return string - */ - public function getShortName(): string - { - return $this->shortName; - } - - /** - * @param string $shortName - * @return BrowseDefinition - */ - public function setShortName(string $shortName): BrowseDefinition - { - $this->shortName = $shortName; - return $this; - } - /** * @return bool */ @@ -122,13 +65,13 @@ public function addColumn(BrowseColumn $column) } /** - * @param $index + * @param $id * @return bool */ - public function removeColumn($index) + public function removeColumn($id) { - if (array_key_exists($index, $this->columns)) { - unset($this->columns[$index]); + if (array_key_exists($id, $this->columns)) { + unset($this->columns[$id]); return true; } else { return false; diff --git a/src/BrowseField.php b/src/BrowseField.php index 28322ce0..a8d9fdc9 100644 --- a/src/BrowseField.php +++ b/src/BrowseField.php @@ -2,10 +2,11 @@ namespace PhpTwinfield; -class BrowseField +use PhpTwinfield\Fields\CodeField; + +class BrowseField extends BaseObject implements HasCodeInterface { - /** @var string */ - private $code; + use CodeField; /** @var string */ private $dataType; @@ -27,24 +28,6 @@ public function __construct() $this->options = []; } - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @param string $code - * @return BrowseField - */ - public function setCode(string $code): BrowseField - { - $this->code = $code; - return $this; - } - /** * @return string */ diff --git a/src/BrowseFieldOption.php b/src/BrowseFieldOption.php index fee48fc4..a8466110 100644 --- a/src/BrowseFieldOption.php +++ b/src/BrowseFieldOption.php @@ -2,47 +2,11 @@ namespace PhpTwinfield; -class BrowseFieldOption -{ - /** @var string */ - private $code; - - /** @var string|null */ - private $name; - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\NameField; - /** - * @param string $code - * @return BrowseFieldOption - */ - public function setCode(string $code): BrowseFieldOption - { - $this->code = $code; - return $this; - } - - /** - * @return string - */ - public function getName(): ?string - { - return $this->name; - } - - /** - * @param string $name - * @return BrowseFieldOption - */ - public function setName(string $name): BrowseFieldOption - { - $this->name = $name; - return $this; - } +class BrowseFieldOption extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; } diff --git a/src/BrowseSortField.php b/src/BrowseSortField.php index 0f2c6d73..0a3036b9 100644 --- a/src/BrowseSortField.php +++ b/src/BrowseSortField.php @@ -3,11 +3,11 @@ namespace PhpTwinfield; use PhpTwinfield\Enums\Order; +use PhpTwinfield\Fields\CodeField; -class BrowseSortField +class BrowseSortField extends BaseObject implements HasCodeInterface { - /** @var string */ - private $code; + use CodeField; /** @var Order|null */ private $order; @@ -24,22 +24,6 @@ public function __construct(string $code, ?Order $order = null) $this->order = $order; } - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @param string $code - */ - public function setCode(string $code): void - { - $this->code = $code; - } - /** * @return null|Order */ diff --git a/src/CashBankBook.php b/src/CashBankBook.php new file mode 100644 index 00000000..287e0c80 --- /dev/null +++ b/src/CashBankBook.php @@ -0,0 +1,26 @@ + + */ +class CashBankBook extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/CashTransaction.php b/src/CashTransaction.php index 3ca394a7..d9f9b991 100644 --- a/src/CashTransaction.php +++ b/src/CashTransaction.php @@ -2,30 +2,29 @@ namespace PhpTwinfield; -use Money\Currency; -use Money\Money; +use PhpTwinfield\CashTransactionLine; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionFields\StartAndCloseValueFields; -use PhpTwinfield\Transactions\TransactionFields\StatementNumberField; -use PhpTwinfield\Transactions\TransactionLine; +use PhpTwinfield\Fields\Transaction\CloseAndStartValueFields; +use PhpTwinfield\Fields\Transaction\StatementNumberField; -/** +/* * @link https://c3.twinfield.com/webservices/documentation/#/ApiReference/Transactions/CashTransactions */ class CashTransaction extends BaseTransaction { - use StatementNumberField; - use StartAndCloseValueFields { + use CloseAndStartValueFields { setCurrency as protected traitSetCurrency; } + use StatementNumberField; + public function __construct() { - $this->startvalue = new Money(0, new Currency('EUR')); + $this->startValue = new \Money\Money(0, new \Money\Currency('XXX')); } - /** + /* * @return string */ public function getLineClassName(): string @@ -33,35 +32,36 @@ public function getLineClassName(): string return CashTransactionLine::class; } - /** + /* * Set the currency. Can only be done when the start value is still 0. * * @param Currency $currency * @return $this */ - public function setCurrency(?Currency $currency): BaseTransaction + public function setCurrency(?Currency $currency): parent { $this->traitSetCurrency($currency); + return $this; } - /** - * @param TransactionLine $line + /* + * @param $line * @return $this */ - public function addLine(TransactionLine $line) + public function addLine($line) { parent::addLine($line); - /** @var CashTransactionLine $line */ + /* @var CashTransactionLine $line */ if (!$line->getLineType()->equals(LineType::TOTAL())) { /* - * Don't add total lines to the closevalue, they are summaries of the details and vat lines. + * Don't add total lines to the close value, they are summaries of the details and vat lines. */ if ($line->getDebitCredit()->equals(DebitCredit::CREDIT())) { - $this->closevalue = $this->getClosevalue()->add($line->getValue()); + $this->closeValue = $this->getCloseValue()->add($line->getValue()); } else { - $this->closevalue = $this->getClosevalue()->subtract($line->getValue()); + $this->closeValue = $this->getCloseValue()->subtract($line->getValue()); } } diff --git a/src/CashTransactionLine.php b/src/CashTransactionLine.php index c6c69ce0..83245300 100644 --- a/src/CashTransactionLine.php +++ b/src/CashTransactionLine.php @@ -3,27 +3,36 @@ namespace PhpTwinfield; use Money\Money; -use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionFields\InvoiceNumberField; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; -use PhpTwinfield\Transactions\TransactionLineFields\VatTotalFields; +use PhpTwinfield\Enums\PerformanceType; +use PhpTwinfield\Enums\MatchStatus; +use PhpTwinfield\Fields\PerformanceDateField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\CurrencyDateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceCountryField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceVatNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatTotalField; use Webmozart\Assert\Assert; class CashTransactionLine extends BaseTransactionLine { - use VatTotalFields; - use PerformanceFields; - use InvoiceNumberField { - setInvoiceNumber as traitSetInvoiceNumber; - } + use CurrencyDateField; + use PerformanceCountryField; + use PerformanceDateField; + use PerformanceTypeField; + use PerformanceVatNumberField; + use VatBaseTotalField; + use VatRepTotalField; + use VatTotalField; - /** + /* * @var CashTransaction */ private $transaction; - /** + /* * @param CashTransaction $object */ public function setTransaction($object): void @@ -33,7 +42,7 @@ public function setTransaction($object): void $this->transaction = $object; } - /** + /* * References the transaction this line belongs too. * * @return CashTransaction @@ -43,222 +52,281 @@ public function getTransaction(): CashTransaction return $this->transaction; } - /** - * If line type = total the cash balance account. - * - * If line type = detail the customer or supplier balance account or profit and loss account. + /* + * Only if line type is detail. The amount still owed in base currency. Read-only attribute. * - * If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account - * will be taken as entered at the VAT code in Twinfield. + * @param Money|null $baseValueOpen + * @return $this + * @throws Exception + */ + public function setBaseValueOpen(?Money $baseValueOpen): parent + { + if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('basevalueopen', $this); + } + + return parent::setBaseValueOpen($baseValueOpen); + } + + /* + * Only if line type is detail. The line date. Only allowed if the line date in the bank book is set to Allowed or Mandatory. * - * @param string|null $dim1 + * @param \DateTimeInterface|null $currencyDate * @return $this + * @throws Exception */ - public function setDim1(?string $dim1): BaseTransactionLine + public function setCurrencyDate(?\DateTimeInterface $currencyDate): self { - return parent::setDim1($dim1); + if ($currencyDate !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('currencydate', $this); + } + + $this->currencyDate = $currencyDate; + + return $this; } - /** + /* * If line type = total empty. * * If line type = detail the customer or supplier or the cost center or empty. * * If line type = vat empty. * - * @param string|null $dim2 + * @param $dim2 * @return $this * @throws Exception */ - public function setDim2(?string $dim2): BaseTransactionLine + public function setDim2($dim2): parent { - if ($dim2 !== null && - ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { + if ($dim2 !== null && ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { throw Exception::invalidDimensionForLineType(2, $this); } return parent::setDim2($dim2); } - /** + /* * If line type = total empty. * * If line type = detail the project or asset or empty. * * If line type = vat empty. * - * @param string|null $dim3 + * @param $dim3 * @return $this * @throws Exception */ - public function setDim3(?string $dim3): BaseTransactionLine + public function setDim3($dim3): parent { - if ($dim3 !== null && - ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { + if ($dim3 !== null && ($this->getLineType()->equals(LineType::VAT()) || $this->getLineType()->equals(LineType::TOTAL()))) { throw Exception::invalidDimensionForLineType(3, $this); } return parent::setDim3($dim3); } - /** - * If line type = total, based on the sum of the individual cash transaction lines. - * - In case of a cash addition debit. - * - In case of a cash withdrawal credit. - * - * If line type = detail - * - In case money is received credit. - * - In case money is paid debit. + /* + * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction + * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. * - * If line type = vat, based on the sum of the vat amounts of the individual cash transaction lines. - * - In case of a cash addition credit. - * - In case of a cash withdrawal debit. + * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing + * transaction type is a Purchase Transaction. * - * @param DebitCredit::DEBIT() $debitCredit - * @return $this + * @return bool */ - public function setDebitCredit(DebitCredit $debitCredit): BaseTransactionLine + protected function isIncomingTransactionType(): bool { - return parent::setDebitCredit($debitCredit); + return true; } - /** - * If line type = total amount including VAT. - * - * If line type = detail amount without VAT. - * - * If line type = vat VAT amount. + /* + * Only if line type is detail. The level of the matchable dimension. Read-only attribute. * - * @param Money $value + * @param int|null $matchLevel * @return $this + * @throws Exception */ - public function setValue(Money $value): BaseTransactionLine + public function setMatchLevel(?int $matchLevel): parent { - return parent::setValue($value); + if ($matchLevel !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('matchlevel', $this); + } + + return parent::setMatchLevel($matchLevel); } - /** - * Payment status of the cash transaction. If line type total or vat always notmatchable. Read-only attribute. + /* + * Payment status of the transaction. If line type total or vat always notmatchable. Read-only attribute. * - * @param string|null $matchStatus + * @param MatchStatus|null $matchStatus * @return $this * @throws Exception */ - public function setMatchStatus(?string $matchStatus): BaseTransactionLine + public function setMatchStatus(?MatchStatus $matchStatus): parent { - if ( - $matchStatus !== null && - in_array($this->getLineType(), [LineType::TOTAL(), LineType::VAT()]) && - $matchStatus != self::MATCHSTATUS_NOTMATCHABLE - ) { + if ($matchStatus !== null && in_array($this->getLineType(), [LineType::TOTAL(), LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { throw Exception::invalidMatchStatusForLineType($matchStatus, $this); } return parent::setMatchStatus($matchStatus); } - /** - * Only if line type is detail. The level of the matchable dimension. Read-only attribute. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. * - * @param int|null $matchLevel + * @param PerformanceType|null $performanceType * @return $this * @throws Exception */ - public function setMatchLevel(?int $matchLevel): BaseTransactionLine + public function setPerformanceType(?PerformanceType $performanceType): self { - if ($matchLevel !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('matchLevel', $this); + if ($performanceType !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancetype', $this); } - return parent::setMatchLevel($matchLevel); + $this->performanceType = $performanceType; + + return $this; } - /** - * Only if line type is detail. The amount still owed in base currency. Read-only attribute. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. * - * @param Money|null $baseValueOpen + * @param Country|null $performanceCountry * @return $this * @throws Exception */ - public function setBaseValueOpen(?Money $baseValueOpen): BaseTransactionLine + public function setPerformanceCountry(?Country $performanceCountry): self { - if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('baseValueOpen', $this); + if ($performanceCountry !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancecountry', $this); } - return parent::setBaseValueOpen($baseValueOpen); + $this->performanceCountry = $performanceCountry; + + return $this; } - /** - * Only if line type is vat. Amount on which VAT was calculated in the currency of the sales transaction. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. * - * @param Money|null $vatTurnover + * @param string|null $performanceVatNumber * @return $this * @throws Exception */ - public function setVatTurnover(?Money $vatTurnover): BaseTransactionLine + public function setPerformanceVatNumber(?string $performanceVatNumber): self { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType('vatturnover', $this); + if ($performanceVatNumber !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancevatnumber', $this); } - return parent::setVatTurnOver($vatTurnover); + + $this->performanceVatNumber = $performanceVatNumber; + + return $this; } - /** - * Only if line type is vat. Amount on which VAT was calculated in base currency. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. * - * @param Money|null $vatBaseTurnover + * @param \DateTimeInterface|null $performanceDate * @return $this * @throws Exception */ - public function setVatBaseTurnover(?Money $vatBaseTurnover): BaseTransactionLine + public function setPerformanceDate(?\DateTimeInterface $performanceDate): self { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType('vatbaseturnover', $this); + if ($performanceDate !== null && (!$this->getPerformanceType()->equals(PerformanceType::SERVICES()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidFieldForLineType('performancedate', $this); } - return parent::setVatBaseTurnover($vatBaseTurnover); + + $this->performanceDate = $performanceDate; + + return $this; } - /** - * Only if line type is vat. Amount on which VAT was calculated in reporting currency. + /* + * Relation of the transaction. Only if line type is detail. Read-only attribute. * - * @param Money|null $vatRepTurnover + * @param int|null $relation * @return $this * @throws Exception */ - public function setVatRepTurnover(?Money $vatRepTurnover): BaseTransactionLine + public function setRelation(?int $relation): parent { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType('vatrepturnover', $this); + if ($relation !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('relation', $this); } - return parent::setVatRepTurnover($vatRepTurnover); + + return parent::setRelation($relation); } - /** - * @param string|null $invoiceNumber + /* + * Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + * + * @param Money|null $repValueOpen * @return $this * @throws Exception */ - public function setInvoiceNumber(?string $invoiceNumber) + public function setRepValueOpen(?Money $repValueOpen): parent { - if (!$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('invoicenumber', $this); + if ($repValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('repvalueopen', $this); } - return $this->traitSetInvoiceNumber($invoiceNumber); + return parent::setRepValueOpen($repValueOpen); } - /** - * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction - * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. + /* + * Only if line type is total. The total VAT amount in the currency of the cash transaction * - * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing - * transaction type is a Purchase Transaction. + * @param Money|null $vatTotal + * @return $this + * @throws Exception + */ + public function setVatTotal(?Money $vatTotal): self + { + if ($vatTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vattotal', $this); + } + + $this->vatTotal = $vatTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in base currency. * - * @return bool + * @param Money|null $vatBaseTotal + * @return $this + * @throws Exception */ - protected function isIncomingTransactionType(): bool + public function setVatBaseTotal(?Money $vatBaseTotal): self { - return true; + if ($vatBaseTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatbasetotal', $this); + } + + $this->vatBaseTotal = $vatBaseTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in reporting currency. + * + * @param Money|null $vatRepTotal + * @return $this + * @throws Exception + */ + public function setVatRepTotal(?Money $vatRepTotal): self + { + if ($vatRepTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatreptotal', $this); + } + + $this->vatRepTotal = $vatRepTotal; + + return $this; } } diff --git a/src/CostCenter.php b/src/CostCenter.php new file mode 100644 index 00000000..7cf6017d --- /dev/null +++ b/src/CostCenter.php @@ -0,0 +1,45 @@ + + */ +class CostCenter extends BaseObject implements HasCodeInterface +{ + use BehaviourField; + use CodeField; + use InUseField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + + public function __construct() + { + $this->setType(\PhpTwinfield\DimensionType::fromCode('KPL')); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/Country.php b/src/Country.php new file mode 100644 index 00000000..4fd9bbe9 --- /dev/null +++ b/src/Country.php @@ -0,0 +1,26 @@ + + */ +class Country extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/Currency.php b/src/Currency.php new file mode 100644 index 00000000..9538eb8c --- /dev/null +++ b/src/Currency.php @@ -0,0 +1,52 @@ +setCode($code); + + return $instance; + } + + public function getRates() + { + return $this->rates; + } + + public function addRate(CurrencyRate $rate) + { + $this->rates[] = $rate; + return $this; + } + + public function removeRate($index) + { + if (array_key_exists($index, $this->rates)) { + unset($this->rates[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/CurrencyRate.php b/src/CurrencyRate.php new file mode 100644 index 00000000..01a40a11 --- /dev/null +++ b/src/CurrencyRate.php @@ -0,0 +1,18 @@ +code; - } - - public function setCode($code) - { - $this->code = $code; - return $this; - } - - public function getID() - { - trigger_error('getID is a deprecated method: Use getCode', E_USER_NOTICE); - return $this->getCode(); - } - - public function setID($ID) - { - trigger_error('setID is a deprecated method: Use setCode', E_USER_NOTICE); - return $this->setCode($ID); - } - - public function getUID() - { - return $this->UID; - } - - public function setUID($UID) - { - $this->UID = $UID; - return $this; - } - - public function getStatus() - { - return $this->status; - } - - public function setStatus($status) - { - $this->status = $status; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - return $this; - } - - public function getType() - { - return $this->type; - } + use PaymentConditionDiscountDaysField; + use PaymentConditionDiscountPercentageField; + use RemittanceAdviceSendMailField; + use RemittanceAdviceSendTypeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + use WebsiteField; - public function getInUse() - { - return $this->inUse; - } - - public function setInUse($inUse) - { - $this->inUse = $inUse; - return $this; - } - - public function getBehaviour() - { - return $this->behaviour; - } - - public function setBehaviour($behaviour) - { - $this->behaviour = $behaviour; - return $this; - } - - public function getTouched() - { - return $this->touched; - } - - public function setTouched($touched) - { - $this->touched = $touched; - return $this; - } - - public function getBeginPeriod() - { - return $this->beginPeriod; - } - - public function setBeginPeriod($beginPeriod) - { - $this->beginPeriod = $beginPeriod; - return $this; - } - - public function getBeginYear() - { - return $this->beginYear; - } + private $creditManagement; + private $financials; - public function setBeginYear($beginYear) - { - $this->beginYear = $beginYear; - return $this; - } + private $addresses = []; + private $banks = []; + private $postingRules = []; - public function getEndPeriod() + public function __construct() { - return $this->endPeriod; - } + $this->setBeginPeriod(0); + $this->setBeginYear(0); + $this->setEndPeriod(0); + $this->setEndYear(0); + $this->setType(\PhpTwinfield\DimensionType::fromCode('DEB')); - public function setEndPeriod($endPeriod) - { - $this->endPeriod = $endPeriod; - return $this; + $this->setCreditManagement(new CustomerCreditManagement); + $this->setFinancials(new CustomerFinancials); } - public function getEndYear() - { - return $this->endYear; - } + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); - public function setEndYear($endYear) - { - $this->endYear = $endYear; - return $this; - } - - public function getWebsite() - { - return $this->website; + return $instance; } - public function setWebsite($website) + public function getCreditManagement(): CustomerCreditManagement { - $this->website = $website; - return $this; - } - - public function getCocNumber() - { - trigger_error('setCocNumber is a deprecated method: get from CustomerAddress::field05', E_USER_NOTICE); - return $this->cocNumber; + return $this->creditManagement; } - public function setCocNumber($cocNumber) + public function setCreditManagement(CustomerCreditManagement $creditManagement) { - trigger_error('setCocNumber is a deprecated method: add to CustomerAddress::field05', E_USER_NOTICE); - $this->cocNumber = $cocNumber; + $this->creditManagement = $creditManagement; return $this; } - public function getVatNumber() + public function getFinancials(): CustomerFinancials { - trigger_error('setVatNumber is a deprecated method: add to CustomerAddress::field04', E_USER_NOTICE); - return $this->vatNumber; + return $this->financials; } - public function setVatNumber($vatNumber) + public function setFinancials(CustomerFinancials $financials) { - trigger_error('setVatNumber is a deprecated method: get CustomerAddress::field04', E_USER_NOTICE); - $this->vatNumber = $vatNumber; + $this->financials = $financials; return $this; } - public function getEditDimensionName() + public function getAddresses() { - return $this->editDimensionName; + return $this->addresses; } - public function setEditDimensionName($editDimensionName) + public function addAddress(CustomerAddress $address) { - $this->editDimensionName = $editDimensionName; + $this->addresses[] = $address; return $this; } - public function getDueDays() - { - return $this->dueDays; - } - - public function setDueDays($dueDays) + public function removeAddress($index) { - $this->dueDays = $dueDays; - return $this; + if (array_key_exists($index, $this->addresses)) { + unset($this->addresses[$index]); + return true; + } else { + return false; + } } - public function getPayAvailable(): bool + public function removeAddressByID($id) { - return $this->payAvailable; - } + $found = false; - public function setPayAvailable(bool $payAvailable): self - { - $this->payAvailable = $payAvailable; - return $this; - } + foreach ($this->addresses as $index => $address) { + if ($id == $address->getID()) { + unset($this->addresses[$index]); + $found = true; + } + } - public function getPayCode() - { - return $this->payCode; - } + if ($found) { + return true; + } - public function setPayCode($payCode) - { - $this->payCode = $payCode; - return $this; + return false; } - public function getEBilling(): bool + public function getBanks() { - return $this->eBilling; + return $this->banks; } - public function setEBilling(bool $eBilling): self + public function addBank(CustomerBank $bank) { - $this->eBilling = $eBilling; + $this->banks[] = $bank; return $this; } - public function getEBillMail() - { - return $this->eBillMail; - } - - public function setEBillMail($eBillMail) + public function removeBank($index) { - $this->eBillMail = $eBillMail; - return $this; + if (array_key_exists($index, $this->banks)) { + unset($this->banks[$index]); + return true; + } else { + return false; + } } - /** - * - * @return CustomerCollectMandate - */ - public function getCollectMandate(): ?CustomerCollectMandate + public function removeBankByID($id) { - return $this->collectMandate; - } + $found = false; - public function setCollectMandate(CustomerCollectMandate $collectMandate): self - { - $this->collectMandate = $collectMandate; - return $this; - } + foreach ($this->banks as $index => $bank) { + if ($id == $bank->getID()) { + unset($this->banks[$index]); + $found = true; + } + } - /** - * - * @return CustomerCreditManagement - */ - public function getCreditManagement(): ?CustomerCreditManagement - { - return $this->creditManagement; - } + if ($found) { + return true; + } - public function setCreditManagement(CustomerCreditManagement $creditManagement) - { - $this->creditManagement = $creditManagement; - return $this; + return false; } - public function getAddresses() + public function getPostingRules() { - return $this->addresses; + return $this->postingRules; } - public function addAddress(CustomerAddress $address) + public function addPostingRule(CustomerPostingRule $postingRule) { - $this->addresses[$address->getID()] = $address; + $this->postingRules[] = $postingRule; return $this; } - public function removeAddress($index) + public function removePostingRule($index) { - if (array_key_exists($index, $this->addresses)) { - unset($this->addresses[$index]); + if (array_key_exists($index, $this->postingRules)) { + unset($this->postingRules[$index]); return true; } else { return false; } } - public function getBanks() + public function removePostingRuleByID($id) { - return $this->banks; - } + $found = false; - public function addBank(CustomerBank $bank) - { - $this->banks[$bank->getID()] = $bank; - return $this; - } + foreach ($this->postingRules as $index => $postingRule) { + if ($id == $postingRule->getID()) { + unset($this->postingRules[$index]); + $found = true; + } + } - public function removeBank($index) - { - if (array_key_exists($index, $this->banks)) { - unset($this->banks[$index]); + if ($found) { return true; - } else { - return false; } - } - public function getGroups() - { - return $this->groups; - } - - public function setGroups($groups) - { - $this->groups = $groups; - return $this; - } - - /** - * @return string - */ - public function getCountry(): string - { - return $this->country; - } - - /** - * @param string $country - */ - public function setCountry(string $country): void - { - $this->country = $country; + return false; } } diff --git a/src/CustomerAddress.php b/src/CustomerAddress.php index e7226c1d..641cdf07 100644 --- a/src/CustomerAddress.php +++ b/src/CustomerAddress.php @@ -2,226 +2,43 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\Dimensions\Level2\CityField; +use PhpTwinfield\Fields\Dimensions\Level2\CountryField; +use PhpTwinfield\Fields\Dimensions\Level2\DefaultField; +use PhpTwinfield\Fields\Dimensions\Level2\Field1Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field2Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field3Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field4Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field5Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field6Field; +use PhpTwinfield\Fields\Dimensions\Level2\PostcodeField; +use PhpTwinfield\Fields\Dimensions\Level2\TelefaxField; +use PhpTwinfield\Fields\Dimensions\Level2\TelephoneField; +use PhpTwinfield\Fields\Dimensions\Level2\TypeField; +use PhpTwinfield\Fields\EmailField; +use PhpTwinfield\Fields\IDField; +use PhpTwinfield\Fields\NameField; + /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Customers * @todo Add documentation and typehints to all properties. */ -class CustomerAddress +class CustomerAddress extends BaseObject { - private $ID; - private $type; - private $default; - private $name; - private $contact; - private $country; - private $city; - private $postcode; - private $telephone; - private $fax; - private $email; - private $field1; - private $field2; - private $field3; - private $field4; - private $field5; - private $field6; - - public function __construct() - { - $this->ID = uniqid(); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - public function getType() - { - return $this->type; - } - - public function setType($type) - { - $this->type = $type; - return $this; - } - - /** - * @return bool - */ - public function getDefault() : bool - { - return $this->default; - } - - /** - * @param bool $default - * @return $this - */ - public function setDefault(bool $default) - { - $this->default = $default; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - return $this; - } - - public function getContact() - { - return $this->contact; - } - - public function setContact($contact) - { - $this->contact = $contact; - return $this; - } - - public function getCountry() - { - return $this->country; - } - - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - public function getCity() - { - return $this->city; - } - - public function setCity($city) - { - $this->city = $city; - return $this; - } - - public function getPostcode() - { - return $this->postcode; - } - - public function setPostcode($postcode) - { - $this->postcode = $postcode; - return $this; - } - - public function getTelephone() - { - return $this->telephone; - } - - public function setTelephone($telephone) - { - $this->telephone = $telephone; - return $this; - } - - public function getFax() - { - return $this->fax; - } - - public function setFax($fax) - { - $this->fax = $fax; - return $this; - } - - public function getEmail() - { - return $this->email; - } - - public function setEmail($email) - { - $this->email = $email; - return $this; - } - - public function getField1() - { - return $this->field1; - } - - public function setField1($field1) - { - $this->field1 = $field1; - return $this; - } - - public function getField2() - { - return $this->field2; - } - - public function setField2($field2) - { - $this->field2 = $field2; - return $this; - } - - public function getField3() - { - return $this->field3; - } - - public function setField3($field3) - { - $this->field3 = $field3; - return $this; - } - - public function getField4() - { - return $this->field4; - } - - public function setField4($field4) - { - $this->field4 = $field4; - return $this; - } - - public function getField5() - { - return $this->field5; - } - - public function setField5($field5) - { - $this->field5 = $field5; - return $this; - } - - public function getField6() - { - return $this->field6; - } - - public function setField6($field6) - { - $this->field6 = $field6; - return $this; - } + use CityField; + use CountryField; + use DefaultField; + use EmailField; + use Field1Field; + use Field2Field; + use Field3Field; + use Field4Field; + use Field5Field; + use Field6Field; + use IDField; + use NameField; + use PostcodeField; + use TelefaxField; + use TelephoneField; + use TypeField; } diff --git a/src/CustomerBank.php b/src/CustomerBank.php index a59fa791..f97d390f 100644 --- a/src/CustomerBank.php +++ b/src/CustomerBank.php @@ -2,190 +2,41 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\Dimensions\Level2\AccountNumberField; +use PhpTwinfield\Fields\Dimensions\Level2\AddressField2Field; +use PhpTwinfield\Fields\Dimensions\Level2\AddressField3Field; +use PhpTwinfield\Fields\Dimensions\Level2\AscriptionField; +use PhpTwinfield\Fields\Dimensions\Level2\BankBlockedField; +use PhpTwinfield\Fields\Dimensions\Level2\BankNameField; +use PhpTwinfield\Fields\Dimensions\Level2\BicCodeField; +use PhpTwinfield\Fields\Dimensions\Level2\CityField; +use PhpTwinfield\Fields\Dimensions\Level2\CountryField; +use PhpTwinfield\Fields\Dimensions\Level2\DefaultField; +use PhpTwinfield\Fields\Dimensions\Level2\IbanField; +use PhpTwinfield\Fields\Dimensions\Level2\NatBicCodeField; +use PhpTwinfield\Fields\Dimensions\Level2\PostcodeField; +use PhpTwinfield\Fields\Dimensions\Level2\StateField; +use PhpTwinfield\Fields\IDField; + /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Customers * @todo Add documentation and typehints to all properties. */ -class CustomerBank +class CustomerBank extends BaseObject { - private $ID; # integer Sequence number of the bank account line. - private $default; # true/false Is this the default bank account, only one default bank account is possible. - private $ascription; # string(40) Account holder. - private $accountnumber; # string(40) Account number. - private $addressField2; # string(128) Bank address. - private $addressField3; # string(128) Bank address number. - private $bankname; # string(40) Bank name. - private $biccode; # string(16) BIC code. - private $city; # string(40) City. - private $country; # string(2) Bank country code. The ISO country codes are used. - private $iban; # string(40) IBAN account number. - private $natbiccode; # string(20) National bank code. - private $postcode; # string(16) Postcode. - private $state; # string(40) State. - - public function __construct() - { - $this->ID = uniqid(); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - /** - * @return bool - */ - public function getDefault() : bool - { - return $this->default; - } - - /** - * @param bool $default - * @return $this - */ - public function setDefault(bool $default) - { - $this->default = $default; - return $this; - } - - public function getAscription() - { - return $this->ascription; - } - - public function setAscription($ascription) - { - $this->ascription = $ascription; - return $this; - } - - public function getAccountnumber() - { - return $this->accountnumber; - } - - public function setAccountnumber($accountnumber) - { - $this->accountnumber = $accountnumber; - return $this; - } - - public function getAddressField2() - { - return $this->addressField2; - } - - public function setAddressField2($addressField2) - { - $this->addressField2 = $addressField2; - return $this; - } - - public function getAddressField3() - { - return $this->addressField3; - } - - public function setAddressField3($addressField3) - { - $this->addressField3 = $addressField3; - return $this; - } - - public function getBankname() - { - return $this->bankname; - } - - public function setBankname($bankname) - { - $this->bankname = $bankname; - return $this; - } - - public function getBiccode() - { - return $this->biccode; - } - - public function setBiccode($biccode) - { - $this->biccode = $biccode; - return $this; - } - - public function getCity() - { - return $this->city; - } - - public function setCity($city) - { - $this->city = $city; - return $this; - } - - public function getCountry() - { - return $this->country; - } - - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - public function getIban() - { - return $this->iban; - } - - public function setIban($iban) - { - $this->iban = $iban; - return $this; - } - - public function getNatbiccode() - { - return $this->natbiccode; - } - - public function setNatbiccode($natbiccode) - { - $this->natbiccode = $natbiccode; - return $this; - } - - public function getPostcode() - { - return $this->postcode; - } - - public function setPostcode($postcode) - { - $this->postcode = $postcode; - return $this; - } - - public function getState() - { - return $this->state; - } - - public function setState($state) - { - $this->state = $state; - return $this; - } + use AccountNumberField; + use AddressField2Field; + use AddressField3Field; + use AscriptionField; + use BankBlockedField; + use BankNameField; + use BicCodeField; + use CityField; + use CountryField; + use DefaultField; + use IbanField; + use IDField; + use NatBicCodeField; + use PostcodeField; + use StateField; } diff --git a/src/CustomerChildValidation.php b/src/CustomerChildValidation.php new file mode 100644 index 00000000..f74f303c --- /dev/null +++ b/src/CustomerChildValidation.php @@ -0,0 +1,18 @@ +ID; - } - - /** - * @param string $ID - * @return $this - */ - public function setID(string $ID): self - { - Assert::maxLength($ID, 35); - $this->ID = $ID; - - return $this; - } - - /** - * @return \DateTimeInterface|null - */ - public function getSignatureDate(): ?\DateTimeInterface - { - return $this->signatureDate; - } - - /** - * @param \DateTimeInterface|null $date - * @return $this - */ - public function setSignatureDate(?\DateTimeInterface $date): self - { - $this->signatureDate = $date; - - return $this; - } - - /** - * @param string|null $dateString - * @return $this - * @throws Exception - */ - public function setSignatureDateFromString(?string $dateString): self - { - if (!empty($dateString)) { - $dateString = Util::parseDate($dateString); - } - - return $this->setSignatureDate($dateString); - } - - /** - * @return \DateTimeInterface|null - */ - public function getFirstRunDate(): ?\DateTimeInterface - { - return $this->firstRunDate; - } - - /** - * @param \DateTimeInterface|null $date - * @return $this - */ - public function setFirstRunDate(?\DateTimeInterface $date): self - { - $this->firstRunDate = $date; - - return $this; - } - - /** - * @param string|null $dateString - * @return $this - * @throws Exception - */ - public function setFirstRunDateFromString(?string $dateString): self - { - if (!empty($dateString)) { - $dateString = Util::parseDate($dateString); - } - - return $this->setFirstRunDate($dateString); - } + use FirstRunDateField; + use IDField; + use SignatureDateField; } diff --git a/src/CustomerCreditManagement.php b/src/CustomerCreditManagement.php index 95f6e4c5..9979d2b0 100644 --- a/src/CustomerCreditManagement.php +++ b/src/CustomerCreditManagement.php @@ -2,110 +2,39 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionLineFields\CommentField; +use PhpTwinfield\Fields\CommentField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\BaseCreditLimitField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\BlockedField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\BlockedLockedField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\BlockedModifiedField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\FreeText1Field; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\ReminderEmailField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\ResponsibleUserField; +use PhpTwinfield\Fields\Dimensions\Level2\Customer\SendReminderField; +use PhpTwinfield\Fields\FreeText2Field; +use PhpTwinfield\Fields\FreeText3Field; /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Customers * @todo Add documentation and typehints to all properties. */ -class CustomerCreditManagement +class CustomerCreditManagement extends BaseObject { + use BaseCreditLimitField; + use BlockedField; + use BlockedLockedField; + use BlockedModifiedField; use CommentField; + use FreeText1Field; + use FreeText2Field; + use FreeText3Field; + use ReminderEmailField; + use ResponsibleUserField; + use SendReminderField; - private $responsibleUser; #string(16) The credit manager. - private $baseCreditLimit = 0; #amount The credit limit amount. - private $sendReminder = true; #true/email/false Determines if and how a customer will be reminded. - private $reminderEmail; #string(200) Mandatory if sendreminder is email. - private $blocked = false; #true/false Are related projects for this cust. blocked in time & expenses. - private $freeText1; #true/false Right of use. - private $freeText2; #string(40) Segment code. - private $freeText3; # Not in use - - public function getResponsibleUser() - { - return $this->responsibleUser; - } - - public function getBaseCreditLimit() - { - return $this->baseCreditLimit; - } - - public function getSendReminder() - { - return $this->sendReminder; - } - - public function getReminderEmail() - { - return $this->reminderEmail; - } - - public function getBlocked() - { - return $this->blocked; - } - - public function getFreeText1() - { - return $this->freeText1; - } - - public function getFreeText2() - { - return $this->freeText2; - } - - public function getFreeText3() - { - return $this->freeText3; - } - - public function setResponsibleUser($responsibleUser) - { - $this->responsibleUser = $responsibleUser; - return $this; - } - - public function setBaseCreditLimit($baseCreditLimit) - { - $this->baseCreditLimit = $baseCreditLimit; - return $this; - } - - public function setSendReminder($sendReminder) - { - $this->sendReminder = $sendReminder; - return $this; - } - - public function setReminderEmail($reminderEmail) - { - $this->reminderEmail = $reminderEmail; - return $this; - } - - public function setBlocked($blocked) - { - $this->blocked = $blocked; - return $this; - } - - public function setFreeText1($freeText1) - { - $this->freeText1 = $freeText1; - return $this; - } - - public function setFreeText2($freeText2) - { - $this->freeText2 = $freeText2; - return $this; - } - - public function setFreeText3($freeText3) + public function __construct() { - $this->freeText3 = $freeText3; - return $this; + $this->setBlocked(false); + $this->setSendReminder(\PhpTwinfield\Enums\SendReminder::TRUE()); } } diff --git a/src/CustomerFinancials.php b/src/CustomerFinancials.php new file mode 100644 index 00000000..5295c211 --- /dev/null +++ b/src/CustomerFinancials.php @@ -0,0 +1,94 @@ +setAccountType(\PhpTwinfield\Enums\AccountType::INHERIT()); + $this->setCollectionSchema(\PhpTwinfield\Enums\CollectionSchema::CORE()); + $this->setDueDays(30); + $this->setMatchType(\PhpTwinfield\Enums\MatchType::CUSTOMERSUPPLIER()); + $this->setSubAnalyse(\PhpTwinfield\Enums\SubAnalyse::FALSE()); + $this->setSubstitutionLevel(1); + + $this->setCollectMandate(new CustomerCollectMandate); + } + + public function getCollectMandate(): CustomerCollectMandate + { + return $this->collectMandate; + } + + public function setCollectMandate(CustomerCollectMandate $collectMandate) + { + $this->collectMandate = $collectMandate; + return $this; + } + + public function getChildValidations() + { + return $this->childValidations; + } + + public function addChildValidation(CustomerChildValidation $childValidation) + { + $this->childValidations[] = $childValidation; + return $this; + } + + public function removeChildValidation($index) + { + if (array_key_exists($index, $this->childValidations)) { + unset($this->childValidations[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/CustomerLine.php b/src/CustomerLine.php new file mode 100644 index 00000000..5237a333 --- /dev/null +++ b/src/CustomerLine.php @@ -0,0 +1,32 @@ +setID(1); + } + + public function getLines() + { + return $this->lines; + } + + public function addLine(CustomerLine $line) + { + $this->lines[] = $line; + return $this; + } + + public function removeLine($index) + { + if (array_key_exists($index, $this->lines)) { + unset($this->lines[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/DimensionGroup.php b/src/DimensionGroup.php new file mode 100644 index 00000000..615e006f --- /dev/null +++ b/src/DimensionGroup.php @@ -0,0 +1,52 @@ +setCode($code); + + return $instance; + } + + public function getDimensions() + { + return $this->dimensions; + } + + public function addDimension(DimensionGroupDimension $dimension) + { + $this->dimensions[] = $dimension; + return $this; + } + + public function removeDimension($index) + { + if (array_key_exists($index, $this->dimensions)) { + unset($this->dimensions[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/DimensionGroupDimension.php b/src/DimensionGroupDimension.php new file mode 100644 index 00000000..eb43f5e7 --- /dev/null +++ b/src/DimensionGroupDimension.php @@ -0,0 +1,16 @@ +setAddress(new DimensionTypeAddress); + $this->setLevels(new DimensionTypeLevels); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getAddress(): DimensionTypeAddress + { + return $this->address; + } + + public function setAddress(DimensionTypeAddress $address) + { + $this->address = $address; + return $this; + } + + public function getLevels(): DimensionTypeLevels + { + return $this->levels; + } + + public function setLevels(DimensionTypeLevels $levels) + { + $this->levels = $levels; + return $this; + } +} diff --git a/src/DimensionTypeAddress.php b/src/DimensionTypeAddress.php new file mode 100644 index 00000000..388bae31 --- /dev/null +++ b/src/DimensionTypeAddress.php @@ -0,0 +1,24 @@ + + */ +class ActivitiesDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensions"; + } + + /** + * Turns a passed Activity class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the Activity to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param Activity $activity + * @return void | [Adds to this instance] + */ + public function addActivity(Activity $activity) + { + $activityElement = $this->createElement('dimension'); + $this->rootElement->appendChild($activityElement); + + $status = $activity->getStatus(); + + if (!empty($status)) { + $activityElement->setAttribute('status', $status); + } + + if (!empty($activity->getCode())) { + $activityElement->appendChild($this->createNodeWithTextContent('code', $activity->getCode())); + } + + $activityElement->appendChild($this->createNodeWithTextContent('name', $activity->getName())); + $activityElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($activity->getOffice()))); + $activityElement->appendChild($this->createNodeWithTextContent('shortname', $activity->getShortName())); + $activityElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($activity->getType()))); + + $financialsElement = $this->createElement('financials'); + $activityElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($activity->getVatCode()))); + + $projects = $activity->getProjects(); + + $projectsElement = $this->createElement('projects'); + $activityElement->appendChild($projectsElement); + + $inheritArray = array('authoriser' => 'getAuthoriserToString', 'billable' => 'getBillableToString', 'customer' => 'getCustomerToString', 'rate' => 'getRateToString'); + + foreach ($inheritArray as $inheritVar => $method) { + $methodLocked = "get" . ucfirst($inheritVar) . "Locked"; + $methodLockedString = $methodLocked . "ToString"; + $methodInherit = "get" . ucfirst($inheritVar) . "Inherit"; + $methodInheritString = $methodInherit . "ToString"; + $elementVar = ""; + + if ($projects->$methodLocked() != true || $projects->$methodInherit() != true) { + $elementVar = $projects->$method(); + } elseif ($inheritVar == 'billable') { + $projects->setBillableForRatio(false); + } + + $attributesArray = array('locked' => $methodLockedString, 'inherit' => $methodInheritString); + + if ($inheritVar == 'billable') { + $attributesArray['forratio'] = 'getBillableForRatioToString'; + } + + $projectsElement->appendChild($this->createNodeWithTextContent($inheritVar, $elementVar, $projects, $attributesArray)); + } + + $projectsElement->appendChild($this->createNodeWithTextContent('invoicedescription', $projects->getInvoiceDescription())); + $projectsElement->appendChild($this->createNodeWithTextContent('validfrom', Util::formatDate($projects->getValidFrom()))); + $projectsElement->appendChild($this->createNodeWithTextContent('validtill', Util::formatDate($projects->getValidTill()))); + + $quantities = $projects->getQuantities(); + + if (!empty($quantities)) { + // Make quantities element + $quantitiesElement = $this->createElement('quantities'); + $projectsElement->appendChild($quantitiesElement); + + // Go through each quantity assigned to the activity project + foreach ($quantities as $quantity) { + // Makes quantity element + $quantityElement = $this->createElement('quantity'); + $quantitiesElement->appendChild($quantityElement); + + $quantityElement->appendChild($this->createNodeWithTextContent('label', $quantity->getLabel())); + $quantityElement->appendChild($this->createNodeWithTextContent('rate', Util::objectToStr($quantity->getRate()))); + $quantityElement->appendChild($this->createNodeWithTextContent('billable', Util::formatBoolean($quantity->getBillable()), $quantity, array('locked' => 'getBillableLockedToString'))); + $quantityElement->appendChild($this->createNodeWithTextContent('mandatory', Util::formatBoolean($quantity->getMandatory()))); + } + } + } +} diff --git a/src/DomDocuments/ArticlesDocument.php b/src/DomDocuments/ArticlesDocument.php index bb184e03..f7e67836 100644 --- a/src/DomDocuments/ArticlesDocument.php +++ b/src/DomDocuments/ArticlesDocument.php @@ -3,74 +3,43 @@ namespace PhpTwinfield\DomDocuments; use PhpTwinfield\Article; +use PhpTwinfield\Util; /** * The Document Holder for making new XML Article. Is a child class * of DOMDocument and makes the required DOM tree for the interaction in * creating a new Article. - * + * * @package PhpTwinfield * @subpackage Article\DOM - * @author Willem van de Sande + * @author Willem van de Sande , extended by Yannick Aerssens */ -class ArticlesDocument extends \DOMDocument +class ArticlesDocument extends BaseDocument { - /** - * Holds the
element - * that all additional elements should be a child of - * @var \DOMElement - */ - private $articleElement; - - /** - * Creates the
element and adds it to the property - * articleElement - * - * @access public - */ - public function __construct() + final protected function getRootTagName(): string { - parent::__construct(); - - $this->articleElement = $this->createElement('article'); - $this->appendChild($this->articleElement); + return "articles"; } /** * Turns a passed Article class into the required markup for interacting * with Twinfield. - * - * This method doesn't return anything, instead just adds the Article to + * + * This method doesn't return anything, instead just adds the Article to * this DOMDOcument instance for submission usage. - * + * * @access public * @param Article $article * @return void | [Adds to this instance] */ public function addArticle(Article $article) { - // Article->header elements and their methods - $articleTags = array( - 'office' => 'getOffice', - 'code' => 'getCode', - 'type' => 'getType', - 'name' => 'getName', - 'shortname' => 'getShortName', - 'unitnamesingular' => 'getUnitNameSingular', - 'unitnameplural' => 'getUnitNamePlural', - 'vatcode' => 'getVatCode', - 'allowchangevatcode' => 'getAllowChangeVatCode', - 'allowdiscountorpremium' => 'getAllowDiscountorPremium', - 'allowchangeunitsprice' => 'getAllowChangeUnitsPrice', - 'allowdecimalquantity' => 'getAllowDecimalQuantity', - 'performancetype' => 'getPerformanceType', - //'allowchangeperformancetype' => 'getAllowChangePerformanceType', - 'percentage' => 'getPercentage', - ); + $articleElement = $this->createElement('article'); + $this->rootElement->appendChild($articleElement); // Make header element $headerElement = $this->createElement('header'); - $this->articleElement->appendChild($headerElement); + $articleElement->appendChild($headerElement); $status = $article->getStatus(); @@ -78,75 +47,61 @@ public function addArticle(Article $article) $headerElement->setAttribute('status', $status); } - // Go through each Article element and use the assigned method - foreach ($articleTags as $tag => $method) { - // Make text node for method value - $nodeValue = $article->$method(); - if (is_bool($nodeValue)) { - $nodeValue = ($nodeValue) ? 'true' : 'false'; - } - $node = $this->createTextNode($nodeValue); - - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); - - // Add the full element - $headerElement->appendChild($element); + $headerElement->appendChild($this->createNodeWithTextContent('allowchangeperformancetype', Util::formatBoolean($article->getAllowChangePerformanceType()))); + $headerElement->appendChild($this->createNodeWithTextContent('allowchangeunitsprice', Util::formatBoolean($article->getAllowChangeUnitsPrice()))); + $headerElement->appendChild($this->createNodeWithTextContent('allowchangevatcode', Util::formatBoolean($article->getAllowChangeVatCode()))); + $headerElement->appendChild($this->createNodeWithTextContent('allowdecimalquantity', Util::formatBoolean($article->getAllowDecimalQuantity()))); + $headerElement->appendChild($this->createNodeWithTextContent('allowdiscountorpremium', Util::formatBoolean($article->getAllowDiscountOrPremium()))); + $headerElement->appendChild($this->createNodeWithTextContent('code', $article->getCode())); + $headerElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($article->getOffice()))); + $headerElement->appendChild($this->createNodeWithTextContent('name', $article->getName())); + $headerElement->appendChild($this->createNodeWithTextContent('percentage', Util::formatBoolean($article->getPercentage()))); + $headerElement->appendChild($this->createNodeWithTextContent('performancetype', $article->getPerformanceType())); + $headerElement->appendChild($this->createNodeWithTextContent('shortname', $article->getShortName())); + $headerElement->appendChild($this->createNodeWithTextContent('type', $article->getType())); + $headerElement->appendChild($this->createNodeWithTextContent('unitnameplural', $article->getUnitNamePlural())); + $headerElement->appendChild($this->createNodeWithTextContent('unitnamesingular', $article->getUnitNameSingular())); + $headerElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($article->getVatCode()))); + + //Clear VAT code in case of a discount/premium article with percentage set to true to prevent errors + if ($article->getType() != "normal" && $article->getPercentage()) { + $headerElement->getElementsByTagName('vatcode')->item(0)->nodeValue = ""; } $lines = $article->getLines(); if (!empty($lines)) { - // Element tags and their methods for lines - $lineTags = [ - 'unitspriceexcl' => 'getUnitsPriceExcl', - 'unitspriceinc' => 'getUnitsPriceInc', - 'units' => 'getUnits', - 'name' => 'getName', - 'shortname' => 'getShortName', - 'subcode' => 'getSubCode', - 'freetext1' => 'getFreeText1', - ]; - - // Make addresses element + // Make lines element $linesElement = $this->createElement('lines'); - $this->articleElement->appendChild($linesElement); + $articleElement->appendChild($linesElement); // Go through each line assigned to the article foreach ($lines as $line) { - // Makes new articleLine element + // Makes new line element $lineElement = $this->createElement('line'); $linesElement->appendChild($lineElement); - $status = $line->getStatus(); $id = $line->getID(); - $inUse = $line->getInUse(); - - if (!empty($status)) { - $lineElement->setAttribute('status', $status); - } if (!empty($id)) { $lineElement->setAttribute('id', $id); } - if (!empty($inUse)) { - $lineElement->setAttribute('inuse', $inUse); - } - - // Go through each line element and use the assigned method - foreach ($lineTags as $tag => $method) { - // Make the text node for the method value - $node = $this->createTextNode($line->$method()); - - // Make the actual element and assign the text node - $element = $this->createElement($tag); - $element->appendChild($node); + $status = $line->getStatus(); - // Add the completed element - $lineElement->appendChild($element); + if (!empty($status)) { + $lineElement->setAttribute('status', $status); } + + $lineElement->appendChild($this->createNodeWithTextContent('freetext1', Util::objectToStr($line->getFreeText1()))); + $lineElement->appendChild($this->createNodeWithTextContent('freetext2', Util::objectToStr($line->getFreeText2()))); + $lineElement->appendChild($this->createNodeWithTextContent('freetext3', $line->getFreeText3())); + $lineElement->appendChild($this->createNodeWithTextContent('name', $line->getName())); + $lineElement->appendChild($this->createNodeWithTextContent('shortname', $line->getShortName())); + $lineElement->appendChild($this->createNodeWithTextContent('subcode', $line->getSubCode())); + $lineElement->appendChild($this->createNodeWithTextContent('units', $line->getUnits())); + $lineElement->appendChild($this->createNodeWithTextContent('unitspriceexcl', Util::formatMoney($line->getUnitsPriceExcl()))); + $lineElement->appendChild($this->createNodeWithTextContent('unitspriceinc', Util::formatMoney($line->getUnitsPriceInc()))); } } } diff --git a/src/DomDocuments/AssetMethodsDocument.php b/src/DomDocuments/AssetMethodsDocument.php new file mode 100644 index 00000000..e5e5a255 --- /dev/null +++ b/src/DomDocuments/AssetMethodsDocument.php @@ -0,0 +1,91 @@ + + */ +class AssetMethodsDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "assetmethods"; + } + + /** + * Turns a passed AssetMethod class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the AssetMethod to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param AssetMethod $assetMethod + * @return void | [Adds to this instance] + */ + public function addAssetMethod(AssetMethod $assetMethod) + { + $assetMethodElement = $this->createElement('assetmethod'); + $this->rootElement->appendChild($assetMethodElement); + + $status = $assetMethod->getStatus(); + + if (!empty($status)) { + $assetMethodElement->setAttribute('status', $status); + } + + $assetMethodElement->appendChild($this->createNodeWithTextContent('calcmethod', $assetMethod->getCalcMethod())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('code', $assetMethod->getCode())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('depreciatereconciliation', $assetMethod->getDepreciateReconciliation())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('name', $assetMethod->getName())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('nrofperiods', $assetMethod->getNrOfPeriods())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($assetMethod->getOffice()))); + $assetMethodElement->appendChild($this->createNodeWithTextContent('percentage', $assetMethod->getPercentage())); + $assetMethodElement->appendChild($this->createNodeWithTextContent('shortname', $assetMethod->getShortName())); + + $balanceAccounts = $assetMethod->getBalanceAccounts(); + + $balanceAccountsElement = $this->createElement('balanceaccounts'); + $assetMethodElement->appendChild($balanceAccountsElement); + + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('assetstoactivate', Util::objectToStr($balanceAccounts->getAssetsToActivate()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('depreciation', Util::objectToStr($balanceAccounts->getDepreciation()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('depreciationgroup', Util::objectToStr($balanceAccounts->getDepreciationGroup()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('purchasevalue', Util::objectToStr($balanceAccounts->getPurchaseValue()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('purchasevaluegroup', Util::objectToStr($balanceAccounts->getPurchaseValueGroup()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('reconciliation', Util::objectToStr($balanceAccounts->getReconciliation()))); + $balanceAccountsElement->appendChild($this->createNodeWithTextContent('tobeinvoiced', Util::objectToStr($balanceAccounts->getToBeInvoiced()))); + + $profitLossAccounts = $assetMethod->getProfitLossAccounts(); + + $profitLossAccountsElement = $this->createElement('profitlossaccounts'); + $assetMethodElement->appendChild($profitLossAccountsElement); + + $profitLossAccountsElement->appendChild($this->createNodeWithTextContent('depreciation', Util::objectToStr($profitLossAccounts->getDepreciation()))); + $profitLossAccountsElement->appendChild($this->createNodeWithTextContent('reconciliation', Util::objectToStr($profitLossAccounts->getReconciliation()))); + $profitLossAccountsElement->appendChild($this->createNodeWithTextContent('sales', Util::objectToStr($profitLossAccounts->getSales()))); + + $freeTexts = $assetMethod->getFreeTexts(); + + if (!empty($freeTexts)) { + // Make freetexts element + $freeTextsElement = $this->createElement('freetexts'); + $assetMethodElement->appendChild($freeTextsElement); + + // Go through each freetext assigned to the asset method + foreach ($freeTexts as $freeText) { + // Make freetext element + $freeTextsElement->appendChild($this->createNodeWithTextContent('freetext', $freeText->getElementValue(), $freeText, array('id' => 'getID', 'type' => 'getType'))); + } + } + } +} diff --git a/src/DomDocuments/BankTransactionDocument.php b/src/DomDocuments/BankTransactionDocument.php deleted file mode 100644 index 0c13d577..00000000 --- a/src/DomDocuments/BankTransactionDocument.php +++ /dev/null @@ -1,180 +0,0 @@ -createElement("transaction"); - - $transaction->appendChild(new \DOMAttr("destiny", $bankTransaction->getDestiny())); - - if ($bankTransaction->isAutoBalanceVat() !== null) { - $transaction->appendChild( - $this->createBooleanAttribute("autobalancevat", $bankTransaction->isAutoBalanceVat()) - ); - } - - if ($bankTransaction->getRaiseWarning() !== null) { - $transaction->appendChild( - $this->createBooleanAttribute("raisewarning", $bankTransaction->getRaiseWarning()) - ); - } - - $header = $this->createElement("header"); - - if ($bankTransaction->getCode() !== null) { - $header->appendChild($this->createNodeWithTextContent("code", $bankTransaction->getCode())); - } - - $header->appendChild($this->createNodeWithTextContent("office", $bankTransaction->getOffice())); - - if ($bankTransaction->getNumber() !== null) { - $header->appendChild($this->createNodeWithTextContent("number", $bankTransaction->getNumber())); - } - - if ($bankTransaction->getPeriod() !== null) { - $header->appendChild($this->createNodeWithTextContent("period", $bankTransaction->getPeriod())); - } - - if ($bankTransaction->getDate() !== null) { - $this->appendDateElement($header, "date", $bankTransaction->getDate()); - } - - if ($bankTransaction->getStatementnumber() !== null) { - $header->appendChild($this->createNodeWithTextContent("statementnumber", $bankTransaction->getStatementnumber())); - } - - $this->appendStartCloseValues($header, $bankTransaction); - - $this->appendFreeTextFields($header, $bankTransaction); - $transaction->appendChild($header); - - $lines = $this->createElement("lines"); - $transaction->appendChild($lines); - - foreach ($bankTransaction->getLines() as $line) { - $lines->appendChild($this->createTransactionLineElement($line)); - } - - $this->rootElement->appendChild($transaction); - } - - protected function createTransactionLineElement(BankTransactionLine\Base $line): \DOMElement - { - $transaction = $this->createElement("line"); - $transaction->appendChild(new \DOMAttr("type", $line->getLineType())); - - if ($line->getId() !== null) { - $transaction->appendChild(new \DOMAttr("id", $line->getId())); - } - - if ($line->getDim1() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("dim1", $line->getDim1())); - } - - if ($line->getDim2() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("dim2", $line->getDim2())); - } - - if ($line->getDim3() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("dim3", $line->getDim3())); - } - - $this->appendValueValues($transaction, $line); - - if ($line->getInvoiceNumber() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("invoicenumber", $line->getInvoiceNumber())); - } - - if ($line->getDescription()) { - $transaction->appendChild($this->createNodeWithTextContent("description", $line->getDescription())); - } - - if ($line instanceof BankTransactionLine\Total) { - if ($line->getVatTotal() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vattotal", Util::formatMoney($line->getVatTotal()))); - } - - if ($line->getVatBaseTotal() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatbasetotal", Util::formatMoney($line->getVatBaseTotal()))); - } - - if ($line->getVatRepTotal() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatreptotal", Util::formatMoney($line->getVatRepTotal()))); - } - } - - if ($line instanceof BankTransactionLine\Vat || $line instanceof BankTransactionLine\Detail) { - if ($line->getVatCode() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatcode", $line->getVatCode())); - } - } - - if ($line instanceof BankTransactionLine\Detail) { - if ($line->getVatValue() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatvalue", Util::formatMoney($line->getVatValue()))); - } - - if ($line->getVatBaseValue() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatbasevalue", Util::formatMoney($line->getVatBaseValue()))); - } - - if ($line->getVatRepValue() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatrepvalue", Util::formatMoney($line->getVatRepValue()))); - } - } - - if ($line instanceof BankTransactionLine\Vat) { - - if ($line->getVatTurnover() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatturnover", Util::formatMoney($line->getVatTurnover()))); - } - if ($line->getVatBaseTurnover() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatbaseturnover", Util::formatMoney($line->getVatBaseTurnover()))); - } - if ($line->getVatRepTurnover() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("vatrepturnover", Util::formatMoney($line->getVatRepTurnover()))); - } - } - - if ($line instanceof BankTransactionLine\Detail || $line instanceof BankTransactionLine\Vat) { - $this->appendPerformanceTypeFields($transaction, $line); - } - - if ($line->getDestOffice() !== null) { - $transaction->appendChild($this->createNodeWithTextContent("destoffice", $line->getDestOffice())); - } - - if ($line->getFreeChar()) { - $transaction->appendChild($this->createNodeWithTextContent("freechar", $line->getFreeChar())); - } - - if ($line->getComment()) { - $transaction->appendChild($this->createNodeWithTextContent("comment", $line->getComment())); - } - - return $transaction; - } -} \ No newline at end of file diff --git a/src/DomDocuments/BaseDocument.php b/src/DomDocuments/BaseDocument.php index ed9cb33b..e204aba2 100644 --- a/src/DomDocuments/BaseDocument.php +++ b/src/DomDocuments/BaseDocument.php @@ -2,14 +2,7 @@ namespace PhpTwinfield\DomDocuments; -use PhpTwinfield\Enums\PerformanceType; -use PhpTwinfield\Office; -use PhpTwinfield\Transactions\TransactionFields\FreeTextFields; -use PhpTwinfield\Transactions\TransactionFields\StartAndCloseValueFields; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; -use PhpTwinfield\Transactions\TransactionLineFields\ValueFields; -use PhpTwinfield\Util; -use Webmozart\Assert\Assert; +use PhpTwinfield\HasMessageInterface; /** * You should add a public function add($instance): void method which will add an instance to the rootElement, so @@ -37,132 +30,30 @@ public function __construct($version = "1.0", $encoding = "UTF-8") $this->appendChild($this->rootElement); } - protected function createBooleanAttribute(string $name, bool $value): \DOMAttr - { - $attr = $this->createAttribute($name); - $attr->value = Util::formatBoolean($value); - - return $attr; - } - - protected function appendDateElement(\DOMElement $element, string $name, \DateTimeInterface $date): void - { - $element->appendChild( - $this->createNodeWithTextContent($name, Util::formatDate($date)) - ); - } - - protected function appendOfficeField(\DOMElement $element, Office $office): void - { - $element->appendChild( - $this->createNodeWithTextContent("office", $office->getCode()) - ); - } - - /** - * Utility method to get a formatted value using a callable. - * - * @param callable $callback - * @return null|string - */ - protected function getValueFromCallback(callable $callback): ?string - { - $value = call_user_func($callback); - - if ($value instanceof \DateTimeInterface) { - $value = Util::formatDate($value); - } - - if (is_bool($value)) { - $value = Util::formatBoolean($value); - } - - return $value; - } - - /** - * Adds currency, startvalue and closevalue to $element. - * - * @param \DOMElement $element - * @param $object - */ - protected function appendStartCloseValues(\DOMElement $element, $object): void - { - Assert::true(Util::objectUses(StartAndCloseValueFields::class, $object)); - - /** @var StartAndCloseValueFields $object */ - $element->appendChild($this->createNodeWithTextContent("currency", $object->getCurrency())); - $element->appendChild($this->createNodeWithTextContent("startvalue", Util::formatMoney($object->getStartvalue()))); - $element->appendChild($this->createNodeWithTextContent("closevalue", Util::formatMoney($object->getClosevalue()))); - } - - /** - * Adds freetext[1-3] to the $element, unless they are null. - * - * @param \DOMElement $element - * @param $object - */ - protected function appendFreeTextFields(\DOMElement $element, $object): void - { - Assert::true(Util::objectUses(FreeTextFields::class, $object)); - - /** @var FreeTextFields $object */ - if ($object->getFreetext1() !== null) { - $element->appendChild($this->createNodeWithTextContent("freetext1", $object->getFreetext1())); - } - if ($object->getFreetext2() !== null) { - $element->appendChild($this->createNodeWithTextContent("freetext2", $object->getFreetext2())); - } - if ($object->getFreetext3() !== null) { - $element->appendChild($this->createNodeWithTextContent("freetext3", $object->getFreetext3())); - } - } - - protected function appendValueValues(\DOMElement $element, $object): void - { - Assert::true(Util::objectUses(ValueFields::class, $object)); - - /** @var ValueFields $object */ - $element->appendChild($this->createNodeWithTextContent("debitcredit", $object->getDebitCredit())); - $element->appendChild($this->createNodeWithTextContent("value", Util::formatMoney($object->getValue()))); - } - - protected function appendPerformanceTypeFields(\DOMElement $element, $object): void - { - /** @var PerformanceFields $object */ - - Assert::true(Util::objectUses(PerformanceFields::class, $object)); - - if ($object->getPerformanceType() !== null) { - $element->appendChild($this->createNodeWithTextContent("performancetype", $object->getPerformanceType())); - } - - if ($object->getPerformanceCountry() !== null) { - $element->appendChild($this->createNodeWithTextContent("performancecountry", $object->getPerformanceCountry())); - } - - if ($object->getPerformanceVatNumber() !== null) { - $element->appendChild($this->createNodeWithTextContent("performancevatnumber", $object->getPerformanceVatNumber())); - } - - if ($object->getPerformanceDate() != null && $object->getPerformanceType()->equals(PerformanceType::SERVICES())) { - $this->appendDateElement($element, "performancedate", $object->getPerformanceDate()); - } - } - /** * Create an element and set some value as its innerText. * * Use this instead of createElement(). * * @param string $tag - * @param string $textContent + * @param string|null $textContent + * @param HasMessageInterface|null $object + * @param array $methodToAttributeMap * @return \DOMElement */ - final protected function createNodeWithTextContent(string $tag, string $textContent): \DOMElement + final protected function createNodeWithTextContent(string $tag, ?string $textContent, ?HasMessageInterface $object = null, array $methodToAttributeMap = []): \DOMElement { $element = $this->createElement($tag); - $element->textContent = $textContent; + + if ($textContent != null) { + $element->textContent = $textContent; + } + + if (isset($object)) { + foreach ($methodToAttributeMap as $attributeName => $method) { + $element->setAttribute($attributeName, $object->$method()); + } + } return $element; } diff --git a/src/DomDocuments/BookingReferenceDeletionDocument.php b/src/DomDocuments/BookingReferenceDeletionDocument.php index 243ae432..3f5fb33e 100644 --- a/src/DomDocuments/BookingReferenceDeletionDocument.php +++ b/src/DomDocuments/BookingReferenceDeletionDocument.php @@ -3,6 +3,7 @@ namespace PhpTwinfield\DomDocuments; use PhpTwinfield\BookingReference; +use PhpTwinfield\Util; class BookingReferenceDeletionDocument extends BaseDocument { @@ -18,7 +19,7 @@ public function __construct(BookingReference $bookingReference, string $reason) $this->rootElement->setAttribute("action", "delete"); $this->rootElement->setAttribute("reason", $reason); - $this->appendOfficeField($this->rootElement, $bookingReference->getOffice()); + $this->rootElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($bookingReference->getOffice()))); $this->rootElement->appendChild( $this->createNodeWithTextContent("code", $bookingReference->getCode()) @@ -28,4 +29,4 @@ public function __construct(BookingReference $bookingReference, string $reason) $this->createNodeWithTextContent("number", $bookingReference->getNumber()) ); } -} \ No newline at end of file +} diff --git a/src/DomDocuments/CostCentersDocument.php b/src/DomDocuments/CostCentersDocument.php new file mode 100644 index 00000000..c62c2a41 --- /dev/null +++ b/src/DomDocuments/CostCentersDocument.php @@ -0,0 +1,54 @@ +, based on ArticlesDocument by Willem van de Sande + */ +class CostCentersDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensions"; + } + + /** + * Turns a passed CostCenter class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the CostCenter to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param CostCenter $costCenter + * @return void | [Adds to this instance] + */ + public function addCostCenter(CostCenter $costCenter) + { + $costCenterElement = $this->createElement('dimension'); + $this->rootElement->appendChild($costCenterElement); + + $status = $costCenter->getStatus(); + + if (!empty($status)) { + $costCenterElement->setAttribute('status', $status); + } + + if (!empty($costCenter->getCode())) { + $costCenterElement->appendChild($this->createNodeWithTextContent('code', $costCenter->getCode())); + } + + $costCenterElement->appendChild($this->createNodeWithTextContent('name', $costCenter->getName())); + $costCenterElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($costCenter->getOffice()))); + $costCenterElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($costCenter->getType()))); + } +} diff --git a/src/DomDocuments/CurrenciesDocument.php b/src/DomDocuments/CurrenciesDocument.php new file mode 100644 index 00000000..2c3ff9bd --- /dev/null +++ b/src/DomDocuments/CurrenciesDocument.php @@ -0,0 +1,75 @@ +, based on ArticlesDocument by Willem van de Sande + */ +class CurrenciesDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "currencies"; + } + + /** + * Turns a passed Currency class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the Currency to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param Currency $currency + * @return void | [Adds to this instance] + */ + public function addCurrency(Currency $currency) + { + $currencyElement = $this->createElement('currency'); + $this->rootElement->appendChild($currencyElement); + + $status = $currency->getStatus(); + + if (!empty($status)) { + $currencyElement->setAttribute('status', $status); + } + + $currencyElement->appendChild($this->createNodeWithTextContent('code', $currency->getCode())); + $currencyElement->appendChild($this->createNodeWithTextContent('name', $currency->getName())); + $currencyElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($currency->getOffice()))); + $currencyElement->appendChild($this->createNodeWithTextContent('shortname', $currency->getShortName())); + + $rates = $currency->getRates(); + + if (!empty($rates)) { + // Make rates element + $ratesElement = $this->createElement('rates'); + $currencyElement->appendChild($ratesElement); + + // Go through each rate assigned to the currency + foreach ($rates as $rate) { + // Makes rate element + $rateElement = $this->createElement('rate'); + $ratesElement->appendChild($rateElement); + + $status = $rate->getStatus(); + + if (!empty($status)) { + $rateElement->setAttribute('status', $status); + } + + $rateElement->appendChild($this->createNodeWithTextContent('rate', $rate->getRate())); + $rateElement->appendChild($this->createNodeWithTextContent('startdate', Util::formatDate($rate->getStartDate()))); + } + } + } +} diff --git a/src/DomDocuments/CustomersDocument.php b/src/DomDocuments/CustomersDocument.php index 21a2cd23..57689727 100644 --- a/src/DomDocuments/CustomersDocument.php +++ b/src/DomDocuments/CustomersDocument.php @@ -2,299 +2,295 @@ namespace PhpTwinfield\DomDocuments; use PhpTwinfield\Customer; -use PhpTwinfield\CustomerAddress; -use PhpTwinfield\CustomerBank; use PhpTwinfield\Util; /** - * The Document Holder for making new XML customers. Is a child class + * The Document Holder for making new XML Customer. Is a child class * of DOMDocument and makes the required DOM tree for the interaction in - * creating a new customer. + * creating a new Customer. * * @package PhpTwinfield * @subpackage Invoice\DOM - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ class CustomersDocument extends BaseDocument { - /** - * Multiple customers can be created at once by enclosing them by the dimensions element. - * - * @return string - */ - protected function getRootTagName(): string + final protected function getRootTagName(): string { - return 'dimensions'; + return "dimensions"; } /** * Turns a passed Customer class into the required markup for interacting * with Twinfield. * + * This method doesn't return anything, instead just adds the Customer to + * this DOMDOcument instance for submission usage. + * + * @access public * @param Customer $customer + * @return void | [Adds to this instance] */ - public function addCustomer(Customer $customer): void + public function addCustomer(Customer $customer) { - $customerEl = $this->createElement("dimension"); - - // Elements and their associated methods for customer - $customerTags = array( - 'code' => 'getCode', - 'name' => 'getName', - 'type' => 'getType', - 'website' => 'getWebsite', - 'office' => 'getOffice', - ); - - if ($customer->getOffice()) { - $customerTags['office'] = 'getOffice'; - } + $customerElement = $this->createElement('dimension'); + $this->rootElement->appendChild($customerElement); - if (!empty($customer->getStatus())) { - $customerEl->setAttribute('status', $customer->getStatus()); - } + $status = $customer->getStatus(); - // Go through each customer element and use the assigned method - foreach ($customerTags as $tag => $method) { + if (!empty($status)) { + $customerElement->setAttribute('status', $status); + } - if($value = $customer->$method()) { - // Make text node for method value - $node = $this->createTextNode($value); + $customerElement->appendChild($this->createNodeWithTextContent('beginperiod', $customer->getBeginPeriod())); + $customerElement->appendChild($this->createNodeWithTextContent('beginyear', $customer->getBeginYear())); - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); + if (!empty($customer->getCode())) { + $customerElement->appendChild($this->createNodeWithTextContent('code', $customer->getCode())); + } - // Add the full element - $customerEl->appendChild($element); - } + $customerElement->appendChild($this->createNodeWithTextContent('endperiod', $customer->getEndPeriod())); + $customerElement->appendChild($this->createNodeWithTextContent('endyear', $customer->getEndYear())); + $customerElement->appendChild($this->createNodeWithTextContent('name', $customer->getName())); + $customerElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($customer->getOffice()))); + $customerElement->appendChild($this->createNodeWithTextContent('shortname', $customer->getShortName())); + $customerElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($customer->getType()))); + $customerElement->appendChild($this->createNodeWithTextContent('website', $customer->getWebsite())); + + $financials = $customer->getFinancials(); + + $financialsElement = $this->createElement('financials'); + $customerElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('collectionschema', $financials->getCollectionSchema())); + $financialsElement->appendChild($this->createNodeWithTextContent('duedays', $financials->getDueDays())); + $financialsElement->appendChild($this->createNodeWithTextContent('ebilling', Util::formatBoolean($financials->getEBilling()))); + $financialsElement->appendChild($this->createNodeWithTextContent('ebillmail', $financials->getEBillMail())); + $financialsElement->appendChild($this->createNodeWithTextContent('meansofpayment', $financials->getMeansOfPayment())); + $financialsElement->appendChild($this->createNodeWithTextContent('payavailable', Util::formatBoolean($financials->getPayAvailable()))); + $financialsElement->appendChild($this->createNodeWithTextContent('paycode', Util::objectToStr($financials->getPayCode()))); + $financialsElement->appendChild($this->createNodeWithTextContent('substitutewith', Util::objectToStr($financials->getSubstituteWith()))); + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($financials->getVatCode()))); + + $collectMandate = $financials->getCollectMandate(); + + if (!empty($collectMandate->getID())) { + // Make collectmandate element + $collectMandateElement = $this->createElement('collectmandate'); + $financialsElement->appendChild($collectMandateElement); + + $collectMandateElement->appendChild($this->createNodeWithTextContent('firstrundate', Util::formatDate($collectMandate->getFirstRunDate()))); + $collectMandateElement->appendChild($this->createNodeWithTextContent('id', $collectMandate->getID())); + $collectMandateElement->appendChild($this->createNodeWithTextContent('signaturedate', Util::formatDate($collectMandate->getSignatureDate()))); } - // Check if the financial information should be supplied - if ($customer->getDueDays() > 0) { - - // Financial elements and their methods - $financialsTags = array( - 'duedays' => 'getDueDays', - 'payavailable' => 'getPayAvailable', - 'paycode' => 'getPayCode', - 'vatcode' => 'getVatCode', - 'ebilling' => 'getEBilling', - 'ebillmail' => 'getEBillMail', - ); - - // Make the financial element - $financialElement = $this->createElement('financials'); - $customerEl->appendChild($financialElement); - - // Go through each financial element and use the assigned method - foreach ($financialsTags as $tag => $method) { - - // Make the text node for the method value - $nodeValue = $customer->$method(); - if (is_bool($nodeValue)) { - $nodeValue = ($nodeValue) ? 'true' : 'false'; - } - $node = $this->createTextNode($nodeValue); + $childValidations = $financials->getChildValidations(); - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); + if (!empty($childValidations)) { + // Make childvalidations element + $childValidationsElement = $this->createElement('childvalidations'); + $financialsElement->appendChild($childValidationsElement); - // Add the full element - $financialElement->appendChild($element); + // Go through each childvalidation assigned to the customer financials + foreach ($childValidations as $childValidation) { + // Make childvalidation element + $childValidationsElement->appendChild($this->createNodeWithTextContent('childvalidation', $childValidation->getElementValue(), $childValidation, array('level' => 'getLevel', 'type' => 'getType'))); } + } - //check if collectmandate should be set - $collectMandate = $customer->getCollectMandate(); - - if ($collectMandate !== null) { - - // Collect mandate elements and their methods - $collectMandateTags = array( - 'id' => 'getID', - 'signaturedate' => 'getSignatureDate', - 'firstrundate' => 'getFirstRunDate', - ); - - // Make the collectmandate element - $collectMandateElement = $this->createElement('collectmandate'); - $financialElement->appendChild($collectMandateElement); - - // Go through each collectmandate element and use the assigned method - foreach ($collectMandateTags as $tag => $method) { - - // Make the text node for the method value - $node = $this->createTextNode($this->getValueFromCallback([$collectMandate, $method])); + $creditManagement = $customer->getCreditManagement(); - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); + // Make creditmanagement element + $creditManagementElement = $this->createElement('creditmanagement'); + $customerElement->appendChild($creditManagementElement); - // Add the full element - $collectMandateElement->appendChild($element); - } - } + if ($creditManagement->getBaseCreditLimit() !== null) { + $creditManagementElement->appendChild($this->createNodeWithTextContent('basecreditlimit', Util::formatMoney($creditManagement->getBaseCreditLimit()))); + } else { + $creditManagementElement->appendChild($this->createNodeWithTextContent('basecreditlimit', 0)); } - //check if creditmanagement should be set - if ($customer->getCreditManagement() !== null) { - - // Credit management elements and their methods - $creditManagementTags = array( - 'responsibleuser' => 'getResponsibleUser', - 'basecreditlimit' => 'getBaseCreditLimit', - 'sendreminder' => 'getSendReminder', - 'reminderemail' => 'getReminderEmail', - 'blocked' => 'getBlocked', - 'freetext1' => 'getFreeText1', - 'freetext2' => 'getFreeText2', - 'comment' => 'getComment', - ); - - // Make the creditmanagement element - $creditManagementElement = $this->createElement('creditmanagement'); - $customerEl->appendChild($creditManagementElement); - - // Go through each credit management element and use the assigned method - foreach ($creditManagementTags as $tag => $method) { - - // Make the text node for the method value - $nodeValue = $customer->getCreditManagement()->$method(); - if (is_bool($nodeValue)) { - $nodeValue = ($nodeValue) ? 'true' : 'false'; - } - $node = $this->createTextNode($nodeValue); + $creditManagementElement->appendChild($this->createNodeWithTextContent('blocked', Util::formatBoolean($creditManagement->getBlocked()))); + $creditManagementElement->appendChild($this->createNodeWithTextContent('comment', $creditManagement->getComment())); + $creditManagementElement->appendChild($this->createNodeWithTextContent('freetext1', Util::formatBoolean($creditManagement->getFreeText1()))); + $creditManagementElement->appendChild($this->createNodeWithTextContent('freetext2', $creditManagement->getFreeText2())); + $creditManagementElement->appendChild($this->createNodeWithTextContent('freetext3', $creditManagement->getFreeText3())); + $creditManagementElement->appendChild($this->createNodeWithTextContent('reminderemail', $creditManagement->getReminderEmail())); + $creditManagementElement->appendChild($this->createNodeWithTextContent('responsibleuser', Util::objectToStr($creditManagement->getResponsibleUser()))); + $creditManagementElement->appendChild($this->createNodeWithTextContent('sendreminder', $creditManagement->getSendReminder())); - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); + // Make invoicing element + $invoicingElement = $this->createElement('invoicing'); + $customerElement->appendChild($invoicingElement); - // Add the full element - $creditManagementElement->appendChild($element); - } - } + $invoicingElement->appendChild($this->createNodeWithTextContent('discountarticle', Util::objectToStr($customer->getDiscountArticle()))); $addresses = $customer->getAddresses(); - if (!empty($addresses)) { - - // Address elements and their methods - $addressTags = array( - 'name' => 'getName', - 'contact' => 'getContact', - 'country' => 'getCountry', - 'city' => 'getCity', - 'postcode' => 'getPostcode', - 'telephone' => 'getTelephone', - 'telefax' => 'getFax', - 'email' => 'getEmail', - 'field1' => 'getField1', - 'field2' => 'getField2', - 'field3' => 'getField3', - 'field4' => 'getField4', - 'field5' => 'getField5', - 'field6' => 'getField6', - ); + if (!empty($addresses)) { // Make addresses element $addressesElement = $this->createElement('addresses'); - $customerEl->appendChild($addressesElement); + $customerElement->appendChild($addressesElement); // Go through each address assigned to the customer - /** @var CustomerAddress $address */ foreach ($addresses as $address) { - - // Makes new address element + // Make address element $addressElement = $this->createElement('address'); $addressesElement->appendChild($addressElement); - // Set attributes - $addressElement->setAttribute('default', Util::formatBoolean($address->getDefault())); - $addressElement->setAttribute('type', $address->getType()); + $default = Util::formatBoolean($address->getDefault()); - // Go through each address element and use the assigned method - foreach ($addressTags as $tag => $method) { + if (!empty($default)) { + $addressElement->setAttribute('default', $default); + } - // Make the text node for the method value - $node = $this->createTextNode($address->$method()); + $id = $address->getID(); - // Make the actual element and assign the text node - $element = $this->createElement($tag); - $element->appendChild($node); + if (!empty($id)) { + $addressElement->setAttribute('id', $id); + } - // Add the completed element - $addressElement->appendChild($element); + $type = $address->getType(); + + if (!empty($type)) { + $addressElement->setAttribute('type', $type); } + + $addressElement->appendChild($this->createNodeWithTextContent('city', $address->getCity())); + $addressElement->appendChild($this->createNodeWithTextContent('country', Util::objectToStr($address->getCountry()))); + $addressElement->appendChild($this->createNodeWithTextContent('email', $address->getEmail())); + $addressElement->appendChild($this->createNodeWithTextContent('field1', $address->getField1())); + $addressElement->appendChild($this->createNodeWithTextContent('field2', $address->getField2())); + $addressElement->appendChild($this->createNodeWithTextContent('field3', $address->getField3())); + $addressElement->appendChild($this->createNodeWithTextContent('field4', $address->getField4())); + $addressElement->appendChild($this->createNodeWithTextContent('field5', $address->getField5())); + $addressElement->appendChild($this->createNodeWithTextContent('field6', $address->getField6())); + $addressElement->appendChild($this->createNodeWithTextContent('name', $address->getName())); + $addressElement->appendChild($this->createNodeWithTextContent('postcode', $address->getPostcode())); + $addressElement->appendChild($this->createNodeWithTextContent('telefax', $address->getTelefax())); + $addressElement->appendChild($this->createNodeWithTextContent('telephone', $address->getTelephone())); } } $banks = $customer->getBanks(); - if (!empty($banks)) { - - // Bank elements and their methods - $bankTags = array( - 'ascription' => 'getAscription', - 'accountnumber' => 'getAccountnumber', - 'bankname' => 'getBankname', - 'biccode' => 'getBiccode', - 'city' => 'getCity', - 'country' => 'getCountry', - 'iban' => 'getIban', - 'natbiccode' => 'getNatbiccode', - 'postcode' => 'getPostcode', - 'state' => 'getState', - ); + if (!empty($banks)) { // Make banks element $banksElement = $this->createElement('banks'); - $customerEl->appendChild($banksElement); + $customerElement->appendChild($banksElement); // Go through each bank assigned to the customer - /** @var CustomerBank $bank */ foreach ($banks as $bank) { - - // Makes new bank element + // Make bank element $bankElement = $this->createElement('bank'); $banksElement->appendChild($bankElement); - // Set attributes - $bankElement->setAttribute('default', Util::formatBoolean($bank->getDefault())); - - // Go through each bank element and use the assigned method - foreach ($bankTags as $tag => $method) { + $default = Util::formatBoolean($bank->getDefault()); - // Make the text node for the method value - $node = $this->createTextNode($bank->$method()); + if (!empty($default)) { + $bankElement->setAttribute('default', $default); + } - // Make the actual element and assign the text node - $element = $this->createElement($tag); - $element->appendChild($node); + $id = $bank->getID(); - // Add the completed element - $bankElement->appendChild($element); + if (!empty($id)) { + $bankElement->setAttribute('id', $id); } - // Bank address fields + $bankAddressElement = $this->createElement('address'); + $bankAddressElement->appendChild($this->createNodeWithTextContent('field2', $bank->getAddressField2())); + $bankAddressElement->appendChild($this->createNodeWithTextContent('field3', $bank->getAddressField3())); + $bankElement->appendChild($bankAddressElement); + + $bankElement->appendChild($this->createNodeWithTextContent('ascription', $bank->getAscription())); + $bankElement->appendChild($this->createNodeWithTextContent('accountnumber', $bank->getAccountNumber())); + $bankElement->appendChild($this->createNodeWithTextContent('bankname', $bank->getBankName())); + $bankElement->appendChild($this->createNodeWithTextContent('biccode', $bank->getBicCode())); + $bankElement->appendChild($this->createNodeWithTextContent('city', $bank->getCity())); + $bankElement->appendChild($this->createNodeWithTextContent('country', Util::objectToStr($bank->getCountry()))); + $bankElement->appendChild($this->createNodeWithTextContent('iban', $bank->getIban())); + $bankElement->appendChild($this->createNodeWithTextContent('natbiccode', $bank->getNatBicCode())); + $bankElement->appendChild($this->createNodeWithTextContent('postcode', $bank->getPostcode())); + $bankElement->appendChild($this->createNodeWithTextContent('state', $bank->getState())); + } + } + + $remittanceAdviceElement = $this->createElement('remittanceadvice'); + $customerElement->appendChild($remittanceAdviceElement); - // Make the text nodes for the bank address fields - $field2Node = $this->createTextNode($bank->getAddressField2()); - $field3Node = $this->createTextNode($bank->getAddressField3()); + $remittanceAdviceElement->appendChild($this->createNodeWithTextContent('sendmail', $customer->getRemittanceAdviceSendMail())); + $remittanceAdviceElement->appendChild($this->createNodeWithTextContent('sendtype', $customer->getRemittanceAdviceSendType())); - // Make the actual elements and assign the text nodes - $field2Element = $this->createElement('field2'); - $field3Element = $this->createElement('field3'); - $field2Element->appendChild($field2Node); - $field3Element->appendChild($field3Node); + $group = Util::objectToStr($customer->getGroup()); - // Combine the fields in an address element and add that to the bank element - $addressElement = $this->createElement('address'); - $addressElement->appendChild($field2Element); - $addressElement->appendChild($field3Element); - $bankElement->appendChild($addressElement); + if (!empty($group)) { + $groupsElement = $this->createElement('groups'); + $groupsElement->appendChild($this->createNodeWithTextContent('group', $group)); + $customerElement->appendChild($groupsElement); + } + + $postingRules = $customer->getPostingRules(); + + if (!empty($postingRules)) { + // Make postingrules element + $postingRulesElement = $this->createElement('postingrules'); + $customerElement->appendChild($postingRulesElement); + + // Go through each posting rule assigned to the customer + foreach ($postingRules as $postingRule) { + // Make postingrule element + $postingRuleElement = $this->createElement('postingrule'); + $postingRulesElement->appendChild($postingRuleElement); + + $id = $postingRule->getID(); + + if (!empty($id)) { + $postingRuleElement->setAttribute('id', $id); + } + + $status = $postingRule->getStatus(); + + if (!empty($status)) { + $postingRuleElement->setAttribute('status', $status); + } + + $postingRuleElement->appendChild($this->createNodeWithTextContent('amount', Util::formatMoney($postingRule->getAmount()))); + $postingRuleElement->appendChild($this->createNodeWithTextContent('currency', Util::objectToStr($postingRule->getCurrency()))); + $postingRuleElement->appendChild($this->createNodeWithTextContent('description', $postingRule->getDescription())); + + $postingRuleLines = $postingRule->getLines(); + + if (!empty($postingRuleLines)) { + // Make lines element + $postingRuleLinesElement = $this->createElement('lines'); + $postingRuleElement->appendChild($postingRuleLinesElement); + + // Go through each line assigned to the customer posting rule + foreach ($postingRuleLines as $postingRuleLine) { + // Make line element + $postingRuleLineElement = $this->createElement('line'); + $postingRuleLinesElement->appendChild($postingRuleLineElement); + + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension1', Util::objectToStr($postingRuleLine->getDimension1()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension2', Util::objectToStr($postingRuleLine->getDimension2()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension3', Util::objectToStr($postingRuleLine->getDimension3()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('description', $postingRuleLine->getDescription())); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($postingRuleLine->getOffice()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('ratio', $postingRuleLine->getRatio())); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($postingRuleLine->getVatCode()))); + } + } } } - $this->rootElement->appendChild($customerEl); + $paymentconditionsElement = $this->createElement('paymentconditions'); + $customerElement->appendChild($paymentconditionsElement); + + $paymentconditionElement = $this->createElement('paymentcondition'); + $paymentconditionsElement->appendChild($paymentconditionElement); + + $paymentconditionElement->appendChild($this->createNodeWithTextContent('discountdays', $customer->getPaymentConditionDiscountDays())); + $paymentconditionElement->appendChild($this->createNodeWithTextContent('discountpercentage', $customer->getPaymentConditionDiscountPercentage())); } } diff --git a/src/DomDocuments/DimensionGroupsDocument.php b/src/DomDocuments/DimensionGroupsDocument.php new file mode 100644 index 00000000..d0308a63 --- /dev/null +++ b/src/DomDocuments/DimensionGroupsDocument.php @@ -0,0 +1,69 @@ + + */ +class DimensionGroupsDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensiongroups"; + } + + /** + * Turns a passed DimensionGroup class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the DimensionGroup to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param DimensionGroup $dimensionGroup + * @return void | [Adds to this instance] + */ + public function addDimensionGroup(DimensionGroup $dimensionGroup) + { + $dimensionGroupElement = $this->createElement('dimensiongroup'); + $this->rootElement->appendChild($dimensionGroupElement); + + $status = $dimensionGroup->getStatus(); + + if (!empty($status)) { + $dimensionGroupElement->setAttribute('status', $status); + } + + $dimensionGroupElement->appendChild($this->createNodeWithTextContent('code', $dimensionGroup->getCode())); + $dimensionGroupElement->appendChild($this->createNodeWithTextContent('name', $dimensionGroup->getName())); + $dimensionGroupElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($dimensionGroup->getOffice()))); + $dimensionGroupElement->appendChild($this->createNodeWithTextContent('shortname', $dimensionGroup->getShortName())); + + $dimensions = $dimensionGroup->getDimensions(); + + if (!empty($dimensions)) { + // Make dimensions element + $dimensionsElement = $this->createElement('dimensions'); + $dimensionGroupElement->appendChild($dimensionsElement); + + // Go through each dimension assigned to the dimension group + foreach ($dimensions as $dimension) { + // Makes dimension element + $dimensionElement = $this->createElement('dimension'); + $dimensionsElement->appendChild($dimensionElement); + + $dimensionElement->appendChild($this->createNodeWithTextContent('code', Util::objectToStr($dimension->getCode()))); + $dimensionElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($dimension->getType()))); + } + } + } +} diff --git a/src/DomDocuments/DimensionTypesDocument.php b/src/DomDocuments/DimensionTypesDocument.php new file mode 100644 index 00000000..c1e2a8bc --- /dev/null +++ b/src/DomDocuments/DimensionTypesDocument.php @@ -0,0 +1,66 @@ + + */ +class DimensionTypesDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensiontypes"; + } + + /** + * Turns a passed DimensionType class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the DimensionType to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param DimensionType $dimensionType + * @return void | [Adds to this instance] + */ + public function addDimensionType(DimensionType $dimensionType) + { + $dimensionTypeElement = $this->createElement('dimensiontype'); + $this->rootElement->appendChild($dimensionTypeElement); + + $dimensionTypeElement->appendChild($this->createNodeWithTextContent('code', $dimensionType->getCode())); + $dimensionTypeElement->appendChild($this->createNodeWithTextContent('mask', $dimensionType->getMask())); + $dimensionTypeElement->appendChild($this->createNodeWithTextContent('name', $dimensionType->getName())); + $dimensionTypeElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($dimensionType->getOffice()))); + $dimensionTypeElement->appendChild($this->createNodeWithTextContent('shortname', $dimensionType->getShortName())); + + $address = $dimensionType->getAddress(); + + $addressElement = $this->createElement('address'); + $dimensionTypeElement->appendChild($addressElement); + + $addressElement->appendChild($this->createNodeWithTextContent('label1', $address->getLabel1())); + $addressElement->appendChild($this->createNodeWithTextContent('label2', $address->getLabel2())); + $addressElement->appendChild($this->createNodeWithTextContent('label3', $address->getLabel3())); + $addressElement->appendChild($this->createNodeWithTextContent('label4', $address->getLabel4())); + $addressElement->appendChild($this->createNodeWithTextContent('label5', $address->getLabel5())); + $addressElement->appendChild($this->createNodeWithTextContent('label6', $address->getLabel6())); + + $levels = $dimensionType->getLevels(); + + $levelsElement = $this->createElement('levels'); + $dimensionTypeElement->appendChild($levelsElement); + + $levelsElement->appendChild($this->createNodeWithTextContent('financials', $levels->getFinancials())); + $levelsElement->appendChild($this->createNodeWithTextContent('time', $levels->getTime())); + } +} diff --git a/src/DomDocuments/ElectronicBankStatementDocument.php b/src/DomDocuments/ElectronicBankStatementDocument.php index 284e0f90..ea2f8200 100644 --- a/src/DomDocuments/ElectronicBankStatementDocument.php +++ b/src/DomDocuments/ElectronicBankStatementDocument.php @@ -3,9 +3,8 @@ namespace PhpTwinfield\DomDocuments; use PhpTwinfield\ElectronicBankStatement; +use PhpTwinfield\Util; -/** - */ class ElectronicBankStatementDocument extends BaseDocument { final protected function getRootTagName(): string @@ -30,14 +29,14 @@ public function addStatement(ElectronicBankStatement $electronicBankStatement) $statement->appendChild($this->createNodeWithTextContent("code", $electronicBankStatement->getCode())); } - $statement->appendChild($this->createNodeWithTextContent("date", $electronicBankStatement->getDate()->format("Ymd"))); - - $this->appendStartCloseValues($statement, $electronicBankStatement); - + $statement->appendChild($this->createNodeWithTextContent("date", Util::formatDate($electronicBankStatement->getDate()))); + $statement->appendChild($this->createNodeWithTextContent("currency", Util::objectToStr($electronicBankStatement->getCurrency()))); + $statement->appendChild($this->createNodeWithTextContent("startvalue", Util::formatMoney($electronicBankStatement->getStartValue()))); + $statement->appendChild($this->createNodeWithTextContent("closevalue", Util::formatMoney($electronicBankStatement->getCloseValue()))); $statement->appendChild($this->createNodeWithTextContent("statementnumber", $electronicBankStatement->getStatementnumber())); if ($electronicBankStatement->getOffice()) { - $statement->appendChild($this->createNodeWithTextContent("office", $electronicBankStatement->getOffice()->getCode())); + $statement->appendChild($this->createNodeWithTextContent("office", Util::objectToStr($electronicBankStatement->getOffice()))); } $transactions = $this->createElement("transactions"); @@ -46,10 +45,10 @@ public function addStatement(ElectronicBankStatement $electronicBankStatement) $node = $this->createElement("transaction"); - if ($transaction->getContraaccount()) { - $node->appendChild($this->createNodeWithTextContent("contraaccount", $transaction->getContraaccount())); - } elseif ($transaction->getContraiban()) { - $node->appendChild($this->createNodeWithTextContent("contraiban", $transaction->getContraiban())); + if ($transaction->getContraAccount()) { + $node->appendChild($this->createNodeWithTextContent("contraaccount", $transaction->getContraAccount())); + } elseif ($transaction->getContraIban()) { + $node->appendChild($this->createNodeWithTextContent("contraiban", $transaction->getContraIban())); } $node->appendChild($this->createNodeWithTextContent("type", $transaction->getType())); @@ -58,15 +57,14 @@ public function addStatement(ElectronicBankStatement $electronicBankStatement) $node->appendChild($this->createNodeWithTextContent("reference", $transaction->getReference())); } - $this->appendValueValues($node, $transaction); - + $node->appendChild($this->createNodeWithTextContent('debitcredit', $transaction->getDebitCredit())); + $node->appendChild($this->createNodeWithTextContent('value', Util::formatMoney($transaction->getValue()))); $node->appendChild($this->createNodeWithTextContent("description", $transaction->getDescription())); $transactions->appendChild($node); } $statement->appendChild($transactions); - $this->rootElement->appendChild($statement); } -} \ No newline at end of file +} diff --git a/src/DomDocuments/FixedAssetsDocument.php b/src/DomDocuments/FixedAssetsDocument.php new file mode 100644 index 00000000..24180c3c --- /dev/null +++ b/src/DomDocuments/FixedAssetsDocument.php @@ -0,0 +1,118 @@ + + */ +class FixedAssetsDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensions"; + } + + /** + * Turns a passed FixedAsset class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the FixedAsset to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param FixedAsset $fixedAsset + * @return void | [Adds to this instance] + */ + public function addFixedAsset(FixedAsset $fixedAsset) + { + $fixedAssetElement = $this->createElement('dimension'); + $this->rootElement->appendChild($fixedAssetElement); + + $status = $fixedAsset->getStatus(); + + if (!empty($status)) { + $fixedAssetElement->setAttribute('status', $status); + } + + if (!empty($fixedAsset->getCode())) { + $fixedAssetElement->appendChild($this->createNodeWithTextContent('code', $fixedAsset->getCode())); + } + + $fixedAssetElement->appendChild($this->createNodeWithTextContent('name', $fixedAsset->getName())); + $fixedAssetElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($fixedAsset->getOffice()))); + $fixedAssetElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($fixedAsset->getType()))); + + $financials = $fixedAsset->getFinancials(); + + $financialsElement = $this->createElement('financials'); + $fixedAssetElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('substitutionlevel', $financials->getSubstitutionLevel())); + $financialsElement->appendChild($this->createNodeWithTextContent('substitutewith', Util::objectToStr($financials->getSubstituteWith()))); + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($financials->getVatCode()))); + + $fixedAssets = $fixedAsset->getFixedAssets(); + + $fixedAssetsElement = $this->createElement('fixedassets'); + $fixedAssetElement->appendChild($fixedAssetsElement); + + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('beginperiod', $fixedAssets->getBeginPeriod())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('freetext1', $fixedAssets->getFreeText1())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('freetext2', $fixedAssets->getFreeText2())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('freetext3', $fixedAssets->getFreeText3())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('freetext4', $fixedAssets->getFreeText4())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('freetext5', $fixedAssets->getFreeText5())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('lastdepreciation', $fixedAssets->getLastDepreciation())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('method', Util::objectToStr($fixedAssets->getMethod()))); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('nrofperiods', $fixedAssets->getNrOfPeriods())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('percentage', $fixedAssets->getPercentage())); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('purchasedate', Util::formatDate($fixedAssets->getPurchaseDate()))); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('residualvalue', Util::formatMoney($fixedAssets->getResidualValue()))); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('selldate', Util::formatDate($fixedAssets->getSellDate()))); + $fixedAssetsElement->appendChild($this->createNodeWithTextContent('stopvalue', Util::formatMoney($fixedAssets->getStopValue()))); + + $transactionLines = $fixedAssets->getTransactionLines(); + + if (!empty($transactionLines)) { + // Make translines element + $transactionLinesElement = $this->createElement('translines'); + $fixedAssetsElement->appendChild($transactionLinesElement); + + // Go through each transaction line assigned to the fixed asset fixed assets + foreach ($transactionLines as $transactionLine) { + // Make transline element + $transactionLineElement = $this->createElement('transline'); + $transactionLinesElement->appendChild($transactionLineElement); + + $transactionLineElement->appendChild($this->createNodeWithTextContent('amount', Util::formatMoney($transactionLine->getAmount()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('code', Util::objectToStr($transactionLine->getCode()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim1', Util::objectToStr($transactionLine->getDim1()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim2', Util::objectToStr($transactionLine->getDim2()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim3', Util::objectToStr($transactionLine->getDim3()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim4', Util::objectToStr($transactionLine->getDim4()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim5', Util::objectToStr($transactionLine->getDim5()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('dim6', Util::objectToStr($transactionLine->getDim6()))); + $transactionLineElement->appendChild($this->createNodeWithTextContent('line', $transactionLine->getLine())); + $transactionLineElement->appendChild($this->createNodeWithTextContent('number', $transactionLine->getNumber())); + $transactionLineElement->appendChild($this->createNodeWithTextContent('period', $transactionLine->getPeriod())); + } + } + + $group = Util::objectToStr($fixedAsset->getGroup()); + + if (!empty($group)) { + $groupsElement = $this->createElement('groups'); + $groupsElement->appendChild($this->createNodeWithTextContent('group', $group)); + $fixedAssetElement->appendChild($groupsElement); + } + } +} diff --git a/src/DomDocuments/GeneralLedgersDocument.php b/src/DomDocuments/GeneralLedgersDocument.php new file mode 100644 index 00000000..b0c10549 --- /dev/null +++ b/src/DomDocuments/GeneralLedgersDocument.php @@ -0,0 +1,92 @@ + + */ +class GeneralLedgersDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensions"; + } + + /** + * Turns a passed GeneralLedger class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the GeneralLedger to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param GeneralLedger $generalLedger + * @return void | [Adds to this instance] + */ + public function addGeneralLedger(GeneralLedger $generalLedger) + { + $generalLedgerElement = $this->createElement('dimension'); + $this->rootElement->appendChild($generalLedgerElement); + + $status = $generalLedger->getStatus(); + + if (!empty($status)) { + $generalLedgerElement->setAttribute('status', $status); + } + + $generalLedgerElement->appendChild($this->createNodeWithTextContent('beginperiod', $generalLedger->getBeginPeriod())); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('beginyear', $generalLedger->getBeginYear())); + + if (!empty($generalLedger->getCode())) { + $generalLedgerElement->appendChild($this->createNodeWithTextContent('code', $generalLedger->getCode())); + } + + $generalLedgerElement->appendChild($this->createNodeWithTextContent('endperiod', $generalLedger->getEndPeriod())); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('endyear', $generalLedger->getEndYear())); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('name', $generalLedger->getName())); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($generalLedger->getOffice()))); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('shortname', $generalLedger->getShortName())); + $generalLedgerElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($generalLedger->getType()))); + + $financials = $generalLedger->getFinancials(); + + $financialsElement = $this->createElement('financials'); + $generalLedgerElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('accounttype', $financials->getAccountType())); + $financialsElement->appendChild($this->createNodeWithTextContent('matchtype', $financials->getMatchType())); + $financialsElement->appendChild($this->createNodeWithTextContent('subanalyse', $financials->getSubAnalyse())); + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($financials->getVatCode()))); + + $childValidations = $financials->getChildValidations(); + + if (!empty($childValidations)) { + // Make childvalidations element + $childValidationsElement = $this->createElement('childvalidations'); + $financialsElement->appendChild($childValidationsElement); + + // Go through each childvalidation assigned to the general ledger financials + foreach ($childValidations as $childValidation) { + // Make childvalidation element + $childValidationsElement->appendChild($this->createNodeWithTextContent('childvalidation', $childValidation->getElementValue(), $childValidation, array('level' => 'getLevel', 'type' => 'getType'))); + } + } + + $group = Util::objectToStr($generalLedger->getGroup()); + + if (!empty($group)) { + $groupsElement = $this->createElement('groups'); + $groupsElement->appendChild($this->createNodeWithTextContent('group', $group)); + $generalLedgerElement->appendChild($groupsElement); + } + } +} diff --git a/src/DomDocuments/InvoicesDocument.php b/src/DomDocuments/InvoicesDocument.php index ad6a9274..62edba08 100644 --- a/src/DomDocuments/InvoicesDocument.php +++ b/src/DomDocuments/InvoicesDocument.php @@ -1,18 +1,22 @@ - * @copyright (c) 2013, Pronamic - * @version 0.0.1 + * @author Willem van de Sande , extended by Yannick Aerssens */ class InvoicesDocument extends BaseDocument { @@ -24,115 +28,110 @@ final protected function getRootTagName(): string /** * Turns a passed Invoice class into the required markup for interacting * with Twinfield. - * - * This method doesn't return anything, instead just adds the invoice - * to this DOMDocument instance for submission usage. - * + * + * This method doesn't return anything, instead just adds the Invoice to + * this DOMDOcument instance for submission usage. + * * @access public * @param Invoice $invoice + * @param AuthenticatedConnection $connection * @return void | [Adds to this instance] */ - public function addInvoice(Invoice $invoice) + public function addInvoice(Invoice $invoice, AuthenticatedConnection $connection) { - // Make a new element $invoiceElement = $this->createElement('salesinvoice'); + $this->rootElement->appendChild($invoiceElement); - // Makes a child header element + // Make header element $headerElement = $this->createElement('header'); $invoiceElement->appendChild($headerElement); - - // Set customer element - $customer = $invoice->getCustomer(); - - // - $customerNode = $this->createTextNode($customer->getCode()); - $customerElement = $this->createElement('customer'); - $customerElement->appendChild($customerNode); - $headerElement->appendChild($customerElement); - - // Elements and their associated methods for invoice - $headerTags = array( - 'office' => 'getOffice', - 'invoicetype' => 'getInvoiceType', - 'invoicenumber' => 'getInvoiceNumber', - 'status' => 'getStatus', - 'currency' => 'getCurrency', - 'period' => 'getPeriod', - 'invoicedate' => 'getInvoiceDate', - 'duedate' => 'getDueDate', - 'bank' => 'getBank', - 'invoiceaddressnumber' => 'getInvoiceAddressNumber', - 'deliveraddressnumber' => 'getDeliverAddressNumber', - 'headertext' => 'getHeaderText', - 'footertext' => 'getFooterText' - ); - - // Go through each element and use the assigned method - foreach ($headerTags as $tag => $method) { - - $value = $this->getValueFromCallback([$invoice, $method]); - - if(null !== $value) { - // Make text node for method value - $node = $this->createTextNode($value); - - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); - - // Add the full element - $headerElement->appendChild($element); - } + + $calculateOnly = $invoice->getCalculateOnly(); + + if (!empty($calculateOnly)) { + $headerElement->setAttribute('calculateonly', $calculateOnly); } - // Add orders - $linesElement = $this->createElement('lines'); - $invoiceElement->appendChild($linesElement); - - // Elements and their associated methods for lines - $lineTags = array( - 'quantity' => 'getQuantity', - 'article' => 'getArticle', - 'subarticle' => 'getSubArticle', - 'description' => 'getDescription', - 'unitspriceexcl' => 'getUnitsPriceExcl', - 'units' => 'getUnits', - 'vatcode' => 'getVatCode', - 'freetext1' => 'getFreeText1', - 'freetext2' => 'getFreeText2', - 'freetext3' => 'getFreeText3', - 'performancedate' => 'getPerformanceDate', - 'performancetype' => 'getPerformanceType', - 'dim1' => 'getDim1', - ); - - // Loop through all orders, and add those elements - foreach ($invoice->getLines() as $line) { - - // Make a new line element, and add to - $lineElement = $this->createElement('line'); - $lineElement->setAttribute('id', $line->getID()); - $linesElement->appendChild($lineElement); - - // Go through each element and use the assigned method - foreach ($lineTags as $tag => $method) { - - // Make text node for method value - $node = $this->createTextNode($this->getValueFromCallback([$line, $method])); - - if ($node->textContent === "") { - continue; + $raiseWarning = $invoice->getRaiseWarning(); + + if (!empty($raiseWarning)) { + $headerElement->setAttribute('raisewarning', $raiseWarning); + } + + $headerElement->appendChild($this->createNodeWithTextContent('bank', Util::objectToStr($invoice->getBank()))); + $headerElement->appendChild($this->createNodeWithTextContent('currency', Util::objectToStr($invoice->getCurrency()))); + $headerElement->appendChild($this->createNodeWithTextContent('customer', Util::objectToStr($invoice->getCustomer()))); + $headerElement->appendChild($this->createNodeWithTextContent('deliveraddressnumber', $invoice->getDeliverAddressNumber())); + $headerElement->appendChild($this->createNodeWithTextContent('duedate', Util::formatDate($invoice->getDueDate()))); + $headerElement->appendChild($this->createNodeWithTextContent('footertext', $invoice->getFooterText())); + $headerElement->appendChild($this->createNodeWithTextContent('headertext', $invoice->getHeaderText())); + $headerElement->appendChild($this->createNodeWithTextContent('invoiceaddressnumber', $invoice->getInvoiceAddressNumber())); + $headerElement->appendChild($this->createNodeWithTextContent('invoicedate', Util::formatDate($invoice->getInvoiceDate()))); + + if (!empty($invoice->getInvoiceNumber())) { + $headerElement->appendChild($this->createNodeWithTextContent('invoicenumber', $invoice->getInvoiceNumber())); + } + + $headerElement->appendChild($this->createNodeWithTextContent('invoicetype', Util::objectToStr($invoice->getInvoiceType()))); + $headerElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($invoice->getOffice()))); + $headerElement->appendChild($this->createNodeWithTextContent('paymentmethod', $invoice->getPaymentMethod())); + $headerElement->appendChild($this->createNodeWithTextContent('period', $invoice->getPeriod())); + $headerElement->appendChild($this->createNodeWithTextContent('status', $invoice->getStatus())); + + $invoiceTypeApiConnector = new InvoiceTypeApiConnector($connection); + $invoiceVatType = $invoiceTypeApiConnector->getInvoiceTypeVatType(Util::objectToStr($invoice->getInvoiceType())); + + $articleApiConnector = new ArticleApiConnector($connection); + + $lines = $invoice->getLines(); + + if (!empty($lines)) { + // Make lines element + $linesElement = $this->createElement('lines'); + $invoiceElement->appendChild($linesElement); + + // Go through each line assigned to the invoice + foreach ($lines as $line) { + // Makes new line element + $lineElement = $this->createElement('line'); + $linesElement->appendChild($lineElement); + + $id = $line->getID(); + + if (!empty($id)) { + $lineElement->setAttribute('id', $id); + } + + $lineElement->appendChild($this->createNodeWithTextContent('allowdiscountorpremium', Util::formatBoolean($line->getAllowDiscountOrPremium()))); + $lineElement->appendChild($this->createNodeWithTextContent('article', Util::objectToStr($line->getArticle()))); + $lineElement->appendChild($this->createNodeWithTextContent('description', $line->getDescription())); + $lineElement->appendChild($this->createNodeWithTextContent('dim1', Util::objectToStr($line->getDim1()))); + $lineElement->appendChild($this->createNodeWithTextContent('freetext1', $line->getFreeText1())); + $lineElement->appendChild($this->createNodeWithTextContent('freetext2', $line->getFreeText2())); + $lineElement->appendChild($this->createNodeWithTextContent('freetext3', $line->getFreeText3())); + $lineElement->appendChild($this->createNodeWithTextContent('performancedate', Util::formatDate($line->getPerformanceDate()))); + $lineElement->appendChild($this->createNodeWithTextContent('performancetype', $line->getPerformanceType())); + $lineElement->appendChild($this->createNodeWithTextContent('quantity', $line->getQuantity())); + $lineElement->appendChild($this->createNodeWithTextContent('subarticle', $line->getSubArticleToString())); + $lineElement->appendChild($this->createNodeWithTextContent('units', $line->getUnits())); + + if ($invoiceVatType == 'inclusive') { + $lineElement->appendChild($this->createNodeWithTextContent('unitspriceinc', Util::formatMoney($line->getUnitsPriceInc()))); + } else { + $lineElement->appendChild($this->createNodeWithTextContent('unitspriceexcl', Util::formatMoney($line->getUnitsPriceExcl()))); } - // Make the actual element with tag - $element = $this->createElement($tag); - $element->appendChild($node); + if (Util::objectToStr($line->getArticle()) != '0') { + $article = $articleApiConnector->get(Util::objectToStr($line->getArticle()), $invoice->getOffice()); + } else { + $article = new Article; + $article->setAllowChangeVatCode(true); + } - // Add the full element - $lineElement->appendChild($element); + if ($article->getAllowChangeVatCode()) { + $lineElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($line->getVatCode()))); + } } } - - $this->rootElement->appendChild($invoiceElement); } } diff --git a/src/DomDocuments/MatchDocument.php b/src/DomDocuments/MatchDocument.php index 3171c7e6..bec3c9f0 100644 --- a/src/DomDocuments/MatchDocument.php +++ b/src/DomDocuments/MatchDocument.php @@ -12,11 +12,11 @@ public function addMatchSet(MatchSet $matchSet) { $set = $this->createElement("set"); - $this->appendOfficeField($set, $matchSet->getOffice()); + $set->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($matchSet->getOffice()))); $set->appendChild($this->createNodeWithTextContent("matchcode", $matchSet->getMatchCode()->getValue())); - $this->appendDateElement($set, "matchdate", $matchSet->getMatchDate()); + $set->appendChild($this->createNodeWithTextContent("matchdate", Util::formatDate($matchSet->getMatchDate()))); $lines = $this->createElement("lines"); @@ -33,9 +33,9 @@ private function createLineElement(MatchLine $line): \DOMElement { $element = $this->createElement("line"); - $element->appendChild($this->createNodeWithTextContent("transcode", $line->getTranscode())); - $element->appendChild($this->createNodeWithTextContent("transnumber", $line->getTransnumber())); - $element->appendChild($this->createNodeWithTextContent("transline", $line->getTransline())); + $element->appendChild($this->createNodeWithTextContent("transcode", $line->getTransCode())); + $element->appendChild($this->createNodeWithTextContent("transnumber", $line->getTransNumber())); + $element->appendChild($this->createNodeWithTextContent("transline", $line->getTransLine())); if ($line->getMatchValue() !== null) { $element->appendChild($this->createNodeWithTextContent("matchvalue", Util::formatMoney($line->getMatchValue()))); @@ -59,4 +59,4 @@ protected function getRootTagName(): string { return "match"; } -} \ No newline at end of file +} diff --git a/src/DomDocuments/ProjectsDocument.php b/src/DomDocuments/ProjectsDocument.php new file mode 100644 index 00000000..4a777bd3 --- /dev/null +++ b/src/DomDocuments/ProjectsDocument.php @@ -0,0 +1,113 @@ + + */ +class ProjectsDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "dimensions"; + } + + /** + * Turns a passed Project class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the Project to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param Project $project + * @return void | [Adds to this instance] + */ + public function addProject(Project $project) + { + $projectElement = $this->createElement('dimension'); + $this->rootElement->appendChild($projectElement); + + $status = $project->getStatus(); + + if (!empty($status)) { + $projectElement->setAttribute('status', $status); + } + + if (!empty($project->getCode())) { + $projectElement->appendChild($this->createNodeWithTextContent('code', $project->getCode())); + } + + $projectElement->appendChild($this->createNodeWithTextContent('name', $project->getName())); + $projectElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($project->getOffice()))); + $projectElement->appendChild($this->createNodeWithTextContent('shortname', $project->getShortName())); + $projectElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($project->getType()))); + + $financialsElement = $this->createElement('financials'); + $projectElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($project->getVatCode()))); + + $projects = $project->getProjects(); + + $projectsElement = $this->createElement('projects'); + $projectElement->appendChild($projectsElement); + + $inheritArray = array('authoriser' => 'getAuthoriserToString', 'billable' => 'getBillableToString', 'customer' => 'getCustomerToString', 'rate' => 'getRateToString'); + + foreach ($inheritArray as $inheritVar => $method) { + $methodLocked = "get" . ucfirst($inheritVar) . "Locked"; + $methodLockedString = $methodLocked . "ToString"; + $methodInherit = "get" . ucfirst($inheritVar) . "Inherit"; + $methodInheritString = $methodInherit . "ToString"; + $elementVar = ""; + + if ($projects->$methodLocked() != true || $projects->$methodInherit() != true) { + $elementVar = $projects->$method(); + } elseif ($inheritVar == 'billable') { + $projects->setBillableForRatio(false); + } + + $attributesArray = array('locked' => $methodLockedString, 'inherit' => $methodInheritString); + + if ($inheritVar == 'billable') { + $attributesArray['forratio'] = 'getBillableForRatioToString'; + } + + $projectsElement->appendChild($this->createNodeWithTextContent($inheritVar, $elementVar, $projects, $attributesArray)); + } + + $projectsElement->appendChild($this->createNodeWithTextContent('invoicedescription', $projects->getInvoiceDescription())); + $projectsElement->appendChild($this->createNodeWithTextContent('validfrom', Util::formatDate($projects->getValidFrom()))); + $projectsElement->appendChild($this->createNodeWithTextContent('validtill', Util::formatDate($projects->getValidTill()))); + + $quantities = $projects->getQuantities(); + + if (!empty($quantities)) { + // Make quantities element + $quantitiesElement = $this->createElement('quantities'); + $projectsElement->appendChild($quantitiesElement); + + // Go through each quantity assigned to the project project + foreach ($quantities as $quantity) { + // Makes quantity element + $quantityElement = $this->createElement('quantity'); + $quantitiesElement->appendChild($quantityElement); + + $quantityElement->appendChild($this->createNodeWithTextContent('label', $quantity->getLabel())); + $quantityElement->appendChild($this->createNodeWithTextContent('rate', Util::objectToStr($quantity->getRate()))); + $quantityElement->appendChild($this->createNodeWithTextContent('billable', Util::formatBoolean($quantity->getBillable()), $quantity, array('locked' => 'getBillableLockedToString'))); + $quantityElement->appendChild($this->createNodeWithTextContent('mandatory', Util::formatBoolean($quantity->getMandatory()))); + } + } + } +} diff --git a/src/DomDocuments/RatesDocument.php b/src/DomDocuments/RatesDocument.php new file mode 100644 index 00000000..2681cac8 --- /dev/null +++ b/src/DomDocuments/RatesDocument.php @@ -0,0 +1,86 @@ + + */ +class RatesDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "projectrates"; + } + + /** + * Turns a passed Rate class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the Rate to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param Rate $rate + * @return void | [Adds to this instance] + */ + public function addRate(Rate $rate) + { + $rateElement = $this->createElement('projectrate'); + $this->rootElement->appendChild($rateElement); + + $status = $rate->getStatus(); + + if (!empty($status)) { + $rateElement->setAttribute('status', $status); + } + + $rateElement->appendChild($this->createNodeWithTextContent('code', $rate->getCode())); + $rateElement->appendChild($this->createNodeWithTextContent('currency', Util::objectToStr($rate->getCurrency()))); + $rateElement->appendChild($this->createNodeWithTextContent('name', $rate->getName())); + $rateElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($rate->getOffice()))); + $rateElement->appendChild($this->createNodeWithTextContent('shortname', $rate->getShortName())); + $rateElement->appendChild($this->createNodeWithTextContent('type', $rate->getType())); + $rateElement->appendChild($this->createNodeWithTextContent('unit', $rate->getUnit())); + + $rateChanges = $rate->getRateChanges(); + + if (!empty($rateChanges)) { + // Make ratechanges element + $rateChangesElement = $this->createElement('ratechanges'); + $rateElement->appendChild($rateChangesElement); + + // Go through each rate change assigned to the rate + foreach ($rateChanges as $rateChange) { + // Makes ratechange element + $rateChangeElement = $this->createElement('ratechange'); + $rateChangesElement->appendChild($rateChangeElement); + + $id = $rateChange->getID(); + + if (!empty($id)) { + $rateChangeElement->setAttribute('id', $id); + } + + $status = $rateChange->getStatus(); + + if (!empty($status)) { + $rateChangeElement->setAttribute('status', $status); + } + + $rateChangeElement->appendChild($this->createNodeWithTextContent('begindate', Util::formatDate($rateChange->getBeginDate()))); + $rateChangeElement->appendChild($this->createNodeWithTextContent('enddate', Util::formatDate($rateChange->getEndDate()))); + $rateChangeElement->appendChild($this->createNodeWithTextContent('externalrate', $rateChange->getExternalRate())); + $rateChangeElement->appendChild($this->createNodeWithTextContent('internalrate', $rateChange->getInternalRate())); + } + } + } +} diff --git a/src/DomDocuments/SuppliersDocument.php b/src/DomDocuments/SuppliersDocument.php index 5f35dab5..bca24128 100644 --- a/src/DomDocuments/SuppliersDocument.php +++ b/src/DomDocuments/SuppliersDocument.php @@ -2,45 +2,30 @@ namespace PhpTwinfield\DomDocuments; use PhpTwinfield\Supplier; +use PhpTwinfield\Util; /** - * The Document Holder for making new XML customers. Is a child class + * The Document Holder for making new XML Supplier. Is a child class * of DOMDocument and makes the required DOM tree for the interaction in - * creating a new customer. + * creating a new Supplier. * * @package PhpTwinfield * @subpackage Invoice\DOM - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ -class SuppliersDocument extends \DOMDocument +class SuppliersDocument extends BaseDocument { - /** - * Holds the element - * that all additional elements should be a child of - * @var \DOMElement - */ - private $dimensionElement; - - /** - * Creates the element and adds it to the property - * dimensionElement - * - * @access public - */ - public function __construct() + final protected function getRootTagName(): string { - parent::__construct('1.0', 'UTF-8'); - - $this->dimensionElement = $this->createElement('dimension'); - $this->appendChild($this->dimensionElement); + return "dimensions"; } /** * Turns a passed Supplier class into the required markup for interacting * with Twinfield. * - * This method doesn't return anything, instead just adds the invoice to + * This method doesn't return anything, instead just adds the Supplier to * this DOMDOcument instance for submission usage. * * @access public @@ -49,190 +34,234 @@ public function __construct() */ public function addSupplier(Supplier $supplier) { - // Elements and their associated methods for customer - $supplierTags = array( - 'code' => 'getCode', - 'name' => 'getName', - 'type' => 'getType', - 'website' => 'getWebsite', - 'office' => 'getOffice', - ); - - if ($supplier->getOffice()) { - $supplierTags['office'] = 'getOffice'; - } + $supplierElement = $this->createElement('dimension'); + $this->rootElement->appendChild($supplierElement); $status = $supplier->getStatus(); + if (!empty($status)) { - $this->dimensionElement->setAttribute('status', $status); + $supplierElement->setAttribute('status', $status); } - // Go through each customer element and use the assigned method - foreach ($supplierTags as $tag => $method) { + $supplierElement->appendChild($this->createNodeWithTextContent('beginperiod', $supplier->getBeginPeriod())); + $supplierElement->appendChild($this->createNodeWithTextContent('beginyear', $supplier->getBeginYear())); - // Make text node for method value - $node = $this->createTextNode($supplier->$method()); - - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); - - // Add the full element - $this->dimensionElement->appendChild($element); + if (!empty($supplier->getCode())) { + $supplierElement->appendChild($this->createNodeWithTextContent('code', $supplier->getCode())); } - // Check if the financial information should be supplied - if ($supplier->getDueDays() > 0) { - - // Financial elements and their methods - $financialsTags = array( - 'duedays' => 'getDueDays', - 'payavailable' => 'getPayAvailable', - 'paycode' => 'getPayCode', - 'vatcode' => 'getVatCode', - 'ebilling' => 'getEBilling', - 'ebillmail' => 'getEBillMail' - ); - - // Make the financial element - $financialElement = $this->createElement('financials'); - $this->dimensionElement->appendChild($financialElement); - - // Go through each financial element and use the assigned method - foreach ($financialsTags as $tag => $method) { - - // Make the text node for the method value - $nodeValue = $supplier->$method(); - if (is_bool($nodeValue)) { - $nodeValue = ($nodeValue) ? 'true' : 'false'; - } - $node = $this->createTextNode($nodeValue); - - // Make the actual element and assign the node - $element = $this->createElement($tag); - $element->appendChild($node); - - // Add the full element - $financialElement->appendChild($element); + $supplierElement->appendChild($this->createNodeWithTextContent('endperiod', $supplier->getEndPeriod())); + $supplierElement->appendChild($this->createNodeWithTextContent('endyear', $supplier->getEndYear())); + $supplierElement->appendChild($this->createNodeWithTextContent('name', $supplier->getName())); + $supplierElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($supplier->getOffice()))); + $supplierElement->appendChild($this->createNodeWithTextContent('shortname', $supplier->getShortName())); + $supplierElement->appendChild($this->createNodeWithTextContent('type', Util::objectToStr($supplier->getType()))); + $supplierElement->appendChild($this->createNodeWithTextContent('website', $supplier->getWebsite())); + + $financials = $supplier->getFinancials(); + + $financialsElement = $this->createElement('financials'); + $supplierElement->appendChild($financialsElement); + + $financialsElement->appendChild($this->createNodeWithTextContent('duedays', $financials->getDueDays())); + $financialsElement->appendChild($this->createNodeWithTextContent('meansofpayment', $financials->getMeansOfPayment())); + $financialsElement->appendChild($this->createNodeWithTextContent('payavailable', Util::formatBoolean($financials->getPayAvailable()))); + $financialsElement->appendChild($this->createNodeWithTextContent('paycode', Util::objectToStr($financials->getPayCode()))); + $financialsElement->appendChild($this->createNodeWithTextContent('relationsreference', $financials->getRelationsReference())); + $financialsElement->appendChild($this->createNodeWithTextContent('substitutewith', Util::objectToStr($financials->getSubstituteWith()))); + $financialsElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($financials->getVatCode()))); + + $childValidations = $financials->getChildValidations(); + + if (!empty($childValidations)) { + // Make childvalidations element + $childValidationsElement = $this->createElement('childvalidations'); + $financialsElement->appendChild($childValidationsElement); + + // Go through each childvalidation assigned to the supplier financials + foreach ($childValidations as $childValidation) { + // Make childvalidation element + $childValidationsElement->appendChild($this->createNodeWithTextContent('childvalidation', $childValidation->getElementValue(), $childValidation, array('level' => 'getLevel', 'type' => 'getType'))); } } - $addresses = $supplier->getAddresses(); - if (!empty($addresses)) { - - // Address elements and their methods - $addressTags = array( - 'name' => 'getName', - 'contact' => 'getContact', - 'country' => 'getCountry', - 'city' => 'getCity', - 'postcode' => 'getPostcode', - 'telephone' => 'getTelephone', - 'telefax' => 'getFax', - 'email' => 'getEmail', - 'field1' => 'getField1', - 'field2' => 'getField2', - 'field3' => 'getField3', - 'field4' => 'getField4', - 'field5' => 'getField5', - 'field6' => 'getField6' - ); + if (!empty($addresses)) { // Make addresses element $addressesElement = $this->createElement('addresses'); - $this->dimensionElement->appendChild($addressesElement); + $supplierElement->appendChild($addressesElement); - // Go through each address assigned to the customer + // Go through each address assigned to the supplier foreach ($addresses as $address) { - - // Makes new address element + // Make address element $addressElement = $this->createElement('address'); $addressesElement->appendChild($addressElement); - // Set attributes - $addressElement->setAttribute('default', $address->getDefault()); - $addressElement->setAttribute('type', $address->getType()); + $default = Util::formatBoolean($address->getDefault()); - // Go through each address element and use the assigned method - foreach ($addressTags as $tag => $method) { + if (!empty($default)) { + $addressElement->setAttribute('default', $default); + } + + $id = $address->getID(); - // Make the text node for the method value - $node = $this->createTextNode($address->$method()); + if (!empty($id)) { + $addressElement->setAttribute('id', $id); + } - // Make the actual element and assign the text node - $element = $this->createElement($tag); - $element->appendChild($node); + $type = $address->getType(); - // Add the completed element - $addressElement->appendChild($element); + if (!empty($type)) { + $addressElement->setAttribute('type', $type); } + + $addressElement->appendChild($this->createNodeWithTextContent('city', $address->getCity())); + $addressElement->appendChild($this->createNodeWithTextContent('country', Util::objectToStr($address->getCountry()))); + $addressElement->appendChild($this->createNodeWithTextContent('email', $address->getEmail())); + $addressElement->appendChild($this->createNodeWithTextContent('field1', $address->getField1())); + $addressElement->appendChild($this->createNodeWithTextContent('field2', $address->getField2())); + $addressElement->appendChild($this->createNodeWithTextContent('field3', $address->getField3())); + $addressElement->appendChild($this->createNodeWithTextContent('field4', $address->getField4())); + $addressElement->appendChild($this->createNodeWithTextContent('field5', $address->getField5())); + $addressElement->appendChild($this->createNodeWithTextContent('field6', $address->getField6())); + $addressElement->appendChild($this->createNodeWithTextContent('name', $address->getName())); + $addressElement->appendChild($this->createNodeWithTextContent('postcode', $address->getPostcode())); + $addressElement->appendChild($this->createNodeWithTextContent('telefax', $address->getTelefax())); + $addressElement->appendChild($this->createNodeWithTextContent('telephone', $address->getTelephone())); } } $banks = $supplier->getBanks(); - if (!empty($banks)) { - - // Bank elements and their methods - $bankTags = array( - 'ascription' => 'getAscription', - 'accountnumber' => 'getAccountnumber', - 'bankname' => 'getBankname', - 'biccode' => 'getBiccode', - 'city' => 'getCity', - 'country' => 'getCountry', - 'iban' => 'getIban', - 'natbiccode' => 'getNatbiccode', - 'postcode' => 'getPostcode', - 'state' => 'getState' - ); + if (!empty($banks)) { // Make banks element $banksElement = $this->createElement('banks'); - $this->dimensionElement->appendChild($banksElement); + $supplierElement->appendChild($banksElement); - // Go through each bank assigned to the customer + // Go through each bank assigned to the supplier foreach ($banks as $bank) { - - // Makes new bank element + // Make bank element $bankElement = $this->createElement('bank'); $banksElement->appendChild($bankElement); - // Set attributes - $bankElement->setAttribute('default', $bank->getDefault()); + $blocked = Util::formatBoolean($bank->getBlocked()); - // Go through each bank element and use the assigned method - foreach ($bankTags as $tag => $method) { + if (!empty($blocked)) { + $bankElement->setAttribute('blocked', $blocked); + } - // Make the text node for the method value - $node = $this->createTextNode($bank->$method()); + $default = Util::formatBoolean($bank->getDefault()); - // Make the actual element and assign the text node - $element = $this->createElement($tag); - $element->appendChild($node); + if (!empty($default)) { + $bankElement->setAttribute('default', $default); + } - // Add the completed element - $bankElement->appendChild($element); + $id = $bank->getID(); + + if (!empty($id)) { + $bankElement->setAttribute('id', $id); } - // Bank address fields + $bankAddressElement = $this->createElement('address'); + $bankAddressElement->appendChild($this->createNodeWithTextContent('field2', $bank->getAddressField2())); + $bankAddressElement->appendChild($this->createNodeWithTextContent('field3', $bank->getAddressField3())); + $bankElement->appendChild($bankAddressElement); + + $bankElement->appendChild($this->createNodeWithTextContent('ascription', $bank->getAscription())); + $bankElement->appendChild($this->createNodeWithTextContent('accountnumber', $bank->getAccountNumber())); + $bankElement->appendChild($this->createNodeWithTextContent('bankname', $bank->getBankName())); + $bankElement->appendChild($this->createNodeWithTextContent('biccode', $bank->getBicCode())); + $bankElement->appendChild($this->createNodeWithTextContent('city', $bank->getCity())); + $bankElement->appendChild($this->createNodeWithTextContent('country', Util::objectToStr($bank->getCountry()))); + $bankElement->appendChild($this->createNodeWithTextContent('iban', $bank->getIban())); + $bankElement->appendChild($this->createNodeWithTextContent('natbiccode', $bank->getNatBicCode())); + $bankElement->appendChild($this->createNodeWithTextContent('postcode', $bank->getPostcode())); + $bankElement->appendChild($this->createNodeWithTextContent('state', $bank->getState())); + } + } - // Make the text nodes for the bank address fields - $field2Node = $this->createTextNode($bank->getAddressField2()); - $field3Node = $this->createTextNode($bank->getAddressField3()); + $remittanceAdviceElement = $this->createElement('remittanceadvice'); + $supplierElement->appendChild($remittanceAdviceElement); - // Make the actual elements and assign the text nodes - $field2Element = $this->createElement('field2'); - $field3Element = $this->createElement('field3'); - $field2Element->appendChild($field2Node); - $field3Element->appendChild($field3Node); + $remittanceAdviceElement->appendChild($this->createNodeWithTextContent('sendmail', $supplier->getRemittanceAdviceSendMail())); + $remittanceAdviceElement->appendChild($this->createNodeWithTextContent('sendtype', $supplier->getRemittanceAdviceSendType())); - // Combine the fields in an address element and add that to the bank element - $addressElement = $this->createElement('address'); - $addressElement->appendChild($field2Element); - $addressElement->appendChild($field3Element); - $bankElement->appendChild($addressElement); + $group = Util::objectToStr($supplier->getGroup()); + + if (!empty($group)) { + $groupsElement = $this->createElement('groups'); + $groupsElement->appendChild($this->createNodeWithTextContent('group', $group)); + $supplierElement->appendChild($groupsElement); + } + + $postingRules = $supplier->getPostingRules(); + + if (!empty($postingRules)) { + // Make postingrules element + $postingRulesElement = $this->createElement('postingrules'); + $supplierElement->appendChild($postingRulesElement); + + // Go through each posting rule assigned to the supplier + foreach ($postingRules as $postingRule) { + // Make postingrule element + $postingRuleElement = $this->createElement('postingrule'); + $postingRulesElement->appendChild($postingRuleElement); + + $id = $postingRule->getID(); + + if (!empty($id)) { + $postingRuleElement->setAttribute('id', $id); + } + + $status = $postingRule->getStatus(); + + if (!empty($status)) { + $postingRuleElement->setAttribute('status', $status); + } + + $postingRuleElement->appendChild($this->createNodeWithTextContent('amount', Util::formatMoney($postingRule->getAmount()))); + $postingRuleElement->appendChild($this->createNodeWithTextContent('currency', Util::objectToStr($postingRule->getCurrency()))); + $postingRuleElement->appendChild($this->createNodeWithTextContent('description', $postingRule->getDescription())); + + $postingRuleLines = $postingRule->getLines(); + + if (!empty($postingRuleLines)) { + // Make lines element + $postingRuleLinesElement = $this->createElement('lines'); + $postingRuleElement->appendChild($postingRuleLinesElement); + + // Go through each line assigned to the supplier posting rule + foreach ($postingRuleLines as $postingRuleLine) { + // Make line element + $postingRuleLineElement = $this->createElement('line'); + $postingRuleLinesElement->appendChild($postingRuleLineElement); + + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension1', Util::objectToStr($postingRuleLine->getDimension1()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension2', Util::objectToStr($postingRuleLine->getDimension2()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('dimension3', Util::objectToStr($postingRuleLine->getDimension3()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('description', $postingRuleLine->getDescription())); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($postingRuleLine->getOffice()))); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('ratio', $postingRuleLine->getRatio())); + $postingRuleLineElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($postingRuleLine->getVatCode()))); + } + } } } + + $paymentconditionsElement = $this->createElement('paymentconditions'); + $supplierElement->appendChild($paymentconditionsElement); + + $paymentconditionElement = $this->createElement('paymentcondition'); + $paymentconditionsElement->appendChild($paymentconditionElement); + + $paymentconditionElement->appendChild($this->createNodeWithTextContent('discountdays', $supplier->getPaymentConditionDiscountDays())); + $paymentconditionElement->appendChild($this->createNodeWithTextContent('discountpercentage', $supplier->getPaymentConditionDiscountPercentage())); + + $blockedAccountPaymentConditionsElement = $this->createElement('blockedaccountpaymentconditions'); + $supplierElement->appendChild($blockedAccountPaymentConditionsElement); + + $blockedAccountPaymentConditionsElement->appendChild($this->createNodeWithTextContent('includevat', $supplier->getBlockedAccountPaymentConditionsIncludeVat())); + $blockedAccountPaymentConditionsElement->appendChild($this->createNodeWithTextContent('percentage', $supplier->getBlockedAccountPaymentConditionsPercentage())); } } diff --git a/src/DomDocuments/TransactionsDocument.php b/src/DomDocuments/TransactionsDocument.php index 2e0d9a9b..e9efc571 100644 --- a/src/DomDocuments/TransactionsDocument.php +++ b/src/DomDocuments/TransactionsDocument.php @@ -2,25 +2,38 @@ namespace PhpTwinfield\DomDocuments; +use PhpTwinfield\BankTransaction; use PhpTwinfield\BaseTransaction; use PhpTwinfield\BaseTransactionLine; use PhpTwinfield\CashTransaction; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\JournalTransactionLine; -use PhpTwinfield\Transactions\TransactionFields\DueDateField; -use PhpTwinfield\Transactions\TransactionFields\FreeTextFields; -use PhpTwinfield\Transactions\TransactionFields\InvoiceNumberField; -use PhpTwinfield\Transactions\TransactionFields\PaymentReferenceField; -use PhpTwinfield\Transactions\TransactionFields\StatementNumberField; -use PhpTwinfield\Transactions\TransactionLineFields\FreeCharField; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; -use PhpTwinfield\Transactions\TransactionLineFields\VatTotalFields; +use PhpTwinfield\Fields\DueDateField; +use PhpTwinfield\Fields\FreeText1Field; +use PhpTwinfield\Fields\FreeText2Field; +use PhpTwinfield\Fields\FreeText3Field; +use PhpTwinfield\Fields\InvoiceNumberField; +use PhpTwinfield\Fields\PerformanceDateField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\Transaction\CloseAndStartValueFields; +use PhpTwinfield\Fields\Transaction\PaymentReferenceField; +use PhpTwinfield\Fields\Transaction\RegimeField; +use PhpTwinfield\Fields\Transaction\StatementNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaselineField; +use PhpTwinfield\Fields\Transaction\TransactionLine\CurrencyDateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\FreeCharField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceCountryField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceVatNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueFields; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueOpenField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatTotalField; use PhpTwinfield\Util; /** * TransactionsDocument class. * - * @author Dylan Schoenmakers + * @author Dylan Schoenmakers , extended by Yannick Aerssens */ class TransactionsDocument extends BaseDocument { @@ -43,11 +56,12 @@ public function addTransaction(BaseTransaction $transaction) // Transaction $transactionElement = $this->createElement('transaction'); $transactionElement->setAttribute('destiny', $transaction->getDestiny()); + if ($transaction->getRaiseWarning() !== null) { - $transactionElement->appendChild($this->createBooleanAttribute('raisewarning', $transaction->getRaiseWarning())); + $transactionElement->setAttribute('raisewarning', Util::formatBoolean($transaction->getRaiseWarning())); } - if ($transaction->isAutoBalanceVat() !== null) { - $transactionElement->appendChild($this->createBooleanAttribute('autobalancevat', $transaction->isAutoBalanceVat())); + if ($transaction->getAutoBalanceVat() !== null) { + $transactionElement->setAttribute('autobalancevat', Util::formatBoolean($transaction->getAutoBalanceVat())); } $this->rootElement->appendChild($transactionElement); @@ -56,62 +70,59 @@ public function addTransaction(BaseTransaction $transaction) $headerElement = $this->createElement('header'); $transactionElement->appendChild($headerElement); - $codeElement = $this->createNodeWithTextContent('code', $transaction->getCode()); - $headerElement->appendChild($codeElement); + $headerElement->appendChild($this->createNodeWithTextContent('office', Util::objectToStr($transaction->getOffice()))); + $headerElement->appendChild($this->createNodeWithTextContent('code', $transaction->getCode())); if ($transaction->getNumber() !== null) { - $numberElement = $this->createNodeWithTextContent('number', $transaction->getNumber()); - $headerElement->appendChild($numberElement); + $headerElement->appendChild($this->createNodeWithTextContent('number', $transaction->getNumber())); + } + + if ($transaction->getPeriod() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent('period', $transaction->getPeriod())); } if ($transaction->getCurrency() !== null) { - $currencyElement = $this->createNodeWithTextContent('currency', $transaction->getCurrency()); - $headerElement->appendChild($currencyElement); + $headerElement->appendChild($this->createNodeWithTextContent('currency', Util::objectToStr($transaction->getCurrency()))); } - $this->appendDateElement($headerElement, "date", $transaction->getDate()); + if (Util::objectUses(RegimeField::class, $transaction) && $transaction->getRegime() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent('regime', $transaction->getRegime())); + } - if ($transaction->getPeriod() !== null) { - $periodElement = $this->createNodeWithTextContent('period', $transaction->getPeriod()); - $headerElement->appendChild($periodElement); + $headerElement->appendChild($this->createNodeWithTextContent("date", Util::formatDate($transaction->getDate()), $transaction, array('raisewarning' => 'getDateRaiseWarningToString'))); + + if (Util::objectUses(StatementNumberField::class, $transaction) && $transaction->getStatementnumber() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent('statementnumber', $transaction->getStatementnumber())); } - if ( - in_array(InvoiceNumberField::class, class_uses($transaction)) && - $transaction->getInvoiceNumber() !== null - ) { - $invoiceNumberElement = $this->createNodeWithTextContent('invoicenumber', $transaction->getInvoiceNumber()); - $headerElement->appendChild($invoiceNumberElement); + if (Util::objectUses(CloseAndStartValueFields::class, $transaction)) { + $headerElement->appendChild($this->createNodeWithTextContent('startvalue', Util::formatMoney($transaction->getStartValue()))); + $headerElement->appendChild($this->createNodeWithTextContent('closevalue', Util::formatMoney($transaction->getCloseValue()))); } - if ( - in_array(PaymentReferenceField::class, class_uses($transaction)) && - $transaction->getPaymentReference() !== null - ) { - $paymentReferenceElement = $this->createNodeWithTextContent('paymentreference', $transaction->getPaymentReference()); - $headerElement->appendChild($paymentReferenceElement); + if (Util::objectUses(DueDateField::class, $transaction) && $transaction->getDueDate() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent("duedate", Util::formatDate($transaction->getDueDate()))); } - $officeElement = $this->createNodeWithTextContent('office', $transaction->getOffice()); - $headerElement->appendChild($officeElement); + if (Util::objectUses(InvoiceNumberField::class, $transaction) && $transaction->getInvoiceNumber() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent('invoicenumber', $transaction->getInvoiceNumber(), $transaction, array('raisewarning' => 'getInvoiceNumberRaiseWarningToString'))); + } - if (Util::objectUses(DueDateField::class, $transaction) && - $transaction->getDueDate() !== null - ) { - $this->appendDateElement($headerElement, "duedate", $transaction->getDueDate()); + if (Util::objectUses(PaymentReferenceField::class, $transaction) && $transaction->getPaymentReference() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent('paymentreference', $transaction->getPaymentReference())); } - if (Util::objectUses(StatementNumberField::class, $transaction) && - $transaction->getStatementnumber() !== null) { - $headerElement->appendChild($this->createNodeWithTextContent('statementnumber', $transaction->getStatementnumber())); + if ($transaction->getFreeText1() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent("freetext1", $transaction->getFreeText1())); } - if ($transaction instanceof CashTransaction) { - $headerElement->appendChild($this->createNodeWithTextContent('startvalue', Util::formatMoney($transaction->getStartvalue()))); - $headerElement->appendChild($this->createNodeWithTextContent('closevalue', Util::formatMoney($transaction->getClosevalue()))); + if ($transaction->getFreeText2() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent("freetext2", $transaction->getFreeText2())); } - $this->appendFreeTextFields($headerElement, $transaction); + if ($transaction->getFreeText3() !== null) { + $headerElement->appendChild($this->createNodeWithTextContent("freetext3", $transaction->getFreeText3())); + } $linesElement = $this->createElement('lines'); $transactionElement->appendChild($linesElement); @@ -124,116 +135,119 @@ public function addTransaction(BaseTransaction $transaction) $lineElement->setAttribute('id', $transactionLine->getId()); $linesElement->appendChild($lineElement); - $dim1Element = $this->createNodeWithTextContent('dim1', $transactionLine->getDim1()); - $lineElement->appendChild($dim1Element); - - $dim2 = $transactionLine->getDim2(); - if (!empty($dim2)) { - $dim2Element = $this->createNodeWithTextContent('dim2', $dim2); - $lineElement->appendChild($dim2Element); + $lineElement->appendChild($this->createNodeWithTextContent('dim1', Util::objectToStr($transactionLine->getDim1()))); + + if (!empty($transactionLine->getDim2())) { + $lineElement->appendChild($this->createNodeWithTextContent('dim2', Util::objectToStr($transactionLine->getDim2()))); } - $this->appendValueValues($lineElement, $transactionLine); + if (!empty($transactionLine->getDim3())) { + $lineElement->appendChild($this->createNodeWithTextContent('dim3', Util::objectToStr($transactionLine->getDim3()))); + } - if (Util::objectUses(PerformanceFields::class, $transactionLine)) { - /** @var PerformanceFields $transactionLine */ - $performanceType = $transactionLine->getPerformanceType(); - if (!empty($performanceType)) { - $perfElement = $this->createNodeWithTextContent('performancetype', $performanceType); - $lineElement->appendChild($perfElement); - } + if (Util::objectUses(ValueFields::class, $transactionLine)) { + $lineElement->appendChild($this->createNodeWithTextContent('debitcredit', $transactionLine->getDebitCredit())); + $lineElement->appendChild($this->createNodeWithTextContent('value', Util::formatMoney($transactionLine->getValue()))); + } - $performanceCountry = $transactionLine->getPerformanceCountry(); - if (!empty($performanceCountry)) { - $perfCountryElement = $this->createNodeWithTextContent('performancecountry', $performanceCountry); - $lineElement->appendChild($perfCountryElement); - } + if (Util::objectUses(BaselineField::class, $transactionLine) && !empty($transactionLine->getBaseline())) { + $lineElement->appendChild($this->createNodeWithTextContent('baseline', $transactionLine->getBaseline())); + } - $performanceVatNumber = $transactionLine->getPerformanceVatNumber(); - if (!empty($performanceVatNumber)) { - $perfVatNumberElement = $this->createNodeWithTextContent('performancevatnumber', $performanceVatNumber); - $lineElement->appendChild($perfVatNumberElement); - } + if (!empty($transactionLine->getBaseValue())) { + $lineElement->appendChild($this->createNodeWithTextContent('basevalue', Util::formatMoney($transactionLine->getBaseValue()))); + } - $performanceDate = $transactionLine->getPerformanceDate(); - if (!empty($performanceDate)) { - $this->appendDateElement($lineElement, "performancedate", $transactionLine->getPerformanceDate()); - } + if (!empty($transactionLine->getComment())) { + $lineElement->appendChild($this->createNodeWithTextContent('comment', $transactionLine->getComment())); } - if (Util::objectUses(FreeCharField::class, $transactionLine)) { - /** @var FreeCharField $transactionLine */ - $freeChar = $transactionLine->getFreeChar(); - if (!empty($freeChar)) { - $freeCharElement = $this->createNodeWithTextContent('freechar', $freeChar); - $lineElement->appendChild($freeCharElement); - } + if (Util::objectUses(CurrencyDateField::class, $transactionLine) && !empty($transactionLine->getCurrencyDate())) { + $lineElement->appendChild($this->createNodeWithTextContent("currencydate", Util::formatDate($transactionLine->getCurrencyDate()))); } - if (Util::objectUses(FreeTextFields::class, $transactionLine)) { - $freetext1 = $transactionLine->getFreetext1(); - if (!empty($freetext1)) { - $freetext1Element = $this->createNodeWithTextContent('freetext1', $freetext1); - $lineElement->appendChild($freetext1Element); - } + if (!empty($transactionLine->getDescription())) { + $lineElement->appendChild($this->createNodeWithTextContent('description', $transactionLine->getDescription())); + } - $freetext2 = $transactionLine->getFreetext2(); - if (!empty($freetext2)) { - $freetext2Element = $this->createNodeWithTextContent('freetext2', $freetext2); - $lineElement->appendChild($freetext2Element); - } + if (!empty($transactionLine->getDestOffice())) { + $lineElement->appendChild($this->createNodeWithTextContent('destoffice', Util::objectToStr($transactionLine->getDestOffice()))); + } + + if (Util::objectUses(FreeCharField::class, $transactionLine) && !empty($transactionLine->getFreeChar())) { + $lineElement->appendChild($this->createNodeWithTextContent('freechar', $transactionLine->getFreeChar())); + } + + if (Util::objectUses(InvoiceNumberField::class, $transactionLine) && !empty($transactionLine->getInvoiceNumber())) { + $lineElement->appendChild($this->createNodeWithTextContent('invoicenumber', $transactionLine->getInvoiceNumber())); + } - $freetext3 = $transactionLine->getFreetext3(); - if (!empty($freetext3)) { - $freetext3Element = $this->createNodeWithTextContent('freetext3', $freetext3); - $lineElement->appendChild($freetext3Element); - } + if (Util::objectUses(PerformanceCountryField::class, $transactionLine) && !empty($transactionLine->getPerformanceCountry())) { + $lineElement->appendChild($this->createNodeWithTextContent('performancecountry', Util::objectToStr($transactionLine->getPerformanceCountry()))); } - if (Util::objectUses(VatTotalFields::class, $transactionLine)) { - /** @var VatTotalFields $transactionLine */ - $vatTotal = $transactionLine->getVatTotal(); - if (!empty($vatTotal)) { - $vatTotalElement = $this->createNodeWithTextContent('vattotal', Util::formatMoney($vatTotal)); - $lineElement->appendChild($vatTotalElement); - } + if (Util::objectUses(PerformanceDateField::class, $transactionLine) && !empty($transactionLine->getPerformanceDate())) { + $lineElement->appendChild($this->createNodeWithTextContent("performancedate", Util::formatDate($transactionLine->getPerformanceDate()))); + } + + if (Util::objectUses(PerformanceTypeField::class, $transactionLine) && !empty($transactionLine->getPerformanceType())) { + $lineElement->appendChild($this->createNodeWithTextContent('performancetype', $transactionLine->getPerformanceType())); + } + + if (Util::objectUses(PerformanceVatNumberField::class, $transactionLine) && !empty($transactionLine->getPerformanceVatNumber())) { + $lineElement->appendChild($this->createNodeWithTextContent('performancevatnumber', $transactionLine->getPerformanceVatNumber())); + } + + if (!empty($transactionLine->getRate())) { + $lineElement->appendChild($this->createNodeWithTextContent('rate', $transactionLine->getRate())); + } + + if (!empty($transactionLine->getRepRate())) { + $lineElement->appendChild($this->createNodeWithTextContent('reprate', $transactionLine->getRepRate())); + } + + if (!empty($transactionLine->getRepValue())) { + $lineElement->appendChild($this->createNodeWithTextContent('repvalue', Util::formatMoney($transactionLine->getRepValue()))); + } + + if (Util::objectUses(VatBaseTotalField::class, $transactionLine) && !empty($transactionLine->getVatBaseTotal())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatbasetotal', Util::formatMoney($transactionLine->getVatBaseTotal()))); + } + + if (!empty($transactionLine->getVatBaseTurnover())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatbaseturnover', Util::formatMoney($transactionLine->getVatBaseTurnover()))); + } + + if (!empty($transactionLine->getVatBaseValue())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatbasevalue', Util::formatMoney($transactionLine->getVatBaseValue()))); + } + + if (!empty($transactionLine->getVatCode())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatcode', Util::objectToStr($transactionLine->getVatCode()))); + } + + if (Util::objectUses(VatRepTotalField::class, $transactionLine) && !empty($transactionLine->getVatRepTotal())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatreptotal', Util::formatMoney($transactionLine->getVatRepTotal()))); + } - $vatBaseTotal= $transactionLine->getVatBaseTotal(); - if (!empty($vatBaseTotal)) { - $vatBaseTotalElement = $this->createNodeWithTextContent('vatbasetotal', Util::formatMoney($vatBaseTotal)); - $lineElement->appendChild($vatBaseTotalElement); - } + if (!empty($transactionLine->getVatRepValue())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatrepvalue', Util::formatMoney($transactionLine->getVatRepValue()))); } - if (Util::objectUses(InvoiceNumberField::class, $transactionLine) && - $transactionLine->getInvoiceNumber() !== null - ) { - $invoiceNumberElement = $this->createNodeWithTextContent('invoicenumber', $transactionLine->getInvoiceNumber()); - $lineElement->appendChild($invoiceNumberElement); + if (!empty($transactionLine->getVatRepTurnover())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatrepturnover', Util::formatMoney($transactionLine->getVatRepTurnover()))); } - $vatValue = $transactionLine->getVatValue(); - if (!empty($vatValue)) { - $vatElement = $this->createNodeWithTextContent('vatvalue', Util::formatMoney($vatValue)); - $lineElement->appendChild($vatElement); + if (Util::objectUses(VatTotalField::class, $transactionLine) && !empty($transactionLine->getVatTotal())) { + $lineElement->appendChild($this->createNodeWithTextContent('vattotal', Util::formatMoney($transactionLine->getVatTotal()))); } - $baseline = $transactionLine->getBaseline(); - if (!empty($baseline)) { - $baselineElement = $this->createNodeWithTextContent('baseline', $baseline); - $lineElement->appendChild($baselineElement); + if (!empty($transactionLine->getVatTurnover())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatturnover', Util::formatMoney($transactionLine->getVatTurnover()))); } - if ($transactionLine->getDescription() !== null) { - $descriptionNode = $this->createTextNode($transactionLine->getDescription()); - $descriptionElement = $this->createElement('description'); - $descriptionElement->appendChild($descriptionNode); - $lineElement->appendChild($descriptionElement); - } - - if (!LineType::TOTAL()->equals($transactionLine->getLineType()) && $transactionLine->getVatCode() !== null) { - $vatCodeElement = $this->createNodeWithTextContent('vatcode', $transactionLine->getVatCode()); - $lineElement->appendChild($vatCodeElement); + if (!empty($transactionLine->getVatValue())) { + $lineElement->appendChild($this->createNodeWithTextContent('vatvalue', Util::formatMoney($transactionLine->getVatValue()))); } } } diff --git a/src/DomDocuments/VatCodesDocument.php b/src/DomDocuments/VatCodesDocument.php new file mode 100644 index 00000000..43a223b7 --- /dev/null +++ b/src/DomDocuments/VatCodesDocument.php @@ -0,0 +1,103 @@ + + */ +class VatCodesDocument extends BaseDocument +{ + final protected function getRootTagName(): string + { + return "vat"; + } + + /** + * Turns a passed VatCode class into the required markup for interacting + * with Twinfield. + * + * This method doesn't return anything, instead just adds the VatCode to + * this DOMDOcument instance for submission usage. + * + * @access public + * @param VatCode $vatCode + * @return void | [Adds to this instance] + */ + public function addVatCode(VatCode $vatCode) + { + $vatCodeElement = $this->rootElement; + + $status = $vatCode->getStatus(); + + if (!empty($status)) { + $vatCodeElement->setAttribute('status', $status); + } + + $vatCodeElement->appendChild($this->createNodeWithTextContent('code', $vatCode->getCode())); + $vatCodeElement->appendChild($this->createNodeWithTextContent('name', $vatCode->getName())); + $vatCodeElement->appendChild($this->createNodeWithTextContent('shortname', $vatCode->getShortName())); + $vatCodeElement->appendChild($this->createNodeWithTextContent('type', $vatCode->getType())); + + $percentages = $vatCode->getPercentages(); + + if (!empty($percentages)) { + // Make percentages element + $percentagesElement = $this->createElement('percentages'); + $vatCodeElement->appendChild($percentagesElement); + + // Go through each percentage assigned to the vatCode + foreach ($percentages as $percentage) { + // Makes percentage element + $percentageElement = $this->createElement('percentage'); + $percentagesElement->appendChild($percentageElement); + + $status = $percentage->getStatus(); + + if (!empty($status)) { + $percentageElement->setAttribute('status', $status); + } + + $percentageElement->appendChild($this->createNodeWithTextContent('date', Util::formatDate($percentage->getDate()))); + $percentageElement->appendChild($this->createNodeWithTextContent('name', $percentage->getName())); + $percentageElement->appendChild($this->createNodeWithTextContent('percentage', $percentage->getPercentage())); + $percentageElement->appendChild($this->createNodeWithTextContent('shortname', $percentage->getShortName())); + + $accounts = $percentage->getAccounts(); + + if (!empty($accounts)) { + // Make accounts element + $accountsElement = $this->createElement('accounts'); + $percentageElement->appendChild($accountsElement); + + // Go through each account assigned to the vat code percentage + foreach ($accounts as $account) { + // Makes account element + $accountElement = $this->createElement('account'); + $accountsElement->appendChild($accountElement); + + $id = $account->getID(); + + if (!empty($id)) { + $accountElement->setAttribute('id', $id); + } + + $accountElement->appendChild($this->createNodeWithTextContent('dim1', Util::objectToStr($account->getDim1()))); + $accountElement->appendChild($this->createNodeWithTextContent('group', Util::objectToStr($account->getGroup()))); + $accountElement->appendChild($this->createNodeWithTextContent('groupcountry', Util::objectToStr($account->getGroupCountry()))); + $accountElement->appendChild($this->createNodeWithTextContent('linetype', $account->getLineType())); + $accountElement->appendChild($this->createNodeWithTextContent('percentage', $account->getPercentage())); + } + } + } + } + } +} diff --git a/src/ElectronicBankStatement.php b/src/ElectronicBankStatement.php index a6b2e77a..9e9443b5 100644 --- a/src/ElectronicBankStatement.php +++ b/src/ElectronicBankStatement.php @@ -2,13 +2,13 @@ namespace PhpTwinfield; -use Money\Currency; use Money\Money; use PhpTwinfield\Enums\DebitCredit; -use PhpTwinfield\Transactions\TransactionFields\OfficeField; -use PhpTwinfield\Transactions\TransactionFields\StartAndCloseValueFields; -use PhpTwinfield\Transactions\TransactionFields\StatementNumberField; -use PhpTwinfield\Transactions\TransactionLineFields\DateField; +use PhpTwinfield\Fields\CurrencyField; +use PhpTwinfield\Fields\DateField; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\Transaction\CloseAndStartValueFields; +use PhpTwinfield\Fields\Transaction\StatementNumberField; use Webmozart\Assert\Assert; /** @@ -16,50 +16,52 @@ */ class ElectronicBankStatement { - use StartAndCloseValueFields; + use CloseAndStartValueFields; use DateField; use OfficeField; use StatementNumberField; - /** - * Optional attribute to indicate whether duplicates may be imported or not. - * - * @var bool - */ - private $importDuplicate = false; - - /** - * Contains the bank statement transactions. + /* + * Account number. Either account or iban or code should be set. * - * @var array + * @var ?string */ - private $transactions = []; + private $account; - /** - * Account number. Either account or iban or code should be set. + /* + * Code of the corresponding bank book. Either account or iban or code should be set. * * @var ?string */ - private $account; + private $code; - /** + /* * IBAN account number. Either account or iban or code should be set. * * @var ?string */ private $iban; - /** - * Code of the corresponding bank book. Either account or iban or code should be set. + /* + * Optional attribute to indicate whether duplicates may be imported or not. * - * @var ?string + * @var bool */ - private $code; + private $importDuplicate = false; + + /* + * Contains the bank statement transactions. + * + * @var array + */ + private $transactions = []; public function __construct() { - $this->currency = new Currency("EUR"); - $this->startvalue = new Money(0, $this->getCurrency()); + $currency = new \PhpTwinfield\Currency; + $currency->setCode('XXX'); + $this->currency = $currency; + $this->startValue = new \Money\Money(0, new \Money\Currency($currency->getCode())); } public function getAccount(): ?string @@ -74,18 +76,6 @@ public function setAccount(string $account): void $this->code = null; } - public function getIban(): ?string - { - return $this->iban; - } - - public function setIban(string $iban): void - { - $this->iban = $iban; - $this->account = null; - $this->code = null; - } - public function getCode(): ?string { return $this->code; @@ -101,6 +91,18 @@ public function setCode($code): void $this->iban = null; } + public function getIban(): ?string + { + return $this->iban; + } + + public function setIban(string $iban): void + { + $this->iban = $iban; + $this->account = null; + $this->code = null; + } + /** * @return bool */ @@ -128,19 +130,19 @@ public function getTransactions(): array public function setTransactions(array $transactions): void { Assert::allIsInstanceOf($transactions, ElectronicBankStatementTransaction::class); - Assert::notEmpty($this->startvalue); + Assert::notEmpty($this->startValue); $this->transactions = $transactions; - $this->closevalue = $this->startvalue; + $this->closeValue = $this->startValue; foreach ($transactions as $transaction) { if ($transaction->getDebitCredit() == DebitCredit::CREDIT()) { - $this->closevalue = $this->closevalue->add($transaction->getValue()); + $this->closeValue = $this->closeValue->add($transaction->getValue()); } else { - $this->closevalue = $this->closevalue->subtract($transaction->getValue()); + $this->closeValue = $this->closeValue->subtract($transaction->getValue()); } } } -} \ No newline at end of file +} diff --git a/src/ElectronicBankStatementTransaction.php b/src/ElectronicBankStatementTransaction.php index 967bd4d6..26332ef5 100644 --- a/src/ElectronicBankStatementTransaction.php +++ b/src/ElectronicBankStatementTransaction.php @@ -3,32 +3,38 @@ namespace PhpTwinfield; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionLineFields\FourDimFields; -use PhpTwinfield\Transactions\TransactionLineFields\ValueFields; +use PhpTwinfield\Fields\Dim1Field; +use PhpTwinfield\Fields\Dim2Field; +use PhpTwinfield\Fields\Dim3Field; +use PhpTwinfield\Fields\Dim4Field; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueFields; class ElectronicBankStatementTransaction { + use Dim1Field; + use Dim2Field; + use Dim3Field; + use Dim4Field; use ValueFields; - use FourDimFields; /** - * Contra account number in BBAN format. Either use contraaccount or contraiban or leave empty. + * Contra account number in BBAN format. Either use contraAccount or contraIban or leave empty. * * @var string */ - private $contraaccount; + private $contraAccount; + /** - * Contra account number in IBAN format. Either use contraaccount or contraiban or leave empty. + * Contra account number in IBAN format. Either use contraAccount or contraIban or leave empty. * * @var string */ - private $contraiban; + private $contraIban; + /** - * Transaction type code. - * * @var string */ - private $type; + private $description; /** * Reference for own use. @@ -38,40 +44,50 @@ class ElectronicBankStatementTransaction private $reference; /** + * Transaction type code. + * * @var string */ - private $description; + private $type; - public function getContraaccount(): ?string + public function getContraAccount(): ?string { - return $this->contraaccount; + return $this->contraAccount; } - public function setContraaccount(string $contraaccount): void + public function setContraAccount(string $contraAccount): void { - $this->contraaccount = $contraaccount; - $this->contraiban = null; + $this->contraAccount = $contraAccount; + $this->contraIban = null; } - public function getContraiban(): ?string + public function getContraIban(): ?string { - return $this->contraiban; + return $this->contraIban; } - public function setContraiban(string $contraiban): void + public function setContraIban(string $contraIban): void { - $this->contraiban = $contraiban; - $this->contraaccount = null; + $this->contraIban = $contraIban; + $this->contraAccount = null; } - public function getType(): string + public function getDescription(): string { - return $this->type; + return $this->description; } - public function setType(string $type): void + public function setDescription(string $description): void { - $this->type = $type; + $this->description = $description; + } + + public function getLineType(): ?LineType + { + /* + * Electronic bank statement transactions don't have line types. + */ + return null; } public function getReference(): ?string @@ -84,22 +100,14 @@ public function setReference(string $reference): void $this->reference = $reference; } - public function getDescription(): string - { - return $this->description; - } - - public function setDescription(string $description): void + public function getType(): string { - $this->description = $description; + return $this->type; } - public function getLineType(): ?LineType + public function setType(string $type): void { - /* - * Electronic bank statement transactions don't have line types. - */ - return null; + $this->type = $type; } /** diff --git a/src/Enums/AccountType.php b/src/Enums/AccountType.php new file mode 100644 index 00000000..210449d3 --- /dev/null +++ b/src/Enums/AccountType.php @@ -0,0 +1,19 @@ +assetsToActivate; + } + + /** + * @return $this + */ + public function setAssetsToActivate(?GeneralLedger $assetsToActivate): self + { + $this->assetsToActivate = $assetsToActivate; + return $this; + } +} diff --git a/src/Fields/AssetMethod/CalcMethodField.php b/src/Fields/AssetMethod/CalcMethodField.php new file mode 100644 index 00000000..7f06805a --- /dev/null +++ b/src/Fields/AssetMethod/CalcMethodField.php @@ -0,0 +1,31 @@ +calcMethod; + } + + /** + * @param CalcMethod|null $calcMethod + * @return $this + */ + public function setCalcMethod(?CalcMethod $calcMethod): self + { + $this->calcMethod = $calcMethod; + return $this; + } +} diff --git a/src/Fields/AssetMethod/DepreciateReconciliationField.php b/src/Fields/AssetMethod/DepreciateReconciliationField.php new file mode 100644 index 00000000..59000d5c --- /dev/null +++ b/src/Fields/AssetMethod/DepreciateReconciliationField.php @@ -0,0 +1,31 @@ +depreciateReconciliation; + } + + /** + * @param DepreciateReconciliation|null $depreciateReconciliation + * @return $this + */ + public function setDepreciateReconciliation(?DepreciateReconciliation $depreciateReconciliation): self + { + $this->depreciateReconciliation = $depreciateReconciliation; + return $this; + } +} diff --git a/src/Fields/AssetMethod/DepreciationField.php b/src/Fields/AssetMethod/DepreciationField.php new file mode 100644 index 00000000..6001ea5d --- /dev/null +++ b/src/Fields/AssetMethod/DepreciationField.php @@ -0,0 +1,33 @@ +depreciation; + } + + /** + * @return $this + */ + public function setDepreciation(?GeneralLedger $depreciation): self + { + $this->depreciation = $depreciation; + return $this; + } +} diff --git a/src/Fields/AssetMethod/DepreciationGroupField.php b/src/Fields/AssetMethod/DepreciationGroupField.php new file mode 100644 index 00000000..fcca80b3 --- /dev/null +++ b/src/Fields/AssetMethod/DepreciationGroupField.php @@ -0,0 +1,33 @@ +depreciationGroup; + } + + /** + * @return $this + */ + public function setDepreciationGroup(?DimensionGroup $depreciationGroup): self + { + $this->depreciationGroup = $depreciationGroup; + return $this; + } +} diff --git a/src/Fields/AssetMethod/FreeTextTypeField.php b/src/Fields/AssetMethod/FreeTextTypeField.php new file mode 100644 index 00000000..7997186f --- /dev/null +++ b/src/Fields/AssetMethod/FreeTextTypeField.php @@ -0,0 +1,31 @@ +type; + } + + /** + * @param FreeTextType|null $type + * @return $this + */ + public function setType(?FreeTextType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/AssetMethod/PurchaseValueField.php b/src/Fields/AssetMethod/PurchaseValueField.php new file mode 100644 index 00000000..1ed37b94 --- /dev/null +++ b/src/Fields/AssetMethod/PurchaseValueField.php @@ -0,0 +1,33 @@ +purchaseValue; + } + + /** + * @return $this + */ + public function setPurchaseValue(?GeneralLedger $purchaseValue): self + { + $this->purchaseValue = $purchaseValue; + return $this; + } +} diff --git a/src/Fields/AssetMethod/PurchaseValueGroupField.php b/src/Fields/AssetMethod/PurchaseValueGroupField.php new file mode 100644 index 00000000..d1723cf7 --- /dev/null +++ b/src/Fields/AssetMethod/PurchaseValueGroupField.php @@ -0,0 +1,33 @@ +purchaseValueGroup; + } + + /** + * @return $this + */ + public function setPurchaseValueGroup(?DimensionGroup $purchaseValueGroup): self + { + $this->purchaseValueGroup = $purchaseValueGroup; + return $this; + } +} diff --git a/src/Fields/AssetMethod/ReconciliationField.php b/src/Fields/AssetMethod/ReconciliationField.php new file mode 100644 index 00000000..d7d53d73 --- /dev/null +++ b/src/Fields/AssetMethod/ReconciliationField.php @@ -0,0 +1,33 @@ +reconciliation; + } + + /** + * @return $this + */ + public function setReconciliation(?GeneralLedger $reconciliation): self + { + $this->reconciliation = $reconciliation; + return $this; + } +} diff --git a/src/Fields/AssetMethod/SalesField.php b/src/Fields/AssetMethod/SalesField.php new file mode 100644 index 00000000..71508363 --- /dev/null +++ b/src/Fields/AssetMethod/SalesField.php @@ -0,0 +1,33 @@ +sales; + } + + /** + * @return $this + */ + public function setSales(?GeneralLedger $sales): self + { + $this->sales = $sales; + return $this; + } +} diff --git a/src/Fields/AssetMethod/ToBeInvoicedField.php b/src/Fields/AssetMethod/ToBeInvoicedField.php new file mode 100644 index 00000000..f3401e59 --- /dev/null +++ b/src/Fields/AssetMethod/ToBeInvoicedField.php @@ -0,0 +1,33 @@ +toBeInvoiced; + } + + /** + * @return $this + */ + public function setToBeInvoiced(?GeneralLedger $toBeInvoiced): self + { + $this->toBeInvoiced = $toBeInvoiced; + return $this; + } +} diff --git a/src/Fields/BehaviourField.php b/src/Fields/BehaviourField.php new file mode 100644 index 00000000..4019267f --- /dev/null +++ b/src/Fields/BehaviourField.php @@ -0,0 +1,31 @@ +behaviour; + } + + /** + * @param Behaviour|null $behaviour + * @return $this + */ + public function setBehaviour(?Behaviour $behaviour): self + { + $this->behaviour = $behaviour; + return $this; + } +} diff --git a/src/Fields/CodeField.php b/src/Fields/CodeField.php new file mode 100644 index 00000000..a637203c --- /dev/null +++ b/src/Fields/CodeField.php @@ -0,0 +1,31 @@ +code; + } + + /** + * @param null|string $code + * @return $this + */ + public function setCode(?string $code): self + { + $this->code = $code; + return $this; + } +} diff --git a/src/Transactions/TransactionLineFields/CommentField.php b/src/Fields/CommentField.php similarity index 76% rename from src/Transactions/TransactionLineFields/CommentField.php rename to src/Fields/CommentField.php index 7b6af6c8..62313c7a 100644 --- a/src/Transactions/TransactionLineFields/CommentField.php +++ b/src/Fields/CommentField.php @@ -1,10 +1,13 @@ comment = $comment; return $this; } -} \ No newline at end of file +} diff --git a/src/Fields/CreatedField.php b/src/Fields/CreatedField.php new file mode 100644 index 00000000..2e8f7fd7 --- /dev/null +++ b/src/Fields/CreatedField.php @@ -0,0 +1,35 @@ +created; + } + + /** + * @param \DateTimeInterface|null $created + * @return $this + */ + public function setCreated(?\DateTimeInterface $created) + { + $this->created = $created; + return $this; + } +} diff --git a/src/Fields/Currency/CurrencyRateRateField.php b/src/Fields/Currency/CurrencyRateRateField.php new file mode 100644 index 00000000..a89db12b --- /dev/null +++ b/src/Fields/Currency/CurrencyRateRateField.php @@ -0,0 +1,32 @@ +rate; + } + + /** + * @param null|float $rate + * @return $this + */ + public function setRate(?float $rate): self + { + $this->rate = $rate; + return $this; + } +} diff --git a/src/Fields/Currency/StartDateField.php b/src/Fields/Currency/StartDateField.php new file mode 100644 index 00000000..b46b5ef0 --- /dev/null +++ b/src/Fields/Currency/StartDateField.php @@ -0,0 +1,34 @@ +startDate; + } + + /** + * @param \DateTimeInterface|null $startDate + * @return $this + */ + public function setStartDate(?\DateTimeInterface $startDate) + { + $this->startDate = $startDate; + return $this; + } +} diff --git a/src/Fields/CurrencyField.php b/src/Fields/CurrencyField.php new file mode 100644 index 00000000..2a19425a --- /dev/null +++ b/src/Fields/CurrencyField.php @@ -0,0 +1,33 @@ +currency; + } + + /** + * @return $this + */ + public function setCurrency(?Currency $currency): self + { + $this->currency = $currency; + return $this; + } +} diff --git a/src/Fields/CustomerField.php b/src/Fields/CustomerField.php new file mode 100644 index 00000000..4dc901f7 --- /dev/null +++ b/src/Fields/CustomerField.php @@ -0,0 +1,54 @@ +customer; + } + + public function getCustomerToString(): ?string + { + if ($this->getCustomer() != null) { + return $this->customer->getCode(); + } else { + return null; + } + } + + /** + * @return $this + */ + public function setCustomer(?Customer $customer): self + { + $this->customer = $customer; + return $this; + } + + /** + * @param string|null $customerString + * @return $this + * @throws Exception + */ + public function setCustomerFromString(?string $customerString) + { + $customer = new Customer(); + $customer->setCode($customerString); + return $this->setCustomer($customer); + } +} diff --git a/src/Fields/DateField.php b/src/Fields/DateField.php new file mode 100644 index 00000000..b78ef17d --- /dev/null +++ b/src/Fields/DateField.php @@ -0,0 +1,37 @@ +date; + } + + /** + * @param \DateTimeInterface|null $date + * @return $this + */ + public function setDate(?\DateTimeInterface $date) + { + $this->date = $date; + return $this; + } +} diff --git a/src/Fields/DescriptionField.php b/src/Fields/DescriptionField.php new file mode 100644 index 00000000..9b6e4258 --- /dev/null +++ b/src/Fields/DescriptionField.php @@ -0,0 +1,32 @@ +description; + } + + /** + * @param null|string $description + * @return $this + */ + public function setDescription(?string $description): self + { + $this->description = $description; + return $this; + } +} diff --git a/src/Fields/Dim1Field.php b/src/Fields/Dim1Field.php new file mode 100644 index 00000000..6f193df2 --- /dev/null +++ b/src/Fields/Dim1Field.php @@ -0,0 +1,33 @@ +dim1; + } + + /** + * @return $this + */ + public function setDim1(?GeneralLedger $dim1): self + { + $this->dim1 = $dim1; + return $this; + } +} diff --git a/src/Fields/Dim2Field.php b/src/Fields/Dim2Field.php new file mode 100644 index 00000000..02d221bd --- /dev/null +++ b/src/Fields/Dim2Field.php @@ -0,0 +1,31 @@ +dim2; + } + + /** + * @return $this + */ + public function setDim2($dim2): self + { + $this->dim2 = $dim2; + return $this; + } +} diff --git a/src/Fields/Dim3Field.php b/src/Fields/Dim3Field.php new file mode 100644 index 00000000..b1b08ed8 --- /dev/null +++ b/src/Fields/Dim3Field.php @@ -0,0 +1,31 @@ +dim3; + } + + /** + * @return $this + */ + public function setDim3($dim3): self + { + $this->dim3 = $dim3; + return $this; + } +} diff --git a/src/Fields/Dim4Field.php b/src/Fields/Dim4Field.php new file mode 100644 index 00000000..4bdbe163 --- /dev/null +++ b/src/Fields/Dim4Field.php @@ -0,0 +1,31 @@ +dim4; + } + + /** + * @return $this + */ + public function setDim4($dim4): self + { + $this->dim4 = $dim4; + return $this; + } +} diff --git a/src/Fields/Dimensions/AccountTypeField.php b/src/Fields/Dimensions/AccountTypeField.php new file mode 100644 index 00000000..abdbb6ef --- /dev/null +++ b/src/Fields/Dimensions/AccountTypeField.php @@ -0,0 +1,31 @@ +accountType; + } + + /** + * @param AccountType|null $accountType + * @return $this + */ + public function setAccountType(?AccountType $accountType): self + { + $this->accountType = $accountType; + return $this; + } +} diff --git a/src/Fields/Dimensions/AmountField.php b/src/Fields/Dimensions/AmountField.php new file mode 100644 index 00000000..a9a69362 --- /dev/null +++ b/src/Fields/Dimensions/AmountField.php @@ -0,0 +1,35 @@ +amount; + } + + /** + * @param Money|null $amount + * @return $this + */ + public function setAmount(?Money $amount) + { + $this->amount = $amount; + + return $this; + } +} diff --git a/src/Fields/Dimensions/BeginPeriodField.php b/src/Fields/Dimensions/BeginPeriodField.php new file mode 100644 index 00000000..a72bb466 --- /dev/null +++ b/src/Fields/Dimensions/BeginPeriodField.php @@ -0,0 +1,32 @@ +beginPeriod; + } + + /** + * @param null|int $beginPeriod + * @return $this + */ + public function setBeginPeriod(?int $beginPeriod): self + { + $this->beginPeriod = $beginPeriod; + return $this; + } +} diff --git a/src/Fields/Dimensions/BeginYearField.php b/src/Fields/Dimensions/BeginYearField.php new file mode 100644 index 00000000..44a9287f --- /dev/null +++ b/src/Fields/Dimensions/BeginYearField.php @@ -0,0 +1,32 @@ +beginYear; + } + + /** + * @param null|int $beginYear + * @return $this + */ + public function setBeginYear(?int $beginYear): self + { + $this->beginYear = $beginYear; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionGroup/CodeField.php b/src/Fields/Dimensions/DimensionGroup/CodeField.php new file mode 100644 index 00000000..9e51e880 --- /dev/null +++ b/src/Fields/Dimensions/DimensionGroup/CodeField.php @@ -0,0 +1,31 @@ +code; + } + + /** + * @return $this + */ + public function setCode($code): self + { + $this->code = $code; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionGroup/GroupField.php b/src/Fields/Dimensions/DimensionGroup/GroupField.php new file mode 100644 index 00000000..c1c5b630 --- /dev/null +++ b/src/Fields/Dimensions/DimensionGroup/GroupField.php @@ -0,0 +1,33 @@ +group; + } + + /** + * @return $this + */ + public function setGroup(?DimensionGroup $group): self + { + $this->group = $group; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/FinancialsField.php b/src/Fields/Dimensions/DimensionType/FinancialsField.php new file mode 100644 index 00000000..5fe6e825 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/FinancialsField.php @@ -0,0 +1,32 @@ +financials; + } + + /** + * @param null|int $financials + * @return $this + */ + public function setFinancials(?int $financials): self + { + $this->financials = $financials; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label1Field.php b/src/Fields/Dimensions/DimensionType/Label1Field.php new file mode 100644 index 00000000..974f940e --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label1Field.php @@ -0,0 +1,32 @@ +label1; + } + + /** + * @param null|string $label1 + * @return $this + */ + public function setLabel1(?string $label1): self + { + $this->label1 = $label1; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label2Field.php b/src/Fields/Dimensions/DimensionType/Label2Field.php new file mode 100644 index 00000000..736bcd67 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label2Field.php @@ -0,0 +1,32 @@ +label2; + } + + /** + * @param null|string $label2 + * @return $this + */ + public function setLabel2(?string $label2): self + { + $this->label2 = $label2; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label3Field.php b/src/Fields/Dimensions/DimensionType/Label3Field.php new file mode 100644 index 00000000..1d475680 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label3Field.php @@ -0,0 +1,32 @@ +label3; + } + + /** + * @param null|string $label3 + * @return $this + */ + public function setLabel3(?string $label3): self + { + $this->label3 = $label3; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label4Field.php b/src/Fields/Dimensions/DimensionType/Label4Field.php new file mode 100644 index 00000000..6f821533 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label4Field.php @@ -0,0 +1,32 @@ +label4; + } + + /** + * @param null|string $label4 + * @return $this + */ + public function setLabel4(?string $label4): self + { + $this->label4 = $label4; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label5Field.php b/src/Fields/Dimensions/DimensionType/Label5Field.php new file mode 100644 index 00000000..383c9f33 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label5Field.php @@ -0,0 +1,32 @@ +label5; + } + + /** + * @param null|string $label5 + * @return $this + */ + public function setLabel5(?string $label5): self + { + $this->label5 = $label5; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/Label6Field.php b/src/Fields/Dimensions/DimensionType/Label6Field.php new file mode 100644 index 00000000..5072ff0e --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/Label6Field.php @@ -0,0 +1,32 @@ +label6; + } + + /** + * @param null|string $label6 + * @return $this + */ + public function setLabel6(?string $label6): self + { + $this->label6 = $label6; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/MaskField.php b/src/Fields/Dimensions/DimensionType/MaskField.php new file mode 100644 index 00000000..d7e6bd51 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/MaskField.php @@ -0,0 +1,32 @@ +mask; + } + + /** + * @param null|string $mask + * @return $this + */ + public function setMask(?string $mask): self + { + $this->mask = $mask; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/TimeField.php b/src/Fields/Dimensions/DimensionType/TimeField.php new file mode 100644 index 00000000..293ad0df --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/TimeField.php @@ -0,0 +1,32 @@ +time; + } + + /** + * @param null|int $time + * @return $this + */ + public function setTime(?int $time): self + { + $this->time = $time; + return $this; + } +} diff --git a/src/Fields/Dimensions/DimensionType/TypeField.php b/src/Fields/Dimensions/DimensionType/TypeField.php new file mode 100644 index 00000000..27886c65 --- /dev/null +++ b/src/Fields/Dimensions/DimensionType/TypeField.php @@ -0,0 +1,45 @@ +type; + } + + /** + * @return $this + */ + public function setType(?DimensionType $type): self + { + $this->type = $type; + return $this; + } + + /** + * @param string|null $typeString + * @return $this + * @throws Exception + */ + public function setTypeFromString(?string $typeString) + { + $type = new DimensionType(); + $type->setCode($typeString); + return $this->setType($type); + } +} diff --git a/src/Fields/Dimensions/EndPeriodField.php b/src/Fields/Dimensions/EndPeriodField.php new file mode 100644 index 00000000..799f27e1 --- /dev/null +++ b/src/Fields/Dimensions/EndPeriodField.php @@ -0,0 +1,32 @@ +endPeriod; + } + + /** + * @param null|int $endPeriod + * @return $this + */ + public function setEndPeriod(?int $endPeriod): self + { + $this->endPeriod = $endPeriod; + return $this; + } +} diff --git a/src/Fields/Dimensions/EndYearField.php b/src/Fields/Dimensions/EndYearField.php new file mode 100644 index 00000000..eb9d4c46 --- /dev/null +++ b/src/Fields/Dimensions/EndYearField.php @@ -0,0 +1,32 @@ +endYear; + } + + /** + * @param null|int $endYear + * @return $this + */ + public function setEndYear(?int $endYear): self + { + $this->endYear = $endYear; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/AccountNumberField.php b/src/Fields/Dimensions/Level2/AccountNumberField.php new file mode 100644 index 00000000..30b87bf7 --- /dev/null +++ b/src/Fields/Dimensions/Level2/AccountNumberField.php @@ -0,0 +1,32 @@ +accountNumber; + } + + /** + * @param null|string $accountNumber + * @return $this + */ + public function setAccountNumber(?string $accountNumber): self + { + $this->accountNumber = $accountNumber; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/AddressField2Field.php b/src/Fields/Dimensions/Level2/AddressField2Field.php new file mode 100644 index 00000000..d978afdf --- /dev/null +++ b/src/Fields/Dimensions/Level2/AddressField2Field.php @@ -0,0 +1,32 @@ +addressField2; + } + + /** + * @param null|string $addressField2 + * @return $this + */ + public function setAddressField2(?string $addressField2): self + { + $this->addressField2 = $addressField2; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/AddressField3Field.php b/src/Fields/Dimensions/Level2/AddressField3Field.php new file mode 100644 index 00000000..75b22cf6 --- /dev/null +++ b/src/Fields/Dimensions/Level2/AddressField3Field.php @@ -0,0 +1,32 @@ +addressField3; + } + + /** + * @param null|string $addressField3 + * @return $this + */ + public function setAddressField3(?string $addressField3): self + { + $this->addressField3 = $addressField3; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/AscriptionField.php b/src/Fields/Dimensions/Level2/AscriptionField.php new file mode 100644 index 00000000..4f3715b1 --- /dev/null +++ b/src/Fields/Dimensions/Level2/AscriptionField.php @@ -0,0 +1,32 @@ +ascription; + } + + /** + * @param null|string $ascription + * @return $this + */ + public function setAscription(?string $ascription): self + { + $this->ascription = $ascription; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/BankBlockedField.php b/src/Fields/Dimensions/Level2/BankBlockedField.php new file mode 100644 index 00000000..0f675d65 --- /dev/null +++ b/src/Fields/Dimensions/Level2/BankBlockedField.php @@ -0,0 +1,32 @@ +blocked; + } + + /** + * @param bool $blocked + * @return $this + */ + public function setBlocked(?bool $blocked): self + { + $this->blocked = $blocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/BankNameField.php b/src/Fields/Dimensions/Level2/BankNameField.php new file mode 100644 index 00000000..cca57205 --- /dev/null +++ b/src/Fields/Dimensions/Level2/BankNameField.php @@ -0,0 +1,32 @@ +bankName; + } + + /** + * @param null|string $bankName + * @return $this + */ + public function setBankName(?string $bankName): self + { + $this->bankName = $bankName; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/BicCodeField.php b/src/Fields/Dimensions/Level2/BicCodeField.php new file mode 100644 index 00000000..ad66e8b8 --- /dev/null +++ b/src/Fields/Dimensions/Level2/BicCodeField.php @@ -0,0 +1,32 @@ +bicCode; + } + + /** + * @param null|string $bicCode + * @return $this + */ + public function setBicCode(?string $bicCode): self + { + $this->bicCode = $bicCode; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/CityField.php b/src/Fields/Dimensions/Level2/CityField.php new file mode 100644 index 00000000..b27d3cb5 --- /dev/null +++ b/src/Fields/Dimensions/Level2/CityField.php @@ -0,0 +1,32 @@ +city; + } + + /** + * @param null|string $city + * @return $this + */ + public function setCity(?string $city): self + { + $this->city = $city; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/CountryField.php b/src/Fields/Dimensions/Level2/CountryField.php new file mode 100644 index 00000000..2b6366cf --- /dev/null +++ b/src/Fields/Dimensions/Level2/CountryField.php @@ -0,0 +1,33 @@ +country; + } + + /** + * @return $this + */ + public function setCountry(?Country $country): self + { + $this->country = $country; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/BaseCreditLimitField.php b/src/Fields/Dimensions/Level2/Customer/BaseCreditLimitField.php new file mode 100644 index 00000000..f2da123e --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/BaseCreditLimitField.php @@ -0,0 +1,35 @@ +baseCreditLimit; + } + + /** + * @param Money|null $baseCreditLimit + * @return $this + */ + public function setBaseCreditLimit(?Money $baseCreditLimit) + { + $this->baseCreditLimit = $baseCreditLimit; + + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/BlockedField.php b/src/Fields/Dimensions/Level2/Customer/BlockedField.php new file mode 100644 index 00000000..e021dd9d --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/BlockedField.php @@ -0,0 +1,32 @@ +blocked; + } + + /** + * @param bool $blocked + * @return $this + */ + public function setBlocked(?bool $blocked): self + { + $this->blocked = $blocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/BlockedLockedField.php b/src/Fields/Dimensions/Level2/Customer/BlockedLockedField.php new file mode 100644 index 00000000..b9a8488d --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/BlockedLockedField.php @@ -0,0 +1,32 @@ +blockedLocked; + } + + /** + * @param bool $blockedLocked + * @return $this + */ + public function setBlockedLocked(?bool $blockedLocked): self + { + $this->blockedLocked = $blockedLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/BlockedModifiedField.php b/src/Fields/Dimensions/Level2/Customer/BlockedModifiedField.php new file mode 100644 index 00000000..849c5b22 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/BlockedModifiedField.php @@ -0,0 +1,35 @@ +blockedModified; + } + + /** + * @param \DateTimeInterface|null $blockedModified + * @return $this + */ + public function setBlockedModified(?\DateTimeInterface $blockedModified) + { + $this->blockedModified = $blockedModified; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/CollectionSchemaField.php b/src/Fields/Dimensions/Level2/Customer/CollectionSchemaField.php new file mode 100644 index 00000000..5f6ee790 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/CollectionSchemaField.php @@ -0,0 +1,31 @@ +collectionSchema; + } + + /** + * @param CollectionSchema|null $collectionSchema + * @return $this + */ + public function setCollectionSchema(?CollectionSchema $collectionSchema): self + { + $this->collectionSchema = $collectionSchema; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/DiscountArticleField.php b/src/Fields/Dimensions/Level2/Customer/DiscountArticleField.php new file mode 100644 index 00000000..ed0a16c9 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/DiscountArticleField.php @@ -0,0 +1,33 @@ +discountArticle; + } + + /** + * @return $this + */ + public function setDiscountArticle(?Article $discountArticle): self + { + $this->discountArticle = $discountArticle; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/DiscountArticleIDField.php b/src/Fields/Dimensions/Level2/Customer/DiscountArticleIDField.php new file mode 100644 index 00000000..d0dd3adc --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/DiscountArticleIDField.php @@ -0,0 +1,32 @@ +discountArticleID; + } + + /** + * @param null|string $discountArticleID + * @return $this + */ + public function setDiscountArticleID(?string $discountArticleID): self + { + $this->discountArticleID = $discountArticleID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/EBillMailField.php b/src/Fields/Dimensions/Level2/Customer/EBillMailField.php new file mode 100644 index 00000000..df793962 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/EBillMailField.php @@ -0,0 +1,32 @@ +eBillMail; + } + + /** + * @param null|string $eBillMail + * @return $this + */ + public function setEBillMail(?string $eBillMail): self + { + $this->eBillMail = $eBillMail; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/EBillingField.php b/src/Fields/Dimensions/Level2/Customer/EBillingField.php new file mode 100644 index 00000000..10d72281 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/EBillingField.php @@ -0,0 +1,32 @@ +eBilling; + } + + /** + * @param bool $eBilling + * @return $this + */ + public function setEBilling(?bool $eBilling): self + { + $this->eBilling = $eBilling; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/FirstRunDateField.php b/src/Fields/Dimensions/Level2/Customer/FirstRunDateField.php new file mode 100644 index 00000000..19c00166 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/FirstRunDateField.php @@ -0,0 +1,35 @@ +firstRunDate; + } + + /** + * @param \DateTimeInterface|null $firstRunDate + * @return $this + */ + public function setFirstRunDate(?\DateTimeInterface $firstRunDate) + { + $this->firstRunDate = $firstRunDate; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/FreeText1Field.php b/src/Fields/Dimensions/Level2/Customer/FreeText1Field.php new file mode 100644 index 00000000..028175ee --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/FreeText1Field.php @@ -0,0 +1,32 @@ +freeText1; + } + + /** + * @param bool $freeText1 + * @return $this + */ + public function setFreeText1(?bool $freeText1): self + { + $this->freeText1 = $freeText1; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/IDField.php b/src/Fields/Dimensions/Level2/Customer/IDField.php new file mode 100644 index 00000000..a78044d1 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/IDField.php @@ -0,0 +1,32 @@ +ID; + } + + /** + * @param null|string $ID + * @return $this + */ + public function setID(?string $ID): self + { + $this->ID = $ID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/ReminderEmailField.php b/src/Fields/Dimensions/Level2/Customer/ReminderEmailField.php new file mode 100644 index 00000000..958b913a --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/ReminderEmailField.php @@ -0,0 +1,32 @@ +reminderEmail; + } + + /** + * @param null|string $reminderEmail + * @return $this + */ + public function setReminderEmail(?string $reminderEmail): self + { + $this->reminderEmail = $reminderEmail; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/ResponsibleUserField.php b/src/Fields/Dimensions/Level2/Customer/ResponsibleUserField.php new file mode 100644 index 00000000..726ec441 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/ResponsibleUserField.php @@ -0,0 +1,34 @@ +responsibleUser; + } + + /** + * @return $this + */ + public function setResponsibleUser(?User $responsibleUser): self + { + $this->responsibleUser = $responsibleUser; + return $this; + } +} + diff --git a/src/Fields/Dimensions/Level2/Customer/SendReminderField.php b/src/Fields/Dimensions/Level2/Customer/SendReminderField.php new file mode 100644 index 00000000..9ae1cc5c --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/SendReminderField.php @@ -0,0 +1,31 @@ +sendReminder; + } + + /** + * @param SendReminder|null $sendReminder + * @return $this + */ + public function setSendReminder(?SendReminder $sendReminder): self + { + $this->sendReminder = $sendReminder; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Customer/SignatureDateField.php b/src/Fields/Dimensions/Level2/Customer/SignatureDateField.php new file mode 100644 index 00000000..194eaf83 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Customer/SignatureDateField.php @@ -0,0 +1,35 @@ +signatureDate; + } + + /** + * @param \DateTimeInterface|null $signatureDate + * @return $this + */ + public function setSignatureDate(?\DateTimeInterface $signatureDate) + { + $this->signatureDate = $signatureDate; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/DefaultField.php b/src/Fields/Dimensions/Level2/DefaultField.php new file mode 100644 index 00000000..b6f17f50 --- /dev/null +++ b/src/Fields/Dimensions/Level2/DefaultField.php @@ -0,0 +1,32 @@ +default; + } + + /** + * @param bool $default + * @return $this + */ + public function setDefault(?bool $default): self + { + $this->default = $default; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension1Field.php b/src/Fields/Dimensions/Level2/Dimension1Field.php new file mode 100644 index 00000000..04c0b089 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension1Field.php @@ -0,0 +1,33 @@ +dimension1; + } + + /** + * @return $this + */ + public function setDimension1(?GeneralLedger $dimension1): self + { + $this->dimension1 = $dimension1; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension1IDField.php b/src/Fields/Dimensions/Level2/Dimension1IDField.php new file mode 100644 index 00000000..25b5fe2d --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension1IDField.php @@ -0,0 +1,32 @@ +dimension1ID; + } + + /** + * @param null|string $dimension1ID + * @return $this + */ + public function setDimension1ID(?string $dimension1ID): self + { + $this->dimension1ID = $dimension1ID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension2Field.php b/src/Fields/Dimensions/Level2/Dimension2Field.php new file mode 100644 index 00000000..4faa64f8 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension2Field.php @@ -0,0 +1,33 @@ +dimension2; + } + + /** + * @return $this + */ + public function setDimension2(?CostCenter $dimension2): self + { + $this->dimension2 = $dimension2; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension2IDField.php b/src/Fields/Dimensions/Level2/Dimension2IDField.php new file mode 100644 index 00000000..af08e427 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension2IDField.php @@ -0,0 +1,32 @@ +dimension2ID; + } + + /** + * @param null|string $dimension2ID + * @return $this + */ + public function setDimension2ID(?string $dimension2ID): self + { + $this->dimension2ID = $dimension2ID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension3Field.php b/src/Fields/Dimensions/Level2/Dimension3Field.php new file mode 100644 index 00000000..d10bb6d1 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension3Field.php @@ -0,0 +1,31 @@ +dimension3; + } + + /** + * @return $this + */ + public function setDimension3($dimension3): self + { + $this->dimension3 = $dimension3; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Dimension3IDField.php b/src/Fields/Dimensions/Level2/Dimension3IDField.php new file mode 100644 index 00000000..0f826bcf --- /dev/null +++ b/src/Fields/Dimensions/Level2/Dimension3IDField.php @@ -0,0 +1,32 @@ +dimension3ID; + } + + /** + * @param null|string $dimension3ID + * @return $this + */ + public function setDimension3ID(?string $dimension3ID): self + { + $this->dimension3ID = $dimension3ID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/DueDaysField.php b/src/Fields/Dimensions/Level2/DueDaysField.php new file mode 100644 index 00000000..9a1a9061 --- /dev/null +++ b/src/Fields/Dimensions/Level2/DueDaysField.php @@ -0,0 +1,32 @@ +dueDays; + } + + /** + * @param null|int $dueDays + * @return $this + */ + public function setDueDays(?int $dueDays): self + { + $this->dueDays = $dueDays; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field1Field.php b/src/Fields/Dimensions/Level2/Field1Field.php new file mode 100644 index 00000000..873b4139 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field1Field.php @@ -0,0 +1,32 @@ +field1; + } + + /** + * @param null|string $field1 + * @return $this + */ + public function setField1(?string $field1): self + { + $this->field1 = $field1; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field2Field.php b/src/Fields/Dimensions/Level2/Field2Field.php new file mode 100644 index 00000000..2bf4b673 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field2Field.php @@ -0,0 +1,32 @@ +field2; + } + + /** + * @param null|string $field2 + * @return $this + */ + public function setField2(?string $field2): self + { + $this->field2 = $field2; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field3Field.php b/src/Fields/Dimensions/Level2/Field3Field.php new file mode 100644 index 00000000..75d78bf4 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field3Field.php @@ -0,0 +1,32 @@ +field3; + } + + /** + * @param null|string $field3 + * @return $this + */ + public function setField3(?string $field3): self + { + $this->field3 = $field3; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field4Field.php b/src/Fields/Dimensions/Level2/Field4Field.php new file mode 100644 index 00000000..8d726c16 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field4Field.php @@ -0,0 +1,32 @@ +field4; + } + + /** + * @param null|string $field4 + * @return $this + */ + public function setField4(?string $field4): self + { + $this->field4 = $field4; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field5Field.php b/src/Fields/Dimensions/Level2/Field5Field.php new file mode 100644 index 00000000..f790df01 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field5Field.php @@ -0,0 +1,32 @@ +field5; + } + + /** + * @param null|string $field5 + * @return $this + */ + public function setField5(?string $field5): self + { + $this->field5 = $field5; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Field6Field.php b/src/Fields/Dimensions/Level2/Field6Field.php new file mode 100644 index 00000000..d3f1f946 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Field6Field.php @@ -0,0 +1,32 @@ +field6; + } + + /** + * @param null|string $field6 + * @return $this + */ + public function setField6(?string $field6): self + { + $this->field6 = $field6; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/IbanField.php b/src/Fields/Dimensions/Level2/IbanField.php new file mode 100644 index 00000000..674c7ea5 --- /dev/null +++ b/src/Fields/Dimensions/Level2/IbanField.php @@ -0,0 +1,32 @@ +iban; + } + + /** + * @param null|string $iban + * @return $this + */ + public function setIban(?string $iban): self + { + $this->iban = $iban; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/MeansOfPaymentField.php b/src/Fields/Dimensions/Level2/MeansOfPaymentField.php new file mode 100644 index 00000000..693802b6 --- /dev/null +++ b/src/Fields/Dimensions/Level2/MeansOfPaymentField.php @@ -0,0 +1,31 @@ +meansOfPayment; + } + + /** + * @param MeansOfPayment|null $meansOfPayment + * @return $this + */ + public function setMeansOfPayment(?MeansOfPayment $meansOfPayment): self + { + $this->meansOfPayment = $meansOfPayment; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/NatBicCodeField.php b/src/Fields/Dimensions/Level2/NatBicCodeField.php new file mode 100644 index 00000000..f364a6c1 --- /dev/null +++ b/src/Fields/Dimensions/Level2/NatBicCodeField.php @@ -0,0 +1,32 @@ +natBicCode; + } + + /** + * @param null|string $natBicCode + * @return $this + */ + public function setNatBicCode(?string $natBicCode): self + { + $this->natBicCode = $natBicCode; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PayAvailableField.php b/src/Fields/Dimensions/Level2/PayAvailableField.php new file mode 100644 index 00000000..cc6c6e43 --- /dev/null +++ b/src/Fields/Dimensions/Level2/PayAvailableField.php @@ -0,0 +1,32 @@ +payAvailable; + } + + /** + * @param bool $payAvailable + * @return $this + */ + public function setPayAvailable(?bool $payAvailable): self + { + $this->payAvailable = $payAvailable; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PayCodeField.php b/src/Fields/Dimensions/Level2/PayCodeField.php new file mode 100644 index 00000000..77fd15e1 --- /dev/null +++ b/src/Fields/Dimensions/Level2/PayCodeField.php @@ -0,0 +1,33 @@ +payCode; + } + + /** + * @return $this + */ + public function setPayCode(?PayCode $payCode): self + { + $this->payCode = $payCode; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PayCodeIDField.php b/src/Fields/Dimensions/Level2/PayCodeIDField.php new file mode 100644 index 00000000..72a58928 --- /dev/null +++ b/src/Fields/Dimensions/Level2/PayCodeIDField.php @@ -0,0 +1,32 @@ +payCodeID; + } + + /** + * @param null|string $payCodeID + * @return $this + */ + public function setPayCodeID(?string $payCodeID): self + { + $this->payCodeID = $payCodeID; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PaymentConditionDiscountDaysField.php b/src/Fields/Dimensions/Level2/PaymentConditionDiscountDaysField.php new file mode 100644 index 00000000..64a534a5 --- /dev/null +++ b/src/Fields/Dimensions/Level2/PaymentConditionDiscountDaysField.php @@ -0,0 +1,32 @@ +paymentConditionDiscountDays; + } + + /** + * @param null|int $paymentConditionDiscountDays + * @return $this + */ + public function setPaymentConditionDiscountDays(?int $paymentConditionDiscountDays): self + { + $this->paymentConditionDiscountDays = $paymentConditionDiscountDays; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PaymentConditionDiscountPercentageField.php b/src/Fields/Dimensions/Level2/PaymentConditionDiscountPercentageField.php new file mode 100644 index 00000000..3540324c --- /dev/null +++ b/src/Fields/Dimensions/Level2/PaymentConditionDiscountPercentageField.php @@ -0,0 +1,32 @@ +paymentConditionDiscountPercentage; + } + + /** + * @param null|float $paymentConditionDiscountPercentage + * @return $this + */ + public function setPaymentConditionDiscountPercentage(?float $paymentConditionDiscountPercentage): self + { + $this->paymentConditionDiscountPercentage = $paymentConditionDiscountPercentage; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/PostcodeField.php b/src/Fields/Dimensions/Level2/PostcodeField.php new file mode 100644 index 00000000..4b8b1768 --- /dev/null +++ b/src/Fields/Dimensions/Level2/PostcodeField.php @@ -0,0 +1,32 @@ +postcode; + } + + /** + * @param null|string $postcode + * @return $this + */ + public function setPostcode(?string $postcode): self + { + $this->postcode = $postcode; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/RatioField.php b/src/Fields/Dimensions/Level2/RatioField.php new file mode 100644 index 00000000..ddadd9cd --- /dev/null +++ b/src/Fields/Dimensions/Level2/RatioField.php @@ -0,0 +1,32 @@ +ratio; + } + + /** + * @param null|float $ratio + * @return $this + */ + public function setRatio(?float $ratio): self + { + $this->ratio = $ratio; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/RemittanceAdviceSendMailField.php b/src/Fields/Dimensions/Level2/RemittanceAdviceSendMailField.php new file mode 100644 index 00000000..ccf83686 --- /dev/null +++ b/src/Fields/Dimensions/Level2/RemittanceAdviceSendMailField.php @@ -0,0 +1,32 @@ +remittanceAdviceSendMail; + } + + /** + * @param null|string $remittanceAdviceSendMail + * @return $this + */ + public function setRemittanceAdviceSendMail(?string $remittanceAdviceSendMail): self + { + $this->remittanceAdviceSendMail = $remittanceAdviceSendMail; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/RemittanceAdviceSendTypeField.php b/src/Fields/Dimensions/Level2/RemittanceAdviceSendTypeField.php new file mode 100644 index 00000000..0342be7e --- /dev/null +++ b/src/Fields/Dimensions/Level2/RemittanceAdviceSendTypeField.php @@ -0,0 +1,31 @@ +remittanceAdviceSendType; + } + + /** + * @param RemittanceAdviceSendType|null $remittanceAdviceSendType + * @return $this + */ + public function setRemittanceAdviceSendType(?RemittanceAdviceSendType $remittanceAdviceSendType): self + { + $this->remittanceAdviceSendType = $remittanceAdviceSendType; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/StateField.php b/src/Fields/Dimensions/Level2/StateField.php new file mode 100644 index 00000000..da7c255f --- /dev/null +++ b/src/Fields/Dimensions/Level2/StateField.php @@ -0,0 +1,32 @@ +state; + } + + /** + * @param null|string $state + * @return $this + */ + public function setState(?string $state): self + { + $this->state = $state; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsIncludeVatField.php b/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsIncludeVatField.php new file mode 100644 index 00000000..c23a8918 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsIncludeVatField.php @@ -0,0 +1,31 @@ +blockedAccountPaymentConditionsIncludeVat; + } + + /** + * @param BlockedAccountPaymentConditionsIncludeVat|null $blockedAccountPaymentConditionsIncludeVat + * @return $this + */ + public function setBlockedAccountPaymentConditionsIncludeVat(?BlockedAccountPaymentConditionsIncludeVat $blockedAccountPaymentConditionsIncludeVat): self + { + $this->blockedAccountPaymentConditionsIncludeVat = $blockedAccountPaymentConditionsIncludeVat; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsPercentageField.php b/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsPercentageField.php new file mode 100644 index 00000000..1aabba11 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Supplier/BlockedAccountPaymentConditionsPercentageField.php @@ -0,0 +1,32 @@ +blockedAccountPaymentConditionsPercentage; + } + + /** + * @param null|float $blockedAccountPaymentConditionsPercentage + * @return $this + */ + public function setBlockedAccountPaymentConditionsPercentage(?float $blockedAccountPaymentConditionsPercentage): self + { + $this->blockedAccountPaymentConditionsPercentage = $blockedAccountPaymentConditionsPercentage; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/Supplier/RelationsReferenceField.php b/src/Fields/Dimensions/Level2/Supplier/RelationsReferenceField.php new file mode 100644 index 00000000..59ac69a0 --- /dev/null +++ b/src/Fields/Dimensions/Level2/Supplier/RelationsReferenceField.php @@ -0,0 +1,32 @@ +relationsReference; + } + + /** + * @param null|string $relationsReference + * @return $this + */ + public function setRelationsReference(?string $relationsReference): self + { + $this->relationsReference = $relationsReference; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/TelefaxField.php b/src/Fields/Dimensions/Level2/TelefaxField.php new file mode 100644 index 00000000..71d00097 --- /dev/null +++ b/src/Fields/Dimensions/Level2/TelefaxField.php @@ -0,0 +1,32 @@ +telefax; + } + + /** + * @param null|string $telefax + * @return $this + */ + public function setTelefax(?string $telefax): self + { + $this->telefax = $telefax; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/TelephoneField.php b/src/Fields/Dimensions/Level2/TelephoneField.php new file mode 100644 index 00000000..369d9db8 --- /dev/null +++ b/src/Fields/Dimensions/Level2/TelephoneField.php @@ -0,0 +1,32 @@ +telephone; + } + + /** + * @param null|string $telephone + * @return $this + */ + public function setTelephone(?string $telephone): self + { + $this->telephone = $telephone; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/TypeField.php b/src/Fields/Dimensions/Level2/TypeField.php new file mode 100644 index 00000000..26cafc68 --- /dev/null +++ b/src/Fields/Dimensions/Level2/TypeField.php @@ -0,0 +1,31 @@ +type; + } + + /** + * @param AddressType|null $type + * @return $this + */ + public function setType(?AddressType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level2/WebsiteField.php b/src/Fields/Dimensions/Level2/WebsiteField.php new file mode 100644 index 00000000..ab22d8b6 --- /dev/null +++ b/src/Fields/Dimensions/Level2/WebsiteField.php @@ -0,0 +1,32 @@ +website; + } + + /** + * @param null|string $website + * @return $this + */ + public function setWebsite(?string $website): self + { + $this->website = $website; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/AuthoriserField.php b/src/Fields/Dimensions/Level34/AuthoriserField.php new file mode 100644 index 00000000..0c93ce31 --- /dev/null +++ b/src/Fields/Dimensions/Level34/AuthoriserField.php @@ -0,0 +1,42 @@ +authoriser; + } + + public function getAuthoriserToString(): ?string + { + if ($this->getAuthoriser() != null) { + return $this->authoriser->getCode(); + } else { + return null; + } + } + + /** + * @return $this + */ + public function setAuthoriser(?User $authoriser): self + { + $this->authoriser = $authoriser; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/AuthoriserInheritField.php b/src/Fields/Dimensions/Level34/AuthoriserInheritField.php new file mode 100644 index 00000000..bda09935 --- /dev/null +++ b/src/Fields/Dimensions/Level34/AuthoriserInheritField.php @@ -0,0 +1,37 @@ +authoriserInherit; + } + + public function getAuthoriserInheritToString(): ?string + { + return ($this->getAuthoriserInherit()) ? 'true' : 'false'; + } + + /** + * @param bool $authoriserInherit + * @return $this + */ + public function setAuthoriserInherit(?bool $authoriserInherit): self + { + $this->authoriserInherit = $authoriserInherit; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/AuthoriserLockedField.php b/src/Fields/Dimensions/Level34/AuthoriserLockedField.php new file mode 100644 index 00000000..35862083 --- /dev/null +++ b/src/Fields/Dimensions/Level34/AuthoriserLockedField.php @@ -0,0 +1,37 @@ +authoriserLocked; + } + + public function getAuthoriserLockedToString(): ?string + { + return ($this->getAuthoriserLocked()) ? 'true' : 'false'; + } + + /** + * @param bool $authoriserLocked + * @return $this + */ + public function setAuthoriserLocked(?bool $authoriserLocked): self + { + $this->authoriserLocked = $authoriserLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/BillableField.php b/src/Fields/Dimensions/Level34/BillableField.php new file mode 100644 index 00000000..84c406aa --- /dev/null +++ b/src/Fields/Dimensions/Level34/BillableField.php @@ -0,0 +1,37 @@ +billable; + } + + public function getBillableToString(): ?string + { + return ($this->getBillable()) ? 'true' : 'false'; + } + + /** + * @param bool $billable + * @return $this + */ + public function setBillable(?bool $billable): self + { + $this->billable = $billable; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/BillableForRatioField.php b/src/Fields/Dimensions/Level34/BillableForRatioField.php new file mode 100644 index 00000000..6a7374fa --- /dev/null +++ b/src/Fields/Dimensions/Level34/BillableForRatioField.php @@ -0,0 +1,37 @@ +billableForRatio; + } + + public function getBillableForRatioToString(): ?string + { + return ($this->getBillableForRatio()) ? 'true' : 'false'; + } + + /** + * @param bool $billableForRatio + * @return $this + */ + public function setBillableForRatio(?bool $billableForRatio): self + { + $this->billableForRatio = $billableForRatio; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/BillableInheritField.php b/src/Fields/Dimensions/Level34/BillableInheritField.php new file mode 100644 index 00000000..7b695316 --- /dev/null +++ b/src/Fields/Dimensions/Level34/BillableInheritField.php @@ -0,0 +1,37 @@ +billableInherit; + } + + public function getBillableInheritToString(): ?string + { + return ($this->getBillableInherit()) ? 'true' : 'false'; + } + + /** + * @param bool $billableInherit + * @return $this + */ + public function setBillableInherit(?bool $billableInherit): self + { + $this->billableInherit = $billableInherit; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/BillableLockedField.php b/src/Fields/Dimensions/Level34/BillableLockedField.php new file mode 100644 index 00000000..fec600e9 --- /dev/null +++ b/src/Fields/Dimensions/Level34/BillableLockedField.php @@ -0,0 +1,37 @@ +billableLocked; + } + + public function getBillableLockedToString(): ?string + { + return ($this->getBillableLocked()) ? 'true' : 'false'; + } + + /** + * @param bool $billableLocked + * @return $this + */ + public function setBillableLocked(?bool $billableLocked): self + { + $this->billableLocked = $billableLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/CustomerInheritField.php b/src/Fields/Dimensions/Level34/CustomerInheritField.php new file mode 100644 index 00000000..1191f37f --- /dev/null +++ b/src/Fields/Dimensions/Level34/CustomerInheritField.php @@ -0,0 +1,37 @@ +customerInherit; + } + + public function getCustomerInheritToString(): ?string + { + return ($this->getCustomerInherit()) ? 'true' : 'false'; + } + + /** + * @param bool $customerInherit + * @return $this + */ + public function setCustomerInherit(?bool $customerInherit): self + { + $this->customerInherit = $customerInherit; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/CustomerLockedField.php b/src/Fields/Dimensions/Level34/CustomerLockedField.php new file mode 100644 index 00000000..7cf47f2c --- /dev/null +++ b/src/Fields/Dimensions/Level34/CustomerLockedField.php @@ -0,0 +1,37 @@ +customerLocked; + } + + public function getCustomerLockedToString(): ?string + { + return ($this->getCustomerLocked()) ? 'true' : 'false'; + } + + /** + * @param bool $customerLocked + * @return $this + */ + public function setCustomerLocked(?bool $customerLocked): self + { + $this->customerLocked = $customerLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/AmountLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/AmountLockedField.php new file mode 100644 index 00000000..4448fb8b --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/AmountLockedField.php @@ -0,0 +1,32 @@ +amountLocked; + } + + /** + * @param bool $amountLocked + * @return $this + */ + public function setAmountLocked(?bool $amountLocked): self + { + $this->amountLocked = $amountLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodField.php b/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodField.php new file mode 100644 index 00000000..cbe18d03 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodField.php @@ -0,0 +1,37 @@ +beginPeriod; + } + + /** + * @param string|null $beginPeriod + * @return $this + */ + public function setBeginPeriod(?string $beginPeriod): self + { + if (!preg_match("!\\d{4}/\\d{1,2}!", $beginPeriod)) { + $beginPeriod = ''; + } + + $this->beginPeriod = $beginPeriod; + + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodLockedField.php new file mode 100644 index 00000000..285ead2a --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/BeginPeriodLockedField.php @@ -0,0 +1,32 @@ +beginPeriodLocked; + } + + /** + * @param bool $beginPeriodLocked + * @return $this + */ + public function setBeginPeriodLocked(?bool $beginPeriodLocked): self + { + $this->beginPeriodLocked = $beginPeriodLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/CodeField.php b/src/Fields/Dimensions/Level34/FixedAsset/CodeField.php new file mode 100644 index 00000000..70e57d88 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/CodeField.php @@ -0,0 +1,31 @@ +code; + } + + /** + * @return $this + */ + public function setCode($code): self + { + $this->code = $code; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/CodeLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/CodeLockedField.php new file mode 100644 index 00000000..dc9ccfa0 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/CodeLockedField.php @@ -0,0 +1,32 @@ +codeLocked; + } + + /** + * @param bool $codeLocked + * @return $this + */ + public function setCodeLocked(?bool $codeLocked): self + { + $this->codeLocked = $codeLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim1LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim1LockedField.php new file mode 100644 index 00000000..462dab39 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim1LockedField.php @@ -0,0 +1,32 @@ +dim1Locked; + } + + /** + * @param bool $dim1Locked + * @return $this + */ + public function setDim1Locked(?bool $dim1Locked): self + { + $this->dim1Locked = $dim1Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim2LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim2LockedField.php new file mode 100644 index 00000000..37995f0a --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim2LockedField.php @@ -0,0 +1,32 @@ +dim2Locked; + } + + /** + * @param bool $dim2Locked + * @return $this + */ + public function setDim2Locked(?bool $dim2Locked): self + { + $this->dim2Locked = $dim2Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim3LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim3LockedField.php new file mode 100644 index 00000000..61f99750 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim3LockedField.php @@ -0,0 +1,32 @@ +dim3Locked; + } + + /** + * @param bool $dim3Locked + * @return $this + */ + public function setDim3Locked(?bool $dim3Locked): self + { + $this->dim3Locked = $dim3Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim4LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim4LockedField.php new file mode 100644 index 00000000..d35f0201 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim4LockedField.php @@ -0,0 +1,32 @@ +dim4Locked; + } + + /** + * @param bool $dim4Locked + * @return $this + */ + public function setDim4Locked(?bool $dim4Locked): self + { + $this->dim4Locked = $dim4Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim5Field.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim5Field.php new file mode 100644 index 00000000..910827d7 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim5Field.php @@ -0,0 +1,31 @@ +dim5; + } + + /** + * @return $this + */ + public function setDim5($dim5): self + { + $this->dim5 = $dim5; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim5LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim5LockedField.php new file mode 100644 index 00000000..f1f84916 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim5LockedField.php @@ -0,0 +1,32 @@ +dim5Locked; + } + + /** + * @param bool $dim5Locked + * @return $this + */ + public function setDim5Locked(?bool $dim5Locked): self + { + $this->dim5Locked = $dim5Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim6Field.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim6Field.php new file mode 100644 index 00000000..b3ddd90d --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim6Field.php @@ -0,0 +1,31 @@ +dim6; + } + + /** + * @return $this + */ + public function setDim6($dim6): self + { + $this->dim6 = $dim6; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/Dim6LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/Dim6LockedField.php new file mode 100644 index 00000000..479a53d4 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/Dim6LockedField.php @@ -0,0 +1,32 @@ +dim6Locked; + } + + /** + * @param bool $dim6Locked + * @return $this + */ + public function setDim6Locked(?bool $dim6Locked): self + { + $this->dim6Locked = $dim6Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText1LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText1LockedField.php new file mode 100644 index 00000000..6d345454 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText1LockedField.php @@ -0,0 +1,32 @@ +freeText1Locked; + } + + /** + * @param bool $freeText1Locked + * @return $this + */ + public function setFreeText1Locked(?bool $freeText1Locked): self + { + $this->freeText1Locked = $freeText1Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText2LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText2LockedField.php new file mode 100644 index 00000000..dc6696ef --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText2LockedField.php @@ -0,0 +1,32 @@ +freeText2Locked; + } + + /** + * @param bool $freeText2Locked + * @return $this + */ + public function setFreeText2Locked(?bool $freeText2Locked): self + { + $this->freeText2Locked = $freeText2Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText3LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText3LockedField.php new file mode 100644 index 00000000..15df407a --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText3LockedField.php @@ -0,0 +1,32 @@ +freeText3Locked; + } + + /** + * @param bool $freeText3Locked + * @return $this + */ + public function setFreeText3Locked(?bool $freeText3Locked): self + { + $this->freeText3Locked = $freeText3Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText4Field.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText4Field.php new file mode 100644 index 00000000..a6018ab0 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText4Field.php @@ -0,0 +1,32 @@ +freeText4; + } + + /** + * @param null|string $freeText4 + * @return $this + */ + public function setFreeText4(?string $freeText4): self + { + $this->freeText4 = $freeText4; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText4LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText4LockedField.php new file mode 100644 index 00000000..6997c671 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText4LockedField.php @@ -0,0 +1,32 @@ +freeText4Locked; + } + + /** + * @param bool $freeText4Locked + * @return $this + */ + public function setFreeText4Locked(?bool $freeText4Locked): self + { + $this->freeText4Locked = $freeText4Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText5Field.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText5Field.php new file mode 100644 index 00000000..e1059181 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText5Field.php @@ -0,0 +1,32 @@ +freeText5; + } + + /** + * @param null|string $freeText5 + * @return $this + */ + public function setFreeText5(?string $freeText5): self + { + $this->freeText5 = $freeText5; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/FreeText5LockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/FreeText5LockedField.php new file mode 100644 index 00000000..c9763112 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/FreeText5LockedField.php @@ -0,0 +1,32 @@ +freeText5Locked; + } + + /** + * @param bool $freeText5Locked + * @return $this + */ + public function setFreeText5Locked(?bool $freeText5Locked): self + { + $this->freeText5Locked = $freeText5Locked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationField.php b/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationField.php new file mode 100644 index 00000000..bb4fe5f6 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationField.php @@ -0,0 +1,37 @@ +lastDepreciation; + } + + /** + * @param string|null $lastDepreciation + * @return $this + */ + public function setLastDepreciation(?string $lastDepreciation): self + { + if (!preg_match("!\\d{4}/\\d{1,2}!", $lastDepreciation)) { + $lastDepreciation = ''; + } + + $this->lastDepreciation = $lastDepreciation; + + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationLockedField.php new file mode 100644 index 00000000..4063d20c --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/LastDepreciationLockedField.php @@ -0,0 +1,32 @@ +lastDepreciationLocked; + } + + /** + * @param bool $lastDepreciationLocked + * @return $this + */ + public function setLastDepreciationLocked(?bool $lastDepreciationLocked): self + { + $this->lastDepreciationLocked = $lastDepreciationLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/LineField.php b/src/Fields/Dimensions/Level34/FixedAsset/LineField.php new file mode 100644 index 00000000..d4d532d7 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/LineField.php @@ -0,0 +1,32 @@ +line; + } + + /** + * @param null|int $line + * @return $this + */ + public function setLine(?int $line): self + { + $this->line = $line; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/LineLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/LineLockedField.php new file mode 100644 index 00000000..74db813a --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/LineLockedField.php @@ -0,0 +1,32 @@ +lineLocked; + } + + /** + * @param bool $lineLocked + * @return $this + */ + public function setLineLocked(?bool $lineLocked): self + { + $this->lineLocked = $lineLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/MethodField.php b/src/Fields/Dimensions/Level34/FixedAsset/MethodField.php new file mode 100644 index 00000000..4fd36b54 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/MethodField.php @@ -0,0 +1,33 @@ +method; + } + + /** + * @return $this + */ + public function setMethod(?AssetMethod $method): self + { + $this->method = $method; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/MethodLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/MethodLockedField.php new file mode 100644 index 00000000..0200cbad --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/MethodLockedField.php @@ -0,0 +1,32 @@ +methodLocked; + } + + /** + * @param bool $methodLocked + * @return $this + */ + public function setMethodLocked(?bool $methodLocked): self + { + $this->methodLocked = $methodLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsInheritedField.php b/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsInheritedField.php new file mode 100644 index 00000000..9a1b8f0e --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsInheritedField.php @@ -0,0 +1,32 @@ +nrOfPeriodsInherited; + } + + /** + * @param bool $nrOfPeriodsInherited + * @return $this + */ + public function setNrOfPeriodsInherited(?bool $nrOfPeriodsInherited): self + { + $this->nrOfPeriodsInherited = $nrOfPeriodsInherited; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsLockedField.php new file mode 100644 index 00000000..7aa22ace --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/NrOfPeriodsLockedField.php @@ -0,0 +1,32 @@ +nrOfPeriodsLocked; + } + + /** + * @param bool $nrOfPeriodsLocked + * @return $this + */ + public function setNrOfPeriodsLocked(?bool $nrOfPeriodsLocked): self + { + $this->nrOfPeriodsLocked = $nrOfPeriodsLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/NumberField.php b/src/Fields/Dimensions/Level34/FixedAsset/NumberField.php new file mode 100644 index 00000000..0398284f --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/NumberField.php @@ -0,0 +1,32 @@ +number; + } + + /** + * @param null|int $number + * @return $this + */ + public function setNumber(?int $number): self + { + $this->number = $number; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/NumberLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/NumberLockedField.php new file mode 100644 index 00000000..169c7978 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/NumberLockedField.php @@ -0,0 +1,32 @@ +numberLocked; + } + + /** + * @param bool $numberLocked + * @return $this + */ + public function setNumberLocked(?bool $numberLocked): self + { + $this->numberLocked = $numberLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/PercentageLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/PercentageLockedField.php new file mode 100644 index 00000000..8508f371 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/PercentageLockedField.php @@ -0,0 +1,32 @@ +percentageLocked; + } + + /** + * @param bool $percentageLocked + * @return $this + */ + public function setPercentageLocked(?bool $percentageLocked): self + { + $this->percentageLocked = $percentageLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/PeriodLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/PeriodLockedField.php new file mode 100644 index 00000000..2d932ff5 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/PeriodLockedField.php @@ -0,0 +1,32 @@ +periodLocked; + } + + /** + * @param bool $periodLocked + * @return $this + */ + public function setPeriodLocked(?bool $periodLocked): self + { + $this->periodLocked = $periodLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateField.php b/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateField.php new file mode 100644 index 00000000..a2f5b5f6 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateField.php @@ -0,0 +1,35 @@ +purchaseDate; + } + + /** + * @param \DateTimeInterface|null $purchaseDate + * @return $this + */ + public function setPurchaseDate(?\DateTimeInterface $purchaseDate) + { + $this->purchaseDate = $purchaseDate; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateLockedField.php new file mode 100644 index 00000000..b783520c --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/PurchaseDateLockedField.php @@ -0,0 +1,32 @@ +purchaseDateLocked; + } + + /** + * @param bool $purchaseDateLocked + * @return $this + */ + public function setPurchaseDateLocked(?bool $purchaseDateLocked): self + { + $this->purchaseDateLocked = $purchaseDateLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueField.php b/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueField.php new file mode 100644 index 00000000..03c437e5 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueField.php @@ -0,0 +1,35 @@ +residualValue; + } + + /** + * @param Money|null $residualValue + * @return $this + */ + public function setResidualValue(?Money $residualValue) + { + $this->residualValue = $residualValue; + + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueLockedField.php new file mode 100644 index 00000000..79480565 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/ResidualValueLockedField.php @@ -0,0 +1,32 @@ +residualValueLocked; + } + + /** + * @param bool $residualValueLocked + * @return $this + */ + public function setResidualValueLocked(?bool $residualValueLocked): self + { + $this->residualValueLocked = $residualValueLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/SellDateField.php b/src/Fields/Dimensions/Level34/FixedAsset/SellDateField.php new file mode 100644 index 00000000..e6ae1d08 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/SellDateField.php @@ -0,0 +1,35 @@ +sellDate; + } + + /** + * @param \DateTimeInterface|null $sellDate + * @return $this + */ + public function setSellDate(?\DateTimeInterface $sellDate) + { + $this->sellDate = $sellDate; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/SellDateLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/SellDateLockedField.php new file mode 100644 index 00000000..e989f2d0 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/SellDateLockedField.php @@ -0,0 +1,32 @@ +sellDateLocked; + } + + /** + * @param bool $sellDateLocked + * @return $this + */ + public function setSellDateLocked(?bool $sellDateLocked): self + { + $this->sellDateLocked = $sellDateLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/StatusField.php b/src/Fields/Dimensions/Level34/FixedAsset/StatusField.php new file mode 100644 index 00000000..615c3a39 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/StatusField.php @@ -0,0 +1,31 @@ +status; + } + + /** + * @param FixedAssetsStatus|null $status + * @return $this + */ + public function setStatus(?FixedAssetsStatus $status): self + { + $this->status = $status; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/StatusLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/StatusLockedField.php new file mode 100644 index 00000000..2ddffd8d --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/StatusLockedField.php @@ -0,0 +1,32 @@ +statusLocked; + } + + /** + * @param bool $statusLocked + * @return $this + */ + public function setStatusLocked(?bool $statusLocked): self + { + $this->statusLocked = $statusLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/StopValueField.php b/src/Fields/Dimensions/Level34/FixedAsset/StopValueField.php new file mode 100644 index 00000000..48a17432 --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/StopValueField.php @@ -0,0 +1,35 @@ +stopValue; + } + + /** + * @param Money|null $stopValue + * @return $this + */ + public function setStopValue(?Money $stopValue) + { + $this->stopValue = $stopValue; + + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/StopValueLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/StopValueLockedField.php new file mode 100644 index 00000000..639184db --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/StopValueLockedField.php @@ -0,0 +1,32 @@ +stopValueLocked; + } + + /** + * @param bool $stopValueLocked + * @return $this + */ + public function setStopValueLocked(?bool $stopValueLocked): self + { + $this->stopValueLocked = $stopValueLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/FixedAsset/TransactionLinesLockedField.php b/src/Fields/Dimensions/Level34/FixedAsset/TransactionLinesLockedField.php new file mode 100644 index 00000000..e52d277e --- /dev/null +++ b/src/Fields/Dimensions/Level34/FixedAsset/TransactionLinesLockedField.php @@ -0,0 +1,32 @@ +transactionLinesLocked; + } + + /** + * @param bool $transactionLinesLocked + * @return $this + */ + public function setTransactionLinesLocked(?bool $transactionLinesLocked): self + { + $this->transactionLinesLocked = $transactionLinesLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/InvoiceDescriptionField.php b/src/Fields/Dimensions/Level34/InvoiceDescriptionField.php new file mode 100644 index 00000000..67a261af --- /dev/null +++ b/src/Fields/Dimensions/Level34/InvoiceDescriptionField.php @@ -0,0 +1,32 @@ +invoiceDescription; + } + + /** + * @param null|string $invoiceDescription + * @return $this + */ + public function setInvoiceDescription(?string $invoiceDescription): self + { + $this->invoiceDescription = $invoiceDescription; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/LabelField.php b/src/Fields/Dimensions/Level34/LabelField.php new file mode 100644 index 00000000..dde21a16 --- /dev/null +++ b/src/Fields/Dimensions/Level34/LabelField.php @@ -0,0 +1,32 @@ +label; + } + + /** + * @param null|string $label + * @return $this + */ + public function setLabel(?string $label): self + { + $this->label = $label; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/MandatoryField.php b/src/Fields/Dimensions/Level34/MandatoryField.php new file mode 100644 index 00000000..8e298bd1 --- /dev/null +++ b/src/Fields/Dimensions/Level34/MandatoryField.php @@ -0,0 +1,32 @@ +mandatory; + } + + /** + * @param bool $mandatory + * @return $this + */ + public function setMandatory(?bool $mandatory): self + { + $this->mandatory = $mandatory; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/RateInheritField.php b/src/Fields/Dimensions/Level34/RateInheritField.php new file mode 100644 index 00000000..fe0804c4 --- /dev/null +++ b/src/Fields/Dimensions/Level34/RateInheritField.php @@ -0,0 +1,37 @@ +rateInherit; + } + + public function getRateInheritToString(): ?string + { + return ($this->getRateInherit()) ? 'true' : 'false'; + } + + /** + * @param bool $rateInherit + * @return $this + */ + public function setRateInherit(?bool $rateInherit): self + { + $this->rateInherit = $rateInherit; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/RateLockedField.php b/src/Fields/Dimensions/Level34/RateLockedField.php new file mode 100644 index 00000000..c78c3a11 --- /dev/null +++ b/src/Fields/Dimensions/Level34/RateLockedField.php @@ -0,0 +1,37 @@ +rateLocked; + } + + public function getRateLockedToString(): ?string + { + return ($this->getRateLocked()) ? 'true' : 'false'; + } + + /** + * @param bool $rateLocked + * @return $this + */ + public function setRateLocked(?bool $rateLocked): self + { + $this->rateLocked = $rateLocked; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/ValidFromField.php b/src/Fields/Dimensions/Level34/ValidFromField.php new file mode 100644 index 00000000..18a92bd6 --- /dev/null +++ b/src/Fields/Dimensions/Level34/ValidFromField.php @@ -0,0 +1,35 @@ +validFrom; + } + + /** + * @param \DateTimeInterface|null $validFrom + * @return $this + */ + public function setValidFrom(?\DateTimeInterface $validFrom) + { + $this->validFrom = $validFrom; + return $this; + } +} diff --git a/src/Fields/Dimensions/Level34/ValidTillField.php b/src/Fields/Dimensions/Level34/ValidTillField.php new file mode 100644 index 00000000..38543817 --- /dev/null +++ b/src/Fields/Dimensions/Level34/ValidTillField.php @@ -0,0 +1,35 @@ +validTill; + } + + /** + * @param \DateTimeInterface|null $validTill + * @return $this + */ + public function setValidTill(?\DateTimeInterface $validTill) + { + $this->validTill = $validTill; + return $this; + } +} diff --git a/src/Fields/Dimensions/MatchTypeField.php b/src/Fields/Dimensions/MatchTypeField.php new file mode 100644 index 00000000..2ed54457 --- /dev/null +++ b/src/Fields/Dimensions/MatchTypeField.php @@ -0,0 +1,31 @@ +matchType; + } + + /** + * @param MatchType|null $matchType + * @return $this + */ + public function setMatchType(?MatchType $matchType): self + { + $this->matchType = $matchType; + return $this; + } +} diff --git a/src/Fields/Dimensions/SubAnalyseField.php b/src/Fields/Dimensions/SubAnalyseField.php new file mode 100644 index 00000000..37bc9c9f --- /dev/null +++ b/src/Fields/Dimensions/SubAnalyseField.php @@ -0,0 +1,31 @@ +subAnalyse; + } + + /** + * @param SubAnalyse|null $subAnalyse + * @return $this + */ + public function setSubAnalyse(?SubAnalyse $subAnalyse): self + { + $this->subAnalyse = $subAnalyse; + return $this; + } +} diff --git a/src/Fields/Dimensions/SubstituteWithField.php b/src/Fields/Dimensions/SubstituteWithField.php new file mode 100644 index 00000000..7850b4c2 --- /dev/null +++ b/src/Fields/Dimensions/SubstituteWithField.php @@ -0,0 +1,31 @@ +substituteWith; + } + + /** + * @return $this + */ + public function setSubstituteWith($substituteWith): self + { + $this->substituteWith = $substituteWith; + return $this; + } +} diff --git a/src/Fields/Dimensions/SubstituteWithIDField.php b/src/Fields/Dimensions/SubstituteWithIDField.php new file mode 100644 index 00000000..c05a827b --- /dev/null +++ b/src/Fields/Dimensions/SubstituteWithIDField.php @@ -0,0 +1,32 @@ +substituteWithID; + } + + /** + * @param null|string $substituteWithID + * @return $this + */ + public function setSubstituteWithID(?string $substituteWithID): self + { + $this->substituteWithID = $substituteWithID; + return $this; + } +} diff --git a/src/Fields/Dimensions/SubstitutionLevelField.php b/src/Fields/Dimensions/SubstitutionLevelField.php new file mode 100644 index 00000000..d6fe4c5a --- /dev/null +++ b/src/Fields/Dimensions/SubstitutionLevelField.php @@ -0,0 +1,32 @@ +substitutionLevel; + } + + /** + * @param null|int $substitutionLevel + * @return $this + */ + public function setSubstitutionLevel(?int $substitutionLevel): self + { + $this->substitutionLevel = $substitutionLevel; + return $this; + } +} diff --git a/src/Fields/Dimensions/TypeField.php b/src/Fields/Dimensions/TypeField.php new file mode 100644 index 00000000..68eda6bd --- /dev/null +++ b/src/Fields/Dimensions/TypeField.php @@ -0,0 +1,31 @@ +type; + } + + /** + * @param ChildValidationType|null $type + * @return $this + */ + public function setType(?ChildValidationType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/Dimensions/VatCodeFixedField.php b/src/Fields/Dimensions/VatCodeFixedField.php new file mode 100644 index 00000000..12b1f63a --- /dev/null +++ b/src/Fields/Dimensions/VatCodeFixedField.php @@ -0,0 +1,32 @@ +vatCodeFixed; + } + + /** + * @param bool $vatCodeFixed + * @return $this + */ + public function setVatCodeFixed(?bool $vatCodeFixed): self + { + $this->vatCodeFixed = $vatCodeFixed; + return $this; + } +} diff --git a/src/Fields/DueDateField.php b/src/Fields/DueDateField.php new file mode 100644 index 00000000..29b2fe26 --- /dev/null +++ b/src/Fields/DueDateField.php @@ -0,0 +1,35 @@ +dueDate; + } + + /** + * @param \DateTimeInterface|null $dueDate + * @return $this + */ + public function setDueDate(?\DateTimeInterface $dueDate) + { + $this->dueDate = $dueDate; + return $this; + } +} diff --git a/src/Fields/ElementValueField.php b/src/Fields/ElementValueField.php new file mode 100644 index 00000000..67eaf852 --- /dev/null +++ b/src/Fields/ElementValueField.php @@ -0,0 +1,32 @@ +value; + } + + /** + * @param null|string $value + * @return $this + */ + public function setElementValue(?string $value): self + { + $this->value = $value; + return $this; + } +} diff --git a/src/Fields/EmailField.php b/src/Fields/EmailField.php new file mode 100644 index 00000000..a6786280 --- /dev/null +++ b/src/Fields/EmailField.php @@ -0,0 +1,32 @@ +email; + } + + /** + * @param null|string $email + * @return $this + */ + public function setEmail(?string $email): self + { + $this->email = $email; + return $this; + } +} diff --git a/src/Fields/FreeText1Field.php b/src/Fields/FreeText1Field.php new file mode 100644 index 00000000..327b1200 --- /dev/null +++ b/src/Fields/FreeText1Field.php @@ -0,0 +1,32 @@ +freeText1; + } + + /** + * @param null|string $freeText1 + * @return $this + */ + public function setFreeText1(?string $freeText1): self + { + $this->freeText1 = $freeText1; + return $this; + } +} diff --git a/src/Fields/FreeText2Field.php b/src/Fields/FreeText2Field.php new file mode 100644 index 00000000..89500d91 --- /dev/null +++ b/src/Fields/FreeText2Field.php @@ -0,0 +1,32 @@ +freeText2; + } + + /** + * @param null|string $freeText2 + * @return $this + */ + public function setFreeText2(?string $freeText2): self + { + $this->freeText2 = $freeText2; + return $this; + } +} diff --git a/src/Fields/FreeText3Field.php b/src/Fields/FreeText3Field.php new file mode 100644 index 00000000..717ab6f1 --- /dev/null +++ b/src/Fields/FreeText3Field.php @@ -0,0 +1,32 @@ +freeText3; + } + + /** + * @param null|string $freeText3 + * @return $this + */ + public function setFreeText3(?string $freeText3): self + { + $this->freeText3 = $freeText3; + return $this; + } +} diff --git a/src/Fields/IDField.php b/src/Fields/IDField.php new file mode 100644 index 00000000..8d6cac73 --- /dev/null +++ b/src/Fields/IDField.php @@ -0,0 +1,32 @@ +ID; + } + + /** + * @param null|int $ID + * @return $this + */ + public function setID(?int $ID): self + { + $this->ID = $ID; + return $this; + } +} diff --git a/src/Fields/InUseField.php b/src/Fields/InUseField.php new file mode 100644 index 00000000..36fbe655 --- /dev/null +++ b/src/Fields/InUseField.php @@ -0,0 +1,32 @@ +inUse; + } + + /** + * @param bool $inUse + * @return $this + */ + public function setInUse(?bool $inUse): self + { + $this->inUse = $inUse; + return $this; + } +} diff --git a/src/Fields/Invoice/AllowDiscountOrPremiumField.php b/src/Fields/Invoice/AllowDiscountOrPremiumField.php new file mode 100644 index 00000000..b2dc356d --- /dev/null +++ b/src/Fields/Invoice/AllowDiscountOrPremiumField.php @@ -0,0 +1,32 @@ +allowDiscountOrPremium; + } + + /** + * @param bool $allowDiscountOrPremium + * @return $this + */ + public function setAllowDiscountOrPremium(?bool $allowDiscountOrPremium): self + { + $this->allowDiscountOrPremium = $allowDiscountOrPremium; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/AllowChangePerformanceTypeField.php b/src/Fields/Invoice/Article/AllowChangePerformanceTypeField.php new file mode 100644 index 00000000..dafd9701 --- /dev/null +++ b/src/Fields/Invoice/Article/AllowChangePerformanceTypeField.php @@ -0,0 +1,32 @@ +allowChangePerformanceType; + } + + /** + * @param bool $allowChangePerformanceType + * @return $this + */ + public function setAllowChangePerformanceType(?bool $allowChangePerformanceType): self + { + $this->allowChangePerformanceType = $allowChangePerformanceType; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/AllowChangeUnitsPriceField.php b/src/Fields/Invoice/Article/AllowChangeUnitsPriceField.php new file mode 100644 index 00000000..103ae714 --- /dev/null +++ b/src/Fields/Invoice/Article/AllowChangeUnitsPriceField.php @@ -0,0 +1,32 @@ +allowChangeUnitsPrice; + } + + /** + * @param bool $allowChangeUnitsPrice + * @return $this + */ + public function setAllowChangeUnitsPrice(?bool $allowChangeUnitsPrice): self + { + $this->allowChangeUnitsPrice = $allowChangeUnitsPrice; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/AllowChangeVatCodeField.php b/src/Fields/Invoice/Article/AllowChangeVatCodeField.php new file mode 100644 index 00000000..8d5f24c2 --- /dev/null +++ b/src/Fields/Invoice/Article/AllowChangeVatCodeField.php @@ -0,0 +1,32 @@ +allowChangeVatCode; + } + + /** + * @param bool $allowChangeVatCode + * @return $this + */ + public function setAllowChangeVatCode(?bool $allowChangeVatCode): self + { + $this->allowChangeVatCode = $allowChangeVatCode; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/AllowDecimalQuantityField.php b/src/Fields/Invoice/Article/AllowDecimalQuantityField.php new file mode 100644 index 00000000..e88b691b --- /dev/null +++ b/src/Fields/Invoice/Article/AllowDecimalQuantityField.php @@ -0,0 +1,32 @@ +allowDecimalQuantity; + } + + /** + * @param bool $allowDecimalQuantity + * @return $this + */ + public function setAllowDecimalQuantity(?bool $allowDecimalQuantity): self + { + $this->allowDecimalQuantity = $allowDecimalQuantity; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/FreeText1Field.php b/src/Fields/Invoice/Article/FreeText1Field.php new file mode 100644 index 00000000..dea64806 --- /dev/null +++ b/src/Fields/Invoice/Article/FreeText1Field.php @@ -0,0 +1,33 @@ +freeText1; + } + + /** + * @return $this + */ + public function setFreeText1(?GeneralLedger $freeText1): self + { + $this->freeText1 = $freeText1; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/FreeText2Field.php b/src/Fields/Invoice/Article/FreeText2Field.php new file mode 100644 index 00000000..a7189bef --- /dev/null +++ b/src/Fields/Invoice/Article/FreeText2Field.php @@ -0,0 +1,33 @@ +freeText2; + } + + /** + * @return $this + */ + public function setFreeText2(?CostCenter $freeText2): self + { + $this->freeText2 = $freeText2; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/PercentageField.php b/src/Fields/Invoice/Article/PercentageField.php new file mode 100644 index 00000000..890325ca --- /dev/null +++ b/src/Fields/Invoice/Article/PercentageField.php @@ -0,0 +1,32 @@ +percentage; + } + + /** + * @param bool $percentage + * @return $this + */ + public function setPercentage(?bool $percentage): self + { + $this->percentage = $percentage; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/SubCodeField.php b/src/Fields/Invoice/Article/SubCodeField.php new file mode 100644 index 00000000..7b8cfcce --- /dev/null +++ b/src/Fields/Invoice/Article/SubCodeField.php @@ -0,0 +1,32 @@ +subCode; + } + + /** + * @param null|string $subCode + * @return $this + */ + public function setSubCode(?string $subCode): self + { + $this->subCode = $subCode; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/TypeField.php b/src/Fields/Invoice/Article/TypeField.php new file mode 100644 index 00000000..0d76d838 --- /dev/null +++ b/src/Fields/Invoice/Article/TypeField.php @@ -0,0 +1,31 @@ +type; + } + + /** + * @param ArticleType|null $type + * @return $this + */ + public function setType(?ArticleType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/UnitNamePluralField.php b/src/Fields/Invoice/Article/UnitNamePluralField.php new file mode 100644 index 00000000..1950a804 --- /dev/null +++ b/src/Fields/Invoice/Article/UnitNamePluralField.php @@ -0,0 +1,32 @@ +unitNamePlural; + } + + /** + * @param null|string $unitNamePlural + * @return $this + */ + public function setUnitNamePlural(?string $unitNamePlural): self + { + $this->unitNamePlural = $unitNamePlural; + return $this; + } +} diff --git a/src/Fields/Invoice/Article/UnitNameSingularField.php b/src/Fields/Invoice/Article/UnitNameSingularField.php new file mode 100644 index 00000000..b2b1fafa --- /dev/null +++ b/src/Fields/Invoice/Article/UnitNameSingularField.php @@ -0,0 +1,32 @@ +unitNameSingular; + } + + /** + * @param null|string $unitNameSingular + * @return $this + */ + public function setUnitNameSingular(?string $unitNameSingular): self + { + $this->unitNameSingular = $unitNameSingular; + return $this; + } +} diff --git a/src/Fields/Invoice/ArticleField.php b/src/Fields/Invoice/ArticleField.php new file mode 100644 index 00000000..bb68a67a --- /dev/null +++ b/src/Fields/Invoice/ArticleField.php @@ -0,0 +1,33 @@ +article; + } + + /** + * @return $this + */ + public function setArticle(?Article $article): self + { + $this->article = $article; + return $this; + } +} diff --git a/src/Fields/Invoice/BankField.php b/src/Fields/Invoice/BankField.php new file mode 100644 index 00000000..27189d2e --- /dev/null +++ b/src/Fields/Invoice/BankField.php @@ -0,0 +1,33 @@ +bank; + } + + /** + * @return $this + */ + public function setBank(?CashBankBook $bank): self + { + $this->bank = $bank; + return $this; + } +} diff --git a/src/Fields/Invoice/CalculateOnlyField.php b/src/Fields/Invoice/CalculateOnlyField.php new file mode 100644 index 00000000..589d6310 --- /dev/null +++ b/src/Fields/Invoice/CalculateOnlyField.php @@ -0,0 +1,32 @@ +calculateOnly; + } + + /** + * @param bool $calculateOnly + * @return $this + */ + public function setCalculateOnly(?bool $calculateOnly): self + { + $this->calculateOnly = $calculateOnly; + return $this; + } +} diff --git a/src/Fields/Invoice/CustomerNameField.php b/src/Fields/Invoice/CustomerNameField.php new file mode 100644 index 00000000..1edad3a1 --- /dev/null +++ b/src/Fields/Invoice/CustomerNameField.php @@ -0,0 +1,32 @@ +customerName; + } + + /** + * @param null|string $customerName + * @return $this + */ + public function setCustomerName(?string $customerName): self + { + $this->customerName = $customerName; + return $this; + } +} diff --git a/src/Fields/Invoice/DebitCreditField.php b/src/Fields/Invoice/DebitCreditField.php new file mode 100644 index 00000000..be0a67b7 --- /dev/null +++ b/src/Fields/Invoice/DebitCreditField.php @@ -0,0 +1,41 @@ +debitCredit; + } + + /** + * @param InvoiceDebitCredit|null $debitCredit + * @return $this + */ + public function setDebitCredit(?InvoiceDebitCredit $debitCredit): self + { + $this->debitCredit = $debitCredit; + return $this; + } + + /** + * @param string|null $debitCreditString + * @return $this + * @throws Exception + */ + public function setDebitCreditFromString(?string $debitCreditString) + { + return $this->setDebitCredit(new InvoiceDebitCredit((string)$debitCreditString)); + } +} diff --git a/src/Fields/Invoice/DeliverAddressNumberField.php b/src/Fields/Invoice/DeliverAddressNumberField.php new file mode 100644 index 00000000..94615620 --- /dev/null +++ b/src/Fields/Invoice/DeliverAddressNumberField.php @@ -0,0 +1,32 @@ +deliverAddressNumber; + } + + /** + * @param null|int $deliverAddressNumber + * @return $this + */ + public function setDeliverAddressNumber(?int $deliverAddressNumber): self + { + $this->deliverAddressNumber = $deliverAddressNumber; + return $this; + } +} diff --git a/src/Fields/Invoice/FinancialCodeField.php b/src/Fields/Invoice/FinancialCodeField.php new file mode 100644 index 00000000..c6641acd --- /dev/null +++ b/src/Fields/Invoice/FinancialCodeField.php @@ -0,0 +1,32 @@ +financialCode; + } + + /** + * @param null|string $financialCode + * @return $this + */ + public function setFinancialCode(?string $financialCode): self + { + $this->financialCode = $financialCode; + return $this; + } +} diff --git a/src/Fields/Invoice/FinancialNumberField.php b/src/Fields/Invoice/FinancialNumberField.php new file mode 100644 index 00000000..5562715a --- /dev/null +++ b/src/Fields/Invoice/FinancialNumberField.php @@ -0,0 +1,32 @@ +financialNumber; + } + + /** + * @param null|int $financialNumber + * @return $this + */ + public function setFinancialNumber(?int $financialNumber): self + { + $this->financialNumber = $financialNumber; + return $this; + } +} diff --git a/src/Fields/Invoice/FooterTextField.php b/src/Fields/Invoice/FooterTextField.php new file mode 100644 index 00000000..f0772237 --- /dev/null +++ b/src/Fields/Invoice/FooterTextField.php @@ -0,0 +1,32 @@ +footerText; + } + + /** + * @param null|string $footerText + * @return $this + */ + public function setFooterText(?string $footerText): self + { + $this->footerText = $footerText; + return $this; + } +} diff --git a/src/Fields/Invoice/HeaderTextField.php b/src/Fields/Invoice/HeaderTextField.php new file mode 100644 index 00000000..977ee938 --- /dev/null +++ b/src/Fields/Invoice/HeaderTextField.php @@ -0,0 +1,32 @@ +headerText; + } + + /** + * @param null|string $headerText + * @return $this + */ + public function setHeaderText(?string $headerText): self + { + $this->headerText = $headerText; + return $this; + } +} diff --git a/src/Fields/Invoice/InvoiceAddressNumberField.php b/src/Fields/Invoice/InvoiceAddressNumberField.php new file mode 100644 index 00000000..4742fc0f --- /dev/null +++ b/src/Fields/Invoice/InvoiceAddressNumberField.php @@ -0,0 +1,32 @@ +invoiceAddressNumber; + } + + /** + * @param null|int $invoiceAddressNumber + * @return $this + */ + public function setInvoiceAddressNumber(?int $invoiceAddressNumber): self + { + $this->invoiceAddressNumber = $invoiceAddressNumber; + return $this; + } +} diff --git a/src/Fields/Invoice/InvoiceAmountField.php b/src/Fields/Invoice/InvoiceAmountField.php new file mode 100644 index 00000000..c0a1335f --- /dev/null +++ b/src/Fields/Invoice/InvoiceAmountField.php @@ -0,0 +1,50 @@ +invoiceAmount; + } + + /** + * @param Money|null $invoiceAmount + * @return $this + */ + public function setInvoiceAmount(?Money $invoiceAmount) + { + $this->invoiceAmount = $invoiceAmount; + + return $this; + } + + /** + * @param float|null $invoiceAmountFloat + * @return $this + * @throws Exception + */ + public function setInvoiceAmountFromFloat(?float $invoiceAmountFloat) + { + if ((float)$invoiceAmountFloat) { + return $this->setInvoiceAmount(Money::EUR(100 * $invoiceAmountFloat)); + } else { + return $this->setInvoiceAmount(Money::EUR(0)); + } + } +} diff --git a/src/Fields/Invoice/InvoiceDateField.php b/src/Fields/Invoice/InvoiceDateField.php new file mode 100644 index 00000000..27e96f5e --- /dev/null +++ b/src/Fields/Invoice/InvoiceDateField.php @@ -0,0 +1,35 @@ +invoiceDate; + } + + /** + * @param \DateTimeInterface|null $invoiceDate + * @return $this + */ + public function setInvoiceDate(?\DateTimeInterface $invoiceDate) + { + $this->invoiceDate = $invoiceDate; + return $this; + } +} diff --git a/src/Fields/Invoice/InvoiceTypeField.php b/src/Fields/Invoice/InvoiceTypeField.php new file mode 100644 index 00000000..a0d8b089 --- /dev/null +++ b/src/Fields/Invoice/InvoiceTypeField.php @@ -0,0 +1,33 @@ +invoiceType; + } + + /** + * @return $this + */ + public function setInvoiceType(?InvoiceType $invoiceType): self + { + $this->invoiceType = $invoiceType; + return $this; + } +} diff --git a/src/Fields/Invoice/PaymentMethodField.php b/src/Fields/Invoice/PaymentMethodField.php new file mode 100644 index 00000000..644b898c --- /dev/null +++ b/src/Fields/Invoice/PaymentMethodField.php @@ -0,0 +1,31 @@ +paymentMethod; + } + + /** + * @param PaymentMethod|null $paymentMethod + * @return $this + */ + public function setPaymentMethod(?PaymentMethod $paymentMethod): self + { + $this->paymentMethod = $paymentMethod; + return $this; + } +} diff --git a/src/Fields/Invoice/PeriodRaiseWarningField.php b/src/Fields/Invoice/PeriodRaiseWarningField.php new file mode 100644 index 00000000..8bcbe56d --- /dev/null +++ b/src/Fields/Invoice/PeriodRaiseWarningField.php @@ -0,0 +1,32 @@ +periodRaiseWarning; + } + + /** + * @param bool $periodRaiseWarning + * @return $this + */ + public function setPeriodRaiseWarning(?bool $periodRaiseWarning): self + { + $this->periodRaiseWarning = $periodRaiseWarning; + return $this; + } +} diff --git a/src/Fields/Invoice/QuantityField.php b/src/Fields/Invoice/QuantityField.php new file mode 100644 index 00000000..7804c80f --- /dev/null +++ b/src/Fields/Invoice/QuantityField.php @@ -0,0 +1,32 @@ +quantity; + } + + /** + * @param null|float $quantity + * @return $this + */ + public function setQuantity(?float $quantity): self + { + $this->quantity = $quantity; + return $this; + } +} diff --git a/src/Fields/Invoice/RaiseWarningField.php b/src/Fields/Invoice/RaiseWarningField.php new file mode 100644 index 00000000..f56abbdc --- /dev/null +++ b/src/Fields/Invoice/RaiseWarningField.php @@ -0,0 +1,32 @@ +raiseWarning; + } + + /** + * @param bool $raiseWarning + * @return $this + */ + public function setRaiseWarning(?bool $raiseWarning): self + { + $this->raiseWarning = $raiseWarning; + return $this; + } +} diff --git a/src/Fields/Invoice/StatusField.php b/src/Fields/Invoice/StatusField.php new file mode 100644 index 00000000..f39536dc --- /dev/null +++ b/src/Fields/Invoice/StatusField.php @@ -0,0 +1,31 @@ +status; + } + + /** + * @param InvoiceStatus|null $status + * @return $this + */ + public function setStatus(?InvoiceStatus $status): self + { + $this->status = $status; + return $this; + } +} diff --git a/src/Fields/Invoice/SubArticleField.php b/src/Fields/Invoice/SubArticleField.php new file mode 100644 index 00000000..b89d7df2 --- /dev/null +++ b/src/Fields/Invoice/SubArticleField.php @@ -0,0 +1,54 @@ +subArticle; + } + + public function getSubArticleToString(): ?string + { + if ($this->getSubArticle() != null) { + return $this->subArticle->getSubCode(); + } else { + return null; + } + } + + /** + * @return $this + */ + public function setSubArticle(?ArticleLine $subArticle): self + { + $this->subArticle = $subArticle; + return $this; + } + + /** + * @param string|null $subArticleString + * @return $this + * @throws Exception + */ + public function setSubArticleFromString(?string $subArticleString) + { + $subArticle = new ArticleLine(); + $subArticle->setSubCode($subArticleString); + return $this->setSubArticle($subArticle); + } +} diff --git a/src/Fields/Invoice/UnitsField.php b/src/Fields/Invoice/UnitsField.php new file mode 100644 index 00000000..7054b04b --- /dev/null +++ b/src/Fields/Invoice/UnitsField.php @@ -0,0 +1,32 @@ +units; + } + + /** + * @param null|int $units + * @return $this + */ + public function setUnits(?int $units): self + { + $this->units = $units; + return $this; + } +} diff --git a/src/Fields/Invoice/UnitsPriceExclField.php b/src/Fields/Invoice/UnitsPriceExclField.php new file mode 100644 index 00000000..db2649f9 --- /dev/null +++ b/src/Fields/Invoice/UnitsPriceExclField.php @@ -0,0 +1,35 @@ +unitsPriceExcl; + } + + /** + * @param Money|null $unitsPriceExcl + * @return $this + */ + public function setUnitsPriceExcl(?Money $unitsPriceExcl) + { + $this->unitsPriceExcl = $unitsPriceExcl; + + return $this; + } +} diff --git a/src/Fields/Invoice/UnitsPriceIncField.php b/src/Fields/Invoice/UnitsPriceIncField.php new file mode 100644 index 00000000..3932b504 --- /dev/null +++ b/src/Fields/Invoice/UnitsPriceIncField.php @@ -0,0 +1,35 @@ +unitsPriceInc; + } + + /** + * @param Money|null $unitsPriceInc + * @return $this + */ + public function setUnitsPriceInc(?Money $unitsPriceInc) + { + $this->unitsPriceInc = $unitsPriceInc; + + return $this; + } +} diff --git a/src/Fields/Invoice/ValueExclField.php b/src/Fields/Invoice/ValueExclField.php new file mode 100644 index 00000000..c45eca25 --- /dev/null +++ b/src/Fields/Invoice/ValueExclField.php @@ -0,0 +1,35 @@ +valueExcl; + } + + /** + * @param Money|null $valueExcl + * @return $this + */ + public function setValueExcl(?Money $valueExcl) + { + $this->valueExcl = $valueExcl; + + return $this; + } +} diff --git a/src/Fields/Invoice/ValueIncField.php b/src/Fields/Invoice/ValueIncField.php new file mode 100644 index 00000000..1a24dc97 --- /dev/null +++ b/src/Fields/Invoice/ValueIncField.php @@ -0,0 +1,35 @@ +valueInc; + } + + /** + * @param Money|null $valueInc + * @return $this + */ + public function setValueInc(?Money $valueInc) + { + $this->valueInc = $valueInc; + + return $this; + } +} diff --git a/src/Transactions/TransactionFields/InvoiceNumberField.php b/src/Fields/InvoiceNumberField.php similarity index 50% rename from src/Transactions/TransactionFields/InvoiceNumberField.php rename to src/Fields/InvoiceNumberField.php index 5683aecf..d9486ba0 100644 --- a/src/Transactions/TransactionFields/InvoiceNumberField.php +++ b/src/Fields/InvoiceNumberField.php @@ -1,16 +1,19 @@ invoiceNumber = $invoiceNumber; - return $this; } } diff --git a/src/Fields/LevelField.php b/src/Fields/LevelField.php new file mode 100644 index 00000000..82936160 --- /dev/null +++ b/src/Fields/LevelField.php @@ -0,0 +1,32 @@ +level; + } + + /** + * @param null|int $level + * @return $this + */ + public function setLevel(?int $level): self + { + $this->level = $level; + return $this; + } +} diff --git a/src/Fields/LineTypeField.php b/src/Fields/LineTypeField.php new file mode 100644 index 00000000..db93ee3b --- /dev/null +++ b/src/Fields/LineTypeField.php @@ -0,0 +1,31 @@ +lineType; + } + + /** + * @param LineType|null $linetype + * @return $this + */ + public function setLineType(?LineType $lineType): self + { + $this->lineType = $lineType; + return $this; + } +} diff --git a/src/Fields/ModifiedField.php b/src/Fields/ModifiedField.php new file mode 100644 index 00000000..51460f04 --- /dev/null +++ b/src/Fields/ModifiedField.php @@ -0,0 +1,35 @@ +modified; + } + + /** + * @param \DateTimeInterface|null $modified + * @return $this + */ + public function setModified(?\DateTimeInterface $modified) + { + $this->modified = $modified; + return $this; + } +} diff --git a/src/Fields/NameField.php b/src/Fields/NameField.php new file mode 100644 index 00000000..d53640e4 --- /dev/null +++ b/src/Fields/NameField.php @@ -0,0 +1,31 @@ +name; + } + + /** + * @param null|string $name + * @return $this + */ + public function setName(?string $name): self + { + $this->name = $name; + return $this; + } +} diff --git a/src/Fields/NrOfPeriodsField.php b/src/Fields/NrOfPeriodsField.php new file mode 100644 index 00000000..77092b3c --- /dev/null +++ b/src/Fields/NrOfPeriodsField.php @@ -0,0 +1,32 @@ +nrOfPeriods; + } + + /** + * @param null|int $nrOfPeriods + * @return $this + */ + public function setNrOfPeriods(?int $nrOfPeriods): self + { + $this->nrOfPeriods = $nrOfPeriods; + return $this; + } +} diff --git a/src/Fields/Office/BaseCurrencyField.php b/src/Fields/Office/BaseCurrencyField.php new file mode 100644 index 00000000..443a0164 --- /dev/null +++ b/src/Fields/Office/BaseCurrencyField.php @@ -0,0 +1,33 @@ +baseCurrency; + } + + /** + * @return $this + */ + public function setBaseCurrency(?Currency $baseCurrency): self + { + $this->baseCurrency = $baseCurrency; + return $this; + } +} diff --git a/src/Fields/Office/CountryCodeField.php b/src/Fields/Office/CountryCodeField.php new file mode 100644 index 00000000..eaee87dd --- /dev/null +++ b/src/Fields/Office/CountryCodeField.php @@ -0,0 +1,45 @@ +countryCode; + } + + /** + * @return $this + */ + public function setCountryCode(?Country $countryCode): self + { + $this->countryCode = $countryCode; + return $this; + } + + /** + * @param string|null $countryCodeString + * @return $this + * @throws Exception + */ + public function setCountryCodeFromString(?string $countryCodeString) + { + $countryCode = new Country(); + $countryCode->setCode($countryCodeString); + return $this->setCountryCode($countryCode); + } +} diff --git a/src/Fields/Office/ReportingCurrencyField.php b/src/Fields/Office/ReportingCurrencyField.php new file mode 100644 index 00000000..2cd3f87e --- /dev/null +++ b/src/Fields/Office/ReportingCurrencyField.php @@ -0,0 +1,33 @@ +reportingCurrency; + } + + /** + * @return $this + */ + public function setReportingCurrency(?Currency $reportingCurrency): self + { + $this->reportingCurrency = $reportingCurrency; + return $this; + } +} diff --git a/src/Fields/Office/VatFirstQuarterStartsInField.php b/src/Fields/Office/VatFirstQuarterStartsInField.php new file mode 100644 index 00000000..8716b90c --- /dev/null +++ b/src/Fields/Office/VatFirstQuarterStartsInField.php @@ -0,0 +1,32 @@ +vatFirstQuarterStartsIn; + } + + /** + * @param null|string $vatFirstQuarterStartsIn + * @return $this + */ + public function setVatFirstQuarterStartsIn(?string $vatFirstQuarterStartsIn): self + { + $this->vatFirstQuarterStartsIn = $vatFirstQuarterStartsIn; + return $this; + } +} diff --git a/src/Fields/Office/VatPeriodField.php b/src/Fields/Office/VatPeriodField.php new file mode 100644 index 00000000..9f754ddd --- /dev/null +++ b/src/Fields/Office/VatPeriodField.php @@ -0,0 +1,32 @@ +vatPeriod; + } + + /** + * @param null|string $vatPeriod + * @return $this + */ + public function setVatPeriod(?string $vatPeriod): self + { + $this->vatPeriod = $vatPeriod; + return $this; + } +} diff --git a/src/Transactions/TransactionFields/OfficeField.php b/src/Fields/OfficeField.php similarity index 63% rename from src/Transactions/TransactionFields/OfficeField.php rename to src/Fields/OfficeField.php index ef0d964a..0ce3679a 100644 --- a/src/Transactions/TransactionFields/OfficeField.php +++ b/src/Fields/OfficeField.php @@ -1,33 +1,32 @@ -office; - } - - /** - * @return $this - */ - public function setOffice(Office $office): self - { - $this->office = $office; - - return $this; - } -} +office; + } + + /** + * @return $this + */ + public function setOffice(?Office $office): self + { + $this->office = $office; + return $this; + } +} diff --git a/src/Fields/PercentageField.php b/src/Fields/PercentageField.php new file mode 100644 index 00000000..22f8de0d --- /dev/null +++ b/src/Fields/PercentageField.php @@ -0,0 +1,32 @@ +percentage; + } + + /** + * @param null|float $percentage + * @return $this + */ + public function setPercentage(?float $percentage): self + { + $this->percentage = $percentage; + return $this; + } +} diff --git a/src/Fields/PerformanceDateField.php b/src/Fields/PerformanceDateField.php new file mode 100644 index 00000000..eea29cba --- /dev/null +++ b/src/Fields/PerformanceDateField.php @@ -0,0 +1,37 @@ +performanceDate; + } + + /** + * @param \DateTimeInterface|null $performanceDate + * @return $this + */ + public function setPerformanceDate(?\DateTimeInterface $performanceDate) + { + $this->performanceDate = $performanceDate; + return $this; + } +} diff --git a/src/Fields/PerformanceTypeField.php b/src/Fields/PerformanceTypeField.php new file mode 100644 index 00000000..ff497ed0 --- /dev/null +++ b/src/Fields/PerformanceTypeField.php @@ -0,0 +1,31 @@ +performanceType; + } + + /** + * @param PerformanceType|null $performanceType + * @return $this + */ + public function setPerformanceType(?PerformanceType $performanceType): self + { + $this->performanceType = $performanceType; + return $this; + } +} diff --git a/src/Fields/PeriodField.php b/src/Fields/PeriodField.php new file mode 100644 index 00000000..4cac81e5 --- /dev/null +++ b/src/Fields/PeriodField.php @@ -0,0 +1,37 @@ +period; + } + + /** + * @param string|null $period + * @return $this + */ + public function setPeriod(?string $period): self + { + if (!preg_match("!\\d{4}/\\d{1,2}!", $period)) { + $period = ''; + } + + $this->period = $period; + + return $this; + } +} diff --git a/src/Fields/Rate/BeginDateField.php b/src/Fields/Rate/BeginDateField.php new file mode 100644 index 00000000..750ead1c --- /dev/null +++ b/src/Fields/Rate/BeginDateField.php @@ -0,0 +1,36 @@ +beginDate; + } + + /** + * @param \DateTimeInterface|null $beginDate + * @return $this + */ + public function setBeginDate(?\DateTimeInterface $beginDate) + { + $this->beginDate = $beginDate; + return $this; + } +} diff --git a/src/Fields/Rate/EndDateField.php b/src/Fields/Rate/EndDateField.php new file mode 100644 index 00000000..a9e0e6c7 --- /dev/null +++ b/src/Fields/Rate/EndDateField.php @@ -0,0 +1,35 @@ +endDate; + } + + /** + * @param \DateTimeInterface|null $endDate + * @return $this + */ + public function setEndDate(?\DateTimeInterface $endDate) + { + $this->endDate = $endDate; + return $this; + } +} diff --git a/src/Fields/Rate/ExternalRateField.php b/src/Fields/Rate/ExternalRateField.php new file mode 100644 index 00000000..8c52d7f0 --- /dev/null +++ b/src/Fields/Rate/ExternalRateField.php @@ -0,0 +1,32 @@ +externalRate; + } + + /** + * @param null|float $externalRate + * @return $this + */ + public function setExternalRate(?float $externalRate): self + { + $this->externalRate = $externalRate; + return $this; + } +} diff --git a/src/Fields/Rate/InternalRateField.php b/src/Fields/Rate/InternalRateField.php new file mode 100644 index 00000000..3e61f833 --- /dev/null +++ b/src/Fields/Rate/InternalRateField.php @@ -0,0 +1,32 @@ +internalRate; + } + + /** + * @param null|float $internalRate + * @return $this + */ + public function setInternalRate(?float $internalRate): self + { + $this->internalRate = $internalRate; + return $this; + } +} diff --git a/src/Fields/Rate/TypeField.php b/src/Fields/Rate/TypeField.php new file mode 100644 index 00000000..32894aa0 --- /dev/null +++ b/src/Fields/Rate/TypeField.php @@ -0,0 +1,31 @@ +type; + } + + /** + * @param RateType|null $type + * @return $this + */ + public function setType(?RateType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/Rate/UnitField.php b/src/Fields/Rate/UnitField.php new file mode 100644 index 00000000..7094abde --- /dev/null +++ b/src/Fields/Rate/UnitField.php @@ -0,0 +1,32 @@ +unit; + } + + /** + * @param null|int $unit + * @return $this + */ + public function setUnit(?int $unit): self + { + $this->unit = $unit; + return $this; + } +} diff --git a/src/Fields/RateField.php b/src/Fields/RateField.php new file mode 100644 index 00000000..61dd9546 --- /dev/null +++ b/src/Fields/RateField.php @@ -0,0 +1,42 @@ +rate; + } + + public function getRateToString(): ?string + { + if ($this->getRate() != null) { + return $this->rate->getCode(); + } else { + return null; + } + } + + /** + * @return $this + */ + public function setRate(?Rate $rate): self + { + $this->rate = $rate; + return $this; + } +} diff --git a/src/Fields/ShortNameField.php b/src/Fields/ShortNameField.php new file mode 100644 index 00000000..f0f14a87 --- /dev/null +++ b/src/Fields/ShortNameField.php @@ -0,0 +1,31 @@ +shortName; + } + + /** + * @param null|string $shortName + * @return $this + */ + public function setShortName(?string $shortName): self + { + $this->shortName = $shortName; + return $this; + } +} diff --git a/src/Fields/StatusField.php b/src/Fields/StatusField.php new file mode 100644 index 00000000..6eaec94d --- /dev/null +++ b/src/Fields/StatusField.php @@ -0,0 +1,30 @@ +status; + } + + /** + * @param Status|null $status + * @return $this + */ + public function setStatus(?Status $status): self + { + $this->status = $status; + return $this; + } +} diff --git a/src/Fields/TouchedField.php b/src/Fields/TouchedField.php new file mode 100644 index 00000000..59387dfb --- /dev/null +++ b/src/Fields/TouchedField.php @@ -0,0 +1,32 @@ +touched; + } + + /** + * @param null|int $touched + * @return $this + */ + public function setTouched(?int $touched): self + { + $this->touched = $touched; + return $this; + } +} diff --git a/src/Transactions/TransactionFields/AutoBalanceVatField.php b/src/Fields/Transaction/AutoBalanceVatField.php similarity index 56% rename from src/Transactions/TransactionFields/AutoBalanceVatField.php rename to src/Fields/Transaction/AutoBalanceVatField.php index 32541332..34a61255 100644 --- a/src/Transactions/TransactionFields/AutoBalanceVatField.php +++ b/src/Fields/Transaction/AutoBalanceVatField.php @@ -1,11 +1,12 @@ autoBalanceVat; } @@ -23,10 +24,9 @@ public function isAutoBalanceVat(): ?bool * @param bool $autoBalanceVat * @return $this */ - public function setAutoBalanceVat(bool $autoBalanceVat): self + public function setAutoBalanceVat(?bool $autoBalanceVat): self { $this->autoBalanceVat = $autoBalanceVat; - return $this; } -} \ No newline at end of file +} diff --git a/src/Fields/Transaction/CloseAndStartValueFields.php b/src/Fields/Transaction/CloseAndStartValueFields.php new file mode 100644 index 00000000..350c3787 --- /dev/null +++ b/src/Fields/Transaction/CloseAndStartValueFields.php @@ -0,0 +1,85 @@ +currency; + } + + /** + * Set the currency. Can only be done when the start value is still 0. + * + * @param Currency $currency + * @return $this + */ + public function setCurrency(?Currency $currency): self + { + Assert::true($this->startValue->isZero()); + $this->setStartValue(new Money(0, new \Money\Currency($currency->getCode()))); + + return $this; + } + + /** + * @return Money|null + */ + public function getStartValue(): ?Money + { + return $this->startValue; + } + + /** + * @param Money|null $startValue + * @return $this + */ + public function setStartValue(?Money $startValue): void + { + if (!empty($startValue->getCurrency())) { + $currency = \PhpTwinfield\Currency::fromCode($startValue->getCurrency()); + $this->currency = $currency; + } + + $this->startValue = $startValue; + $this->closeValue = $startValue; + } + + public function getCloseValue(): Money + { + if (!empty($this->getCurrency())) { + $currencyCode = $this->getCurrency()->getCode(); + } else { + $currencyCode = 'EUR'; + } + + return $this->closeValue ?? new Money(0, new \Money\Currency($currencyCode)); + } +} diff --git a/src/Fields/Transaction/DateRaiseWarningField.php b/src/Fields/Transaction/DateRaiseWarningField.php new file mode 100644 index 00000000..5a56d073 --- /dev/null +++ b/src/Fields/Transaction/DateRaiseWarningField.php @@ -0,0 +1,37 @@ +dateRaiseWarning; + } + + public function getDateRaiseWarningToString(): ?string + { + return ($this->getDateRaiseWarning()) ? 'true' : 'false'; + } + + /** + * @param bool $dateRaiseWarning + * @return $this + */ + public function setDateRaiseWarning(?bool $dateRaiseWarning): self + { + $this->dateRaiseWarning = $dateRaiseWarning; + return $this; + } +} diff --git a/src/Fields/Transaction/DestinyField.php b/src/Fields/Transaction/DestinyField.php new file mode 100644 index 00000000..f96be78b --- /dev/null +++ b/src/Fields/Transaction/DestinyField.php @@ -0,0 +1,31 @@ +destiny; + } + + /** + * @param Destiny|null $destiny + * @return $this + */ + public function setDestiny(?Destiny $destiny): self + { + $this->destiny = $destiny; + return $this; + } +} diff --git a/src/Fields/Transaction/InputDateField.php b/src/Fields/Transaction/InputDateField.php new file mode 100644 index 00000000..30a213b3 --- /dev/null +++ b/src/Fields/Transaction/InputDateField.php @@ -0,0 +1,35 @@ +inputDate; + } + + /** + * @param \DateTimeInterface|null $inputDate + * @return $this + */ + public function setInputDate(?\DateTimeInterface $inputDate) + { + $this->inputDate = $inputDate; + return $this; + } +} diff --git a/src/Fields/Transaction/InvoiceNumberRaiseWarningField.php b/src/Fields/Transaction/InvoiceNumberRaiseWarningField.php new file mode 100644 index 00000000..459ee440 --- /dev/null +++ b/src/Fields/Transaction/InvoiceNumberRaiseWarningField.php @@ -0,0 +1,37 @@ +invoiceNumberRaiseWarning; + } + + public function getInvoiceNumberRaiseWarningToString(): ?string + { + return ($this->getInvoiceNumberRaiseWarning()) ? 'true' : 'false'; + } + + /** + * @param bool $invoiceNumberRaiseWarning + * @return $this + */ + public function setInvoiceNumberRaiseWarning(?bool $invoiceNumberRaiseWarning): self + { + $this->invoiceNumberRaiseWarning = $invoiceNumberRaiseWarning; + return $this; + } +} diff --git a/src/Transactions/TransactionFields/LinesField.php b/src/Fields/Transaction/LinesField.php similarity index 84% rename from src/Transactions/TransactionFields/LinesField.php rename to src/Fields/Transaction/LinesField.php index 8b2a7d6f..e4ca3fc0 100644 --- a/src/Transactions/TransactionFields/LinesField.php +++ b/src/Fields/Transaction/LinesField.php @@ -1,18 +1,18 @@ [], @@ -21,8 +21,7 @@ trait LinesField ]; /** - * @return string The class name for transaction lines supported by this transaction. Must be an implementation of - * TransactionLine. + * @return string The class name for transaction lines supported by this transaction. Must be an implementation of BaseTransactionLine. */ abstract public function getLineClassName(): string; @@ -39,7 +38,7 @@ private function getLineCountForType(LineType $line_type): int } /** - * @return TransactionLine[] + * @return array[] */ public function getLines(): array { @@ -71,10 +70,10 @@ private function getVatLines(): array } /** - * @param TransactionLine $line + * @param $line * @return $this */ - public function addLine(TransactionLine $line) + public function addLine($line) { Assert::isInstanceOf($line, $this->getLineClassName()); @@ -89,7 +88,7 @@ public function addLine(TransactionLine $line) } /** - * @param TransactionLine[] $lines + * @param array $lines */ public function setLines(array $lines): void { diff --git a/src/Fields/Transaction/ModificationDateField.php b/src/Fields/Transaction/ModificationDateField.php new file mode 100644 index 00000000..fab37f1e --- /dev/null +++ b/src/Fields/Transaction/ModificationDateField.php @@ -0,0 +1,35 @@ +modificationDate; + } + + /** + * @param \DateTimeInterface|null $modificationDate + * @return $this + */ + public function setModificationDate(?\DateTimeInterface $modificationDate) + { + $this->modificationDate = $modificationDate; + return $this; + } +} diff --git a/src/Fields/Transaction/NumberField.php b/src/Fields/Transaction/NumberField.php new file mode 100644 index 00000000..548e1116 --- /dev/null +++ b/src/Fields/Transaction/NumberField.php @@ -0,0 +1,32 @@ +number; + } + + /** + * @param null|int $number + * @return $this + */ + public function setNumber(?int $number): self + { + $this->number = $number; + return $this; + } +} diff --git a/src/Fields/Transaction/OriginField.php b/src/Fields/Transaction/OriginField.php new file mode 100644 index 00000000..91c574cd --- /dev/null +++ b/src/Fields/Transaction/OriginField.php @@ -0,0 +1,32 @@ +origin; + } + + /** + * @param null|string $origin + * @return $this + */ + public function setOrigin(?string $origin): self + { + $this->origin = $origin; + return $this; + } +} diff --git a/src/Fields/Transaction/OriginReferenceField.php b/src/Fields/Transaction/OriginReferenceField.php new file mode 100644 index 00000000..8efc259c --- /dev/null +++ b/src/Fields/Transaction/OriginReferenceField.php @@ -0,0 +1,32 @@ +originReference; + } + + /** + * @param null|string $originReference + * @return $this + */ + public function setOriginReference(?string $originReference): self + { + $this->originReference = $originReference; + return $this; + } +} diff --git a/src/Transactions/TransactionFields/PaymentReferenceField.php b/src/Fields/Transaction/PaymentReferenceField.php similarity index 63% rename from src/Transactions/TransactionFields/PaymentReferenceField.php rename to src/Fields/Transaction/PaymentReferenceField.php index 143452a4..dc58b413 100644 --- a/src/Transactions/TransactionFields/PaymentReferenceField.php +++ b/src/Fields/Transaction/PaymentReferenceField.php @@ -1,16 +1,19 @@ paymentReference = $paymentReference; - return $this; } } diff --git a/src/Transactions/TransactionFields/RaiseWarningField.php b/src/Fields/Transaction/RaiseWarningField.php similarity index 55% rename from src/Transactions/TransactionFields/RaiseWarningField.php rename to src/Fields/Transaction/RaiseWarningField.php index 6a70bbd5..782c09ff 100644 --- a/src/Transactions/TransactionFields/RaiseWarningField.php +++ b/src/Fields/Transaction/RaiseWarningField.php @@ -1,16 +1,19 @@ raiseWarning = $raiseWarning; - return $this; } -} \ No newline at end of file +} diff --git a/src/Fields/Transaction/RegimeField.php b/src/Fields/Transaction/RegimeField.php new file mode 100644 index 00000000..ce03e896 --- /dev/null +++ b/src/Fields/Transaction/RegimeField.php @@ -0,0 +1,31 @@ +regime; + } + + /** + * @param Regime|null $regime + * @return $this + */ + public function setRegime(?Regime $regime): self + { + $this->regime = $regime; + return $this; + } +} diff --git a/src/Fields/Transaction/StatementNumberField.php b/src/Fields/Transaction/StatementNumberField.php new file mode 100644 index 00000000..0b11eead --- /dev/null +++ b/src/Fields/Transaction/StatementNumberField.php @@ -0,0 +1,32 @@ +statementNumber; + } + + /** + * @param null|int $statementNumber + * @return $this + */ + public function setStatementNumber(?int $statementNumber): self + { + $this->statementNumber = $statementNumber; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/BaseValueField.php b/src/Fields/Transaction/TransactionLine/BaseValueField.php new file mode 100644 index 00000000..ede0778b --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/BaseValueField.php @@ -0,0 +1,35 @@ +baseValue; + } + + /** + * @param Money|null $baseValue + * @return $this + */ + public function setBaseValue(?Money $baseValue) + { + $this->baseValue = $baseValue; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/BaseValueOpenField.php b/src/Fields/Transaction/TransactionLine/BaseValueOpenField.php new file mode 100644 index 00000000..a8e4ea6d --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/BaseValueOpenField.php @@ -0,0 +1,35 @@ +baseValueOpen; + } + + /** + * @param Money|null $baseValueOpen + * @return $this + */ + public function setBaseValueOpen(?Money $baseValueOpen) + { + $this->baseValueOpen = $baseValueOpen; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/BaselineField.php b/src/Fields/Transaction/TransactionLine/BaselineField.php new file mode 100644 index 00000000..64364e4b --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/BaselineField.php @@ -0,0 +1,32 @@ +baseline; + } + + /** + * @param null|int $baseline + * @return $this + */ + public function setBaseline(?int $baseline): self + { + $this->baseline = $baseline; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/CurrencyDateField.php b/src/Fields/Transaction/TransactionLine/CurrencyDateField.php new file mode 100644 index 00000000..f6c49a7d --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/CurrencyDateField.php @@ -0,0 +1,35 @@ +currencyDate; + } + + /** + * @param \DateTimeInterface|null $currencyDate + * @return $this + */ + public function setCurrencyDate(?\DateTimeInterface $currencyDate) + { + $this->currencyDate = $currencyDate; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/DestOfficeField.php b/src/Fields/Transaction/TransactionLine/DestOfficeField.php new file mode 100644 index 00000000..96c9d72d --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/DestOfficeField.php @@ -0,0 +1,32 @@ +destOffice; + } + + /** + * @return $this + */ + public function setDestOffice(?Office $destOffice): self + { + $this->destOffice = $destOffice; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/Dim1Field.php b/src/Fields/Transaction/TransactionLine/Dim1Field.php new file mode 100644 index 00000000..1f09319f --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/Dim1Field.php @@ -0,0 +1,31 @@ +dim1; + } + + /** + * @return $this + */ + public function setDim1($dim1): self + { + $this->dim1 = $dim1; + return $this; + } +} diff --git a/src/Transactions/TransactionLineFields/FreeCharField.php b/src/Fields/Transaction/TransactionLine/FreeCharField.php similarity index 84% rename from src/Transactions/TransactionLineFields/FreeCharField.php rename to src/Fields/Transaction/TransactionLine/FreeCharField.php index 0096da8e..1cb155a7 100644 --- a/src/Transactions/TransactionLineFields/FreeCharField.php +++ b/src/Fields/Transaction/TransactionLine/FreeCharField.php @@ -1,13 +1,15 @@ matchDate; + } + + /** + * @param \DateTimeInterface|null $matchDate + * @return $this + */ + public function setMatchDate(?\DateTimeInterface $matchDate) + { + $this->matchDate = $matchDate; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/MatchLevelField.php b/src/Fields/Transaction/TransactionLine/MatchLevelField.php new file mode 100644 index 00000000..0d98e33f --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/MatchLevelField.php @@ -0,0 +1,32 @@ +matchLevel; + } + + /** + * @param null|int $matchLevel + * @return $this + */ + public function setMatchLevel(?int $matchLevel): self + { + $this->matchLevel = $matchLevel; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/MatchStatusField.php b/src/Fields/Transaction/TransactionLine/MatchStatusField.php new file mode 100644 index 00000000..8679e60a --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/MatchStatusField.php @@ -0,0 +1,30 @@ +matchStatus; + } + + /** + * @param MatchStatus|null $matchStatus + * @return $this + */ + public function setMatchStatus(?MatchStatus $matchStatus): self + { + $this->matchStatus = $matchStatus; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/PerformanceCountryField.php b/src/Fields/Transaction/TransactionLine/PerformanceCountryField.php new file mode 100644 index 00000000..9efd578f --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/PerformanceCountryField.php @@ -0,0 +1,33 @@ +performanceCountry; + } + + /** + * @return $this + */ + public function setPerformanceCountry(?Country $performanceCountry): self + { + $this->performanceCountry = $performanceCountry; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/PerformanceVatNumberField.php b/src/Fields/Transaction/TransactionLine/PerformanceVatNumberField.php new file mode 100644 index 00000000..e10a1647 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/PerformanceVatNumberField.php @@ -0,0 +1,32 @@ +performanceVatNumber; + } + + /** + * @param null|string $performanceVatNumber + * @return $this + */ + public function setPerformanceVatNumber(?string $performanceVatNumber): self + { + $this->performanceVatNumber = $performanceVatNumber; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/RateField.php b/src/Fields/Transaction/TransactionLine/RateField.php new file mode 100644 index 00000000..d742c842 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/RateField.php @@ -0,0 +1,32 @@ +rate; + } + + /** + * @param null|float $rate + * @return $this + */ + public function setRate(?float $rate): self + { + $this->rate = $rate; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/RelationField.php b/src/Fields/Transaction/TransactionLine/RelationField.php new file mode 100644 index 00000000..9f35e09c --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/RelationField.php @@ -0,0 +1,32 @@ +relation; + } + + /** + * @param null|int $relation + * @return $this + */ + public function setRelation(?int $relation): self + { + $this->relation = $relation; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/RepRateField.php b/src/Fields/Transaction/TransactionLine/RepRateField.php new file mode 100644 index 00000000..54996c49 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/RepRateField.php @@ -0,0 +1,32 @@ +repRate; + } + + /** + * @param null|float $repRate + * @return $this + */ + public function setRepRate(?float $repRate): self + { + $this->repRate = $repRate; + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/RepValueField.php b/src/Fields/Transaction/TransactionLine/RepValueField.php new file mode 100644 index 00000000..04910aca --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/RepValueField.php @@ -0,0 +1,35 @@ +repValue; + } + + /** + * @param Money|null $repValue + * @return $this + */ + public function setRepValue(?Money $repValue) + { + $this->repValue = $repValue; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/RepValueOpenField.php b/src/Fields/Transaction/TransactionLine/RepValueOpenField.php new file mode 100644 index 00000000..e0f01d5a --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/RepValueOpenField.php @@ -0,0 +1,35 @@ +repValueOpen; + } + + /** + * @param Money|null $repValueOpen + * @return $this + */ + public function setRepValueOpen(?Money $repValueOpen) + { + $this->repValueOpen = $repValueOpen; + + return $this; + } +} diff --git a/src/Transactions/TransactionLineFields/ValueFields.php b/src/Fields/Transaction/TransactionLine/ValueFields.php similarity index 97% rename from src/Transactions/TransactionLineFields/ValueFields.php rename to src/Fields/Transaction/TransactionLine/ValueFields.php index 54286673..a405c7f8 100644 --- a/src/Transactions/TransactionLineFields/ValueFields.php +++ b/src/Fields/Transaction/TransactionLine/ValueFields.php @@ -1,6 +1,6 @@ value = $value; return $this; } -} \ No newline at end of file +} diff --git a/src/Fields/Transaction/TransactionLine/ValueOpenField.php b/src/Fields/Transaction/TransactionLine/ValueOpenField.php new file mode 100644 index 00000000..4e053397 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/ValueOpenField.php @@ -0,0 +1,35 @@ +valueOpen; + } + + /** + * @param Money|null $valueOpen + * @return $this + */ + public function setValueOpen(?Money $valueOpen) + { + $this->valueOpen = $valueOpen; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatBaseTotalField.php b/src/Fields/Transaction/TransactionLine/VatBaseTotalField.php new file mode 100644 index 00000000..b760f58d --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatBaseTotalField.php @@ -0,0 +1,35 @@ +vatBaseTotal; + } + + /** + * @param Money|null $vatBaseTotal + * @return $this + */ + public function setVatBaseTotal(?Money $vatBaseTotal) + { + $this->vatBaseTotal = $vatBaseTotal; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatBaseTurnoverField.php b/src/Fields/Transaction/TransactionLine/VatBaseTurnoverField.php new file mode 100644 index 00000000..8ddb15a0 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatBaseTurnoverField.php @@ -0,0 +1,35 @@ +vatBaseTurnover; + } + + /** + * @param Money|null $vatBaseTurnover + * @return $this + */ + public function setVatBaseTurnover(?Money $vatBaseTurnover) + { + $this->vatBaseTurnover = $vatBaseTurnover; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatBaseValueField.php b/src/Fields/Transaction/TransactionLine/VatBaseValueField.php new file mode 100644 index 00000000..6190a248 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatBaseValueField.php @@ -0,0 +1,35 @@ +vatBaseValue; + } + + /** + * @param Money|null $vatBaseValue + * @return $this + */ + public function setVatBaseValue(?Money $vatBaseValue) + { + $this->vatBaseValue = $vatBaseValue; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatRepTotalField.php b/src/Fields/Transaction/TransactionLine/VatRepTotalField.php new file mode 100644 index 00000000..334af949 --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatRepTotalField.php @@ -0,0 +1,35 @@ +vatRepTotal; + } + + /** + * @param Money|null $vatRepTotal + * @return $this + */ + public function setVatRepTotal(?Money $vatRepTotal) + { + $this->vatRepTotal = $vatRepTotal; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatRepTurnoverField.php b/src/Fields/Transaction/TransactionLine/VatRepTurnoverField.php new file mode 100644 index 00000000..621bcbca --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatRepTurnoverField.php @@ -0,0 +1,35 @@ +vatRepTurnover; + } + + /** + * @param Money|null $vatRepTurnover + * @return $this + */ + public function setVatRepTurnover(?Money $vatRepTurnover) + { + $this->vatRepTurnover = $vatRepTurnover; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatRepValueField.php b/src/Fields/Transaction/TransactionLine/VatRepValueField.php new file mode 100644 index 00000000..23f751df --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatRepValueField.php @@ -0,0 +1,35 @@ +vatRepValue; + } + + /** + * @param Money|null $vatRepValue + * @return $this + */ + public function setVatRepValue(?Money $vatRepValue) + { + $this->vatRepValue = $vatRepValue; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatTotalField.php b/src/Fields/Transaction/TransactionLine/VatTotalField.php new file mode 100644 index 00000000..0c4514cb --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatTotalField.php @@ -0,0 +1,35 @@ +vatTotal; + } + + /** + * @param Money|null $vatTotal + * @return $this + */ + public function setVatTotal(?Money $vatTotal) + { + $this->vatTotal = $vatTotal; + + return $this; + } +} diff --git a/src/Fields/Transaction/TransactionLine/VatTurnoverField.php b/src/Fields/Transaction/TransactionLine/VatTurnoverField.php new file mode 100644 index 00000000..1a6bcb2f --- /dev/null +++ b/src/Fields/Transaction/TransactionLine/VatTurnoverField.php @@ -0,0 +1,35 @@ +vatTurnover; + } + + /** + * @param Money|null $vatTurnover + * @return $this + */ + public function setVatTurnover(?Money $vatTurnover) + { + $this->vatTurnover = $vatTurnover; + + return $this; + } +} diff --git a/src/Fields/UIDField.php b/src/Fields/UIDField.php new file mode 100644 index 00000000..e7758ab6 --- /dev/null +++ b/src/Fields/UIDField.php @@ -0,0 +1,32 @@ +UID; + } + + /** + * @param null|string $UID + * @return $this + */ + public function setUID(?string $UID): self + { + $this->UID = $UID; + return $this; + } +} diff --git a/src/Fields/User/AcceptExtraCostField.php b/src/Fields/User/AcceptExtraCostField.php new file mode 100644 index 00000000..0106eb66 --- /dev/null +++ b/src/Fields/User/AcceptExtraCostField.php @@ -0,0 +1,32 @@ +acceptExtraCost; + } + + /** + * @param bool $acceptExtraCost + * @return $this + */ + public function setAcceptExtraCost(?bool $acceptExtraCost): self + { + $this->acceptExtraCost = $acceptExtraCost; + return $this; + } +} diff --git a/src/Fields/User/CultureField.php b/src/Fields/User/CultureField.php new file mode 100644 index 00000000..115b6c87 --- /dev/null +++ b/src/Fields/User/CultureField.php @@ -0,0 +1,30 @@ +culture; + } + + /** + * @param Culture|null $culture + * @return $this + */ + public function setCulture(?Culture $culture): self + { + $this->culture = $culture; + return $this; + } +} diff --git a/src/Fields/User/CultureNameField.php b/src/Fields/User/CultureNameField.php new file mode 100644 index 00000000..8ebde913 --- /dev/null +++ b/src/Fields/User/CultureNameField.php @@ -0,0 +1,31 @@ +cultureName; + } + + /** + * @param null|string $cultureName + * @return $this + */ + public function setCultureName(?string $cultureName): self + { + $this->cultureName = $cultureName; + return $this; + } +} diff --git a/src/Fields/User/CultureNativeNameField.php b/src/Fields/User/CultureNativeNameField.php new file mode 100644 index 00000000..5216f2fa --- /dev/null +++ b/src/Fields/User/CultureNativeNameField.php @@ -0,0 +1,31 @@ +cultureNativeName; + } + + /** + * @param null|string $cultureNativeName + * @return $this + */ + public function setCultureNativeName(?string $cultureNativeName): self + { + $this->cultureNativeName = $cultureNativeName; + return $this; + } +} diff --git a/src/Fields/User/DemoField.php b/src/Fields/User/DemoField.php new file mode 100644 index 00000000..68734bea --- /dev/null +++ b/src/Fields/User/DemoField.php @@ -0,0 +1,32 @@ +demo; + } + + /** + * @param bool $demo + * @return $this + */ + public function setDemo(?bool $demo): self + { + $this->demo = $demo; + return $this; + } +} diff --git a/src/Fields/User/DemoLockedField.php b/src/Fields/User/DemoLockedField.php new file mode 100644 index 00000000..61428276 --- /dev/null +++ b/src/Fields/User/DemoLockedField.php @@ -0,0 +1,32 @@ +demoLocked; + } + + /** + * @param bool $demoLocked + * @return $this + */ + public function setDemoLocked(?bool $demoLocked): self + { + $this->demoLocked = $demoLocked; + return $this; + } +} diff --git a/src/Fields/User/ExchangeQuotaField.php b/src/Fields/User/ExchangeQuotaField.php new file mode 100644 index 00000000..0f31ce67 --- /dev/null +++ b/src/Fields/User/ExchangeQuotaField.php @@ -0,0 +1,32 @@ +exchangeQuota; + } + + /** + * @param null|int $exchangeQuota + * @return $this + */ + public function setExchangeQuota(?int $exchangeQuota): self + { + $this->exchangeQuota = $exchangeQuota; + return $this; + } +} diff --git a/src/Fields/User/ExchangeQuotaLockedField.php b/src/Fields/User/ExchangeQuotaLockedField.php new file mode 100644 index 00000000..5433f50d --- /dev/null +++ b/src/Fields/User/ExchangeQuotaLockedField.php @@ -0,0 +1,32 @@ +exchangeQuotaLocked; + } + + /** + * @param bool $exchangeQuotaLocked + * @return $this + */ + public function setExchangeQuotaLocked(?bool $exchangeQuotaLocked): self + { + $this->exchangeQuotaLocked = $exchangeQuotaLocked; + return $this; + } +} diff --git a/src/Fields/User/FileManagerQuotaField.php b/src/Fields/User/FileManagerQuotaField.php new file mode 100644 index 00000000..047d588c --- /dev/null +++ b/src/Fields/User/FileManagerQuotaField.php @@ -0,0 +1,32 @@ +fileManagerQuota; + } + + /** + * @param null|int $fileManagerQuota + * @return $this + */ + public function setFileManagerQuota(?int $fileManagerQuota): self + { + $this->fileManagerQuota = $fileManagerQuota; + return $this; + } +} diff --git a/src/Fields/User/FileManagerQuotaLockedField.php b/src/Fields/User/FileManagerQuotaLockedField.php new file mode 100644 index 00000000..b8512ed4 --- /dev/null +++ b/src/Fields/User/FileManagerQuotaLockedField.php @@ -0,0 +1,32 @@ +fileManagerQuotaLocked; + } + + /** + * @param bool $fileManagerQuotaLocked + * @return $this + */ + public function setFileManagerQuotaLocked(?bool $fileManagerQuotaLocked): self + { + $this->fileManagerQuotaLocked = $fileManagerQuotaLocked; + return $this; + } +} diff --git a/src/Fields/User/IsCurrentUserField.php b/src/Fields/User/IsCurrentUserField.php new file mode 100644 index 00000000..7d38f5c9 --- /dev/null +++ b/src/Fields/User/IsCurrentUserField.php @@ -0,0 +1,32 @@ +isCurrentUser; + } + + /** + * @param bool $isCurrentUser + * @return $this + */ + public function setIsCurrentUser(?bool $isCurrentUser): self + { + $this->isCurrentUser = $isCurrentUser; + return $this; + } +} diff --git a/src/Fields/User/LevelField.php b/src/Fields/User/LevelField.php new file mode 100644 index 00000000..b8d85ebd --- /dev/null +++ b/src/Fields/User/LevelField.php @@ -0,0 +1,32 @@ +level; + } + + /** + * @param null|string $level + * @return $this + */ + public function setLevel(?string $level): self + { + $this->level = $level; + return $this; + } +} diff --git a/src/Fields/User/PasswordField.php b/src/Fields/User/PasswordField.php new file mode 100644 index 00000000..0bb1f6af --- /dev/null +++ b/src/Fields/User/PasswordField.php @@ -0,0 +1,31 @@ +password; + } + + /** + * @param null|string $password + * @return $this + */ + public function setPassword(?string $password): self + { + $this->password = $password; + return $this; + } +} diff --git a/src/Fields/User/RoleField.php b/src/Fields/User/RoleField.php new file mode 100644 index 00000000..01367097 --- /dev/null +++ b/src/Fields/User/RoleField.php @@ -0,0 +1,34 @@ +role; + } + + /** + * @return $this + */ + public function setRole(?UserRole $role): self + { + $this->role = $role; + return $this; + } +} + diff --git a/src/Fields/User/RoleLockedField.php b/src/Fields/User/RoleLockedField.php new file mode 100644 index 00000000..6d535b82 --- /dev/null +++ b/src/Fields/User/RoleLockedField.php @@ -0,0 +1,32 @@ +roleLocked; + } + + /** + * @param bool $roleLocked + * @return $this + */ + public function setRoleLocked(?bool $roleLocked): self + { + $this->roleLocked = $roleLocked; + return $this; + } +} diff --git a/src/Fields/User/TypeField.php b/src/Fields/User/TypeField.php new file mode 100644 index 00000000..a9b745d0 --- /dev/null +++ b/src/Fields/User/TypeField.php @@ -0,0 +1,30 @@ +type; + } + + /** + * @param UserType|null $type + * @return $this + */ + public function setType(?UserType $type): self + { + $this->type = $type; + return $this; + } +} diff --git a/src/Fields/User/TypeLockedField.php b/src/Fields/User/TypeLockedField.php new file mode 100644 index 00000000..124d9347 --- /dev/null +++ b/src/Fields/User/TypeLockedField.php @@ -0,0 +1,32 @@ +typeLocked; + } + + /** + * @param bool $typeLocked + * @return $this + */ + public function setTypeLocked(?bool $typeLocked): self + { + $this->typeLocked = $typeLocked; + return $this; + } +} diff --git a/src/Fields/UserField.php b/src/Fields/UserField.php new file mode 100644 index 00000000..0a8ac524 --- /dev/null +++ b/src/Fields/UserField.php @@ -0,0 +1,34 @@ +user; + } + + /** + * @return $this + */ + public function setUser(?User $user): self + { + $this->user = $user; + return $this; + } +} + diff --git a/src/Fields/VatCode/GroupCountryField.php b/src/Fields/VatCode/GroupCountryField.php new file mode 100644 index 00000000..c532a5e3 --- /dev/null +++ b/src/Fields/VatCode/GroupCountryField.php @@ -0,0 +1,33 @@ +groupCountry; + } + + /** + * @return $this + */ + public function setGroupCountry(?VatGroupCountry $groupCountry): self + { + $this->groupCountry = $groupCountry; + return $this; + } +} diff --git a/src/Fields/VatCode/GroupField.php b/src/Fields/VatCode/GroupField.php new file mode 100644 index 00000000..aa87f528 --- /dev/null +++ b/src/Fields/VatCode/GroupField.php @@ -0,0 +1,33 @@ +group; + } + + /** + * @return $this + */ + public function setGroup(?VatGroup $group): self + { + $this->group = $group; + return $this; + } +} diff --git a/src/Fields/VatCode/TypeField.php b/src/Fields/VatCode/TypeField.php new file mode 100644 index 00000000..e9e42aec --- /dev/null +++ b/src/Fields/VatCode/TypeField.php @@ -0,0 +1,41 @@ +type; + } + + /** + * @param VatType|null $type + * @return $this + */ + public function setType(?VatType $type): self + { + $this->type = $type; + return $this; + } + + /** + * @param string|null $typeString + * @return $this + * @throws Exception + */ + public function setTypeFromString(?string $typeString) + { + return $this->setType(new VatType((string)$typeString)); + } +} diff --git a/src/Fields/VatCodeField.php b/src/Fields/VatCodeField.php new file mode 100644 index 00000000..e54d785b --- /dev/null +++ b/src/Fields/VatCodeField.php @@ -0,0 +1,33 @@ +vatCode; + } + + /** + * @return $this + */ + public function setVatCode(?VatCode $vatCode): self + { + $this->vatCode = $vatCode; + return $this; + } +} diff --git a/src/Fields/VatValueField.php b/src/Fields/VatValueField.php new file mode 100644 index 00000000..de9070f2 --- /dev/null +++ b/src/Fields/VatValueField.php @@ -0,0 +1,35 @@ +vatValue; + } + + /** + * @param Money|null $vatValue + * @return $this + */ + public function setVatValue(?Money $vatValue) + { + $this->vatValue = $vatValue; + + return $this; + } +} diff --git a/src/FixedAsset.php b/src/FixedAsset.php new file mode 100644 index 00000000..5c8acc1b --- /dev/null +++ b/src/FixedAsset.php @@ -0,0 +1,74 @@ + + */ +class FixedAsset extends BaseObject implements HasCodeInterface +{ + use BehaviourField; + use CodeField; + use GroupField; + use InUseField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + + private $financials; + private $fixedAssets; + + public function __construct() + { + $this->setType(\PhpTwinfield\DimensionType::fromCode('AST')); + $this->setFinancials(new FixedAssetFinancials); + $this->setFixedAssets(new FixedAssetFixedAssets); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getFinancials(): FixedAssetFinancials + { + return $this->financials; + } + + public function setFinancials(FixedAssetFinancials $financials) + { + $this->financials = $financials; + return $this; + } + + public function getFixedAssets(): FixedAssetFixedAssets + { + return $this->fixedAssets; + } + + public function setFixedAssets(FixedAssetFixedAssets $fixedAssets) + { + $this->fixedAssets = $fixedAssets; + return $this; + } +} diff --git a/src/FixedAssetFinancials.php b/src/FixedAssetFinancials.php new file mode 100644 index 00000000..d6131d4a --- /dev/null +++ b/src/FixedAssetFinancials.php @@ -0,0 +1,35 @@ +setSubstitutionLevel(2); + } +} diff --git a/src/FixedAssetFixedAssets.php b/src/FixedAssetFixedAssets.php new file mode 100644 index 00000000..7d9a7ff1 --- /dev/null +++ b/src/FixedAssetFixedAssets.php @@ -0,0 +1,99 @@ +transactionLines; + } + + public function addTransactionLine(FixedAssetTransactionLine $transactionLine) + { + $this->transactionLines[] = $transactionLine; + return $this; + } + + public function removeTransactionLine($index) + { + if (array_key_exists($index, $this->transactionLines)) { + unset($this->transactionLines[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/FixedAssetTransactionLine.php b/src/FixedAssetTransactionLine.php new file mode 100644 index 00000000..1c44b3f9 --- /dev/null +++ b/src/FixedAssetTransactionLine.php @@ -0,0 +1,56 @@ + + */ +class GeneralLedger extends BaseObject implements HasCodeInterface +{ + use BeginPeriodField; + use BeginYearField; + use BehaviourField; + use CodeField; + use EndPeriodField; + use EndYearField; + use GroupField; + use InUseField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + + private $financials; + + public function __construct() + { + $this->setBeginPeriod(0); + $this->setBeginYear(0); + $this->setEndPeriod(0); + $this->setEndYear(0); + + $this->setFinancials(new GeneralLedgerFinancials); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getFinancials(): GeneralLedgerFinancials + { + return $this->financials; + } + + public function setFinancials(GeneralLedgerFinancials $financials) + { + $this->financials = $financials; + return $this; + } +} diff --git a/src/GeneralLedgerChildValidation.php b/src/GeneralLedgerChildValidation.php new file mode 100644 index 00000000..cab9ba4c --- /dev/null +++ b/src/GeneralLedgerChildValidation.php @@ -0,0 +1,18 @@ +setMatchType(\PhpTwinfield\Enums\MatchType::NOTMATCHABLE()); + $this->setSubAnalyse(\PhpTwinfield\Enums\SubAnalyse::MAYBE()); + } + + public function getChildValidations() + { + return $this->childValidations; + } + + public function addChildValidation(GeneralLedgerChildValidation $childValidation) + { + $this->childValidations[] = $childValidation; + return $this; + } + + public function removeChildValidation($index) + { + if (array_key_exists($index, $this->childValidations)) { + unset($this->childValidations[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/HasCodeInterface.php b/src/HasCodeInterface.php new file mode 100644 index 00000000..fc412224 --- /dev/null +++ b/src/HasCodeInterface.php @@ -0,0 +1,16 @@ + + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Leon Rowland * @version 0.0.1 * * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesInvoices * @todo Add documentation and typehints to all properties. - * @todo Add support for VatLines. */ -class Invoice +class Invoice extends BaseObject { - use PeriodField; + use BankField; + use CalculateOnlyField; + use CurrencyField; + use CustomerField; + use CustomerNameField; + use DebitCreditField; + use DeliverAddressNumberField; use DueDateField; + use FinancialCodeField; + use FinancialNumberField; + use FooterTextField; + use HeaderTextField; + use InvoiceAddressNumberField; + use InvoiceAmountField; + use InvoiceDateField; + use InvoiceNumberField; + use InvoiceTypeField; use OfficeField; + use PaymentMethodField; + use PerformanceDateField; + use PeriodField; + use PeriodRaiseWarningField; + use RaiseWarningField; + use StatusField; - private $customer; - private $invoiceType; - private $invoiceNumber; - private $status; - private $currency; - private $invoiceDate; - private $performanceDate; - private $paymentMethod; - private $bank; - private $invoiceAddressNumber; - private $deliverAddressNumber; - private $headerText; - private $footerText; private $totals; - private $financialCode; - private $financialNumber; - - /** - * @var InvoiceLine[] - */ private $lines = []; - - public function addLine(InvoiceLine $line) - { - $this->lines[$line->getID()] = $line; - return $this; - } - - /** - * @return InvoiceLine[] - */ - public function getLines(): array - { - return $this->lines; - } - - public function getCustomer(): Customer - { - return $this->customer; - } - - public function setCustomer(Customer $customer) - { - $this->customer = $customer; - return $this; - } - - public function setTotals(InvoiceTotals $totals) - { - $this->totals = $totals; - return $this; - } + private $vatLines = []; public function getTotals(): InvoiceTotals { return $this->totals; } - public function getInvoiceType() - { - return $this->invoiceType; - } - - public function setInvoiceType($invoiceType) - { - $this->invoiceType = $invoiceType; - return $this; - } - - public function getInvoiceNumber() - { - return $this->invoiceNumber; - } - - public function setInvoiceNumber($invoiceNumber) - { - $this->invoiceNumber = $invoiceNumber; - return $this; - } - - public function getStatus() - { - return $this->status; - } - - public function setStatus($status) - { - $this->status = $status; - return $this; - } - - public function getCurrency() - { - return $this->currency; - } - - public function setCurrency($currency) - { - $this->currency = $currency; - return $this; - } - - public function getInvoiceDate() - { - return $this->invoiceDate; - } - - public function setInvoiceDate($invoiceDate) - { - $this->invoiceDate = $invoiceDate; - return $this; - } - - public function getPerformanceDate() - { - return $this->performanceDate; - } - - public function setPerformanceDate($performanceDate) - { - $this->performanceDate = $performanceDate; - return $this; - } - - public function getPaymentMethod() - { - return $this->paymentMethod; - } - - public function setPaymentMethod($paymentMethod) + public function setTotals(InvoiceTotals $totals) { - $this->paymentMethod = $paymentMethod; + $this->totals = $totals; return $this; } - public function getBank() + /** + * @return InvoiceLine[] + */ + public function getLines(): array { - return $this->bank; + return $this->lines; } - public function setBank($bank) + public function addLine(InvoiceLine $line) { - $this->bank = $bank; + $this->lines[] = $line; return $this; } - public function getInvoiceAddressNumber() + public function removeLine($index) { - return $this->invoiceAddressNumber; + if (array_key_exists($index, $this->lines)) { + unset($this->lines[$index]); + return true; + } else { + return false; + } } - public function setInvoiceAddressNumber($invoiceAddressNumber) + public function removeLineByID($id) { - $this->invoiceAddressNumber = $invoiceAddressNumber; - return $this; - } + $found = false; - public function getDeliverAddressNumber() - { - return $this->deliverAddressNumber; - } + foreach ($this->lines as $index => $line) { + if ($id == $line->getID()) { + unset($this->lines[$index]); + $found = true; + } + } - public function setDeliverAddressNumber($delivererAddressNumber) - { - $this->deliverAddressNumber = $delivererAddressNumber; - return $this; - } - - public function getHeaderText() - { - return $this->headerText; - } + if ($found) { + return true; + } - public function setHeaderText($headerText) - { - $this->headerText = $headerText; - return $this; + return false; } - public function getFooterText() + /** + * @return InvoiceVatLine[] + */ + public function getVatLines(): array { - return $this->footerText; + return $this->vatLines; } - public function setFooterText($footerText) + public function addVatLine(InvoiceVatLine $vatLine) { - $this->footerText = $footerText; + $this->vatLines[] = $vatLine; return $this; } - public function getFinancialCode() - { - return $this->financialCode; - } - - public function setFinancialCode($financialCode) - { - $this->financialCode = $financialCode; - return $this; - } - - public function getFinancialNumber() - { - return $this->financialNumber; - } - - public function setFinancialNumber($financialNumber) + public function removeVatLine($index) { - $this->financialNumber = $financialNumber; - return $this; + if (array_key_exists($index, $this->vatLines)) { + unset($this->vatLines[$index]); + return true; + } else { + return false; + } } public function getMatchReference(): MatchReferenceInterface diff --git a/src/InvoiceLine.php b/src/InvoiceLine.php index a8a14c8d..6f40558f 100644 --- a/src/InvoiceLine.php +++ b/src/InvoiceLine.php @@ -1,211 +1,58 @@ ID = uniqid(); - $this->quantity = $quantity; $this->article = $article; $this->setFreeText1($freeText1); $this->setFreeText2($freeText2); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - public function getQuantity() - { - return $this->quantity; - } - - public function setQuantity($quantity) - { - $this->quantity = $quantity; - return $this; - } - - public function getArticle() - { - return $this->article; - } - - public function setArticle($article) - { - $this->article = $article; - return $this; - } - - public function getSubArticle() - { - return $this->subArticle; - } - - public function setSubArticle($subArticle) - { - $this->subArticle = $subArticle; - return $this; - } - - public function getDescription() - { - return $this->description; - } - - public function setDescription($description) - { - $this->description = $description; - return $this; - } - - public function getUnitsPriceExcl() - { - return $this->unitsPriceExcl; - } - - public function setUnitsPriceExcl($unitsPriceExcl) - { - $this->unitsPriceExcl = $unitsPriceExcl; - return $this; - } - - public function getUnits() - { - return $this->units; - } - - public function setUnits($units) - { - $this->units = $units; - return $this; - } - - public function getAllowDiscountOrPremium() - { - return $this->allowDiscountOrPremium; - } - - public function setAllowDiscountOrPremium($allowDiscountOrPremium) - { - $this->allowDiscountOrPremium = $allowDiscountOrPremium; - return $this; - } - - public function getValueExcl() - { - return $this->valueExcl; - } - - public function setValueExcl($valueExcl) - { - $this->valueExcl = $valueExcl; - return $this; - } - - public function getVatValue() - { - return $this->vatValue; - } - - public function setVatValue($vatValue) - { - $this->vatValue = $vatValue; - return $this; - } - - public function getValueInc() - { - return $this->valueInc; - } - - public function setValueInc($valueInc) - { - $this->valueInc = $valueInc; - return $this; - } - - public function getUnitsPriceInc() - { - return $this->unitsPriceInc; - } - - public function setUnitsPriceInc($unitsPriceInc) - { - $this->unitsPriceInc = $unitsPriceInc; - return $this; - } - - public function getPerformanceDate() - { - return $this->performanceDate; - } - - public function setPerformanceDate($performanceDate) - { - $this->performanceDate = $performanceDate; - return $this; - } - - public function getPerformanceType(): ?PerformanceType - { - return $this->performanceType; - } - - public function setPerformanceType(?PerformanceType $performanceType): self - { - $this->performanceType = $performanceType; - return $this; - } - - public function getDim1() - { - return $this->dim1; - } - - public function setDim1($dim1) - { - $this->dim1 = $dim1; - return $this; + $this->setAllowDiscountOrPremium(true); } } diff --git a/src/InvoiceTotals.php b/src/InvoiceTotals.php index dbe12595..a0aae10f 100644 --- a/src/InvoiceTotals.php +++ b/src/InvoiceTotals.php @@ -1,32 +1,15 @@ valueExcl; - } - - public function setValueExcl($valueExcl) - { - $this->valueExcl = $valueExcl; - } - - public function getValueInc() - { - return $this->valueInc; - } - - public function setValueInc($valueInc) - { - $this->valueInc = $valueInc; - } + use ValueExclField; + use ValueIncField; } diff --git a/src/InvoiceType.php b/src/InvoiceType.php new file mode 100644 index 00000000..116650d1 --- /dev/null +++ b/src/InvoiceType.php @@ -0,0 +1,26 @@ + + */ +class InvoiceType extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/InvoiceVatLine.php b/src/InvoiceVatLine.php new file mode 100644 index 00000000..5f25667e --- /dev/null +++ b/src/InvoiceVatLine.php @@ -0,0 +1,19 @@ +regime; - } - - /** - * @param string|null $regime - * @return $this - */ - public function setRegime(?string $regime): JournalTransaction - { - $this->regime = $regime; - - return $this; - } } diff --git a/src/JournalTransactionLine.php b/src/JournalTransactionLine.php index aa477a60..3fe8e04b 100644 --- a/src/JournalTransactionLine.php +++ b/src/JournalTransactionLine.php @@ -4,26 +4,33 @@ use Money\Money; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionFields\InvoiceNumberField; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; +use PhpTwinfield\Enums\PerformanceType; +use PhpTwinfield\Enums\MatchStatus; +use PhpTwinfield\Fields\InvoiceNumberField; +use PhpTwinfield\Fields\PerformanceDateField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaselineField; +use PhpTwinfield\Fields\Transaction\TransactionLine\CurrencyDateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceCountryField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceVatNumberField; use Webmozart\Assert\Assert; -/** - * @todo $currencyDate Only if line type is detail. The line date. - */ class JournalTransactionLine extends BaseTransactionLine { - use PerformanceFields; - use InvoiceNumberField { - setInvoiceNumber as traitSetInvoiceNumber; - } + use BaselineField; + use CurrencyDateField; + use InvoiceNumberField; + use PerformanceCountryField; + use PerformanceDateField; + use PerformanceTypeField; + use PerformanceVatNumberField; - /** + /* * @var JournalTransaction */ private $transaction; - /** + /* * @param JournalTransaction $object */ public function setTransaction($object): void @@ -33,7 +40,7 @@ public function setTransaction($object): void $this->transaction = $object; } - /** + /* * References the transaction this line belongs too. * * @return JournalTransaction @@ -43,45 +50,68 @@ public function getTransaction(): JournalTransaction return $this->transaction; } - /** - * @param LineType $lineType + /* + * Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + * + * @param int|null $baseline * @return $this * @throws Exception */ - public function setLineType(LineType $lineType): BaseTransactionLine + public function setBaseline(?int $baseline): self { - // Only 'detail' and 'vat' are supported. - if ($lineType->equals(LineType::TOTAL())) { - throw Exception::invalidLineTypeForTransaction($lineType, $this); + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType("baseline", $this); } - return parent::setLineType($lineType); + $this->baseline = $baseline; + + return $this; } - /** - * If line type = detail the journal balance account or profit and loss account. + /* + * Only if line type is detail. The amount still owed in base currency. Read-only attribute. * - * If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account - * will be taken as entered at the VAT code in Twinfield. + * @param Money|null $baseValueOpen + * @return $this + * @throws Exception + */ + public function setBaseValueOpen(?Money $baseValueOpen): parent + { + if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('basevalueopen', $this); + } + + return parent::setBaseValueOpen($baseValueOpen); + } + + /* + * Only if line type is detail. The line date. Only allowed if the line date in the journal book is set to Allowed or Mandatory. * - * @param string|null $dim1 + * @param \DateTimeInterface|null $currencyDate * @return $this + * @throws Exception */ - public function setDim1(?string $dim1): BaseTransactionLine + public function setCurrencyDate(?\DateTimeInterface $currencyDate): self { - return parent::setDim1($dim1); + if ($currencyDate !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('currencydate', $this); + } + + $this->currencyDate = $currencyDate; + + return $this; } - /** + /* * If line type = detail the customer or supplier or the cost center or empty. * * If line type = vat empty. * - * @param string|null $dim2 + * @param $dim2 * @return $this * @throws Exception */ - public function setDim2(?string $dim2): BaseTransactionLine + public function setDim2($dim2): parent { if ($dim2 !== null && $this->getLineType()->equals(LineType::VAT())) { throw Exception::invalidDimensionForLineType(2, $this); @@ -90,97 +120,202 @@ public function setDim2(?string $dim2): BaseTransactionLine return parent::setDim2($dim2); } - /** - * If line type = detail amount without VAT. + /* + * If line type = detail the project or asset or empty. * - * If line type = vat VAT amount. + * If line type = vat empty. * - * @param Money $value + * @param $dim3 * @return $this + * @throws Exception */ - public function setValue(Money $value): BaseTransactionLine + public function setDim3($dim3): parent { - parent::setValue($value); - return $this; + if ($dim3 !== null && $this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidDimensionForLineType(3, $this); + } + + return parent::setDim3($dim3); } - /** + /* * @param string|null $invoiceNumber * @return $this * @throws Exception */ - public function setInvoiceNumber(?string $invoiceNumber): BaseTransactionLine + public function setInvoiceNumber(?string $invoiceNumber): self { if ($invoiceNumber !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('invoiceNumber', $this); + throw Exception::invalidFieldForLineType('invoicenumber', $this); } - return $this->traitSetInvoiceNumber($invoiceNumber); + $this->invoiceNumber = $invoiceNumber; + + return $this; } - /** - * Payment status of the journal transaction. If line type vat always notmatchable. Read-only attribute. + /* + * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction + * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. * - * @param string|null $matchStatus + * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing + * transaction type is a Purchase Transaction. + * + * @return bool + */ + protected function isIncomingTransactionType(): bool + { + return true; + } + + /* + * @param LineType|null $lineType * @return $this * @throws Exception */ - public function setMatchStatus(?string $matchStatus): BaseTransactionLine + public function setLineType(?LineType $lineType): parent { - if ( - $matchStatus !== null && - $this->getLineType()->equals(LineType::VAT()) && - $matchStatus != self::MATCHSTATUS_NOTMATCHABLE - ) { - throw Exception::invalidMatchStatusForLineType($matchStatus, $this); + // Only 'detail' and 'vat' are supported. + if ($lineType->equals(LineType::TOTAL())) { + throw Exception::invalidLineTypeForTransaction($lineType, $this); } - return parent::setMatchStatus($matchStatus); + return parent::setLineType($lineType); } - /** + /* * Only if line type is detail. The level of the matchable dimension. Read-only attribute. * * @param int|null $matchLevel * @return $this * @throws Exception */ - public function setMatchLevel(?int $matchLevel): BaseTransactionLine + public function setMatchLevel(?int $matchLevel): parent { if ($matchLevel !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('matchLevel', $this); + throw Exception::invalidFieldForLineType('matchlevel', $this); } return parent::setMatchLevel($matchLevel); } - /** - * Only if line type is detail. The amount still owed in base currency. Read-only attribute. + /* + * Payment status of the transaction. If line type vat always notmatchable. Read-only attribute. * - * @param Money|null $baseValueOpen + * @param MatchStatus|null $matchStatus * @return $this * @throws Exception */ - public function setBaseValueOpen(?Money $baseValueOpen): BaseTransactionLine + public function setMatchStatus(?MatchStatus $matchStatus): parent { - if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidFieldForLineType('baseValueOpen', $this); + if ($matchStatus !== null && in_array($this->getLineType(), [LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { + throw Exception::invalidMatchStatusForLineType($matchStatus, $this); } - return parent::setBaseValueOpen($baseValueOpen); + return parent::setMatchStatus($matchStatus); } - /** - * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction - * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. * - * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing - * transaction type is a Purchase Transaction. + * @param PerformanceType|null $performanceType + * @return $this + * @throws Exception + */ + public function setPerformanceType(?PerformanceType $performanceType): self + { + if ($performanceType !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancetype', $this); + } + + $this->performanceType = $performanceType; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. * - * @return bool + * @param Country|null $performanceCountry + * @return $this + * @throws Exception */ - protected function isIncomingTransactionType(): bool + public function setPerformanceCountry(?Country $performanceCountry): self { - return true; + if ($performanceCountry !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancecountry', $this); + } + + $this->performanceCountry = $performanceCountry; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. + * + * @param string|null $performanceVatNumber + * @return $this + * @throws Exception + */ + public function setPerformanceVatNumber(?string $performanceVatNumber): self + { + if ($performanceVatNumber !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancevatnumber', $this); + } + + $this->performanceVatNumber = $performanceVatNumber; + + return $this; + } + + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. + * + * @param \DateTimeInterface|null $performanceDate + * @return $this + * @throws Exception + */ + public function setPerformanceDate(?\DateTimeInterface $performanceDate): self + { + if ($performanceDate !== null && (!$this->getPerformanceType()->equals(PerformanceType::SERVICES()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidFieldForLineType('performancedate', $this); + } + + $this->performanceDate = $performanceDate; + + return $this; + } + + /* + * Relation of the transaction. Only if line type is detail. Read-only attribute. + * + * @param int|null $relation + * @return $this + * @throws Exception + */ + public function setRelation(?int $relation): parent + { + if ($relation !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('relation', $this); + } + + return parent::setRelation($relation); + } + + /* + * Only if line type is detail. The amount still owed in reporting currency. Read-only attribute. + * + * @param Money|null $repValueOpen + * @return $this + * @throws Exception + */ + public function setRepValueOpen(?Money $repValueOpen): parent + { + if ($repValueOpen !== null && !$this->getLineType()->equals(LineType::DETAIL())) { + throw Exception::invalidFieldForLineType('repvalueopen', $this); + } + + return parent::setRepValueOpen($repValueOpen); } } diff --git a/src/Mappers/ActivityMapper.php b/src/Mappers/ActivityMapper.php new file mode 100644 index 00000000..7b049aaa --- /dev/null +++ b/src/Mappers/ActivityMapper.php @@ -0,0 +1,120 @@ + + */ +class ActivityMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean Activity entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Activity + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new Activity object + $activity = new Activity(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/activity element + $activityElement = $responseDOM->documentElement; + + // Set the result and status attribute + $activity->setResult($activityElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $activityElement->getAttribute('status'))); + + // Set the activity elements from the activity element + $activity->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($activityElement, 'behaviour', $activity))) + ->setCode(self::getField($activityElement, 'code', $activity)) + ->setInUse(Util::parseBoolean(self::getField($activityElement, 'name', $activity))) + ->setName(self::getField($activityElement, 'name', $activity)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $activity, $activityElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($activityElement, 'shortname', $activity)) + ->setTouched(self::getField($activityElement, 'touched', $activity)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $activity, $activityElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($activityElement, 'uid', $activity)) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $activity, $activityElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + // Get the projects element + $projectsElement = $responseDOM->getElementsByTagName('projects')->item(0); + + if ($projectsElement !== null) { + // Make a new temporary ActivityProjects class + $activityProjects = new ActivityProjects(); + + // Set the projects elements from the projects element + $activityProjects->setAuthoriser(self::parseObjectAttribute(\PhpTwinfield\User::class, $activityProjects, $projectsElement, 'authoriser')) + ->setBillable(Util::parseBoolean(self::getField($projectsElement, 'billable', $activityProjects))) + ->setCustomer(self::parseObjectAttribute(\PhpTwinfield\Customer::class, $activityProjects, $projectsElement, 'customer')) + ->setInvoiceDescription(self::getField($projectsElement, 'invoicedescription', $activityProjects)) + ->setRate(self::parseObjectAttribute(\PhpTwinfield\Rate::class, $activityProjects, $projectsElement, 'rate')) + ->setValidFrom(self::parseDateAttribute(self::getField($projectsElement, 'validfrom', $activityProjects))) + ->setValidTill(self::parseDateAttribute(self::getField($projectsElement, 'validtill', $activityProjects))); + + // Set the projects elements from the projects element attributes + $activityProjects->setAuthoriserInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'authoriser', 'inherit'))) + ->setAuthoriserLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'authoriser', 'locked'))) + ->setBillableForRatio(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'forratio'))) + ->setBillableInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'inherit'))) + ->setBillableLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'locked'))) + ->setCustomerInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'customer', 'inherit'))) + ->setCustomerLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'customer', 'locked'))) + ->setRateInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'rate', 'inherit'))) + ->setRateLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'rate', 'locked'))); + + // Get the quantities element + $quantitiesDOMTag = $projectsElement->getElementsByTagName('quantities'); + + if (isset($quantitiesDOMTag) && $quantitiesDOMTag->length > 0) { + // Loop through each returned quantity for the project + foreach ($quantitiesDOMTag->item(0)->childNodes as $quantityElement) { + if ($quantityElement->nodeType !== 1) { + continue; + } + + // Make a new temporary ActivityQuantity class + $activityQuantity = new ActivityQuantity(); + + // Set the quantity elements from the quantity element + $activityQuantity->setBillable(Util::parseBoolean(self::getField($quantityElement, 'billable', $activityQuantity))) + ->setLabel(self::getField($quantityElement, 'label', $activityQuantity)) + ->setMandatory(Util::parseBoolean(self::getField($quantityElement, 'mandatory', $activityQuantity))) + ->setRate(self::parseObjectAttribute(\PhpTwinfield\Rate::class, $activityQuantity, $quantityElement, 'rate')); + + // Set the quantity elements from the quantity element attributes + $activityQuantity->setBillableLocked(Util::parseBoolean(self::getAttribute($quantityElement, 'billable', 'locked'))); + + // Add the quantity to the project + $activityProjects->addQuantity($activityQuantity); + + // Clean that memory! + unset ($activityQuantity); + } + } + + // Set the custom class to the project + $activity->setProjects($activityProjects); + } + + // Return the complete object + return $activity; + } +} diff --git a/src/Mappers/ArticleMapper.php b/src/Mappers/ArticleMapper.php index b9b10268..ac392e04 100644 --- a/src/Mappers/ArticleMapper.php +++ b/src/Mappers/ArticleMapper.php @@ -4,28 +4,30 @@ use PhpTwinfield\Article; use PhpTwinfield\ArticleLine; use PhpTwinfield\Response\Response; +use PhpTwinfield\Secure\AuthenticatedConnection; +use PhpTwinfield\Util; /** * Maps a response DOMDocument to the corresponding entity. - * + * * @package PhpTwinfield * @subpackage Mapper - * @author Willem van de Sande + * @author Willem van de Sande , extended by Yannick Aerssens */ class ArticleMapper extends BaseMapper { - /** * Maps a Response object to a clean Article entity. * * @access public * * @param \PhpTwinfield\Response\Response $response + * @param \PhpTwinfield\Secure\AuthenticatedConnection $connection * * @return Article * @throws \PhpTwinfield\Exception */ - public static function map(Response $response) + public static function map(Response $response, AuthenticatedConnection $connection) { // Generate new Article object $article = new Article(); @@ -33,80 +35,88 @@ public static function map(Response $response) // Gets the raw DOMDocument response. $responseDOM = $response->getResponseDocument(); + // Get the root/article element + $articleElement = $responseDOM->documentElement; + + // Set the result attribute + $article->setResult($articleElement->getAttribute('result')); + + // Get the header element + $headerElement = $articleElement->getElementsByTagName('header')->item(0); + // Set the status attribute - $dimensionElement = $responseDOM->getElementsByTagName('header')->item(0); - $article->setStatus($dimensionElement->getAttribute('status')); - - // Article elements and their methods - $articleTags = [ - 'code' => 'setCode', - 'office' => 'setOffice', - 'type' => 'setType', - 'name' => 'setName', - 'shortname' => 'setShortName', - 'unitnamesingular' => 'setUnitNameSingular', - 'unitnameplural' => 'setUnitNamePlural', - 'vatcode' => 'setVatCode', - 'allowchangevatcode' => 'setAllowChangeVatCode', - 'performancetype' => 'setPerformanceType', - 'allowchangeperformancetype' => 'setAllowChangePerformanceType', - 'percentage' => 'setPercentage', - 'allowdiscountorpremium' => 'setAllowDiscountorPremium', - 'allowchangeunitsprice' => 'setAllowChangeUnitsPrice', - 'allowdecimalquantity' => 'setAllowDecimalQuantity', - ]; - - // Loop through all the tags - foreach ($articleTags as $tag => $method) { - self::setFromTagValue($responseDOM, $tag, [$article, $method]); + $article->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $headerElement->getAttribute('status'))); + + // Set the article elements from the header + $article->setAllowChangePerformanceType(Util::parseBoolean(self::getField($headerElement, 'allowchangeperformancetype', $article))) + ->setAllowChangeUnitsPrice(Util::parseBoolean(self::getField($headerElement, 'allowchangeunitsprice', $article))) + ->setAllowChangeVatCode(Util::parseBoolean(self::getField($headerElement, 'allowchangevatcode', $article))) + ->setAllowDecimalQuantity(Util::parseBoolean(self::getField($headerElement, 'allowdecimalquantity', $article))) + ->setAllowDiscountOrPremium(Util::parseBoolean(self::getField($headerElement, 'allowdiscountorpremium', $article))) + ->setCode(self::getField($headerElement, 'code', $article)) + ->setName(self::getField($headerElement, 'name', $article)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $article, $headerElement, 'office')) + ->setPercentage(Util::parseBoolean(self::getField($headerElement, 'percentage', $article))) + ->setPerformanceType(self::parseEnumAttribute(\PhpTwinfield\Enums\PerformanceType::class, self::getField($headerElement, 'performancetype', $article))) + ->setShortName(self::getField($headerElement, 'shortname', $article)) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\ArticleType::class, self::getField($headerElement, 'type', $article))) + ->setUnitNameSingular(self::getField($headerElement, 'unitnamesingular', $article)) + ->setUnitNamePlural(self::getField($headerElement, 'unitnameplural', $article)) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $article, $headerElement, 'vatcode')); + + if ($article->getOffice() !== null) { + $currencies = self::getOfficeCurrencies($connection, $article->getOffice()); } + // Get the lines element $linesDOMTag = $responseDOM->getElementsByTagName('lines'); if (isset($linesDOMTag) && $linesDOMTag->length > 0) { - // Element tags and their methods for lines - $lineTags = [ - 'unitspriceexcl' => 'setUnitsPriceExcl', - 'unitspriceinc' => 'setUnitsPriceInc', - 'units' => 'setUnits', - 'name' => 'setName', - 'shortname' => 'setShortName', - 'subcode' => 'setSubCode', - 'freetext1' => 'setFreeText1', - ]; - - $linesDOM = $linesDOMTag->item(0); + $lineNumber = 0; // Loop through each returned line for the article - foreach ($linesDOM->getElementsByTagName('line') as $lineDOM) { - - // Make a new tempory ArticleLine class - $articleLine = new ArticleLine(); - - // Set the attributes ( id,status,inuse) - $articleLine->setID($lineDOM->getAttribute('id')) - ->setStatus($lineDOM->getAttribute('status')) - ->setInUse($lineDOM->getAttribute('inuse')); + foreach ($linesDOMTag->item(0)->childNodes as $lineElement) { + // Skip child nodes that are not of the DOMElement type + if ($lineElement->nodeType !== 1) { + continue; + } - // Loop through the element tags. Determine if it exists and set it if it does - foreach ($lineTags as $tag => $method) { + $lineNumber++; - // Get the dom element - $_tag = $lineDOM->getElementsByTagName($tag)->item(0); + // Make a new temporary ArticleLine class + $articleLine = new ArticleLine(); - // Check if the tag is set, and its content is set, to prevent DOMNode errors - if (isset($_tag) && isset($_tag->textContent)) { - $articleLine->$method($_tag->textContent); - } + // Set the ID attributes if it is not null, else set the current line number + if ($lineElement->getAttribute('id') != null) { + $articleLine->setID($lineElement->getAttribute('id')); + } else { + $articleLine->setID($lineNumber); } - // Add the bank to the customer + // Set the inuse and status attributes + $articleLine->setInUse($lineElement->getAttribute('inuse')); + $articleLine->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $lineElement->getAttribute('status'))); + + // Set the article line elements + $articleLine->setFreeText1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $articleLine, $lineElement, 'freetext1', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setFreeText2(self::parseObjectAttribute(\PhpTwinfield\CostCenter::class, $articleLine, $lineElement, 'freetext2', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setFreeText3(self::getField($lineElement, 'freetext3', $articleLine)) + ->setUnits(self::getField($lineElement, 'units', $articleLine)) + ->setName(self::getField($lineElement, 'name', $articleLine)) + ->setShortName(self::getField($lineElement, 'shortname', $articleLine)) + ->setSubCode(self::getField($lineElement, 'subcode', $articleLine)) + ->setUnitsPriceExcl(self::parseMoneyAttribute(self::getField($lineElement, 'unitspriceexcl', $articleLine), $currencies['base'])) + ->setUnitsPriceInc(self::parseMoneyAttribute(self::getField($lineElement, 'unitspriceinc', $articleLine), $currencies['base'])); + + // Add the line to the article $article->addLine($articleLine); // Clean that memory! unset ($articleLine); } } + + // Return the complete object return $article; } } diff --git a/src/Mappers/AssetMethodMapper.php b/src/Mappers/AssetMethodMapper.php new file mode 100644 index 00000000..a3af3939 --- /dev/null +++ b/src/Mappers/AssetMethodMapper.php @@ -0,0 +1,127 @@ + + */ +class AssetMethodMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean AssetMethod entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return AssetMethod + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new AssetMethod object + $assetmethod = new AssetMethod(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/assetmethod element + $assetmethodElement = $responseDOM->documentElement; + + // Set the inuse, result and status attribute + $assetmethod->setInUse(Util::parseBoolean($assetmethodElement->getAttribute('inuse'))) + ->setResult($assetmethodElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $assetmethodElement->getAttribute('status'))); + + // Set the asset method elements from the asset method element + $assetmethod->setCalcMethod(self::parseEnumAttribute(\PhpTwinfield\Enums\CalcMethod::class, self::getField($assetmethodElement, 'calcmethod', $assetmethod))) + ->setCode(self::getField($assetmethodElement, 'code', $assetmethod)) + ->setCreated(self::parseDateTimeAttribute(self::getField($assetmethodElement, 'created', $assetmethod))) + ->setDepreciateReconciliation(self::parseEnumAttribute(\PhpTwinfield\Enums\DepreciateReconciliation::class, self::getField($assetmethodElement, 'depreciatereconciliation', $assetmethod))) + ->setModified(self::parseDateTimeAttribute(self::getField($assetmethodElement, 'modified', $assetmethod))) + ->setName(self::getField($assetmethodElement, 'name', $assetmethod)) + ->setNrOfPeriods(self::getField($assetmethodElement, 'nrofperiods', $assetmethod)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $assetmethod, $assetmethodElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setPercentage(self::getField($assetmethodElement, 'percentage', $assetmethod)) + ->setShortName(self::getField($assetmethodElement, 'shortname', $assetmethod)) + ->setTouched(self::getField($assetmethodElement, 'touched', $assetmethod)) + ->setUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $assetmethod, $assetmethodElement, 'user', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Get the balanceaccounts element + $balanceAccountsElement = $responseDOM->getElementsByTagName('balanceaccounts')->item(0); + + if ($balanceAccountsElement !== null) { + // Make a new temporary AssetMethodBalanceAccounts class + $assetMethodBalanceAccounts = new AssetMethodBalanceAccounts(); + + // Set the asset method balance account elements from the balance accounts element + $assetMethodBalanceAccounts + ->setAssetsToActivate(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'assetstoactivate', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDepreciation(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'depreciation', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDepreciationGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'depreciationgroup', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setPurchaseValue(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'purchasevalue', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setPurchaseValueGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'purchasevaluegroup', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setReconciliation(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'reconciliation', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setToBeInvoiced(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodBalanceAccounts, $balanceAccountsElement, 'tobeinvoiced', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))); + + // Set the custom class to the assetmethod + $assetmethod->setBalanceAccounts($assetMethodBalanceAccounts); + } + + // Get the profitlossaccounts element + $profitLossAccountsElement = $responseDOM->getElementsByTagName('profitlossaccounts')->item(0); + + if ($profitLossAccountsElement !== null) { + // Make a new temporary AssetMethodProfitLossAccounts class + $assetMethodProfitLossAccounts = new AssetMethodProfitLossAccounts(); + + // Set the asset method profit loss account elements from the profit loss accounts element + $assetMethodProfitLossAccounts + ->setDepreciation(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodProfitLossAccounts, $profitLossAccountsElement, 'depreciation', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setReconciliation(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodProfitLossAccounts, $profitLossAccountsElement, 'reconciliation', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setSales(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $assetMethodProfitLossAccounts, $profitLossAccountsElement, 'sales', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))); + + // Set the custom class to the assetmethod + $assetmethod->setProfitLossAccounts($assetMethodProfitLossAccounts); + } + + // Get the freetexts element + $freetextsDOMTag = $responseDOM->getElementsByTagName('freetexts'); + + if (isset($freetextsDOMTag) && $freetextsDOMTag->length > 0) { + // Loop through each returned freetext for the assetmethod + foreach ($freetextsDOMTag->item(0)->childNodes as $freetextElement) { + if ($freetextElement->nodeType !== 1) { + continue; + } + + // Make a new temporary AssetMethodFreeText class + $assetmethodFreeText = new AssetMethodFreeText(); + + // Set the attributes (id, type, value) + $assetmethodFreeText->setID($freetextElement->getAttribute('id')) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\FreeTextType::class, $freetextElement->getAttribute('type'))) + ->setElementValue($freetextElement->nodeValue); + + // Add the freetext to the assetmethod + $assetmethod->addFreeText($assetmethodFreeText); + + // Clean that memory! + unset ($assetmethodFreeText); + } + } + + // Return the complete object + return $assetmethod; + } +} diff --git a/src/Mappers/BankTransactionMapper.php b/src/Mappers/BankTransactionMapper.php deleted file mode 100644 index d4b5f027..00000000 --- a/src/Mappers/BankTransactionMapper.php +++ /dev/null @@ -1,206 +0,0 @@ -documentElement; - - if (!empty($element->getAttribute("autobalancevat"))) { - $bankTransaction->setAutoBalanceVat(Util::parseBoolean($element->getAttribute("autobalancevat"))); - } - - if (!empty($element->getAttribute("raisewarning"))) { - $bankTransaction->setRaiseWarning(Util::parseBoolean($element->getAttribute("raisewarning"))); - } - - self::setFromTagValue($document, "code", [$bankTransaction, "setCode"]); - self::setFromTagValue($document, "office", [$bankTransaction, "setOffice"]); - self::setFromTagValue($document, "date", [$bankTransaction, "setDate"]); - self::setFromTagValue($document, "period", [$bankTransaction, "setPeriod"]); - self::setFromTagValue($document, "startvalue", [$bankTransaction, "setStartValue"]); - - self::setFromTagValue($document, "statementnumber", [$bankTransaction, "setStatementNumber"]); - self::setFromTagValue($document, "number", [$bankTransaction, "setNumber"]); - - /** @var \DOMElement $lineElement */ - foreach ($element->getElementsByTagName("line") as $lineElement) { - switch ($lineElement->getAttribute("type")) { - case LineType::TOTAL(): - $bankTransaction->addLine(self::createTotalBankTransactionLine($bankTransaction, $lineElement)); - break; - case LineType::DETAIL(): - $bankTransaction->addLine(self::createDetailBankTransactionLine($bankTransaction, $lineElement)); - break; - case LineType::VAT(): - $bankTransaction->addLine(self::createVatBankTransactionLine($bankTransaction, $lineElement)); - break; - } - } - - return $bankTransaction; - } - - private static function createTotalBankTransactionLine(BankTransaction $bankTransaction, \DOMElement $lineElement): Total - { - $line = new Total(); - self::setBankTransactionLineBaseFields($bankTransaction, $lineElement, $line); - - $line->setBankBalanceAccount(self::getField($lineElement, "dim1")); - - $vatTotal = self::getField($lineElement, "vattotal"); - if ($vatTotal) { - $line->setVatTotal(Util::parseMoney($vatTotal, $bankTransaction->getCurrency())); - } - $vatBaseTotal = self::getField($lineElement, "vatbasetotal"); - if ($vatBaseTotal) { - $line->setVatBaseTotal(Util::parseMoney($vatBaseTotal, $bankTransaction->getCurrency())); - } - $vatRepTotal = self::getField($lineElement, "vatreptotal"); - if ($vatRepTotal) { - $line->setVatRepTotal(Util::parseMoney($vatRepTotal, $bankTransaction->getCurrency())); - } - - return $line; - } - - private static function createDetailBankTransactionLine(BankTransaction $bankTransaction, \DOMElement $lineElement): Detail - { - $line = new Detail(); - self::setBankTransactionLineBaseFields($bankTransaction, $lineElement, $line); - self::setBankTransactionLinePerformanceFields($lineElement, $line); - - $line->setAccount(self::getField($lineElement, "dim1")); - - $customerOrSupplierOrCostCenter = self::getField($lineElement, "dim2"); - if ($customerOrSupplierOrCostCenter !== null) { - $line->setCustomerOrSupplierOrCostCenter($customerOrSupplierOrCostCenter); - } - $vatCode = self::getField($lineElement, "vatcode"); - if ($vatCode !== null) { - $line->setVatCode($vatCode); - } - $vatValue = self::getField($lineElement, "vatvalue"); - if ($vatValue) { - $line->setVatValue(Util::parseMoney($vatValue, $bankTransaction->getCurrency())); - } - $vatBaseValue = self::getField($lineElement, "vatbasevalue"); - if ($vatBaseValue) { - $line->setVatBaseValue(Util::parseMoney($vatBaseValue, $bankTransaction->getCurrency())); - } - $vatRepValue = self::getField($lineElement, "vatrepvalue"); - if ($vatRepValue) { - $line->setVatRepValue(Util::parseMoney($vatRepValue, $bankTransaction->getCurrency())); - } - $projectOrAsset = self::getField($lineElement, "dim3"); - if ($projectOrAsset !== null) { - $line->setProjectOrAsset($projectOrAsset); - } - - return $line; - } - - private static function createVatBankTransactionLine(BankTransaction $bankTransaction, \DOMElement $lineElement): Vat - { - $line = new Vat(); - self::setBankTransactionLineBaseFields($bankTransaction, $lineElement, $line); - self::setBankTransactionLinePerformanceFields($lineElement, $line); - - $vatTurnover = self::getField($lineElement, "vatturnover"); - $line->setVatTurnover(Util::parseMoney($vatTurnover, $bankTransaction->getCurrency())); - $vatBaseTurnover = self::getField($lineElement, "vatbaseturnover"); - $line->setVatBaseTurnover(Util::parseMoney($vatBaseTurnover, $bankTransaction->getCurrency())); - - $vatRepTurnover = self::getField($lineElement, "vatrepturnover"); - if ($vatRepTurnover) { - $line->setVatRepTurnover(Util::parseMoney($vatRepTurnover, $bankTransaction->getCurrency())); - } - $vatCode = self::getField($lineElement, "vatcode"); - if ($vatCode !== null) { - $line->setVatCode($vatCode); - } - $vatBalanceAccount = self::getField($lineElement, "dim1"); - if ($vatBalanceAccount !== null) { - $line->setVatBalanceAccount($vatBalanceAccount); - } - - return $line; - } - - private static function setBankTransactionLineBaseFields( - BankTransaction $bankTransaction, - \DOMElement $lineElement, - Base $line - ): void { - /* - * When a bank transaction fails, it isn't created at Twinfield, so it is likely that they haven't generated - * any ids for the lines. - */ - $id = $lineElement->getAttribute("id"); - if (!empty($id)) { - $line->setId($id); - } - - $value = self::getField($lineElement, 'value'); - $line->setValue(Util::parseMoney($value, $bankTransaction->getCurrency())); - $line->setInvoiceNumber(self::getField($lineElement, "invoicenumber")); - - $description = self::getField($lineElement, "description"); - if ($description !== null) { - $line->setDescription($description); - } - $debitCredit = self::getField($lineElement, 'debitcredit'); - if ($debitCredit) { - $line->setDebitCredit(new DebitCredit($debitCredit)); - } - $destOffice = self::getField($lineElement, "destoffice"); - if ($destOffice) { - $line->setDestOffice(Office::fromCode($destOffice)); - } - $freeChar = self::getField($lineElement, "freechar"); - if ($freeChar) { - $line->setFreeChar($freeChar); - } - $comment = self::getField($lineElement, "comment"); - if ($comment !== null) { - $line->setComment($comment); - } - } - - private static function setBankTransactionLinePerformanceFields(\DOMElement $lineElement, Base $line): void - { - $performanceType = self::getField($lineElement, "performancetype"); - if ($performanceType) { - $line->setPerformanceType(new PerformanceType($performanceType)); - } - $performanceCountry = self::getField($lineElement, "performancecountry"); - if ($performanceCountry) { - $line->setPerformanceCountry($performanceCountry); - } - $performanceVatNumber = self::getField($lineElement, "performancevatnumber"); - if ($performanceVatNumber !== null) { - $line->setPerformanceVatNumber($performanceVatNumber); - } - $performanceDate = self::getField($lineElement, "performancedate"); - if ($performanceDate) { - $line->setPerformanceDate($performanceDate); - } - } -} \ No newline at end of file diff --git a/src/Mappers/BaseMapper.php b/src/Mappers/BaseMapper.php index d98027bb..a294358b 100644 --- a/src/Mappers/BaseMapper.php +++ b/src/Mappers/BaseMapper.php @@ -3,76 +3,184 @@ namespace PhpTwinfield\Mappers; use Money\Currency; +use Money\Money; +use PhpTwinfield\ApiConnectors\OfficeApiConnector; +use PhpTwinfield\HasCodeInterface; +use PhpTwinfield\HasMessageInterface; +use PhpTwinfield\Message\Message; use PhpTwinfield\Office; +use PhpTwinfield\Secure\AuthenticatedConnection; use PhpTwinfield\Util; use Webmozart\Assert\Assert; abstract class BaseMapper { - /** - * @throws \PhpTwinfield\Exception - */ - protected static function setFromTagValue(\DOMDocument $document, string $tag, callable $setter): void + protected static function checkForMessage(HasMessageInterface $object, \DOMElement $element): void { - $value = self::getValueFromTag($document, $tag); + if ($element->hasAttribute('msg')) { + $message = new Message(); + $message->setType($element->getAttribute('msgtype')); + $message->setMessage($element->getAttribute('msg')); + $message->setField($element->nodeName); - if ($value === null) { - return; + $object->addMessage($message); } + } - if ($tag === "office") { - \call_user_func($setter, Office::fromCode($value)); - return; + protected static function getAttribute(\DOMElement $element, string $fieldTagName, string $attributeName): ?string + { + $fieldElement = $element->getElementsByTagName($fieldTagName)->item(0); + + if (!isset($fieldElement)) { + return null; } - if ($tag === "date") { - \call_user_func($setter, Util::parseDate($value)); - return; + if ($fieldElement->getAttribute($attributeName) === "") { + return null; } - if ($tag === "startvalue") { - $currency = new Currency(self::getValueFromTag($document, "currency")); + return $fieldElement->getAttribute($attributeName); + } + + protected static function getField(\DOMElement $element, string $fieldTagName, $object = null): ?string + { + $fieldElement = $element->getElementsByTagName($fieldTagName)->item(0); + + if (!isset($fieldElement)) { + return null; + } - \call_user_func($setter, Util::parseMoney($value, $currency)); + if (isset($object)) { + self::checkForMessage($object, $fieldElement); + } - return; + if ($fieldElement->textContent === "") { + return null; } - \call_user_func($setter, $value); + return $fieldElement->textContent; } - protected static function getValueFromTag(\DOMDocument $document, string $tag): ?string + protected static function getOfficeCurrencies(AuthenticatedConnection $connection, Office $office): array { - /** @var \DOMNodeList $nodelist */ - $nodelist = $document->getElementsByTagName($tag); + $currencies = ["base" => '', "reporting" => '']; - if ($nodelist->length === 0) { - return null; + $officeApiConnector = new OfficeApiConnector($connection); + $fullOffice = $officeApiConnector->get($office->getCode()); + + if ($fullOffice->getResult() == 1) { + $currencies['base'] = Util::objectToStr($fullOffice->getBaseCurrency()); + $currencies['reporting'] = Util::objectToStr($fullOffice->getReportingCurrency()); } - Assert::greaterThanEq($nodelist->length, 1); + return $currencies; + } - /** @var \DOMElement $element */ - $element = $nodelist[0]; + protected static function parseDateAttribute(?string $value): ?\DateTimeImmutable + { + if (false !== strtotime($value)) { + return Util::parseDate($value); + } - if ("" === $element->textContent) { + return null; + } + + protected static function parseDateTimeAttribute(?string $value): ?\DateTimeImmutable + { + if (false !== strtotime($value)) { + return Util::parseDateTime($value); + } + + return null; + } + + protected static function parseEnumAttribute(string $enumClass, ?string $value) + { + if ($value === null) { return null; } - return $element->textContent; + try { + return new $enumClass($value); + } catch (\Exception $e) { + return null; + } } - protected static function getField(\DOMElement $element, string $fieldTagName): ?string + protected static function parseMoneyAttribute(?float $value, ?string $currency): ?Money { - $fieldElement = $element->getElementsByTagName($fieldTagName)->item(0); - if (!isset($fieldElement)) { + if ($value === null || $currency === null) { return null; } - if ($fieldElement->textContent === "") { + return Util::parseMoney($value, new Currency($currency)); + } + + protected static function parseUnknownEntity(HasMessageInterface $object, \DOMElement $element, string $fieldTagName): string + { + if (is_a($object, \PhpTwinfield\DimensionGroupDimension::class)) { + $type = self::getField($element, "type", $object); + } elseif (is_a($object, \PhpTwinfield\TransactionLineInterface::class)) { + $type = self::getAttribute($element, $fieldTagName, "type"); + } else { + $type = self::getAttribute($element, $fieldTagName, "dimensiontype"); + } + + switch ($type) { + case "ACT": + return \PhpTwinfield\Activity::class; + case "AST": + return \PhpTwinfield\FixedAsset::class; + case "BAS": + return \PhpTwinfield\GeneralLedger::class; + case "CRD": + return \PhpTwinfield\Supplier::class; + case "DEB": + return \PhpTwinfield\Customer::class; + case "KPL": + return \PhpTwinfield\CostCenter::class; + case "PNL": + return \PhpTwinfield\GeneralLedger::class; + case "PRJ": + return \PhpTwinfield\Project::class; + default: + if (is_a($object, \PhpTwinfield\TransactionLineInterface::class)) { + return \PhpTwinfield\GeneralLedger::class; + } + + throw new \InvalidArgumentException("parseUnknownEntity function was unable to determine class name from \"{$type}\""); + } + } + + /** + * Parse a code referring to a Twinfield Entity / PHP Twinfield object + * + * @param string|null $objectClass + * @param HasMessageInterface $object + * @param \DOMElement $element + * @param string $fieldTagName + * @param array $attributes + * @return HasCodeInterface + */ + protected static function parseObjectAttribute(?string $objectClass, HasMessageInterface $object, \DOMElement $element, string $fieldTagName, array $attributes = []) + { + $value = self::getField($element, $fieldTagName, $object); + + if ($value === null) { return null; } - return $fieldElement->textContent; + if ($objectClass === null) { + $objectClass = self::parseUnknownEntity($object, $element, $fieldTagName); + } + + $object2 = new $objectClass(); + $object2->setCode($value); + + foreach ($attributes as $attributeName => $method) { + $object2->$method(self::getAttribute($element, $fieldTagName, $attributeName)); + } + + return $object2; } -} \ No newline at end of file +} diff --git a/src/Mappers/BrowseDataMapper.php b/src/Mappers/BrowseDataMapper.php index 13d06e8a..3e3aa4e8 100644 --- a/src/Mappers/BrowseDataMapper.php +++ b/src/Mappers/BrowseDataMapper.php @@ -55,10 +55,10 @@ public static function map(Response $response) $keyElement = $rowElement->getElementsByTagName('key')[0]; $browseDataRow - ->setOffice(Office::fromCode(self::getField($keyElement, 'office'))) - ->setCode(self::getField($keyElement, 'code')) - ->setNumber(self::getField($keyElement, 'number')) - ->setLine(self::getField($keyElement, 'line')); + ->setOffice(Office::fromCode(self::getField($keyElement, 'office', $browseDataRow))) + ->setCode(self::getField($keyElement, 'code', $browseDataRow)) + ->setNumber(self::getField($keyElement, 'number', $browseDataRow)) + ->setLine(self::getField($keyElement, 'line', $browseDataRow)); $browseData->addRow($browseDataRow); diff --git a/src/Mappers/BrowseDefinitionMapper.php b/src/Mappers/BrowseDefinitionMapper.php index 76d7a648..469ecc05 100644 --- a/src/Mappers/BrowseDefinitionMapper.php +++ b/src/Mappers/BrowseDefinitionMapper.php @@ -29,32 +29,32 @@ public static function map(Response $response) $browseDefinitionElement = $document->documentElement; $browseDefinition - ->setOffice(Office::fromCode(self::getField($browseDefinitionElement, 'office'))) - ->setCode(self::getField($browseDefinitionElement, 'code')) - ->setName(self::getField($browseDefinitionElement, 'name')) - ->setShortName(self::getField($browseDefinitionElement, 'shortname')) - ->setVisible(self::getField($browseDefinitionElement, 'visible')); + ->setOffice(Office::fromCode(self::getField($browseDefinitionElement, 'office', $browseDefinition))) + ->setCode(self::getField($browseDefinitionElement, 'code', $browseDefinition)) + ->setName(self::getField($browseDefinitionElement, 'name', $browseDefinition)) + ->setShortName(self::getField($browseDefinitionElement, 'shortname', $browseDefinition)) + ->setVisible(self::getField($browseDefinitionElement, 'visible', $browseDefinition)); foreach ($browseDefinitionElement->getElementsByTagName('column') as $columnElement) { $browseColumn = new BrowseColumn(); $browseColumn ->setId($columnElement->getAttribute('id')) - ->setField(self::getField($columnElement, 'field')) - ->setVisible(Util::parseBoolean(self::getField($columnElement, 'visible'))) - ->setAsk(Util::parseBoolean(self::getField($columnElement, 'ask'))) - ->setOperator(new BrowseColumnOperator(self::getField($columnElement, 'operator'))); + ->setField(self::getField($columnElement, 'field', $browseColumn)) + ->setVisible(Util::parseBoolean(self::getField($columnElement, 'visible', $browseColumn))) + ->setAsk(Util::parseBoolean(self::getField($columnElement, 'ask', $browseColumn))) + ->setOperator(new BrowseColumnOperator(self::getField($columnElement, 'operator', $browseColumn))); - $label = self::getField($columnElement, 'label'); + $label = self::getField($columnElement, 'label', $browseColumn); if (!empty($label)) { $browseColumn->setLabel($label); } - $from = self::getField($columnElement, 'from'); + $from = self::getField($columnElement, 'from', $browseColumn); if (!empty($from)) { $browseColumn->setFrom($from); } - $to = self::getField($columnElement, 'to'); + $to = self::getField($columnElement, 'to', $browseColumn); if (!empty($to)) { $browseColumn->setTo($to); } diff --git a/src/Mappers/BrowseFieldMapper.php b/src/Mappers/BrowseFieldMapper.php index 3765680d..c9d78993 100644 --- a/src/Mappers/BrowseFieldMapper.php +++ b/src/Mappers/BrowseFieldMapper.php @@ -25,15 +25,15 @@ public static function map(Response $response) foreach ($browseFieldsElement->getElementsByTagName('browsefield') as $browseFieldElement) { $browseField = new BrowseField(); $browseField - ->setCode(self::getField($browseFieldElement, 'code')) - ->setDataType(self::getField($browseFieldElement, 'datatype')); + ->setCode(self::getField($browseFieldElement, 'code', $browseField)) + ->setDataType(self::getField($browseFieldElement, 'datatype', $browseField)); - $finder = self::getField($browseFieldElement, 'finder'); + $finder = self::getField($browseFieldElement, 'finder', $browseField); if (!empty($finder)) { $browseField->setFinder($finder); } - $canOrder = self::getField($browseFieldElement, 'canorder'); + $canOrder = self::getField($browseFieldElement, 'canorder', $browseField); if (!empty($canOrder)) { $browseField->setCanOrder($canOrder); } diff --git a/src/Mappers/CashBankBookMapper.php b/src/Mappers/CashBankBookMapper.php new file mode 100644 index 00000000..1c37d177 --- /dev/null +++ b/src/Mappers/CashBankBookMapper.php @@ -0,0 +1,45 @@ + + */ +class CashBankBookMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean CashBankBook entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return CashBankBook + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new CashBankBook object + $cashBankBook = new CashBankBook(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/cash or bank book element + $cashBankBookElement = $responseDOM->documentElement; + + // Set the cash or bank book elements from the cash or bank book element + $cashBankBook->setCode(self::getField($cashBankBookElement, 'code', $cashBankBook)) + ->setName(self::getField($cashBankBookElement, 'name', $cashBankBook)) + ->setShortName(self::getField($cashBankBookElement, 'shortname', $cashBankBook)); + + // Return the complete object + return $cashBankBook; + } +} diff --git a/src/Mappers/CostCenterMapper.php b/src/Mappers/CostCenterMapper.php new file mode 100644 index 00000000..d40eefec --- /dev/null +++ b/src/Mappers/CostCenterMapper.php @@ -0,0 +1,55 @@ + + */ +class CostCenterMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean CostCenter entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return CostCenter + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new CostCenter object + $costCenter = new CostCenter(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/costcenter element + $costCenterElement = $responseDOM->documentElement; + + // Set the result and status attribute + $costCenter->setResult($costCenterElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $costCenterElement->getAttribute('status'))); + + // Set the cost center elements from the cost center element + $costCenter->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($costCenterElement, 'behaviour', $costCenter))) + ->setCode(self::getField($costCenterElement, 'code', $costCenter)) + ->setInUse(Util::parseBoolean(self::getField($costCenterElement, 'name', $costCenter))) + ->setName(self::getField($costCenterElement, 'name', $costCenter)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $costCenter, $costCenterElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setTouched(self::getField($costCenterElement, 'touched', $costCenter)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $costCenter, $costCenterElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($costCenterElement, 'uid', $costCenter)); + + // Return the complete object + return $costCenter; + } +} diff --git a/src/Mappers/CurrencyMapper.php b/src/Mappers/CurrencyMapper.php new file mode 100644 index 00000000..8a036424 --- /dev/null +++ b/src/Mappers/CurrencyMapper.php @@ -0,0 +1,80 @@ + + */ +class CurrencyMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean Currency entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Currency + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new Currency object + $currency = new Currency(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/currency element + $currencyElement = $responseDOM->documentElement; + + // Set the result and status attribute + $currency->setResult($currencyElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $currencyElement->getAttribute('status'))); + + // Set the currency elements from the currency element + $currency->setCode(self::getField($currencyElement, 'code', $currency)) + ->setName(self::getField($currencyElement, 'name', $currency)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $currency, $currencyElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($currencyElement, 'shortname', $currency)); + + // Get the rates element + $ratesDOMTag = $responseDOM->getElementsByTagName('rates'); + + if (isset($ratesDOMTag) && $ratesDOMTag->length > 0) { + // Loop through each returned rate for the currency + foreach ($ratesDOMTag->item(0)->childNodes as $rateElement) { + if ($rateElement->nodeType !== 1) { + continue; + } + + // Make a new temporary CurrencyRate class + $currencyRate = new CurrencyRate(); + + // Set the status + // NOTE: Contrary to what is written in the API documentation status is not implemented for currency rates, DO NOT SET! + //$currencyRate->setStatus($rateElement->getAttribute('status')); + + // Set the currency rate elements from the rate element + $currencyRate->setRate(self::getField($rateElement, 'rate', $currencyRate)) + ->setStartDate(self::parseDateAttribute(self::getField($rateElement, 'startdate', $currencyRate))); + + // Add the rate to the currency + $currency->addRate($currencyRate); + + // Clean that memory! + unset ($currencyRate); + } + } + + // Return the complete object + return $currency; + } +} diff --git a/src/Mappers/CustomerMapper.php b/src/Mappers/CustomerMapper.php index 50805326..dc986d58 100644 --- a/src/Mappers/CustomerMapper.php +++ b/src/Mappers/CustomerMapper.php @@ -4,8 +4,14 @@ use PhpTwinfield\Customer; use PhpTwinfield\CustomerAddress; use PhpTwinfield\CustomerBank; -use PhpTwinfield\Exception; +use PhpTwinfield\CustomerChildValidation; +use PhpTwinfield\CustomerCollectMandate; +use PhpTwinfield\CustomerCreditManagement; +use PhpTwinfield\CustomerFinancials; +use PhpTwinfield\CustomerLine; +use PhpTwinfield\CustomerPostingRule; use PhpTwinfield\Response\Response; +use PhpTwinfield\Secure\AuthenticatedConnection; use PhpTwinfield\Util; /** @@ -13,7 +19,7 @@ * * @package PhpTwinfield * @subpackage Mapper - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ class CustomerMapper extends BaseMapper @@ -23,241 +29,318 @@ class CustomerMapper extends BaseMapper * * @access public * @param \PhpTwinfield\Response\Response $response + * @param \PhpTwinfield\Secure\AuthenticatedConnection $connection * @return Customer - * @throws Exception + * @throws \PhpTwinfield\Exception */ - public static function map(Response $response) + public static function map(Response $response, AuthenticatedConnection $connection) { - // Generate new customer object + // Generate new Customer object $customer = new Customer(); // Gets the raw DOMDocument response. $responseDOM = $response->getResponseDocument(); - // Set the status attribute - $dimensionElement = $responseDOM->documentElement; - $customer->setStatus($dimensionElement->getAttribute('status')); - - // Customer elements and their methods - $customerTags = array( - 'code' => 'setCode', - 'uid' => 'setUID', - 'name' => 'setName', - 'inuse' => 'setInUse', - 'behaviour' => 'setBehaviour', - 'touched' => 'setTouched', - 'beginperiod' => 'setBeginPeriod', - 'beginyear' => 'setBeginYear', - 'endperiod' => 'setEndPeriod', - 'endyear' => 'setEndYear', - 'website' => 'setWebsite', - 'editdimensionname' => 'setEditDimensionName', - 'office' => 'setOffice', - 'country' => 'setCountry', - ); - - // Loop through all the tags - foreach ($customerTags as $tag => $method) { - self::setFromTagValue($responseDOM, $tag, [$customer, $method]); + // Get the root/customer element + $customerElement = $responseDOM->documentElement; + + // Set the result and status attribute + $customer->setResult($customerElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $customerElement->getAttribute('status'))); + + // Set the customer elements from the customer element + $customer->setBeginPeriod(self::getField($customerElement, 'beginperiod', $customer)) + ->setBeginYear(self::getField($customerElement, 'beginyear', $customer)) + ->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($customerElement, 'behaviour', $customer))) + ->setDiscountArticle(self::parseObjectAttribute(\PhpTwinfield\Article::class, $customer, $customerElement, 'discountarticle', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setCode(self::getField($customerElement, 'code', $customer)) + ->setEndPeriod(self::getField($customerElement, 'endperiod', $customer)) + ->setEndYear(self::getField($customerElement, 'endyear', $customer)) + ->setGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $customer, $customerElement, 'group', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setInUse(Util::parseBoolean(self::getField($customerElement, 'name', $customer))) + ->setName(self::getField($customerElement, 'name', $customer)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $customer, $customerElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setTouched(self::getField($customerElement, 'touched', $customer)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $customer, $customerElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($customerElement, 'uid', $customer)) + ->setWebsite(self::getField($customerElement, 'website', $customer)); + + if ($customer->getOffice() !== null) { + $currencies = self::getOfficeCurrencies($connection, $customer->getOffice()); } - // Financial elements and their methods - $financialsTags = array( - 'duedays' => 'setDueDays', - 'payavailable' => 'setPayAvailable', - 'paycode' => 'setPayCode', - 'ebilling' => 'setEBilling', - 'ebillmail' => 'setEBillMail', - 'vatcode' => 'setVatCode', - ); - - // Financial elements - $financialElement = $responseDOM->getElementsByTagName('financials')->item(0); - - if ($financialElement) { - // Go through each financial element and add to the assigned method - foreach ($financialsTags as $tag => $method) { - - // Get the dom element - $_tag = $financialElement->getElementsByTagName($tag)->item(0); - - // If it has a value, set it to the associated method - if (isset($_tag) && isset($_tag->textContent)) { - $value = $_tag->textContent; - if ($value == 'true' || $value == 'false') { - $value = $value == 'true'; - } + // Set the customer elements from the customer element attributes + $customer->setDiscountArticleID(self::getAttribute($customerElement, 'discountarticle', 'id')); + + // Get the financials element + $financialsElement = $responseDOM->getElementsByTagName('financials')->item(0); + + if ($financialsElement !== null) { + // Make a new temporary CustomerFinancials class + $customerFinancials = new CustomerFinancials(); + + // Set the financials elements from the financials element + $customerFinancials->setAccountType(self::parseEnumAttribute(\PhpTwinfield\Enums\AccountType::class, self::getField($financialsElement, 'accounttype', $customerFinancials))) + ->setCollectionSchema(self::parseEnumAttribute(\PhpTwinfield\Enums\CollectionSchema::class, self::getField($financialsElement, 'collectionschema', $customerFinancials))) + ->setDueDays(self::getField($financialsElement, 'duedays', $customerFinancials)) + ->setEBilling(Util::parseBoolean(self::getField($financialsElement, 'ebilling', $customerFinancials))) + ->setEBillMail(self::getField($financialsElement, 'ebillmail', $customerFinancials)) + ->setLevel(self::getField($financialsElement, 'level', $customerFinancials)) + ->setMatchType(self::parseEnumAttribute(\PhpTwinfield\Enums\MatchType::class, self::getField($financialsElement, 'matchtype', $customerFinancials))) + ->setMeansOfPayment(self::parseEnumAttribute(\PhpTwinfield\Enums\MeansOfPayment::class, self::getField($financialsElement, 'meansofpayment', $customerFinancials))) + ->setPayAvailable(Util::parseBoolean(self::getField($financialsElement, 'payavailable', $customerFinancials))) + ->setPayCode(self::parseObjectAttribute(\PhpTwinfield\PayCode::class, $customerFinancials, $financialsElement, 'paycode', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setSubAnalyse(self::parseEnumAttribute(\PhpTwinfield\Enums\SubAnalyse::class, self::getField($financialsElement, 'subanalyse', $customerFinancials))) + ->setSubstitutionLevel(self::getField($financialsElement, 'substitutionlevel', $customerFinancials)) + ->setSubstituteWith(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $customerFinancials, $financialsElement, 'substitutewith', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $customerFinancials, $financialsElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + // Set the financials elements from the financials element attributes + $customerFinancials->setPayCodeID(self::getAttribute($financialsElement, 'paycode', 'id')) + ->setSubstituteWithID(self::getAttribute($financialsElement, 'substitutewith', 'id')) + ->setVatCodeFixed(Util::parseBoolean(self::getAttribute($financialsElement, 'vatcode', 'fixed'))); + + // Get the collectmandate element + $collectMandateElement = $financialsElement->getElementsByTagName('collectmandate')->item(0); - $customer->$method($value); - } + if ($collectMandateElement !== null) { + // Make a new temporary CustomerCollectMandate class + $customerCollectMandate = new CustomerCollectMandate(); + + // Set the collect mandate elements from the collect mandate element + $customerCollectMandate->setFirstRunDate(self::parseDateAttribute(self::getField($collectMandateElement, 'firstrundate', $customerCollectMandate))) + ->setID(self::getField($collectMandateElement, 'id', $customerCollectMandate)) + ->setSignatureDate(self::parseDateAttribute(self::getField($collectMandateElement, 'signaturedate', $customerCollectMandate))); + + // Add the collect mandate element to the customer financials class + $customerFinancials->setCollectMandate($customerCollectMandate); + + // Clean that memory! + unset ($customerCollectMandate); } - $collectMandateElement = $responseDOM->getElementsByTagName('collectmandate')->item(0); + // Get the childvalidations element + $childValidationsDOMTag = $financialsElement->getElementsByTagName('childvalidations'); - if ($collectMandateElement !== null) { + if (isset($childValidationsDOMTag) && $childValidationsDOMTag->length > 0) { + // Loop through each returned child validation for the customer + foreach ($childValidationsDOMTag->item(0)->childNodes as $childValidationElement) { + if ($childValidationElement->nodeType !== 1) { + continue; + } - // Collect mandate elements and their methods - $collectMandateTags = array( - 'id' => 'setID', - 'signaturedate' => 'setSignatureDateFromString', - 'firstrundate' => 'setFirstRunDateFromString', - ); + // Make a new temporary CustomerChildValidation class + $customerChildValidation = new CustomerChildValidation(); - $customer->setCollectMandate(new \PhpTwinfield\CustomerCollectMandate()); + // Set the child validation elements from the child validation element en element attributes + $customerChildValidation->setLevel($childValidationElement->getAttribute('level')) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\ChildValidationType::class, $childValidationElement->getAttribute('type'))) + ->setElementValue($childValidationElement->textContent); - // Go through each collect mandate element and add to the assigned method - foreach ($collectMandateTags as $tag => $method) { - $customer->getCollectMandate()->$method(self::getField($collectMandateElement, $tag)); + // Add the child validation to the customer financials class + $customerFinancials->addChildValidation($customerChildValidation); + + // Clean that memory! + unset ($customerChildValidation); } } + + // Set the custom class to the customer + $customer->setFinancials($customerFinancials); } - // Credit management elements + // Get the creditmanagement element $creditManagementElement = $responseDOM->getElementsByTagName('creditmanagement')->item(0); - if ($creditManagementElement) { - - // Credit management elements and their methods - $creditManagementTags = array( - 'responsibleuser' => 'setResponsibleUser', - 'basecreditlimit' => 'setBaseCreditLimit', - 'sendreminder' => 'setSendReminder', - 'reminderemail' => 'setReminderEmail', - 'blocked' => 'setBlocked', - 'freetext1' => 'setFreeText1', - 'freetext2' => 'setFreeText2', - 'freetext3' => 'setFreeText3', - 'comment' => 'setComment', - ); - - $customer->setCreditManagement(new \PhpTwinfield\CustomerCreditManagement()); - - // Go through each financial element and add to the assigned method - foreach ($creditManagementTags as $tag => $method) { - - // Get the dom element - $_tag = $creditManagementElement->getElementsByTagName($tag)->item(0); - - // If it has a value, set it to the associated method - if (isset($_tag) && isset($_tag->textContent)) { - $value = $_tag->textContent; - if ($value == 'true' || $value == 'false') { - $value = $value == 'true'; - } + if ($creditManagementElement !== null) { + // Make a new temporary CustomerCreditManagement class + $customerCreditManagement = new CustomerCreditManagement(); + + // Set the customer credit management elements from the creditmanagement element + $customerCreditManagement->setBaseCreditLimit(self::parseMoneyAttribute(self::getField($creditManagementElement, 'basecreditlimit', $customerCreditManagement), $currencies['base'])) + ->setBlocked(Util::parseBoolean(self::getField($creditManagementElement, 'blocked', $customerCreditManagement))) + ->setComment(self::getField($creditManagementElement, 'comment', $customerCreditManagement)) + ->setFreeText1(Util::parseBoolean(self::getField($creditManagementElement, 'freetext1', $customerCreditManagement))) + ->setFreeText2(self::getField($creditManagementElement, 'freetext2', $customerCreditManagement)) + ->setFreeText3(self::getField($creditManagementElement, 'freetext3', $customerCreditManagement)) + ->setReminderEmail(self::getField($creditManagementElement, 'reminderemail', $customerCreditManagement)) + ->setResponsibleUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $customerCreditManagement, $creditManagementElement, 'responsibleuser', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setSendReminder(self::parseEnumAttribute(\PhpTwinfield\Enums\SendReminder::class, self::getField($creditManagementElement, 'sendreminder', $customerCreditManagement))); + + // Set the customer credit management elements from the creditmanagement element attributes + $customerCreditManagement->setBlockedLocked(Util::parseBoolean(self::getAttribute($creditManagementElement, 'blocked', 'locked'))) + ->setBlockedModified(self::parseDateTimeAttribute(self::getAttribute($creditManagementElement, 'blocked', 'modified'))); + + // Set the custom class to the customer + $customer->setCreditManagement($customerCreditManagement); + } - $customer->getCreditManagement()->$method($value); - } - } + // Get the remittanceadvice element + $remittanceAdviceElement = $responseDOM->getElementsByTagName('remittanceadvice')->item(0); + + if ($remittanceAdviceElement !== null) { + // Set the customer elements from the remittanceadvice element + $customer->setRemittanceAdviceSendType(self::parseEnumAttribute(\PhpTwinfield\Enums\RemittanceAdviceSendType::class, self::getField($remittanceAdviceElement, 'sendtype', $customer))) + ->setRemittanceAdviceSendMail(self::getField($remittanceAdviceElement, 'sendmail', $customer)); } + // Get the addresses element $addressesDOMTag = $responseDOM->getElementsByTagName('addresses'); - if (isset($addressesDOMTag) && $addressesDOMTag->length > 0) { - - // Element tags and their methods for address - $addressTags = array( - 'name' => 'setName', - 'contact' => 'setContact', - 'country' => 'setCountry', - 'city' => 'setCity', - 'postcode' => 'setPostcode', - 'telephone' => 'setTelephone', - 'telefax' => 'setFax', - 'email' => 'setEmail', - 'field1' => 'setField1', - 'field2' => 'setField2', - 'field3' => 'setField3', - 'field4' => 'setField4', - 'field5' => 'setField5', - 'field6' => 'setField6', - ); - - $addressesDOM = $addressesDOMTag->item(0); + if (isset($addressesDOMTag) && $addressesDOMTag->length > 0) { // Loop through each returned address for the customer - foreach ($addressesDOM->getElementsByTagName('address') as $addressDOM) { + foreach ($addressesDOMTag->item(0)->childNodes as $addressElement) { + if ($addressElement->nodeType !== 1) { + continue; + } - // Make a new tempory CustomerAddress class - $temp_address = new CustomerAddress(); + // Make a new temporary CustomerAddress class + $customerAddress = new CustomerAddress(); + + // Set the default, id and type attribute + $customerAddress->setDefault(Util::parseBoolean($addressElement->getAttribute('default'))) + ->setID($addressElement->getAttribute('id')) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\AddressType::class, $addressElement->getAttribute('type'))); + + // Set the address elements from the address element + $customerAddress->setCity(self::getField($addressElement, 'city', $customerAddress)) + ->setCountry(self::parseObjectAttribute(\PhpTwinfield\Country::class, $customerAddress, $addressElement, 'country', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setEmail(self::getField($addressElement, 'email', $customerAddress)) + ->setField1(self::getField($addressElement, 'field1', $customerAddress)) + ->setField2(self::getField($addressElement, 'field2', $customerAddress)) + ->setField3(self::getField($addressElement, 'field3', $customerAddress)) + ->setField4(self::getField($addressElement, 'field4', $customerAddress)) + ->setField5(self::getField($addressElement, 'field5', $customerAddress)) + ->setField6(self::getField($addressElement, 'field6', $customerAddress)) + ->setName(self::getField($addressElement, 'name', $customerAddress)) + ->setPostcode(self::getField($addressElement, 'postcode', $customerAddress)) + ->setTelephone(self::getField($addressElement, 'telephone', $customerAddress)) + ->setTelefax(self::getField($addressElement, 'telefax', $customerAddress)); - // Set the attributes ( id, type, default ) - $temp_address - ->setID($addressDOM->getAttribute('id')) - ->setType($addressDOM->getAttribute('type')) - ->setDefault(Util::parseBoolean($addressDOM->getAttribute('default'))); + // Add the address to the customer + $customer->addAddress($customerAddress); - // Loop through the element tags. Determine if it exists and set it if it does - foreach ($addressTags as $tag => $method) { + // Clean that memory! + unset ($customerAddress); + } + } - // Get the dom element - $_tag = $addressDOM->getElementsByTagName($tag)->item(0); + // Get the banks element + $banksDOMTag = $responseDOM->getElementsByTagName('banks'); - // Check if the tag is set, and its content is set, to prevent DOMNode errors - if (isset($_tag) && isset($_tag->textContent)) { - $temp_address->$method($_tag->textContent); - } + if (isset($banksDOMTag) && $banksDOMTag->length > 0) { + // Loop through each returned bank for the customer + foreach ($banksDOMTag->item(0)->childNodes as $bankElement) { + if ($bankElement->nodeType !== 1) { + continue; } - // Add the address to the customer - $customer->addAddress($temp_address); + // Make a new temporary CustomerBank class + $customerBank = new CustomerBank(); + + // Set the default and id attribute + $customerBank->setBlocked(Util::parseBoolean($bankElement->getAttribute('blocked'))) + ->setDefault(Util::parseBoolean($bankElement->getAttribute('default'))) + ->setID($bankElement->getAttribute('id')); + + // Set the bank elements from the bank element + $customerBank->setAccountNumber(self::getField($bankElement, 'accountnumber', $customerBank)) + ->setAddressField2(self::getField($bankElement, 'field2', $customerBank)) + ->setAddressField3(self::getField($bankElement, 'field3', $customerBank)) + ->setAscription(self::getField($bankElement, 'ascription', $customerBank)) + ->setBankName(self::getField($bankElement, 'bankname', $customerBank)) + ->setBicCode(self::getField($bankElement, 'biccode', $customerBank)) + ->setCity(self::getField($bankElement, 'city', $customerBank)) + ->setCountry(self::parseObjectAttribute(\PhpTwinfield\Country::class, $customerBank, $bankElement, 'country', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setIban(self::getField($bankElement, 'iban', $customerBank)) + ->setNatBicCode(self::getField($bankElement, 'natbiccode', $customerBank)) + ->setPostcode(self::getField($bankElement, 'postcode', $customerBank)) + ->setState(self::getField($bankElement, 'state', $customerBank)); + + // Add the bank to the customer + $customer->addBank($customerBank); // Clean that memory! - unset($temp_address); + unset ($customerBank); } } - $banksDOMTag = $responseDOM->getElementsByTagName('banks'); - if (isset($banksDOMTag) && $banksDOMTag->length > 0) { + // Get the postingrules element + $postingrulesDOMTag = $responseDOM->getElementsByTagName('postingrules'); - // Element tags and their methods for bank - $bankTags = array( - 'ascription' => 'setAscription', - 'accountnumber' => 'setAccountnumber', - 'field2' => 'setAddressField2', - 'field3' => 'setAddressField3', - 'bankname' => 'setBankname', - 'biccode' => 'setBiccode', - 'city' => 'setCity', - 'country' => 'setCountry', - 'iban' => 'setIban', - 'natbiccode' => 'setNatbiccode', - 'postcode' => 'setPostcode', - 'state' => 'setState', - ); - - $banksDOM = $banksDOMTag->item(0); + if (isset($postingrulesDOMTag) && $postingrulesDOMTag->length > 0) { + // Loop through each returned postingrule for the customer + foreach ($postingrulesDOMTag->item(0)->childNodes as $postingruleElement) { + if ($postingruleElement->nodeType !== 1) { + continue; + } - // Loop through each returned bank for the customer - /** @var \DOMElement $bankDOM */ - foreach ($banksDOM->getElementsByTagName('bank') as $bankDOM) { + // Make a new temporary CustomerPostingRule class + $customerPostingRule = new CustomerPostingRule(); + + // Set the id and status attribute + $customerPostingRule->setID($postingruleElement->getAttribute('id')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $postingruleElement->getAttribute('status'))); + + // Set the postingrule elements from the postingrule element + $customerPostingRule->setCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $customerPostingRule, $postingruleElement, 'currency', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setDescription(self::getField($postingruleElement, 'description', $customerPostingRule)); + + $customerPostingRule->setAmount(self::parseMoneyAttribute(self::getField($postingruleElement, 'amount', $customerPostingRule), Util::objectToStr($customerPostingRule->getCurrency()))); + + // Get the lines element + $linesDOMTag = $postingruleElement->getElementsByTagName('lines'); - // Make a new tempory CustomerBank class - $temp_bank = new CustomerBank(); + if (isset($linesDOMTag) && $linesDOMTag->length > 0) { + // Loop through each returned line for the posting rule + foreach ($linesDOMTag->item(0)->childNodes as $lineElement) { + if ($lineElement->nodeType !== 1) { + continue; + } - // Set the attributes ( id, default ) - $temp_bank - ->setID($bankDOM->getAttribute('id')) - ->setDefault(Util::parseBoolean($bankDOM->getAttribute('default'))); + // Make a new temporary CustomerLine class + $customerLine = new CustomerLine(); - // Loop through the element tags. Determine if it exists and set it if it does - foreach ($bankTags as $tag => $method) { + // Set the line elements from the line element + $customerLine->setDescription(self::getField($lineElement, 'description', $customerLine)) + ->setDimension1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $customerLine, $lineElement, 'dimension1', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDimension2(self::parseObjectAttribute(\PhpTwinfield\CostCenter::class, $customerLine, $lineElement, 'dimension2', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDimension3(self::parseObjectAttribute(null, $customerLine, $lineElement, 'dimension3', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $customerLine, $lineElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setRatio(self::getField($lineElement, 'ratio', $customerLine)) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $customerLine, $lineElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); - // Get the dom element - $_tag = $bankDOM->getElementsByTagName($tag)->item(0); + // Set the line elements from the line element attributes + $customerLine->setDimension1ID(self::getAttribute($lineElement, 'dimension1', 'id')) + ->setDimension2ID(self::getAttribute($lineElement, 'dimension2', 'id')) + ->setDimension3ID(self::getAttribute($lineElement, 'dimension2', 'id')); - // Check if the tag is set, and its content is set, to prevent DOMNode errors - if (isset($_tag) && isset($_tag->textContent)) { - $temp_bank->$method($_tag->textContent); + // Add the line to the customer posting rule + $customerPostingRule->addLine($customerLine); + + // Clean that memory! + unset ($customerLine); } } - // Add the bank to the customer - $customer->addBank($temp_bank); + // Add the postingrule to the customer + $customer->addPostingRule($customerPostingRule); // Clean that memory! - unset($temp_bank); + unset ($customerPostingRule); } } + // Get the paymentconditions element + $paymentConditionsElement = $responseDOM->getElementsByTagName('paymentconditions')->item(0); + + if ($paymentConditionsElement !== null) { + // Set the customer elements from the paymentconditions element + $customer->setPaymentConditionDiscountDays(self::getField($paymentConditionsElement, 'discountdays', $customer)) + ->setPaymentConditionDiscountPercentage(self::getField($paymentConditionsElement, 'discountpercentage', $customer)); + } + + // Return the complete object return $customer; } } diff --git a/src/Mappers/DimensionGroupMapper.php b/src/Mappers/DimensionGroupMapper.php new file mode 100644 index 00000000..9412c539 --- /dev/null +++ b/src/Mappers/DimensionGroupMapper.php @@ -0,0 +1,77 @@ + + */ +class DimensionGroupMapper extends BaseMapper +{ + + /** + * Maps a Response object to a clean DimensionGroup entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return DimensionGroup + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new DimensionGroup object + $dimensiongroup = new DimensionGroup(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/dimensiongroup element + $dimensiongroupElement = $responseDOM->documentElement; + + // Set the result and status attribute + $dimensiongroup->setResult($dimensiongroupElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $dimensiongroupElement->getAttribute('status'))); + + // Set the dimension group elements from the dimension group element + $dimensiongroup->setCode(self::getField($dimensiongroupElement, 'code', $dimensiongroup)) + ->setName(self::getField($dimensiongroupElement, 'name', $dimensiongroup)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $dimensiongroup, $dimensiongroupElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($dimensiongroupElement, 'shortname', $dimensiongroup)); + + // Get the dimensions element + $dimensionsDOMTag = $responseDOM->getElementsByTagName('dimensions'); + + if (isset($dimensionsDOMTag) && $dimensionsDOMTag->length > 0) { + // Loop through each returned dimension for the dimensiongroup + foreach ($dimensionsDOMTag->item(0)->childNodes as $dimensionElement) { + if ($dimensionElement->nodeType !== 1) { + continue; + } + + // Make a new temporary DimensionGroupDimension class + $dimensionGroupDimension = new DimensionGroupDimension(); + + // Set the dimension group dimension elements from the dimension element + $dimensionGroupDimension->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $dimensionGroupDimension, $dimensionElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))); + $dimensionGroupDimension->setCode(self::parseObjectAttribute(null, $dimensionGroupDimension, $dimensionElement, 'code', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Add the dimension to the dimension group + $dimensiongroup->addDimension($dimensionGroupDimension); + + // Clean that memory! + unset ($dimensionGroupDimension); + } + } + + // Return the complete object + return $dimensiongroup; + } +} diff --git a/src/Mappers/DimensionTypeMapper.php b/src/Mappers/DimensionTypeMapper.php new file mode 100644 index 00000000..cf610a2e --- /dev/null +++ b/src/Mappers/DimensionTypeMapper.php @@ -0,0 +1,87 @@ + + */ +class DimensionTypeMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean DimensionType entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return DimensionType + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new DimensionType object + $dimensiontype = new DimensionType(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/dimensiontype element + $dimensiontypeElement = $responseDOM->documentElement; + + // Set the result and status attribute + $dimensiontype->setResult($dimensiontypeElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $dimensiontypeElement->getAttribute('status'))); + + // Set the dimension type elements from the dimension type element + $dimensiontype->setCode(self::getField($dimensiontypeElement, 'code', $dimensiontype)) + ->setMask(self::getField($dimensiontypeElement, 'mask', $dimensiontype)) + ->setName(self::getField($dimensiontypeElement, 'name', $dimensiontype)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $dimensiontype, $dimensiontypeElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($dimensiontypeElement, 'shortname', $dimensiontype)); + + // Get the levels element + $levelsElement = $responseDOM->getElementsByTagName('levels')->item(0); + + if ($levelsElement !== null) { + // Make a new temporary DimensionTypeLevels class + $dimensionTypeLevels = new DimensionTypeLevels(); + + // Set the dimension type levels elements from the levels element + $dimensionTypeLevels->setFinancials(self::getField($levelsElement, 'financials', $dimensionTypeLevels)) + ->setTime(self::getField($levelsElement, 'time', $dimensionTypeLevels)); + + // Set the custom class to the dimension type + $dimensiontype->setLevels($dimensionTypeLevels); + } + + // Get the address element + $addressElement = $responseDOM->getElementsByTagName('address')->item(0); + + if ($addressElement !== null) { + // Make a new temporary DimensionTypeAddress class + $dimensionTypeAddress = new DimensionTypeAddress(); + + // Set the dimension type address elements from the address element + $dimensionTypeAddress->setLabel1(self::getField($addressElement, 'label1', $dimensionTypeAddress)) + ->setLabel2(self::getField($addressElement, 'label2', $dimensionTypeAddress)) + ->setLabel3(self::getField($addressElement, 'label3', $dimensionTypeAddress)) + ->setLabel4(self::getField($addressElement, 'label4', $dimensionTypeAddress)) + ->setLabel5(self::getField($addressElement, 'label5', $dimensionTypeAddress)) + ->setLabel6(self::getField($addressElement, 'label6', $dimensionTypeAddress)); + + // Set the custom class to the dimensiontype + $dimensiontype->setAddress($dimensionTypeAddress); + } + + // Return the complete object + return $dimensiontype; + } +} diff --git a/src/Mappers/FixedAssetMapper.php b/src/Mappers/FixedAssetMapper.php new file mode 100644 index 00000000..34ebdd4a --- /dev/null +++ b/src/Mappers/FixedAssetMapper.php @@ -0,0 +1,181 @@ + + */ +class FixedAssetMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean FixedAsset entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * @param \PhpTwinfield\Secure\AuthenticatedConnection $connection + * + * @return FixedAsset + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response, AuthenticatedConnection $connection) + { + // Generate new FixedAsset object + $fixedAsset = new FixedAsset(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + // Get the root/fixed asset element + $fixedAssetElement = $responseDOM->documentElement; + + // Set the result and status attribute + $fixedAsset->setResult($fixedAssetElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $fixedAssetElement->getAttribute('status'))); + + // Set the fixed asset elements from the fixed asset element + $fixedAsset->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($fixedAssetElement, 'behaviour', $fixedAsset))) + ->setCode(self::getField($fixedAssetElement, 'code', $fixedAsset)) + ->setGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $fixedAsset, $fixedAssetElement, 'group', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setInUse(Util::parseBoolean(self::getField($fixedAssetElement, 'name', $fixedAsset))) + ->setName(self::getField($fixedAssetElement, 'name', $fixedAsset)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $fixedAsset, $fixedAssetElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setTouched(self::getField($fixedAssetElement, 'touched', $fixedAsset)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $fixedAsset, $fixedAssetElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($fixedAssetElement, 'uid', $fixedAsset)); + + if ($fixedAsset->getOffice() !== null) { + $currencies = self::getOfficeCurrencies($connection, $fixedAsset->getOffice()); + } + + // Get the financials element + $financialsElement = $responseDOM->getElementsByTagName('financials')->item(0); + + if ($financialsElement !== null) { + // Make a new temporary FixedAssetFinancials class + $fixedAssetFinancials = new FixedAssetFinancials(); + + // Set the financials elements from the financials element + $fixedAssetFinancials->setAccountType(self::parseEnumAttribute(\PhpTwinfield\Enums\AccountType::class, self::getField($financialsElement, 'accounttype', $fixedAssetFinancials))) + ->setLevel(self::getField($financialsElement, 'level', $fixedAssetFinancials)) + ->setMatchType(self::parseEnumAttribute(\PhpTwinfield\Enums\MatchType::class, self::getField($financialsElement, 'matchtype', $fixedAssetFinancials))) + ->setSubAnalyse(self::parseEnumAttribute(\PhpTwinfield\Enums\SubAnalyse::class, self::getField($financialsElement, 'subanalyse', $fixedAssetFinancials))) + ->setSubstitutionLevel(self::getField($financialsElement, 'substitutionlevel', $fixedAssetFinancials)) + ->setSubstituteWith(self::parseObjectAttribute(\PhpTwinfield\CostCenter::class, $fixedAssetFinancials, $financialsElement, 'substitutewith', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $fixedAssetFinancials, $financialsElement, 'vatcode')); + + // Set the financials elements from the financials element attributes + $fixedAssetFinancials->setSubstituteWithID(self::getAttribute($financialsElement, 'substitutewith', 'id')); + $fixedAssetFinancials->setVatCodeFixed(Util::parseBoolean(self::getAttribute($financialsElement, 'vatcode', 'fixed'))); + + // Set the custom class to the fixedAsset + $fixedAsset->setFinancials($fixedAssetFinancials); + } + + // Get the fixedassets element + $fixedAssetsElement = $responseDOM->getElementsByTagName('fixedassets')->item(0); + + if ($fixedAssetsElement !== null) { + // Make a new temporary FixedAssetFixedAssets class + $fixedAssetFixedAssets = new FixedAssetFixedAssets(); + + // Set the fixed assets elements from the fixed assets element + $fixedAssetFixedAssets->setBeginPeriod(self::getField($fixedAssetsElement, 'beginperiod', $fixedAssetFixedAssets)) + ->setFreeText1(self::getField($fixedAssetsElement, 'freetext1', $fixedAssetFixedAssets)) + ->setFreeText2(self::getField($fixedAssetsElement, 'freetext2', $fixedAssetFixedAssets)) + ->setFreeText3(self::getField($fixedAssetsElement, 'freetext3', $fixedAssetFixedAssets)) + ->setFreeText4(self::getField($fixedAssetsElement, 'freetext4', $fixedAssetFixedAssets)) + ->setFreeText5(self::getField($fixedAssetsElement, 'freetext5', $fixedAssetFixedAssets)) + ->setLastDepreciation(self::getField($fixedAssetsElement, 'lastdepreciation', $fixedAssetFixedAssets)) + ->setMethod(self::parseObjectAttribute(\PhpTwinfield\AssetMethod::class, $fixedAssetFixedAssets, $fixedAssetsElement, 'method', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setNrOfPeriods(self::getField($fixedAssetsElement, 'nrofperiods', $fixedAssetFixedAssets)) + ->setPercentage(self::getField($fixedAssetsElement, 'percentage', $fixedAssetFixedAssets)) + ->setPurchaseDate(self::parseDateAttribute(self::getField($fixedAssetsElement, 'purchasedate', $fixedAssetFixedAssets))) + ->setResidualValue(self::parseMoneyAttribute(self::getField($fixedAssetsElement, 'residualvalue', $fixedAssetFixedAssets), $currencies['base'])) + ->setSellDate(self::parseDateAttribute(self::getField($fixedAssetsElement, 'selldate', $fixedAssetFixedAssets))) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\FixedAssetsStatus::class, self::getField($fixedAssetsElement, 'status', $fixedAssetFixedAssets))) + ->setStopValue(self::parseMoneyAttribute(self::getField($fixedAssetsElement, 'stopvalue', $fixedAssetFixedAssets), $currencies['base'])); + + // Set the fixed assets elements from the fixed assets element attributes + $fixedAssetFixedAssets->setBeginPeriodLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'beginperiod', 'locked'))) + ->setMethodLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'method', 'locked'))) + ->setStatusLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'status', 'locked'))) + ->setFreeText1Locked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'freetext1', 'locked'))) + ->setFreeText2Locked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'freetext2', 'locked'))) + ->setFreeText3Locked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'freetext3', 'locked'))) + ->setFreeText4Locked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'freetext4', 'locked'))) + ->setFreeText5Locked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'freetext5', 'locked'))) + ->setLastDepreciationLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'lastdepreciation', 'locked'))) + ->setNrOfPeriodsInherited(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'nrofperiods', 'inherited'))) + ->setNrOfPeriodsLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'nrofperiods', 'locked'))) + ->setPercentageLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'percentage', 'locked'))) + ->setPurchaseDateLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'purchasedate', 'locked'))) + ->setResidualValueLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'residualvalue', 'locked'))) + ->setSellDateLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'selldate', 'locked'))) + ->setStopValueLocked(Util::parseBoolean(self::getAttribute($fixedAssetsElement, 'stopvalue', 'locked'))); + + // Get the translines element + $transactionLinesDOMTag = $fixedAssetsElement->getElementsByTagName('translines'); + + if (isset($transactionLinesDOMTag) && $transactionLinesDOMTag->length > 0) { + // Loop through each returned transactionLine for the fixedAsset + foreach ($transactionLinesDOMTag->item(0)->childNodes as $transactionLineElement) { + if ($transactionLineElement->nodeType !== 1) { + continue; + } + + // Make a new temporary FixedAssetTransactionLine class + $fixedAssetTransactionLine = new FixedAssetTransactionLine(); + + // Set the fixed assets transaction line elements from the fixed assets transline element + $fixedAssetTransactionLine->setAmount(self::parseMoneyAttribute(self::getField($transactionLineElement, 'amount', $fixedAssetTransactionLine), $currencies['base'])) + ->setCode(self::getField($transactionLineElement, 'code', $fixedAssetTransactionLine)) + ->setDim1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $fixedAssetTransactionLine, $transactionLineElement, 'dim1', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setDim2(self::parseObjectAttribute(null, $fixedAssetTransactionLine, $transactionLineElement, 'dim2', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setDim3(self::parseObjectAttribute(null, $fixedAssetTransactionLine, $transactionLineElement, 'dim3', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setDim4(self::parseObjectAttribute(null, $fixedAssetTransactionLine, $transactionLineElement, 'dim4', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setDim5(self::parseObjectAttribute(null, $fixedAssetTransactionLine, $transactionLineElement, 'dim5', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setDim6(self::parseObjectAttribute(null, $fixedAssetTransactionLine, $transactionLineElement, 'dim6', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setType'))) + ->setLine(self::getField($transactionLineElement, 'line', $fixedAssetTransactionLine)) + ->setNumber(self::getField($transactionLineElement, 'number', $fixedAssetTransactionLine)) + ->setPeriod(self::getField($transactionLineElement, 'period', $fixedAssetTransactionLine)); + + // Set the fixed assets transaction line elements from the fixed assets transline attributes + $fixedAssetTransactionLine->setAmountLocked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'amount', 'locked'))) + ->setCodeLocked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'code', 'locked'))) + ->setDim1Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim1', 'locked'))) + ->setDim2Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim2', 'locked'))) + ->setDim3Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim3', 'locked'))) + ->setDim4Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim4', 'locked'))) + ->setDim5Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim5', 'locked'))) + ->setDim6Locked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'dim6', 'locked'))) + ->setLineLocked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'line', 'locked'))) + ->setNumberLocked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'number', 'locked'))) + ->setPeriodLocked(Util::parseBoolean(self::getAttribute($transactionLineElement, 'period', 'locked'))); + + // Add the transactionLine to the fixedAsset + $fixedAssetFixedAssets->addTransactionLine($fixedAssetTransactionLine); + + // Clean that memory! + unset ($fixedAssetTransactionLine); + } + } + + // Set the custom class to the fixedAsset + $fixedAsset->setFixedAssets($fixedAssetFixedAssets); + } + + // Return the complete object + return $fixedAsset; + } +} diff --git a/src/Mappers/GeneralLedgerMapper.php b/src/Mappers/GeneralLedgerMapper.php new file mode 100644 index 00000000..62a0a78e --- /dev/null +++ b/src/Mappers/GeneralLedgerMapper.php @@ -0,0 +1,110 @@ + + */ +class GeneralLedgerMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean GeneralLedger entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return GeneralLedger + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new GeneralLedger object + $generalLedger = new GeneralLedger(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/dimension element + $generalLedgerElement = $responseDOM->documentElement; + + // Set the result and status attribute + $generalLedger->setResult($generalLedgerElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $generalLedgerElement->getAttribute('status'))); + + // Set the general ledger elements from the general ledger element + $generalLedger->setBeginPeriod(self::getField($generalLedgerElement, 'beginperiod', $generalLedger)) + ->setBeginYear(self::getField($generalLedgerElement, 'beginyear', $generalLedger)) + ->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($generalLedgerElement, 'behaviour', $generalLedger))) + ->setCode(self::getField($generalLedgerElement, 'code', $generalLedger)) + ->setEndPeriod(self::getField($generalLedgerElement, 'endperiod', $generalLedger)) + ->setEndYear(self::getField($generalLedgerElement, 'endyear', $generalLedger)) + ->setGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $generalLedger, $generalLedgerElement, 'group', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setInUse(Util::parseBoolean(self::getField($generalLedgerElement, 'inuse', $generalLedger))) + ->setName(self::getField($generalLedgerElement, 'name', $generalLedger)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $generalLedger, $generalLedgerElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($generalLedgerElement, 'shortname', $generalLedger)) + ->setTouched(self::getField($generalLedgerElement, 'touched', $generalLedger)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $generalLedger, $generalLedgerElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($generalLedgerElement, 'uid', $generalLedger)); + + // Get the financials element + $financialsElement = $responseDOM->getElementsByTagName('financials')->item(0); + + if ($financialsElement !== null) { + // Make a new temporary GeneralLedgerFinancials class + $generalLedgerFinancials = new GeneralLedgerFinancials(); + + // Set the financials elements from the financials element + $generalLedgerFinancials->setAccountType(self::parseEnumAttribute(\PhpTwinfield\Enums\AccountType::class, self::getField($financialsElement, 'accounttype', $generalLedgerFinancials))) + ->setLevel(self::getField($financialsElement, 'level', $generalLedgerFinancials)) + ->setMatchType(self::parseEnumAttribute(\PhpTwinfield\Enums\MatchType::class, self::getField($financialsElement, 'matchtype', $generalLedgerFinancials))) + ->setSubAnalyse(self::parseEnumAttribute(\PhpTwinfield\Enums\SubAnalyse::class, self::getField($financialsElement, 'subanalyse', $generalLedgerFinancials))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $generalLedgerFinancials, $financialsElement, 'vatcode')); + + // Set the financials elements from the financials element attributes + $generalLedgerFinancials->setVatCodeFixed(Util::parseBoolean(self::getAttribute($financialsElement, 'vatcode', 'fixed'))); + + // Get the childvalidations element + $childValidationsDOMTag = $financialsElement->getElementsByTagName('childvalidations'); + + if (isset($childValidationsDOMTag) && $childValidationsDOMTag->length > 0) { + // Loop through each returned childValidation for the generalLedger + foreach ($childValidationsDOMTag->item(0)->childNodes as $childValidationElement) { + if ($childValidationElement->nodeType !== 1) { + continue; + } + + // Make a new temporary GeneralLedgerChildValidation class + $generalLedgerChildValidation = new GeneralLedgerChildValidation(); + + // Set the child validation elements from the child validation element en element attributes + $generalLedgerChildValidation->setLevel($childValidationElement->getAttribute('level')); + $generalLedgerChildValidation->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\ChildValidationType::class, $childValidationElement->getAttribute('type'))); + $generalLedgerChildValidation->setElementValue($childValidationElement->textContent); + + // Add the child validation to the general ledger financials class + $generalLedgerFinancials->addChildValidation($generalLedgerChildValidation); + + // Clean that memory! + unset ($generalLedgerChildValidation); + } + } + + // Set the custom class to the general ledger + $generalLedger->setFinancials($generalLedgerFinancials); + } + + // Return the complete object + return $generalLedger; + } +} diff --git a/src/Mappers/InvoiceMapper.php b/src/Mappers/InvoiceMapper.php index 5fccf1f9..5e123036 100644 --- a/src/Mappers/InvoiceMapper.php +++ b/src/Mappers/InvoiceMapper.php @@ -1,133 +1,154 @@ + */ class InvoiceMapper extends BaseMapper { - public static function map(Response $response) + /** + * Maps a Response object to a clean Invoice entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Invoice + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) { - $responseDOM = $response->getResponseDocument(); - - $invoiceTags = array( - 'office' => 'setOffice', - 'invoicetype' => 'setInvoiceType', - 'invoicenumber' => 'setInvoiceNumber', - 'status' => 'setStatus', - 'currency' => 'setCurrency', - 'period' => 'setPeriod', - 'invoicedate' => 'setInvoiceDate', - 'duedate' => 'setDueDateFromString', - 'performancedate' => 'setPerformanceDate', - 'paymentmethod' => 'setPaymentMethod', - 'bank' => 'setBank', - 'invoiceaddressnumber' => 'setInvoiceAddressNumber', - 'deliveraddressnumber' => 'setDeliverAddressNumber', - 'headertext' => 'setHeaderText', - 'footertext' => 'setFooterText', - ); - - $customerTags = array( - 'customer' => 'setCode', - ); - - $totalsTags = array( - 'valueexcl' => 'setValueExcl', - 'valueinc' => 'setValueInc', - ); - - // Generate new Invoice + // Generate new Invoice object $invoice = new Invoice(); - // Loop through all invoice tags - foreach ($invoiceTags as $tag => $method) { + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); - self::setFromTagValue($responseDOM, $tag, [$invoice, $method]); + // Get the root/salesinvoice element + $invoiceElement = $responseDOM->documentElement; + + // Set the result attribute + $invoice->setResult($invoiceElement->getAttribute('result')); + + // Set the invoice elements from the invoice element + $invoice->setBank(self::parseObjectAttribute(\PhpTwinfield\CashBankBook::class, $invoice, $invoiceElement, 'bank')) + ->setCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $invoice, $invoiceElement, 'currency')) + ->setCustomer(self::parseObjectAttribute(\PhpTwinfield\Customer::class, $invoice, $invoiceElement, 'customer')) + ->setDeliverAddressNumber(self::getField($invoiceElement, 'deliveraddressnumber', $invoice)) + ->setDueDate(self::parseDateAttribute(self::getField($invoiceElement, 'duedate', $invoice))) + ->setFooterText(self::getField($invoiceElement, 'footertext', $invoice)) + ->setHeaderText(self::getField($invoiceElement, 'headertext', $invoice)) + ->setInvoiceAddressNumber(self::getField($invoiceElement, 'invoiceaddressnumber', $invoice)) + ->setInvoiceDate(self::parseDateAttribute(self::getField($invoiceElement, 'invoicedate', $invoice))) + ->setInvoiceNumber(self::getField($invoiceElement, 'invoicenumber', $invoice)) + ->setInvoiceType(self::parseObjectAttribute(\PhpTwinfield\InvoiceType::class, $invoice, $invoiceElement, 'invoicetype')) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $invoice, $invoiceElement, 'office')) + ->setPaymentMethod(self::parseEnumAttribute(\PhpTwinfield\Enums\PaymentMethod::class, self::getField($invoiceElement, 'paymentmethod', $invoice))) + ->setPeriod(self::getField($invoiceElement, 'period', $invoice)) + ->setPerformanceDate(self::parseDateAttribute(self::getField($invoiceElement, 'performancedate', $invoice))) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\InvoiceStatus::class, self::getField($invoiceElement, 'status', $invoice))); + + // Get the totals element + $totalsElement = $responseDOM->getElementsByTagName('totals')->item(0); + + if ($totalsElement !== null) { + // Make a new temporary InvoiceTotals class + $invoiceTotals = new InvoiceTotals(); + + // Set the invoice totals elements from the totals element + $invoiceTotals->setValueExcl(self::parseMoneyAttribute(self::getField($totalsElement, 'valueexcl', $invoiceTotals), Util::objectToStr($invoice->getCurrency()))) + ->setValueInc(self::parseMoneyAttribute(self::getField($totalsElement, 'valueinc', $invoiceTotals), Util::objectToStr($invoice->getCurrency()))); + + // Set the custom class to the invoice + $invoice->setTotals($invoiceTotals); } - // Make a custom, and loop through custom tags - $customer = new Customer(); - foreach ($customerTags as $tag => $method) { - $_tag = $responseDOM->getElementsByTagName($tag)->item(0); - - if (isset($_tag) && isset($_tag->textContent)) { - $customer->$method($_tag->textContent); - } - } + // Get the lines element + $linesDOMTag = $responseDOM->getElementsByTagName('lines'); - // Make an InvoiceTotals and loop through custom tags - $invoiceTotals = new InvoiceTotals(); - foreach ($totalsTags as $tag => $method) { - $_tag = $responseDOM->getElementsByTagName($tag)->item(0); + if (isset($linesDOMTag) && $linesDOMTag->length > 0) { + // Loop through each returned lines for the invoice + foreach ($linesDOMTag->item(0)->childNodes as $lineElement) { + if ($lineElement->nodeType !== 1) { + continue; + } - if (isset($_tag) && isset($_tag->textContent)) { - $invoiceTotals->$method($_tag->textContent); + // Make a new temporary InvoiceLine class + $invoiceLine = new InvoiceLine(); + + // Set the ID attribute + $invoiceLine->setID($lineElement->getAttribute('id')); + + // Set the invoice line elements from the line element + $invoiceLine->setAllowDiscountOrPremium(Util::parseBoolean(self::getField($lineElement, 'allowdiscountorpremium', $invoiceLine))) + ->setArticle(self::parseObjectAttribute(\PhpTwinfield\Article::class, $invoiceLine, $lineElement, 'article')) + ->setDescription(self::getField($lineElement, 'description', $invoiceLine)) + ->setDim1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $invoiceLine, $lineElement, 'dim1')) + ->setFreeText1(self::getField($lineElement, 'freetext1', $invoiceLine)) + ->setFreeText2(self::getField($lineElement, 'freetext2', $invoiceLine)) + ->setFreeText3(self::getField($lineElement, 'freetext3', $invoiceLine)) + ->setPerformanceDate(self::parseDateAttribute(self::getField($lineElement, 'performancedate', $invoiceLine))) + ->setPerformanceType(self::parseEnumAttribute(\PhpTwinfield\Enums\PerformanceType::class, self::getField($lineElement, 'performancetype', $invoiceLine))) + ->setQuantity(self::getField($lineElement, 'quantity', $invoiceLine)) + ->setSubArticleFromString(self::getField($lineElement, 'subarticle', $invoiceLine)) + ->setUnits(self::getField($lineElement, 'units', $invoiceLine)) + ->setUnitsPriceExcl(self::parseMoneyAttribute(self::getField($lineElement, 'unitspriceexcl', $invoiceLine), Util::objectToStr($invoice->getCurrency()))) + ->setUnitsPriceInc(self::parseMoneyAttribute(self::getField($lineElement, 'unitspriceinc', $invoiceLine), Util::objectToStr($invoice->getCurrency()))) + ->setValueExcl(self::parseMoneyAttribute(self::getField($lineElement, 'valueexcl', $invoiceLine), Util::objectToStr($invoice->getCurrency()))) + ->setValueInc(self::parseMoneyAttribute(self::getField($lineElement, 'valueinc', $invoiceLine), Util::objectToStr($invoice->getCurrency()))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $invoiceLine, $lineElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))) + ->setVatValue(self::parseMoneyAttribute(self::getField($lineElement, 'vatvalue', $invoiceLine), Util::objectToStr($invoice->getCurrency()))); + + // Set the custom class to the invoice + $invoice->addLine($invoiceLine); } } - // Set the custom classes to the invoice - $invoice->setCustomer($customer); - $invoice->setTotals($invoiceTotals); - - $lineTags = array( - 'article' => 'setArticle', - 'subarticle' => 'setSubArticle', - 'quantity' => 'setQuantity', - 'units' => 'setUnits', - 'allowdiscountorpremium' => 'setAllowDiscountOrPremium', - 'description' => 'setDescription', - 'valueexcl' => 'setValueExcl', - 'vatvalue' => 'setVatValue', - 'valueinc' => 'setValueInc', - 'unitspriceexcl' => 'setUnitsPriceExcl', - 'unitspriceinc' => 'setUnitsPriceInc', - 'freetext1' => 'setFreeText1', - 'freetext2' => 'setFreeText2', - 'freetext3' => 'setFreeText3', - 'performancedate' => 'setPerformanceDate', - 'performancetype' => 'setPerformanceType', - 'dim1' => 'setDim1', - ); - - /** @var \DOMElement $lineDOM */ - foreach ($responseDOM->getElementsByTagName('line') as $lineDOM) { - - $invoiceLine = new InvoiceLine(); - $invoiceLine->setID($lineDOM->getAttribute('id')); - - foreach ($lineTags as $tag => $method) { - - $content = self::getField($lineDOM, $tag); - - if (null !== $content) { - $invoiceLine->$method($content); + // Get the vatlines element + $vatlinesDOMTag = $responseDOM->getElementsByTagName('vatlines'); + + if (isset($vatlinesDOMTag) && $vatlinesDOMTag->length > 0) { + // Loop through each returned lines for the invoice + foreach ($vatlinesDOMTag->item(0)->childNodes as $vatlineElement) { + if ($vatlineElement->nodeType !== 1) { + continue; } - } - $invoice->addLine($invoiceLine); - } + // Make a new temporary InvoiceVatLine class + $invoiceVatLine = new InvoiceVatLine(); - // Financial elements and their methods - $financialsTags = array( - 'code' => 'setFinancialCode', - 'number' => 'setFinancialNumber' - ); + // Set the invoice vat line elements from the vat line element + $invoiceVatLine->setPerformanceDate(self::parseDateAttribute(self::getField($vatlineElement, 'performancedate', $invoiceVatLine))) + ->setPerformanceType(self::parseEnumAttribute(\PhpTwinfield\Enums\PerformanceType::class, self::getField($vatlineElement, 'performancetype', $invoiceVatLine))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $invoiceVatLine, $vatlineElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))) + ->setVatValue(self::parseMoneyAttribute(self::getField($vatlineElement, 'vatvalue', $invoiceVatLine), Util::objectToStr($invoice->getCurrency()))); - // Financial elements - $financialElement = $responseDOM->getElementsByTagName('financials')->item(0); + // Set the custom class to the invoice + $invoice->addVatLine($invoiceVatLine); + } + } - if ($financialElement !== null) { + // Get the financials element + $financialsElement = $responseDOM->getElementsByTagName('financials')->item(0); - // Go through each financial element and add to the assigned method - foreach ($financialsTags as $tag => $method) { - $invoice->$method(self::getField($financialElement, $tag)); - } + if ($financialsElement !== null) { + // Set the invoice elements from the financials element + $invoice->setFinancialCode(self::getField($financialsElement, 'code', $invoice)) + ->setFinancialNumber(self::getField($financialsElement, 'number', $invoice)); } + //Return the complete object return $invoice; } } diff --git a/src/Mappers/InvoiceTypeMapper.php b/src/Mappers/InvoiceTypeMapper.php new file mode 100644 index 00000000..da4ca044 --- /dev/null +++ b/src/Mappers/InvoiceTypeMapper.php @@ -0,0 +1,45 @@ + + */ +class InvoiceTypeMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean InvoiceType entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return InvoiceType + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new InvoiceType object + $invoiceType = new InvoiceType(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/invoice type element + $invoiceTypeElement = $responseDOM->documentElement; + + // Set the invoice type elements from the invoice type element + $invoiceType->setCode(self::getField($invoiceTypeElement, 'code', $invoiceType)) + ->setName(self::getField($invoiceTypeElement, 'name', $invoiceType)) + ->setShortName(self::getField($invoiceTypeElement, 'shortname', $invoiceType)); + + // Return the complete object + return $invoiceType; + } +} diff --git a/src/Mappers/MatchSetMapper.php b/src/Mappers/MatchSetMapper.php index 81eba2d1..a8e6ce1b 100644 --- a/src/Mappers/MatchSetMapper.php +++ b/src/Mappers/MatchSetMapper.php @@ -29,13 +29,13 @@ public static function map(\DOMDocument $document): MatchSet private static function createMatchSetFrom(\DOMDocument $document): MatchSet { + $MatchSetElement = $document->documentElement; + $matchSet = new MatchSet(); - $matchSet->setOffice(Office::fromCode(self::getValueFromTag($document, "office"))); - $matchSet->setMatchCode(new MatchCode(self::getValueFromTag($document, "matchcode"))); - $matchSet->setMatchDate( - \DateTimeImmutable::createFromFormat("Ymd", self::getValueFromTag($document, "matchdate")) - ); + $matchSet->setOffice(Office::fromCode(self::getField($MatchSetElement, "office"))); + $matchSet->setMatchCode(new MatchCode(self::getField($MatchSetElement, "matchcode"))); + $matchSet->setMatchDate(\DateTimeImmutable::createFromFormat("Ymd", self::getField($MatchSetElement, "matchdate"))); return $matchSet; } @@ -54,10 +54,7 @@ private static function addLines(\DOMDocument $document, MatchSet $matchSet): vo } } - private static function getMatchReferenceFrom( - \DOMElement $lineElement, - Office $office - ): MatchReferenceInterface { + private static function getMatchReferenceFrom(\DOMElement $lineElement, Office $office): MatchReferenceInterface { return new MatchReference( $office, self::getField($lineElement, 'transcode'), diff --git a/src/Mappers/OfficeMapper.php b/src/Mappers/OfficeMapper.php index 5e043fb5..414a3875 100644 --- a/src/Mappers/OfficeMapper.php +++ b/src/Mappers/OfficeMapper.php @@ -2,8 +2,8 @@ namespace PhpTwinfield\Mappers; -use PhpTwinfield\Response\Response; use PhpTwinfield\Office; +use PhpTwinfield\Response\Response; /** * Maps a response DOMDocument to the corresponding entity. @@ -13,6 +13,46 @@ */ class OfficeMapper extends BaseMapper { + /** + * Maps a Response object to a clean Office entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Office + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new Office object + $office = new Office(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/office element + $officeElement = $responseDOM->documentElement; + + // Set the result and status attribute + $office->setResult($officeElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $officeElement->getAttribute('status'))); + + // Set the office elements from the office element + $office->setBaseCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $office, $officeElement, 'basecurrency', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setCode(self::getField($officeElement, 'code', $office)) + ->setCreated(self::parseDateTimeAttribute(self::getField($officeElement, 'created', $office))) + ->setModified(self::parseDateTimeAttribute(self::getField($officeElement, 'modified', $office))) + ->setName(self::getField($officeElement, 'name', $office)) + ->setReportingCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $office, $officeElement, 'reportingcurrency', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($officeElement, 'shortname', $office)) + ->setTouched(self::getField($officeElement, 'touched', $office)) + ->setUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $office, $officeElement, 'user', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Return the complete object + return $office; + } + /** * Maps multiple offices to an office array. * @@ -40,4 +80,4 @@ public static function mapElement(\DOMElement $officeElement): Office return $office; } -} \ No newline at end of file +} diff --git a/src/Mappers/PayCodeMapper.php b/src/Mappers/PayCodeMapper.php new file mode 100644 index 00000000..02ce3f9e --- /dev/null +++ b/src/Mappers/PayCodeMapper.php @@ -0,0 +1,45 @@ + + */ +class PayCodeMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean PayCode entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return PayCode + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new PayCode object + $payCode = new PayCode(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/paycode element + $payCodeElement = $responseDOM->documentElement; + + // Set the paycode elements from the paycode element + $payCode->setCode(self::getField($payCodeElement, 'code', $payCode)) + ->setName(self::getField($payCodeElement, 'name', $payCode)) + ->setShortName(self::getField($payCodeElement, 'shortname', $payCode)); + + // Return the complete object + return $payCode; + } +} diff --git a/src/Mappers/ProjectMapper.php b/src/Mappers/ProjectMapper.php new file mode 100644 index 00000000..06f2bf8a --- /dev/null +++ b/src/Mappers/ProjectMapper.php @@ -0,0 +1,120 @@ + + */ +class ProjectMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean Project entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Project + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new Project object + $project = new Project(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/project element + $projectElement = $responseDOM->documentElement; + + // Set the result and status attribute + $project->setResult($projectElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $projectElement->getAttribute('status'))); + + // Set the project elements from the project element + $project->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($projectElement, 'behaviour', $project))) + ->setCode(self::getField($projectElement, 'code', $project)) + ->setInUse(Util::parseBoolean(self::getField($projectElement, 'name', $project))) + ->setName(self::getField($projectElement, 'name', $project)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $project, $projectElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($projectElement, 'shortname', $project)) + ->setTouched(self::getField($projectElement, 'touched', $project)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $project, $projectElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($projectElement, 'uid', $project)) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $project, $projectElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + // Get the projects element + $projectsElement = $responseDOM->getElementsByTagName('projects')->item(0); + + if ($projectsElement !== null) { + // Make a new temporary ProjectProjects class + $projectProjects = new ProjectProjects(); + + // Set the projects elements from the projects element + $projectProjects->setAuthoriser(self::parseObjectAttribute(\PhpTwinfield\User::class, $projectProjects, $projectsElement, 'authoriser')) + ->setBillable(Util::parseBoolean(self::getField($projectsElement, 'billable', $projectProjects))) + ->setCustomer(self::parseObjectAttribute(\PhpTwinfield\Customer::class, $projectProjects, $projectsElement, 'customer')) + ->setInvoiceDescription(self::getField($projectsElement, 'invoicedescription', $projectProjects)) + ->setRate(self::parseObjectAttribute(\PhpTwinfield\Rate::class, $projectProjects, $projectsElement, 'rate')) + ->setValidFrom(self::parseDateAttribute(self::getField($projectsElement, 'validfrom', $projectProjects))) + ->setValidTill(self::parseDateAttribute(self::getField($projectsElement, 'validtill', $projectProjects))); + + // Set the projects elements from the projects element attributes + $projectProjects->setAuthoriserInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'authoriser', 'inherit'))) + ->setAuthoriserLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'authoriser', 'locked'))) + ->setBillableForRatio(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'forratio'))) + ->setBillableInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'inherit'))) + ->setBillableLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'billable', 'locked'))) + ->setCustomerInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'customer', 'inherit'))) + ->setCustomerLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'customer', 'locked'))) + ->setRateInherit(Util::parseBoolean(self::getAttribute($projectsElement, 'rate', 'inherit'))) + ->setRateLocked(Util::parseBoolean(self::getAttribute($projectsElement, 'rate', 'locked'))); + + // Get the quantities element + $quantitiesDOMTag = $projectsElement->getElementsByTagName('quantities'); + + if (isset($quantitiesDOMTag) && $quantitiesDOMTag->length > 0) { + // Loop through each returned quantity for the project + foreach ($quantitiesDOMTag->item(0)->childNodes as $quantityElement) { + if ($quantityElement->nodeType !== 1) { + continue; + } + + // Make a new temporary ProjectQuantity class + $projectQuantity = new ProjectQuantity(); + + // Set the quantity elements from the quantity element + $projectQuantity->setBillable(Util::parseBoolean(self::getField($quantityElement, 'billable', $projectQuantity))) + ->setLabel(self::getField($quantityElement, 'label', $projectQuantity)) + ->setMandatory(Util::parseBoolean(self::getField($quantityElement, 'mandatory', $projectQuantity))) + ->setRate(self::parseObjectAttribute(\PhpTwinfield\Rate::class, $projectQuantity, $quantityElement, 'rate')); + + // Set the quantity elements from the quantity element attributes + $projectQuantity->setBillableLocked(Util::parseBoolean(self::getAttribute($quantityElement, 'billable', 'locked'))); + + // Add the quantity to the project + $projectProjects->addQuantity($projectQuantity); + + // Clean that memory! + unset ($projectQuantity); + } + } + + // Set the custom class to the project + $project->setProjects($projectProjects); + } + + // Return the complete object + return $project; + } +} diff --git a/src/Mappers/RateMapper.php b/src/Mappers/RateMapper.php new file mode 100644 index 00000000..29076596 --- /dev/null +++ b/src/Mappers/RateMapper.php @@ -0,0 +1,88 @@ + + */ +class RateMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean Rate entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return Rate + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new Rate object + $rate = new Rate(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/rate element + $rateElement = $responseDOM->documentElement; + + // Set the result and status attribute + $rate->setResult($rateElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $rateElement->getAttribute('status'))); + + // Set the rate elements from the rate element + $rate->setCode(self::getField($rateElement, 'code', $rate)) + ->setCreated(self::parseDateTimeAttribute(self::getField($rateElement, 'created', $rate))) + ->setCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $rate, $rateElement, 'currency', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setModified(self::parseDateTimeAttribute(self::getField($rateElement, 'modified', $rate))) + ->setName(self::getField($rateElement, 'name', $rate)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $rate, $rateElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($rateElement, 'shortname', $rate)) + ->setTouched(self::getField($rateElement, 'touched', $rate)) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\RateType::class, self::getField($rateElement, 'type', $rate))) + ->setUnit(self::getField($rateElement, 'unit', $rate)) + ->setUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $rate, $rateElement, 'user', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Get the ratechanges element + $ratechangesDOMTag = $responseDOM->getElementsByTagName('ratechanges'); + + if (isset($ratechangesDOMTag) && $ratechangesDOMTag->length > 0) { + // Loop through each returned ratechange for the rate + foreach ($ratechangesDOMTag->item(0)->childNodes as $ratechangeElement) { + if ($ratechangeElement->nodeType !== 1) { + continue; + } + + // Make a new temporary RateRateChange class + $rateRateChange = new RateRateChange(); + + $rateRateChange->setID($ratechangeElement->getAttribute('id')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $rateElement->getAttribute('status'))); + + // Set the project rate rate change elements from the ratechange element + $rateRateChange->setBeginDate(self::parseDateAttribute(self::getField($ratechangeElement, 'begindate', $rateRateChange))) + ->setEndDate(self::parseDateAttribute(self::getField($ratechangeElement, 'enddate', $rateRateChange))) + ->setExternalRate(self::getField($ratechangeElement, 'externalrate', $rateRateChange)) + ->setInternalRate(self::getField($ratechangeElement, 'internalrate', $rateRateChange)); + + // Add the rate change to the project rate + $rate->addRateChange($rateRateChange); + + // Clean that memory! + unset ($rateRateChange); + } + } + + // Return the complete object + return $rate; + } +} diff --git a/src/Mappers/SupplierMapper.php b/src/Mappers/SupplierMapper.php index 0078321b..5cf3f706 100644 --- a/src/Mappers/SupplierMapper.php +++ b/src/Mappers/SupplierMapper.php @@ -5,195 +5,292 @@ use PhpTwinfield\Supplier; use PhpTwinfield\SupplierAddress; use PhpTwinfield\SupplierBank; +use PhpTwinfield\SupplierChildValidation; +use PhpTwinfield\SupplierFinancials; +use PhpTwinfield\SupplierLine; +use PhpTwinfield\SupplierPostingRule; +use PhpTwinfield\Util; /** * Maps a response DOMDocument to the corresponding entity. - * + * * @package PhpTwinfield * @subpackage Mapper - * @author Leon Rowland + * @author Leon Rowland , extended by Yannick Aerssens * @copyright (c) 2013, Pronamic */ class SupplierMapper extends BaseMapper { /** * Maps a Response object to a clean Supplier entity. - * + * * @access public * @param \PhpTwinfield\Response\Response $response * @return Supplier + * @throws \PhpTwinfield\Exception */ public static function map(Response $response) { - // Generate new customer object + // Generate new Supplier object $supplier = new Supplier(); - + // Gets the raw DOMDocument response. $responseDOM = $response->getResponseDocument(); - // Set the status attribute - $dimensionElement = $responseDOM->getElementsByTagName('dimension')->item(0); - $supplier->setStatus($dimensionElement->getAttribute('status')); - - // Supplier elements and their methods - $supplierTags = array( - 'code' => 'setCode', - 'uid' => 'setUID', - 'name' => 'setName', - 'inuse' => 'setInUse', - 'behaviour' => 'setBehaviour', - 'touched' => 'setTouched', - 'beginperiod' => 'setBeginPeriod', - 'endperiod' => 'setEndPeriod', - 'endyear' => 'setEndYear', - 'website' => 'setWebsite', - 'editdimensionname' => 'setEditDimensionName', - 'office' => 'setOffice', - ); - - // Loop through all the tags - foreach ($supplierTags as $tag => $method) { - self::setFromTagValue($responseDOM, $tag, [$supplier, $method]); - } - - // Financial elements and their methods - $financialsTags = array( - 'duedays' => 'setDueDays', - 'payavailable' => 'setPayAvailable', - 'paycode' => 'setPayCode', - 'ebilling' => 'setEBilling', - 'ebillmail' => 'setEBillMail' - ); - - // Financial elements - $financialElement = $responseDOM->getElementsByTagName('financials')->item(0); - - if ($financialElement) { - // Go through each financial element and add to the assigned method - foreach ($financialsTags as $tag => $method) { - - // Get the dom element - $_tag = $financialElement->getElementsByTagName($tag)->item(0); - - // If it has a value, set it to the associated method - if (isset($_tag) && isset($_tag->textContent)) { - $value = $_tag->textContent; - if ($value == 'true' || $value == 'false') { - $value = $value == 'true'; + // Get the root/supplier element + $supplierElement = $responseDOM->documentElement; + + // Set the result and status attribute + $supplier->setResult($supplierElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $supplierElement->getAttribute('status'))); + + // Set the supplier elements from the supplier element + $supplier->setBeginPeriod(self::getField($supplierElement, 'beginperiod', $supplier)) + ->setBeginYear(self::getField($supplierElement, 'beginyear', $supplier)) + ->setBehaviour(self::parseEnumAttribute(\PhpTwinfield\Enums\Behaviour::class, self::getField($supplierElement, 'behaviour', $supplier))) + ->setCode(self::getField($supplierElement, 'code', $supplier)) + ->setEndPeriod(self::getField($supplierElement, 'endperiod', $supplier)) + ->setEndYear(self::getField($supplierElement, 'endyear', $supplier)) + ->setGroup(self::parseObjectAttribute(\PhpTwinfield\DimensionGroup::class, $supplier, $supplierElement, 'group', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setInUse(Util::parseBoolean(self::getField($supplierElement, 'name', $supplier))) + ->setName(self::getField($supplierElement, 'name', $supplier)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $supplier, $supplierElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setTouched(self::getField($supplierElement, 'touched', $supplier)) + ->setType(self::parseObjectAttribute(\PhpTwinfield\DimensionType::class, $supplier, $supplierElement, 'type', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setUID(self::getField($supplierElement, 'uid', $supplier)) + ->setWebsite(self::getField($supplierElement, 'website', $supplier)); + + // Get the financials element + $financialsElement = $responseDOM->getElementsByTagName('financials')->item(0); + + if ($financialsElement !== null) { + // Make a new temporary SupplierFinancials class + $supplierFinancials = new SupplierFinancials(); + + // Set the financials elements from the financials element + $supplierFinancials->setAccountType(self::parseEnumAttribute(\PhpTwinfield\Enums\AccountType::class, self::getField($financialsElement, 'accounttype', $supplierFinancials))) + ->setDueDays(self::getField($financialsElement, 'duedays', $supplierFinancials)) + ->setLevel(self::getField($financialsElement, 'level', $supplierFinancials)) + ->setMatchType(self::parseEnumAttribute(\PhpTwinfield\Enums\MatchType::class, self::getField($financialsElement, 'matchtype', $supplierFinancials))) + ->setMeansOfPayment(self::parseEnumAttribute(\PhpTwinfield\Enums\MeansOfPayment::class, self::getField($financialsElement, 'meansofpayment', $supplierFinancials))) + ->setPayAvailable(Util::parseBoolean(self::getField($financialsElement, 'payavailable', $supplierFinancials))) + ->setPayCode(self::parseObjectAttribute(\PhpTwinfield\PayCode::class, $supplierFinancials, $financialsElement, 'paycode', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setRelationsReference(self::getField($financialsElement, 'relationsreference', $supplierFinancials)) + ->setSubAnalyse(self::parseEnumAttribute(\PhpTwinfield\Enums\SubAnalyse::class, self::getField($financialsElement, 'subanalyse', $supplierFinancials))) + ->setSubstitutionLevel(self::getField($financialsElement, 'substitutionlevel', $supplierFinancials)) + ->setSubstituteWith(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $supplierFinancials, $financialsElement, 'substitutewith', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $supplierFinancials, $financialsElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + // Set the financials elements from the financials element attributes + $supplierFinancials->setPayCodeID(self::getAttribute($financialsElement, 'paycode', 'id')) + ->setSubstituteWithID(self::getAttribute($financialsElement, 'substitutewith', 'id')) + ->setVatCodeFixed(Util::parseBoolean(self::getAttribute($financialsElement, 'vatcode', 'fixed'))); + + // Get the childvalidations element + $childValidationsDOMTag = $financialsElement->getElementsByTagName('childvalidations'); + + if (isset($childValidationsDOMTag) && $childValidationsDOMTag->length > 0) { + // Loop through each returned childValidation for the supplier + foreach ($childValidationsDOMTag->item(0)->childNodes as $childValidationElement) { + if ($childValidationElement->nodeType !== 1) { + continue; } - $supplier->$method($value); + // Make a new temporary SupplierChildValidation class + $supplierChildValidation = new SupplierChildValidation(); + + // Set the child validation elements from the child validation element en element attributes + $supplierChildValidation->setLevel($childValidationElement->getAttribute('level')) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\ChildValidationType::class, $childValidationElement->getAttribute('type'))) + ->setElementValue($childValidationElement->textContent); + + // Add the child validation to the supplier financials class + $supplierFinancials->addChildValidation($supplierChildValidation); + + // Clean that memory! + unset ($supplierChildValidation); } } + + // Set the custom class to the supplier + $supplier->setFinancials($supplierFinancials); + } + + // Get the remittanceadvice element + $remittanceAdviceElement = $responseDOM->getElementsByTagName('remittanceadvice')->item(0); + + if ($remittanceAdviceElement !== null) { + // Set the supplier elements from the remittanceadvice element + $supplier->setRemittanceAdviceSendType(self::parseEnumAttribute(\PhpTwinfield\Enums\RemittanceAdviceSendType::class, self::getField($remittanceAdviceElement, 'sendtype', $supplier))) + ->setRemittanceAdviceSendMail(self::getField($remittanceAdviceElement, 'sendmail', $supplier)); } + // Get the addresses element $addressesDOMTag = $responseDOM->getElementsByTagName('addresses'); - if (isset($addressesDOMTag) && $addressesDOMTag->length > 0) { - // Element tags and their methods for address - $addressTags = array( - 'name' => 'setName', - 'contact' => 'setContact', - 'country' => 'setCountry', - 'city' => 'setCity', - 'postcode' => 'setPostcode', - 'telephone' => 'setTelephone', - 'telefax' => 'setFax', - 'email' => 'setEmail', - 'field1' => 'setField1', - 'field2' => 'setField2', - 'field3' => 'setField3', - 'field4' => 'setField4', - 'field5' => 'setField5', - 'field6' => 'setField6', - ); - - $addressesDOM = $addressesDOMTag->item(0); - - // Loop through each returned address for the customer - foreach ($addressesDOM->getElementsByTagName('address') as $addressDOM) { - - // Make a new tempory SupplierAddress class - $temp_address = new SupplierAddress(); - - // Set the attributes ( id, type, default ) - $temp_address - ->setID($addressDOM->getAttribute('id')) - ->setType($addressDOM->getAttribute('type')) - ->setDefault($addressDOM->getAttribute('default')); - - // Loop through the element tags. Determine if it exists and set it if it does - foreach ($addressTags as $tag => $method) { - - // Get the dom element - $_tag = $addressDOM->getElementsByTagName($tag)->item(0); - - // Check if the tag is set, and its content is set, to prevent DOMNode errors - if (isset($_tag) && isset($_tag->textContent)) { - $temp_address->$method($_tag->textContent); - } + if (isset($addressesDOMTag) && $addressesDOMTag->length > 0) { + // Loop through each returned address for the supplier + foreach ($addressesDOMTag->item(0)->childNodes as $addressElement) { + if ($addressElement->nodeType !== 1) { + continue; } - // Add the address to the customer - $supplier->addAddress($temp_address); + // Make a new temporary SupplierAddress class + $supplierAddress = new SupplierAddress(); + + // Set the default, id and type attribute + $supplierAddress->setDefault(Util::parseBoolean($addressElement->getAttribute('default'))) + ->setID($addressElement->getAttribute('id')) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\AddressType::class, $addressElement->getAttribute('type'))); + + // Set the address elements from the address element + $supplierAddress->setCity(self::getField($addressElement, 'city', $supplierAddress)) + ->setCountry(self::parseObjectAttribute(\PhpTwinfield\Country::class, $supplierAddress, $addressElement, 'country', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setEmail(self::getField($addressElement, 'email', $supplierAddress)) + ->setField1(self::getField($addressElement, 'field1', $supplierAddress)) + ->setField2(self::getField($addressElement, 'field2', $supplierAddress)) + ->setField3(self::getField($addressElement, 'field3', $supplierAddress)) + ->setField4(self::getField($addressElement, 'field4', $supplierAddress)) + ->setField5(self::getField($addressElement, 'field5', $supplierAddress)) + ->setField6(self::getField($addressElement, 'field6', $supplierAddress)) + ->setName(self::getField($addressElement, 'name', $supplierAddress)) + ->setPostcode(self::getField($addressElement, 'postcode', $supplierAddress)) + ->setTelephone(self::getField($addressElement, 'telephone', $supplierAddress)) + ->setTelefax(self::getField($addressElement, 'telefax', $supplierAddress)); + + // Add the address to the supplier + $supplier->addAddress($supplierAddress); // Clean that memory! - unset($temp_address); + unset ($supplierAddress); } } + // Get the banks element $banksDOMTag = $responseDOM->getElementsByTagName('banks'); + if (isset($banksDOMTag) && $banksDOMTag->length > 0) { + // Loop through each returned bank for the supplier + foreach ($banksDOMTag->item(0)->childNodes as $bankElement) { + if ($bankElement->nodeType !== 1) { + continue; + } + + // Make a new temporary SupplierBank class + $supplierBank = new SupplierBank(); + + // Set the default and id attribute + $supplierBank->setBlocked(Util::parseBoolean($bankElement->getAttribute('blocked'))) + ->setDefault(Util::parseBoolean($bankElement->getAttribute('default'))) + ->setID($bankElement->getAttribute('id')); + + // Set the bank elements from the bank element + $supplierBank->setAccountNumber(self::getField($bankElement, 'accountnumber', $supplierBank)) + ->setAddressField2(self::getField($bankElement, 'field2', $supplierBank)) + ->setAddressField3(self::getField($bankElement, 'field3', $supplierBank)) + ->setAscription(self::getField($bankElement, 'ascription', $supplierBank)) + ->setBankName(self::getField($bankElement, 'bankname', $supplierBank)) + ->setBicCode(self::getField($bankElement, 'biccode', $supplierBank)) + ->setCity(self::getField($bankElement, 'city', $supplierBank)) + ->setCountry(self::parseObjectAttribute(\PhpTwinfield\Country::class, $supplierBank, $bankElement, 'country', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setIban(self::getField($bankElement, 'iban', $supplierBank)) + ->setNatBicCode(self::getField($bankElement, 'natbiccode', $supplierBank)) + ->setPostcode(self::getField($bankElement, 'postcode', $supplierBank)) + ->setState(self::getField($bankElement, 'state', $supplierBank)); + + // Add the bank to the supplier + $supplier->addBank($supplierBank); + + // Clean that memory! + unset ($supplierBank); + } + } - // Element tags and their methods for bank - $bankTags = array( - 'ascription' => 'setAscription', - 'accountnumber' => 'setAccountnumber', - 'field2' => 'setAddressField2', - 'field3' => 'setAddressField3', - 'bankname' => 'setBankname', - 'biccode' => 'setBiccode', - 'city' => 'setCity', - 'country' => 'setCountry', - 'iban' => 'setIban', - 'natbiccode' => 'setNatbiccode', - 'postcode' => 'setPostcode', - 'state' => 'setState' - ); - - $banksDOM = $banksDOMTag->item(0); - - // Loop through each returned bank for the customer - foreach ($banksDOM->getElementsByTagName('bank') as $bankDOM) { - - // Make a new tempory SupplierBank class - $temp_bank = new SupplierBank(); - - // Set the attributes ( id, default ) - $temp_bank - ->setID($bankDOM->getAttribute('id')) - ->setDefault($bankDOM->getAttribute('default')); - - // Loop through the element tags. Determine if it exists and set it if it does - foreach ($bankTags as $tag => $method) { - - // Get the dom element - $_tag = $bankDOM->getElementsByTagName($tag)->item(0); - - // Check if the tag is set, and its content is set, to prevent DOMNode errors - if (isset($_tag) && isset($_tag->textContent)) { - $temp_bank->$method($_tag->textContent); + // Get the postingrules element + $postingrulesDOMTag = $responseDOM->getElementsByTagName('postingrules'); + + if (isset($postingrulesDOMTag) && $postingrulesDOMTag->length > 0) { + // Loop through each returned postingrule for the supplier + foreach ($postingrulesDOMTag->item(0)->childNodes as $postingruleElement) { + if ($postingruleElement->nodeType !== 1) { + continue; + } + + // Make a new temporary SupplierPostingRule class + $supplierPostingRule = new SupplierPostingRule(); + + // Set the id and status attribute + $supplierPostingRule->setID($postingruleElement->getAttribute('id')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $postingruleElement->getAttribute('status'))); + + // Set the postingrule elements from the postingrule element + $supplierPostingRule->setCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $supplierPostingRule, $postingruleElement, 'currency', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setDescription(self::getField($postingruleElement, 'description', $supplierPostingRule)); + + $supplierPostingRule->setAmount(self::parseMoneyAttribute(self::getField($postingruleElement, 'amount', $supplierPostingRule), Util::objectToStr($supplierPostingRule->getCurrency()))); + + // Get the lines element + $linesDOMTag = $postingruleElement->getElementsByTagName('lines'); + + if (isset($linesDOMTag) && $linesDOMTag->length > 0) { + // Loop through each returned line for the posting rule + foreach ($linesDOMTag->item(0)->childNodes as $lineElement) { + if ($lineElement->nodeType !== 1) { + continue; + } + + // Make a new temporary SupplierLine class + $supplierLine = new SupplierLine(); + + // Set the line elements from the line element + $supplierLine->setDescription(self::getField($lineElement, 'description', $supplierLine)) + ->setDimension1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $supplierLine, $lineElement, 'dimension1', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDimension2(self::parseObjectAttribute(\PhpTwinfield\CostCenter::class, $supplierLine, $lineElement, 'dimension2', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setDimension3(self::parseObjectAttribute(null, $supplierLine, $lineElement, 'dimension3', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $supplierLine, $lineElement, 'office', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setRatio(self::getField($lineElement, 'ratio', $supplierLine)) + ->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $supplierLine, $lineElement, 'vatcode', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + // Set the line elements from the line element attributes + $supplierLine->setDimension1ID(self::getAttribute($lineElement, 'dimension1', 'id')) + ->setDimension2ID(self::getAttribute($lineElement, 'dimension2', 'id')) + ->setDimension3ID(self::getAttribute($lineElement, 'dimension2', 'id')); + + // Add the line to the supplier posting rule + $supplierPostingRule->addLine($supplierLine); + + // Clean that memory! + unset ($supplierLine); } } - // Add the bank to the customer - $supplier->addBank($temp_bank); + // Add the postingrule to the supplier + $supplier->addPostingRule($supplierPostingRule); // Clean that memory! - unset($temp_bank); + unset ($supplierPostingRule); } } + // Get the paymentconditions element + $paymentConditionsElement = $responseDOM->getElementsByTagName('paymentconditions')->item(0); + + if ($paymentConditionsElement !== null) { + // Set the supplier elements from the paymentconditions element + $supplier->setPaymentConditionDiscountDays(self::getField($paymentConditionsElement, 'discountdays', $supplier)) + ->setPaymentConditionDiscountPercentage(self::getField($paymentConditionsElement, 'discountpercentage', $supplier)); + } + + // Get the blockedaccountpaymentconditions element + $blockedAccountPaymentConditionsElement = $responseDOM->getElementsByTagName('blockedaccountpaymentconditions')->item(0); + + if ($blockedAccountPaymentConditionsElement !== null) { + // Set the supplier elements from the blockedaccountpaymentconditions element + $supplier->setBlockedAccountPaymentConditionsIncludeVat(self::parseEnumAttribute(\PhpTwinfield\Enums\BlockedAccountPaymentConditionsIncludeVat::class, self::getField($blockedAccountPaymentConditionsElement, 'includevat', $supplier))) + ->setBlockedAccountPaymentConditionsPercentage(self::getField($blockedAccountPaymentConditionsElement, 'percentage', $supplier)); + } + + // Return the complete object return $supplier; } } diff --git a/src/Mappers/TransactionMapper.php b/src/Mappers/TransactionMapper.php index cd928ae5..af97f32e 100644 --- a/src/Mappers/TransactionMapper.php +++ b/src/Mappers/TransactionMapper.php @@ -2,48 +2,58 @@ namespace PhpTwinfield\Mappers; -use Money\Currency; -use Money\Money; +use PhpTwinfield\BankTransaction; use PhpTwinfield\BaseTransaction; -use PhpTwinfield\BaseTransactionLine; use PhpTwinfield\CashTransaction; -use PhpTwinfield\Enums\DebitCredit; -use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Enums\PerformanceType; use PhpTwinfield\Exception; +use PhpTwinfield\Fields\DueDateField; +use PhpTwinfield\Fields\FreeText1Field; +use PhpTwinfield\Fields\FreeText2Field; +use PhpTwinfield\Fields\FreeText3Field; +use PhpTwinfield\Fields\InvoiceNumberField; +use PhpTwinfield\Fields\PerformanceDateField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\Transaction\CloseAndStartValueFields; +use PhpTwinfield\Fields\Transaction\OriginReferenceField; +use PhpTwinfield\Fields\Transaction\PaymentReferenceField; +use PhpTwinfield\Fields\Transaction\RegimeField; +use PhpTwinfield\Fields\Transaction\StatementNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaselineField; +use PhpTwinfield\Fields\Transaction\TransactionLine\CurrencyDateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\MatchDateField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceCountryField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceVatNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueOpenField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatTotalField; use PhpTwinfield\JournalTransaction; use PhpTwinfield\Message\Message; -use PhpTwinfield\Office; -use PhpTwinfield\Response\Response; +use PhpTwinfield\PurchaseTransaction; use PhpTwinfield\SalesTransaction; -use PhpTwinfield\Transactions\TransactionFields\DueDateField; -use PhpTwinfield\Transactions\TransactionFields\FreeTextFields; -use PhpTwinfield\Transactions\TransactionFields\InvoiceNumberField; -use PhpTwinfield\Transactions\TransactionFields\PaymentReferenceField; -use PhpTwinfield\Transactions\TransactionFields\StatementNumberField; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; -use PhpTwinfield\Transactions\TransactionLineFields\ValueOpenField; -use PhpTwinfield\Transactions\TransactionLineFields\VatTotalFields; +use PhpTwinfield\Secure\AuthenticatedConnection; +use PhpTwinfield\Response\Response; use PhpTwinfield\Util; -class TransactionMapper +class TransactionMapper extends BaseMapper { /** * @param string $transactionClassName * @param Response $response + * @param AuthenticatedConnection $connection * * @return iterable|BaseTransaction[] * @throws Exception */ - public static function mapAll(string $transactionClassName, Response $response): iterable + public static function mapAll(string $transactionClassName, Response $response, AuthenticatedConnection $connection): iterable { foreach ($response->getResponseDocument()->getElementsByTagName('transaction') as $transactionElement) { - yield self::map($transactionClassName, $transactionElement); + yield self::map($transactionClassName, $transactionElement, $connection); } } - public static function map(string $transactionClassName, Response $response): BaseTransaction + public static function map(string $transactionClassName, Response $response, AuthenticatedConnection $connection): BaseTransaction { if (!is_a($transactionClassName, BaseTransaction::class, true)) { throw Exception::invalidTransactionClassName($transactionClassName); @@ -52,212 +62,222 @@ public static function map(string $transactionClassName, Response $response): Ba $document = $response->getResponseDocument(); $transactionElement = $document->documentElement; - /** @var BaseTransaction $transaction */ $transaction = new $transactionClassName(); $transaction->setResult($transactionElement->getAttribute('result')); + $autoBalanceVat = $transactionElement->getAttribute('autobalancevat'); + + if (!empty($autoBalanceVat)) { + $transaction->setAutoBalanceVat(Util::parseBoolean($autoBalanceVat)); + } + $destiny = $transactionElement->getAttribute('location'); + if (empty($destiny)) { - /* - * This field should be sent to Twinfield as 'destiny' attribute and Twinfield should return it as - * 'location' attribute. But in case of an error elsewhere in this object, Twinfield returns this field as - * 'destiny' attibute. - */ $destiny = $transactionElement->getAttribute('destiny'); } - if (!empty($destiny)) { - $transaction->setDestiny(new Destiny($destiny)); - } - $autoBalanceVat = $transactionElement->getAttribute('autobalancevat'); - if (!empty($autoBalanceVat)) { - $transaction->setAutoBalanceVat($autoBalanceVat == 'true'); + if (!empty($destiny)) { + $transaction->setDestiny(self::parseEnumAttribute(\PhpTwinfield\Enums\Destiny::class, $destiny)); } $raiseWarning = $transactionElement->getAttribute('raisewarning'); + if (!empty($raiseWarning)) { $transaction->setRaiseWarning(Util::parseBoolean($raiseWarning)); } - $office = new Office(); - $office->setCode(self::getField($transaction, $transactionElement, 'office')); - - $transaction - ->setOffice($office) - ->setCode(self::getField($transaction, $transactionElement, 'code')) - ->setPeriod(self::getField($transaction, $transactionElement, 'period')) - ->setDateFromString(self::getField($transaction, $transactionElement, 'date')) - ->setOrigin(self::getField($transaction, $transactionElement, 'origin')) - ->setFreetext1(self::getField($transaction, $transactionElement, 'freetext1')) - ->setFreetext2(self::getField($transaction, $transactionElement, 'freetext2')) - ->setFreetext3(self::getField($transaction, $transactionElement, 'freetext3')); - - $currency = self::getField($transaction, $transactionElement, 'currency'); - if (!empty($currency)) { - $transaction->setCurrency(new Currency($currency)); + $transaction->setCode(self::getField($transactionElement, 'code', $transaction)) + ->setCurrency(self::parseObjectAttribute(\PhpTwinfield\Currency::class, $transaction, $transactionElement, 'currency')) + ->setDate(self::parseDateAttribute(self::getField($transactionElement, 'date', $transaction))) + ->setFreeText1(self::getField($transactionElement, 'freetext1', $transaction)) + ->setFreeText2(self::getField($transactionElement, 'freetext2', $transaction)) + ->setFreeText3(self::getField($transactionElement, 'freetext3', $transaction)) + ->setOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $transaction, $transactionElement, 'office')) + ->setOrigin(self::getField($transactionElement, 'origin', $transaction)) + ->setNumber(self::getField($transactionElement, 'number', $transaction)) + ->setPeriod(self::getField($transactionElement, 'period', $transaction)); + + if ($transaction->getOffice() !== null) { + $currencies = self::getOfficeCurrencies($connection, $transaction->getOffice()); } - $number = self::getField($transaction, $transactionElement, 'number'); - if (!empty($number)) { - $transaction->setNumber($number); + if (Util::objectUses(CloseAndStartValueFields::class, $transaction)) { + $transaction->setStartValue(self::parseMoneyAttribute(self::getField($transactionElement, 'startvalue', $transaction), Util::objectToStr($transaction->getCurrency()))); } if (Util::objectUses(DueDateField::class, $transaction)) { - $transaction->setDueDateFromString(self::getField($transaction, $transactionElement, 'duedate')); + $transaction->setDueDate(self::parseDateAttribute(self::getField($transactionElement, 'duedate', $transaction))); } + if (Util::objectUses(InvoiceNumberField::class, $transaction)) { - $transaction->setInvoiceNumber(self::getField($transaction, $transactionElement, 'invoicenumber')); - } - if (Util::objectUses(PaymentReferenceField::class, $transaction)) { - $transaction - ->setPaymentReference(self::getField($transaction, $transactionElement, 'paymentreference')); + $transaction->setInvoiceNumber(self::getField($transactionElement, 'invoicenumber', $transaction)); + $transaction->setInvoiceNumberRaiseWarning(Util::parseBoolean(self::getAttribute($transactionElement, 'invoicenumber', 'raisewarning'))); } - if (Util::objectUses(StatementNumberField::class, $transaction)) { - $transaction->setStatementnumber(self::getField($transaction, $transactionElement, 'statementnumber')); + + if (Util::objectUses(OriginReferenceField::class, $transaction)) { + $transaction->setOriginReference(self::getField($transactionElement, 'originreference', $transaction)); } - if ($transaction instanceof SalesTransaction) { - $transaction->setOriginReference(self::getField($transaction, $transactionElement, 'originreference')); + if (Util::objectUses(PaymentReferenceField::class, $transaction)) { + $transaction->setPaymentReference(self::getField($transactionElement, 'paymentreference', $transaction)); } - if ($transaction instanceof JournalTransaction) { - $transaction->setRegime(self::getField($transaction, $transactionElement, 'regime')); + + if (Util::objectUses(RegimeField::class, $transaction)) { + $transaction->setRegime(self::parseEnumAttribute(\PhpTwinfield\Enums\Regime::class, self::getField($transactionElement, 'regime', $transaction))); } - if ($transaction instanceof CashTransaction) { - $transaction->setStartvalue( - Util::parseMoney( - self::getField($transaction, $transactionElement, 'startvalue'), - $transaction->getCurrency() - ) - ); + + if (Util::objectUses(StatementNumberField::class, $transaction)) { + $transaction->setStatementnumber(self::getField($transactionElement, 'statementnumber', $transaction)); } // Parse the transaction lines $transactionLineClassName = $transaction->getLineClassName(); - foreach ($transactionElement->getElementsByTagName('line') as $lineElement) { - self::checkForMessage($transaction, $lineElement); - - /** @var BaseTransactionLine $transactionLine */ - $transactionLine = new $transactionLineClassName(); - $lineType = $lineElement->getAttribute('type'); - - $transactionLine - ->setLineType(new LineType($lineType)) - ->setId($lineElement->getAttribute('id')) - ->setDim1(self::getField($transaction, $lineElement, 'dim1')) - ->setDim2(self::getField($transaction, $lineElement, 'dim2')) - ->setValue(Money::EUR(100 * self::getField($transaction, $lineElement, 'value'))) - ->setDebitCredit(new DebitCredit(self::getField($transaction, $lineElement, 'debitcredit'))) - ->setBaseValue(Money::EUR(100 * self::getField($transaction, $lineElement, 'basevalue'))) - ->setRate(self::getField($transaction, $lineElement, 'rate')) - ->setRepValue(Money::EUR(100 * self::getField($transaction, $lineElement, 'repvalue'))) - ->setRepRate(self::getField($transaction, $lineElement, 'reprate')) - ->setDescription(self::getField($transaction, $lineElement, 'description')) - ->setMatchStatus(self::getField($transaction, $lineElement, 'matchstatus')) - ->setMatchLevel(self::getField($transaction, $lineElement, 'matchlevel')) - ->setVatCode(self::getField($transaction, $lineElement, 'vatcode')); - - // TODO - according to the docs, the field is called , but the examples use . - $baseValueOpen = self::getField($transaction, $lineElement, 'basevalueopen') ?: self::getField($transaction, $lineElement, 'openbasevalue'); - if ($baseValueOpen) { - $transactionLine->setBaseValueOpen(Money::EUR(100 * $baseValueOpen)); - } - - $vatValue = self::getField($transaction, $lineElement, 'vatvalue'); - if ($lineType == LineType::DETAIL() && $vatValue) { - $transactionLine->setVatValue(Money::EUR(100 * $vatValue)); - } + $linesDOMTag = $transactionElement->getElementsByTagName('lines'); - $baseline = self::getField($transaction, $lineElement, 'baseline'); - if ($baseline) { - $transactionLine->setBaseline($baseline); - } + if (isset($linesDOMTag) && $linesDOMTag->length > 0) { + $linesDOM = $linesDOMTag->item(0); - if (Util::objectUses(FreeTextFields::class, $transactionLine)) { - $freetext1 = self::getField($transaction, $lineElement, 'freetext1'); - if ($freetext1) { - $transactionLine->setFreetext1($freetext1); + foreach ($linesDOM->childNodes as $lineElement) { + if ($lineElement->nodeType !== 1) { + continue; } - $freetext2 = self::getField($transaction, $lineElement, 'freetext2'); - if ($freetext2) { - $transactionLine->setFreetext2($freetext2); - } + self::checkForMessage($transaction, $lineElement); - $freetext3 = self::getField($transaction, $lineElement, 'freetext3'); - if ($freetext3) { - $transactionLine->setFreetext3($freetext3); - } - } + $transactionLine = new $transactionLineClassName(); + $lineType = $lineElement->getAttribute('type'); + + $transactionLine->setLineType(self::parseEnumAttribute(\PhpTwinfield\Enums\LineType::class, $lineType)); - if (Util::objectUses(PerformanceFields::class, $transactionLine)) { - /** @var BaseTransactionLine|PerformanceFields $transactionLine */ - $performanceType = self::getField($transaction, $lineElement, 'performancetype'); $transactionLine - ->setPerformanceType($performanceType ? new PerformanceType($performanceType) : null) - ->setPerformanceCountry(self::getField($transaction, $lineElement, 'performancecountry')) - ->setPerformanceVatNumber(self::getField($transaction, $lineElement, 'performancevatnumber')); + ->setBaseValue(self::parseMoneyAttribute(self::getField($lineElement, 'basevalue', $transactionLine), $currencies['base'])) + ->setComment(self::getField($lineElement, 'comment', $transactionLine)) + ->setValue(self::parseMoneyAttribute(self::getField($lineElement, 'value', $transactionLine), Util::objectToStr($transaction->getCurrency()))) + ->setDebitCredit(self::parseEnumAttribute(\PhpTwinfield\Enums\DebitCredit::class, self::getField($lineElement, 'debitcredit', $transactionLine))) + ->setDescription(self::getField($lineElement, 'description', $transactionLine)) + ->setDestOffice(self::parseObjectAttribute(\PhpTwinfield\Office::class, $transactionLine, $lineElement, 'destoffice')) + ->setDim1(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim1', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))) + ->setId($lineElement->getAttribute('id')) + ->setMatchStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\MatchStatus::class, self::getField($lineElement, 'matchstatus', $transactionLine))) + ->setRate(self::getField($lineElement, 'rate', $transactionLine)) + ->setRepRate(self::getField($lineElement, 'reprate', $transactionLine)) + ->setRepValue(self::parseMoneyAttribute(self::getField($lineElement, 'repvalue', $transactionLine), $currencies['reporting'])); + + $freeChar = self::getField($lineElement, 'freechar', $transactionLine); + + if ($freeChar !== null && strlen($freeChar) == 1) { + $transactionLine->setFreeChar($freeChar); + } - $performanceDate = self::getField($transaction, $lineElement, 'performancedate'); + if ($transaction instanceof BankTransaction || $transaction instanceof CashTransaction || $transaction instanceof JournalTransaction) { + if ($lineType == LineType::DETAIL()) { + $baseValueOpen = self::getField($lineElement, 'basevalueopen', $transactionLine) ?: self::getField($lineElement, 'openbasevalue', $transactionLine); - if ($performanceDate) { - $transactionLine->setPerformanceDate(Util::parseDate($performanceDate)); - } - } - if (in_array(ValueOpenField::class, class_uses($transactionLine))) { - // TODO - according to the docs, the field is called , but the examples use . - $valueOpen = self::getField($transaction, $lineElement, 'valueopen') ?: self::getField($transaction, $lineElement, 'openvalue'); - if ($valueOpen) { - $transactionLine->setValueOpen(Money::EUR(100 * $valueOpen)); - } - } - if (in_array(VatTotalFields::class, class_uses($transactionLine))) { - $vatTotal = self::getField($transaction, $lineElement, 'vattotal'); - if ($vatTotal) { - $transactionLine->setVatTotal(Money::EUR(100 * $vatTotal)); - } + if ($baseValueOpen) { + $transactionLine->setBaseValueOpen(self::parseMoneyAttribute($baseValueOpen, $currencies['base'])); + } - $vatBaseTotal = self::getField($transaction, $lineElement, 'vatbasetotal'); - if ($vatBaseTotal) { - $transactionLine->setVatBaseTotal(Money::EUR(100 * $vatBaseTotal)); + $transactionLine->setDim2(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim2', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + $transactionLine->setDim3(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim3', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + $transactionLine->setMatchLevel(self::getField($lineElement, 'matchlevel', $transactionLine)); + $transactionLine->setRelation(self::getField($lineElement, 'relation', $transactionLine)); + $transactionLine->setRepValueOpen(self::parseMoneyAttribute(self::getField($lineElement, 'repvalueopen', $transactionLine), $currencies['reporting'])); + } } - } - if (Util::objectUses(InvoiceNumberField::class, $transactionLine)) { - /** @var InvoiceNumberField $transactionLine */ - $invoiceNumber = self::getField($transaction, $lineElement, 'invoicenumber'); - if ($invoiceNumber) { - $transactionLine->setInvoiceNumber(self::getField($transaction, $lineElement, 'invoicenumber')); - } - } - $transaction->addLine($transactionLine); - } + if ($transaction instanceof PurchaseTransaction || $transaction instanceof SalesTransaction) { + if ($lineType == LineType::DETAIL()) { + $transactionLine->setDim2(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim2', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + $transactionLine->setDim3(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim3', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + } elseif ($transaction instanceof PurchaseTransaction && $lineType == LineType::VAT()) { + $transactionLine->setDim3(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim3', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + } elseif ($lineType == LineType::TOTAL()) { + $transactionLine->setDim2(self::parseObjectAttribute(null, $transactionLine, $lineElement, 'dim2', array('name' => 'setName', 'shortname' => 'setShortName', 'type' => 'setTypeFromString'))); + + $baseValueOpen = self::getField($lineElement, 'basevalueopen', $transactionLine) ?: self::getField($lineElement, 'openbasevalue', $transactionLine); + + if ($baseValueOpen) { + $transactionLine->setBaseValueOpen(self::parseMoneyAttribute($baseValueOpen, $currencies['base'])); + } + + $transactionLine->setMatchLevel(self::getField($lineElement, 'matchlevel', $transactionLine)); + $transactionLine->setRelation(self::getField($lineElement, 'relation', $transactionLine)); + $transactionLine->setRepValueOpen(self::parseMoneyAttribute(self::getField($lineElement, 'repvalueopen', $transactionLine), $currencies['reporting'])); + } + } - return $transaction; - } + if ($lineType == LineType::DETAIL()) { + if (Util::objectUses(CurrencyDateField::class, $transactionLine)) { + $transactionLine->setCurrencyDate(self::parseDateAttribute(self::getField($lineElement, 'currencydate', $transactionLine))); + } + + if (Util::objectUses(InvoiceNumberField::class, $transactionLine)) { + $transactionLine->setInvoiceNumber(self::getField($lineElement, 'invoicenumber', $transactionLine)); + } + + $transactionLine->setVatBaseValue(self::parseMoneyAttribute(self::getField($lineElement, 'vatbasevalue', $transactionLine), $currencies['base'])); + $transactionLine->setVatRepValue(self::parseMoneyAttribute(self::getField($lineElement, 'vatrepvalue', $transactionLine), $currencies['reporting'])); + $transactionLine->setVatValue(self::parseMoneyAttribute(self::getField($lineElement, 'vatvalue', $transactionLine), Util::objectToStr($transaction->getCurrency()))); + } elseif ($lineType == LineType::VAT()) { + if (Util::objectUses(BaselineField::class, $transactionLine)) { + $transactionLine->setBaseline(self::getField($lineElement, 'baseline', $transactionLine)); + } + + $transactionLine->setVatBaseTurnover(self::parseMoneyAttribute(self::getField($lineElement, 'vatbaseturnover', $transactionLine), $currencies['base'])); + $transactionLine->setVatRepTurnover(self::parseMoneyAttribute(self::getField($lineElement, 'vatrepturnover', $transactionLine), $currencies['reporting'])); + $transactionLine->setVatTurnover(self::parseMoneyAttribute(self::getField($lineElement, 'vatturnover', $transactionLine), Util::objectToStr($transaction->getCurrency()))); + } elseif ($lineType == LineType::TOTAL()) { + if (Util::objectUses(MatchDateField::class, $transactionLine)) { + $transactionLine->setMatchDate(self::parseDateAttribute(self::getField($lineElement, 'matchdate', $transactionLine))); + } + + if (Util::objectUses(ValueOpenField::class, $transactionLine)) { + $valueOpen = self::getField($lineElement, 'valueopen', $transactionLine) ?: self::getField($lineElement, 'openvalue', $transactionLine); + + if ($valueOpen) { + $transactionLine->setValueOpen(self::parseMoneyAttribute($valueOpen, Util::objectToStr($transaction->getCurrency()))); + } + } + + if (Util::objectUses(VatBaseTotalField::class, $transactionLine)) { + $transactionLine->setVatBaseTotal(self::parseMoneyAttribute(self::getField($lineElement, 'vatbasetotal', $transactionLine), $currencies['base'])); + } + + if (Util::objectUses(VatRepTotalField::class, $transactionLine)) { + $transactionLine->setVatRepTotal(self::parseMoneyAttribute(self::getField($lineElement, 'vatreptotal', $transactionLine), $currencies['reporting'])); + } + + if (Util::objectUses(VatTotalField::class, $transactionLine)) { + $transactionLine->setVatTotal(self::parseMoneyAttribute(self::getField($lineElement, 'vattotal', $transactionLine), Util::objectToStr($transaction->getCurrency()))); + } + } - private static function getField(BaseTransaction $transaction, \DOMElement $element, string $fieldTagName): ?string - { - $fieldElement = $element->getElementsByTagName($fieldTagName)->item(0); + if ($lineType != LineType::TOTAL()) { + if (Util::objectUses(PerformanceCountryField::class, $transactionLine)) { + $transactionLine->setPerformanceCountry(self::parseObjectAttribute(\PhpTwinfield\Country::class, $transactionLine, $lineElement, 'performancecountry')); + } - if (!isset($fieldElement)) { - return null; - } + if (Util::objectUses(PerformanceDateField::class, $transactionLine)) { + $transactionLine->setPerformanceDate(self::parseDateAttribute(self::getField($lineElement, 'performancedate', $transactionLine))); + } - self::checkForMessage($transaction, $fieldElement); + if (Util::objectUses(PerformanceTypeField::class, $transactionLine)) { + $transactionLine->setPerformanceType(self::parseEnumAttribute(\PhpTwinfield\Enums\PerformanceType::class, self::getField($lineElement, 'performancetype', $transactionLine))); + } - return $fieldElement->textContent; - } + if (Util::objectUses(PerformanceVatNumberField::class, $transactionLine)) { + $transactionLine->setPerformanceVatNumber(self::getField($lineElement, 'performancevatnumber', $transactionLine)); + } - private static function checkForMessage(BaseTransaction $transaction, \DOMElement $element): void - { - if ($element->hasAttribute('msg')) { - $message = new Message(); - $message->setType($element->getAttribute('msgtype')); - $message->setMessage($element->getAttribute('msg')); - $message->setField($element->nodeName); + $transactionLine->setVatCode(self::parseObjectAttribute(\PhpTwinfield\VatCode::class, $transactionLine, $lineElement, 'vatcode')); + } - $transaction->addMessage($message); + $transaction->addLine($transactionLine); + } } + + return $transaction; } } diff --git a/src/Mappers/UserMapper.php b/src/Mappers/UserMapper.php new file mode 100644 index 00000000..e005b879 --- /dev/null +++ b/src/Mappers/UserMapper.php @@ -0,0 +1,74 @@ + + */ +class UserMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean User entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return User + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new User object + $user = new User(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/user element + $userElement = $responseDOM->documentElement; + + // Set the iscurrentuser, level, result and status attribute + $user->setIsCurrentUser(Util::parseBoolean($userElement->getAttribute('iscurrentuser'))); + $user->setLevel($userElement->getAttribute('level')); + $user->setResult($userElement->getAttribute('result')); + $user->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $userElement->getAttribute('status'))); + + // Set the user elements from the user element + $user->setAcceptExtraCost(Util::parseBoolean(self::getField($userElement, 'acceptextracost', $user))) + ->setCulture(self::parseEnumAttribute(\PhpTwinfield\Enums\Culture::class, self::getField($userElement, 'culture', $user))) + ->setCode(self::getField($userElement, 'code', $user)) + ->setCreated(self::parseDateTimeAttribute(self::getField($userElement, 'created', $user))) + ->setDemo(Util::parseBoolean(self::getField($userElement, 'demo', $user))) + ->setEmail(self::getField($userElement, 'email', $user)) + ->setExchangeQuota(self::getField($userElement, 'exchangequota', $user)) + ->setFileManagerQuota(self::getField($userElement, 'filemanagerquota', $user)) + ->setModified(self::parseDateTimeAttribute(self::getField($userElement, 'modified', $user))) + ->setName(self::getField($userElement, 'name', $user)) + ->setRole(self::parseObjectAttribute(\PhpTwinfield\UserRole::class, $user, $userElement, 'method', array('level' => 'setLevel', 'name' => 'setName', 'shortname' => 'setShortName'))) + ->setShortName(self::getField($userElement, 'shortname', $user)) + ->setTouched(self::getField($userElement, 'touched', $user)) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\UserType::class, self::getField($userElement, 'type', $user))); + + // Set the user elements from the user element attributes + $user->setCultureName(self::getAttribute($userElement, 'culture', 'name')) + ->setCultureNativeName(self::getAttribute($userElement, 'culture', 'nativename')) + ->setDemoLocked(self::getAttribute($userElement, 'demo', 'locked')) + ->setExchangeQuotaLocked(self::getAttribute($userElement, 'exchangequota', 'locked')) + ->setFileManagerQuotaLocked(self::getAttribute($userElement, 'filemanagerquota', 'locked')) + ->setRoleLocked(self::getAttribute($userElement, 'role', 'locked')) + ->setTypeLocked(self::getAttribute($userElement, 'type', 'locked')); + + // Return the complete object + return $user; + } +} diff --git a/src/Mappers/UserRoleMapper.php b/src/Mappers/UserRoleMapper.php new file mode 100644 index 00000000..a2d4aa9d --- /dev/null +++ b/src/Mappers/UserRoleMapper.php @@ -0,0 +1,45 @@ + + */ +class UserRoleMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean UserRole entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return UserRole + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new UserRole object + $userRole = new UserRole(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/user role element + $userRoleElement = $responseDOM->documentElement; + + // Set the user role elements from the user role element + $userRole->setCode(self::getField($userRoleElement, 'code', $userRole)) + ->setName(self::getField($userRoleElement, 'name', $userRole)) + ->setShortName(self::getField($userRoleElement, 'shortname', $userRole)); + + // Return the complete object + return $userRole; + } +} diff --git a/src/Mappers/VatCodeMapper.php b/src/Mappers/VatCodeMapper.php new file mode 100644 index 00000000..0feb4785 --- /dev/null +++ b/src/Mappers/VatCodeMapper.php @@ -0,0 +1,127 @@ + + */ +class VatCodeMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean VatCode entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return VatCode + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new VatCode object + $vatCode = new VatCode(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/vat element + $vatCodeElement = $responseDOM->documentElement; + + // Set the result and status attribute + $vatCode->setResult($vatCodeElement->getAttribute('result')) + ->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $vatCodeElement->getAttribute('status'))); + + // Set the vat code elements from the vat element + $vatCode->setCode(self::getField($vatCodeElement, 'code', $vatCode)) + ->setCreated(self::parseDateTimeAttribute(self::getField($vatCodeElement, 'created', $vatCode))) + ->setModified(self::parseDateTimeAttribute(self::getField($vatCodeElement, 'modified', $vatCode))) + ->setName(self::getField($vatCodeElement, 'name', $vatCode)) + ->setShortName(self::getField($vatCodeElement, 'shortname', $vatCode)) + ->setTouched(self::getField($vatCodeElement, 'touched', $vatCode)) + ->setType(self::parseEnumAttribute(\PhpTwinfield\Enums\VatType::class, self::getField($vatCodeElement, 'type', $vatCode))) + ->setUID(self::getField($vatCodeElement, 'uid', $vatCode)) + ->setUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $vatCode, $vatCodeElement, 'user', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Get the percentages element + $percentagesDOMTag = $responseDOM->getElementsByTagName('percentages'); + + if (isset($percentagesDOMTag) && $percentagesDOMTag->length > 0) { + // Loop through each returned percentage for the vatcode + foreach ($percentagesDOMTag->item(0)->childNodes as $percentageElement) { + if ($percentageElement->nodeType !== 1) { + continue; + } + + // Make a new temporary VatCodePercentage class + $vatCodePercentage = new VatCodePercentage(); + + if (!empty($percentageElement->getAttribute('inuse'))) { + $vatCodePercentage->setInUse($percentageElement->getAttribute('inuse')); + } + + if (!empty($percentageElement->getAttribute('status'))) { + $vatCodePercentage->setStatus(self::parseEnumAttribute(\PhpTwinfield\Enums\Status::class, $percentageElement->getAttribute('status'))); + } + + // Set the vat code percentage elements from the percentage element + $vatCodePercentage->setCreated(self::parseDateTimeAttribute(self::getField($percentageElement, 'created', $vatCodePercentage))) + ->setDate(self::parseDateAttribute(self::getField($percentageElement, 'date', $vatCodePercentage))) + ->setName(self::getField($percentageElement, 'name', $vatCodePercentage)) + ->setPercentage(self::getField($percentageElement, 'percentage', $vatCodePercentage)) + ->setShortName(self::getField($percentageElement, 'shortname', $vatCodePercentage)) + ->setUser(self::parseObjectAttribute(\PhpTwinfield\User::class, $vatCodePercentage, $percentageElement, 'user', array('name' => 'setName', 'shortname' => 'setShortName'))); + + // Get the accounts element + $accountsDOMTag = $percentageElement->getElementsByTagName('accounts'); + + if (isset($accountsDOMTag) && $accountsDOMTag->length > 0) { + // Loop through each returned account for the percentage + foreach ($accountsDOMTag->item(0)->childNodes as $accountElement) { + if ($accountElement->nodeType !== 1) { + continue; + } + + // Make a new temporary VatCodeAccount class + $vatCodeAccount = new VatCodeAccount(); + + // Set the ID attribute + if (!empty($accountElement->getAttribute('id'))) { + $vatCodeAccount->setID($accountElement->getAttribute('id')); + } + + // Set the vat code percentage account elements from the account element + $vatCodeAccount->setDim1(self::parseObjectAttribute(\PhpTwinfield\GeneralLedger::class, $vatCodeAccount, $accountElement, 'dim1', array('name' => 'setName', 'shortname' => 'setShortName', 'dimensiontype' => 'setTypeFromString'))) + ->setGroup(self::parseObjectAttribute(\PhpTwinfield\VatGroup::class, $vatCodeAccount, $accountElement, 'group', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setGroupCountry(self::parseObjectAttribute(\PhpTwinfield\VatGroupCountry::class, $vatCodeAccount, $accountElement, 'groupcountry', array('name' => 'setName', 'shortname' => 'setShortName'))) + ->setLineType(self::parseEnumAttribute(\PhpTwinfield\Enums\LineType::class, self::getField($accountElement, 'linetype', $vatCodeAccount))) + ->setPercentage(self::getField($accountElement, 'percentage', $vatCodeAccount)); + + // Add the account to the percentage + $vatCodePercentage->addAccount($vatCodeAccount); + + // Clean that memory! + unset ($vatCodeAccount); + } + } + + // Add the percentage to the vat code + $vatCode->addPercentage($vatCodePercentage); + + // Clean that memory! + unset ($vatCodePercentage); + } + } + + // Return the complete object + return $vatCode; + } +} diff --git a/src/Mappers/VatGroupCountryMapper.php b/src/Mappers/VatGroupCountryMapper.php new file mode 100644 index 00000000..ce492434 --- /dev/null +++ b/src/Mappers/VatGroupCountryMapper.php @@ -0,0 +1,45 @@ + + */ +class VatGroupCountryMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean VatGroupCountry entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return VatGroupCountry + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new VatGroupCountry object + $vatGroupCountry = new VatGroupCountry(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/vat group country element + $vatGroupElement = $responseDOM->documentElement; + + // Set the vat group country elements from the vat group country element + $vatGroupCountry->setCode(self::getField($vatGroupElement, 'code', $vatGroupCountry)) + ->setName(self::getField($vatGroupElement, 'name', $vatGroupCountry)) + ->setShortName(self::getField($vatGroupElement, 'shortname', $vatGroupCountry)); + + // Return the complete object + return $vatGroupCountry; + } +} diff --git a/src/Mappers/VatGroupMapper.php b/src/Mappers/VatGroupMapper.php new file mode 100644 index 00000000..18c3a2d2 --- /dev/null +++ b/src/Mappers/VatGroupMapper.php @@ -0,0 +1,45 @@ + + */ +class VatGroupMapper extends BaseMapper +{ + /** + * Maps a Response object to a clean VatGroup entity. + * + * @access public + * + * @param \PhpTwinfield\Response\Response $response + * + * @return VatGroup + * @throws \PhpTwinfield\Exception + */ + public static function map(Response $response) + { + // Generate new VatGroup object + $vatGroup = new VatGroup(); + + // Gets the raw DOMDocument response. + $responseDOM = $response->getResponseDocument(); + + // Get the root/vat group element + $vatGroupElement = $responseDOM->documentElement; + + // Set the vat group elements from the vat group element + $vatGroup->setCode(self::getField($vatGroupElement, 'code', $vatGroup)) + ->setName(self::getField($vatGroupElement, 'name', $vatGroup)) + ->setShortName(self::getField($vatGroupElement, 'shortname', $vatGroup)); + + // Return the complete object + return $vatGroup; + } +} diff --git a/src/MatchLine.php b/src/MatchLine.php index 78b5ac33..6f9a37eb 100644 --- a/src/MatchLine.php +++ b/src/MatchLine.php @@ -12,36 +12,36 @@ class MatchLine * * @var string */ - private $transcode; + private $transCode; /** * Transaction number. * * @var int */ - private $transnumber; + private $transNumber; /** * Transaction line number. * * @var int */ - private $transline; + private $transLine; /** * @var Money|null */ - private $matchvalue; + private $matchValue; /** * @var Money|null */ - private $writeoff; + private $writeOff; /** * @var Enums\WriteOffType|null */ - private $writeofftype; + private $writeOffType; /** * Create a new matchline based on a MatchReferenceInterface. @@ -54,10 +54,10 @@ public static function addToMatchSet(MatchSet $set, MatchReferenceInterface $ref Assert::eq($set->getOffice(), $reference->getOffice()); $instance = new self; - $instance->transcode = $reference->getCode(); - $instance->transnumber = $reference->getNumber(); - $instance->transline = $reference->getLineId(); - $instance->setMatchvalue($value); + $instance->transCode = $reference->getCode(); + $instance->transNumber = $reference->getNumber(); + $instance->transLine = $reference->getLineId(); + $instance->setMatchValue($value); $set->addLine($instance); @@ -73,39 +73,39 @@ private function __construct() {} /** * @return string */ - public function getTranscode(): string + public function getTransCode(): string { - return $this->transcode; + return $this->transCode; } - public function getTransnumber(): int + public function getTransNumber(): int { - return $this->transnumber; + return $this->transNumber; } - public function getTransline(): int + public function getTransLine(): int { - return $this->transline; + return $this->transLine; } public function getMatchValue(): ?Money { - return $this->matchvalue; + return $this->matchValue; } /** * Optional; only for partial payments. Include an "-" on credit lines. */ - public function setMatchvalue(?Money $matchvalue): self + public function setMatchValue(?Money $matchValue): self { - $this->matchvalue = $matchvalue; + $this->matchValue = $matchValue; return $this; } public function getWriteOff(): ?Money { - return $this->writeoff; + return $this->writeOff; } /** @@ -113,8 +113,8 @@ public function getWriteOff(): ?Money */ public function setWriteOff(Money $amount, Enums\WriteOffType $type): self { - $this->writeoff = $amount; - $this->writeofftype = $type; + $this->writeOff = $amount; + $this->writeOffType = $type; return $this; } @@ -124,6 +124,6 @@ public function setWriteOff(Money $amount, Enums\WriteOffType $type): self */ public function getWriteOffType(): ?Enums\WriteOffType { - return $this->writeofftype; + return $this->writeOffType; } -} \ No newline at end of file +} diff --git a/src/MatchReference.php b/src/MatchReference.php index e7b57d37..ff186929 100644 --- a/src/MatchReference.php +++ b/src/MatchReference.php @@ -14,10 +14,7 @@ final class MatchReference implements MatchReferenceInterface */ private $lineId; - public static function fromBookingReference( - BookingReferenceInterface $bookingReference, - int $lineId - ): MatchReferenceInterface { + public static function fromBookingReference(BookingReferenceInterface $bookingReference, int $lineId): MatchReferenceInterface { return new self( $bookingReference->getOffice(), $bookingReference->getCode(), @@ -51,4 +48,4 @@ public function getLineId(): int { return $this->lineId; } -} \ No newline at end of file +} diff --git a/src/MatchReferenceInterface.php b/src/MatchReferenceInterface.php index 071c7a78..39385a4b 100644 --- a/src/MatchReferenceInterface.php +++ b/src/MatchReferenceInterface.php @@ -35,4 +35,4 @@ public function getNumber(): int; * Reference the exact line in the transaction. */ public function getLineId(): int; -} \ No newline at end of file +} diff --git a/src/MatchSet.php b/src/MatchSet.php index 36527ab5..4f02f5a8 100644 --- a/src/MatchSet.php +++ b/src/MatchSet.php @@ -2,11 +2,14 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionFields\OfficeField; +use PhpTwinfield\Enums\MatchCode; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\MatchDateField; use Webmozart\Assert\Assert; class MatchSet { + use MatchDateField; use OfficeField; /** @@ -14,54 +17,30 @@ class MatchSet */ private $matchCode; - /** - * @var \DateTimeInterface - */ - private $matchDate; - /** * @var MatchLine[] */ private $lines = []; /** - * @return Enums\MatchCode + * @return MatchCode */ - public function getMatchCode(): Enums\MatchCode + public function getMatchCode(): MatchCode { return $this->matchCode; } /** - * @param Enums\MatchCode $matchCode + * @param MatchCode $matchCode * @return $this */ - public function setMatchCode(Enums\MatchCode $matchCode) + public function setMatchCode(MatchCode $matchCode) { $this->matchCode = $matchCode; return $this; } - /** - * @return \DateTimeInterface - */ - public function getMatchDate(): \DateTimeInterface - { - return $this->matchDate; - } - - /** - * @param \DateTimeInterface $matchDate - * @return $this - */ - public function setMatchDate(\DateTimeInterface $matchDate) - { - $this->matchDate = $matchDate; - - return $this; - } - /** * @param MatchLine $line * @internal Don't call this, use \PhpTwinfield\MatchLine::addToMatchSet diff --git a/src/Office.php b/src/Office.php index 9e59693d..56d6c365 100644 --- a/src/Office.php +++ b/src/Office.php @@ -2,22 +2,35 @@ namespace PhpTwinfield; -class Office +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\CreatedField; +use PhpTwinfield\Fields\ModifiedField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\Office\BaseCurrencyField; +use PhpTwinfield\Fields\Office\CountryCodeField; +use PhpTwinfield\Fields\Office\ReportingCurrencyField; +use PhpTwinfield\Fields\Office\VatFirstQuarterStartsInField; +use PhpTwinfield\Fields\Office\VatPeriodField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; +use PhpTwinfield\Fields\TouchedField; +use PhpTwinfield\Fields\UserField; + +class Office extends BaseObject implements HasCodeInterface { - /** - * @var string The code of the office. - */ - private $code; - - /** - * @var string The code of the country of the office. - */ - private $countryCode; - - /** - * @var string The name of the office. - */ - private $name; + use BaseCurrencyField; + use CodeField; + use CountryCodeField; + use CreatedField; + use ModifiedField; + use NameField; + use ReportingCurrencyField; + use ShortNameField; + use StatusField; + use TouchedField; + use UserField; + use VatFirstQuarterStartsInField; + use VatPeriodField; public static function fromCode(string $code) { $instance = new self; @@ -26,36 +39,6 @@ public static function fromCode(string $code) { return $instance; } - public function getCode(): string - { - return $this->code; - } - - public function setCode(string $code): void - { - $this->code = $code; - } - - public function getCountryCode(): string - { - return $this->countryCode; - } - - public function setCountryCode(string $countryCode): void - { - $this->countryCode = $countryCode; - } - - public function getName(): string - { - return $this->name; - } - - public function setName(string $name): void - { - $this->name = $name; - } - public function __toString() { return $this->getCode(); diff --git a/src/PayCode.php b/src/PayCode.php new file mode 100644 index 00000000..117f2f0b --- /dev/null +++ b/src/PayCode.php @@ -0,0 +1,26 @@ + + */ +class PayCode extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/Project.php b/src/Project.php new file mode 100644 index 00000000..571dde77 --- /dev/null +++ b/src/Project.php @@ -0,0 +1,61 @@ + + */ +class Project extends BaseObject implements HasCodeInterface +{ + use BehaviourField; + use CodeField; + use InUseField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + use VatCodeField; + + private $projects; + + public function __construct() + { + $this->setType(\PhpTwinfield\DimensionType::fromCode('PRJ')); + $this->setProjects(new ProjectProjects); + } + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getProjects(): ProjectProjects + { + return $this->projects; + } + + public function setProjects(ProjectProjects $projects) + { + $this->projects = $projects; + return $this; + } +} diff --git a/src/ProjectProjects.php b/src/ProjectProjects.php new file mode 100644 index 00000000..a6887a75 --- /dev/null +++ b/src/ProjectProjects.php @@ -0,0 +1,79 @@ +setAuthoriserInherit(true); + $this->setAuthoriserLocked(true); + $this->setBillableInherit(true); + $this->setBillableLocked(true); + $this->setCustomerInherit(true); + $this->setCustomerLocked(true); + $this->setRateInherit(true); + $this->setRateLocked(true); + } + + public function getQuantities() + { + return $this->quantities; + } + + public function addQuantity(ProjectQuantity $quantity) + { + $this->quantities[] = $quantity; + return $this; + } + + public function removeQuantity($index) + { + if (array_key_exists($index, $this->quantities)) { + unset($this->quantities[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/ProjectQuantity.php b/src/ProjectQuantity.php new file mode 100644 index 00000000..15e0d183 --- /dev/null +++ b/src/ProjectQuantity.php @@ -0,0 +1,22 @@ +transaction = $object; } - /** + /* * References the transaction this line belongs too. * * @return PurchaseTransaction @@ -42,133 +48,225 @@ public function getTransaction(): PurchaseTransaction return $this->transaction; } - /** - * If line type = total the accounts payable balance account. When dim1 is omitted, by default the general ledger - * account will be taken as entered at the supplier in Twinfield. + /* + * Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. * - * If line type = detail the profit and loss account. - * - * If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account - * will be taken as entered at the VAT code in Twinfield. + * @param int|null $baseline + * @return $this + * @throws Exception + */ + public function setBaseline(?int $baseline): self + { + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType("baseline", $this); + } + + $this->baseline = $baseline; + + return $this; + } + + /* + * Only if line type is total. The amount still to be paid in base currency. Read-only attribute. * - * @param string|null $dim1 + * @param Money|null $baseValueOpen * @return $this + * @throws Exception */ - public function setDim1(?string $dim1): BaseTransactionLine + public function setBaseValueOpen(?Money $baseValueOpen): parent { - return parent::setDim1($dim1); + if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('basevalueopen', $this); + } + + return parent::setBaseValueOpen($baseValueOpen); } - /** - * If line type = total the account payable. + /* + * If line type = total empty. * - * If line type = detail the cost center or empty. + * If line type = detail the project or asset or empty. * - * If line type = vat the cost center or empty. + * If line type = vat the project or asset or empty. * - * @param string|null $dim2 + * @param $dim3 * @return $this + * @throws Exception */ - public function setDim2(?string $dim2): BaseTransactionLine + public function setDim3($dim3): parent { - return parent::setDim2($dim2); + if ($dim3 !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidDimensionForLineType(3, $this); + } + + return parent::setDim3($dim3); } - /** - * If line type = total - * - In case of a 'normal' purchase transaction credit. - * - In case of a credit purchase transaction debit. + /* + * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction + * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. * - * If line type = detail or vat - * - In case of a 'normal' purchase transaction debit. - * - In case of a credit purchase transaction credit. + * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing + * transaction type is a Purchase Transaction. * - * @param DebitCredit $debitCredit - * @return $this + * @return bool */ - public function setDebitCredit(DebitCredit $debitCredit): BaseTransactionLine + protected function isIncomingTransactionType(): bool { - return parent::setDebitCredit($debitCredit); + return false; } - /** - * If line type = total amount including VAT. - * - * If line type = detail amount without VAT. + /* + * Only if line type is total. The date on which the purchase invoice is matched. Read-only attribute. * - * If line type = vat VAT amount. + * @param \DateTimeInterface|null $matchDate + * @return $this + * @throws Exception + */ + public function setMatchDate(?\DateTimeInterface $matchDate): self + { + if ($matchDate !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('matchdate', $this); + } + + $this->matchDate = $matchDate; + + return $this; + } + + /* + * Only if line type is total. The level of the matchable dimension. Read-only attribute. * - * @param Money $value + * @param int|null $matchLevel * @return $this + * @throws Exception */ - public function setValue(Money $value): BaseTransactionLine + public function setMatchLevel(?int $matchLevel): parent { - return parent::setValue($value); + if ($matchLevel !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('matchlevel', $this); + } + + return parent::setMatchLevel($matchLevel); } - /** - * Payment status of the purchase transaction. If line type detail or vat always notmatchable. Read-only attribute. + /* + * Payment status of the transaction. If line type detail or vat always notmatchable. Read-only attribute. * - * @param string|null $matchStatus + * @param MatchStatus|null $matchStatus * @return $this * @throws Exception */ - public function setMatchStatus(?string $matchStatus): BaseTransactionLine + public function setMatchStatus(?MatchStatus $matchStatus): parent { - if ( - $matchStatus !== null && - in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) && - $matchStatus != self::MATCHSTATUS_NOTMATCHABLE - ) { + if ($matchStatus !== null && in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { throw Exception::invalidMatchStatusForLineType($matchStatus, $this); } return parent::setMatchStatus($matchStatus); } - /** - * Only if line type is total. The level of the matchable dimension. Read-only attribute. + /* + * Relation of the transaction. Only if line type is total. Read-only attribute. * - * @param int|null $matchLevel + * @param int|null $relation * @return $this * @throws Exception */ - public function setMatchLevel(?int $matchLevel): BaseTransactionLine + public function setRelation(?int $relation): parent { - if ($matchLevel !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('matchLevel', $this); + if ($relation !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('relation', $this); } - return parent::setMatchLevel($matchLevel); + return parent::setRelation($relation); } - /** - * Only if line type is total. The amount still to be paid in base currency. Read-only attribute. + /* + * Only if line type is total. The amount still owed in reporting currency. Read-only attribute. * - * @param Money|null $baseValueOpen + * @param Money|null $repValueOpen * @return $this * @throws Exception */ - public function setBaseValueOpen(?Money $baseValueOpen): BaseTransactionLine + public function setRepValueOpen(?Money $repValueOpen): parent { - if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('baseValueOpen', $this); + if ($repValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('repvalueopen', $this); } - return parent::setBaseValueOpen($baseValueOpen); + return parent::setRepValueOpen($repValueOpen); } - /** - * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction - * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. + /* + * Only if line type is total. The amount still to be paid in the currency of the purchase transaction. Read-only attribute. * - * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing - * transaction type is a Purchase Transaction. + * @param Money|null $valueOpen + * @return $this + * @throws Exception + */ + public function setValueOpen(?Money $valueOpen): self + { + if ($valueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('valueopen', $this); + } + + $this->valueOpen = $valueOpen; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in the currency of the purchase transaction * - * @return bool + * @param Money|null $vatTotal + * @return $this + * @throws Exception */ - protected function isIncomingTransactionType(): bool + public function setVatTotal(?Money $vatTotal): self { - return false; + if ($vatTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vattotal', $this); + } + + $this->vatTotal = $vatTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in base currency. + * + * @param Money|null $vatBaseTotal + * @return $this + * @throws Exception + */ + public function setVatBaseTotal(?Money $vatBaseTotal): self + { + if ($vatBaseTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatbasetotal', $this); + } + + $this->vatBaseTotal = $vatBaseTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in reporting currency. + * + * @param Money|null $vatRepTotal + * @return $this + * @throws Exception + */ + public function setVatRepTotal(?Money $vatRepTotal): self + { + if ($vatRepTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatreptotal', $this); + } + + $this->vatRepTotal = $vatRepTotal; + + return $this; } } diff --git a/src/Rate.php b/src/Rate.php new file mode 100644 index 00000000..08475065 --- /dev/null +++ b/src/Rate.php @@ -0,0 +1,85 @@ + + */ +class Rate extends BaseObject implements HasCodeInterface +{ + use CodeField; + use CreatedField; + use CurrencyField; + use ModifiedField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UnitField; + use UserField; + + private $rateChanges = []; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } + + public function getRateChanges() + { + return $this->rateChanges; + } + + public function addRateChange(RateRateChange $rateChange) + { + $this->rateChanges[] = $rateChange; + return $this; + } + + public function removeRateChange($index) + { + if (array_key_exists($index, $this->rateChanges)) { + unset($this->rateChanges[$index]); + return true; + } else { + return false; + } + } + + public function removeRateChangeByID($id) + { + $found = false; + + foreach ($this->rateChanges as $index => $rateChange) { + if ($id == $rateChange->getID()) { + unset($this->rateChanges[$index]); + $found = true; + } + } + + if ($found) { + return true; + } + + return false; + } +} diff --git a/src/RateRateChange.php b/src/RateRateChange.php new file mode 100644 index 00000000..c9336294 --- /dev/null +++ b/src/RateRateChange.php @@ -0,0 +1,24 @@ + + * @version 0.0.1 + */ +class AssetMethod extends DOMDocument +{ + /** + * Holds the element that all + * additional elements should be a child of. + * + * @access private + * @var DOMElement + */ + private $assetMethodElement; + + /** + * Creates the element and adds it to the property + * assetMethodElement and sets office and code if they are present. + * + * @access public + */ + public function __construct($office = null, $code = null) + { + parent::__construct(); + + $this->assetMethodElement = $this->createElement('assetmethod'); + $this->appendChild($this->assetMethodElement); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } + + /** + * Adds additional elements to the dom element. + * + * See the documentation over what requires to know + * and what additional elements you need. + * + * @access protected + * @param string $element + * @param mixed $value + * @return void + */ + protected function add($element, $value) + { + $_element = $this->createElement($element, $value); + $this->assetMethodElement->appendChild($_element); + } + + /** + * Sets the office code for this request. + * + * @access public + * @param int $office + * @return \PhpTwinfield\Request\AssetMethod + */ + public function setOffice($office) + { + $this->add('office', $office); + return $this; + } + + /** + * Sets the code for this request. + * + * @access public + * @param string $code + * @return \PhpTwinfield\Request\AssetMethod + */ + public function setCode($code) + { + $this->add('code', $code); + return $this; + } +} diff --git a/src/Request/Catalog/Catalog.php b/src/Request/Catalog/Catalog.php index cfb21cf8..a56e9b75 100644 --- a/src/Request/Catalog/Catalog.php +++ b/src/Request/Catalog/Catalog.php @@ -5,13 +5,13 @@ * Abstract parent class Catalog. Catalog is the name of the request * for LIST. List is a protected term in PHP so all instances of the word * catalog are just a replacement. - * + * * All aspects of LIST request require a parent element called 'list' - * + * * The constructor makes this element, appends to the itself. All requirements * to add new elements to this dom element are done through * the add() method. - * + * * @package PhpTwinfield * @subpackage Request\Catalog * @author Leon Rowland @@ -23,7 +23,7 @@ abstract class Catalog extends \DOMDocument /** * Holds the element that all * additional elements should be a child of. - * + * * @access private * @var \DOMElement */ @@ -32,7 +32,7 @@ abstract class Catalog extends \DOMDocument /** * Creates the element and adds it to the property * listElement - * + * * @access public */ public function __construct() @@ -45,10 +45,10 @@ public function __construct() /** * Adds additional elements to the dom element. - * + * * See the documentation over what requires to know * what additional elements you need. - * + * * @access protected * @param string $element * @param mixed $value diff --git a/src/Request/Catalog/Dimension.php b/src/Request/Catalog/Dimension.php deleted file mode 100644 index f64620c3..00000000 --- a/src/Request/Catalog/Dimension.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright (c) 2013, Pronamic - * @version 0.0.1 - */ -class Dimension extends Catalog -{ - /** - * Sets the to dimensions for the request - * and sets the office and dimtype if they are passed - * in. - * - * @access public - * @param Office|null $office - * @param string|null $dimType - */ - public function __construct(Office $office = null, $dimType = null) - { - parent::__construct(); - - $this->add('type', 'dimensions'); - - if (null !== $office) { - $this->setOffice($office); - } - - if (null !== $dimType) { - $this->setDimType($dimType); - } - } - - /** - * Sets the officecode for the dimension request. - * - * @param Office $office - */ - public function setOffice(Office $office) - { - $this->add('office', $office->getCode()); - } - - /** - * Sets the dimtype for the request. - * - * @access public - * @param string $dimType - */ - public function setDimType($dimType) - { - $this->add('dimtype', $dimType); - } -} diff --git a/src/Request/Catalog/Office.php b/src/Request/Catalog/Office.php index ac20adec..5865add7 100644 --- a/src/Request/Catalog/Office.php +++ b/src/Request/Catalog/Office.php @@ -1,27 +1,27 @@ - - * @copyright (c) 2013, Pronamic - * @version 0.0.1 - */ -class Office extends Catalog -{ - /** - * Adds the only required element for this request. - * - * No other methods exist or are required, - * - * @access public - */ - public function __construct() - { - parent::__construct(); - $this->add('type', 'offices'); - } -} + + * @copyright (c) 2013, Pronamic + * @version 0.0.1 + */ +class Office extends Catalog +{ + /** + * Adds the only required element for this request. + * + * No other methods exist or are required, + * + * @access public + */ + public function __construct() + { + parent::__construct(); + $this->add('type', 'offices'); + } +} diff --git a/src/Request/DimensionGroup.php b/src/Request/DimensionGroup.php new file mode 100644 index 00000000..f90fb379 --- /dev/null +++ b/src/Request/DimensionGroup.php @@ -0,0 +1,90 @@ + + * @version 0.0.1 + */ +class DimensionGroup extends DOMDocument +{ + /** + * Holds the element that all + * additional elements should be a child of. + * + * @access private + * @var DOMElement + */ + private $dimensionGroupElement; + + /** + * Creates the element and adds it to the property + * dimensionGroupElement and sets office and code if they are present. + * + * @access public + */ + public function __construct($office = null, $code = null) + { + parent::__construct(); + + $this->dimensionGroupElement = $this->createElement('dimensiongroup'); + $this->appendChild($this->dimensionGroupElement); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } + + /** + * Adds additional elements to the dom element. + * + * See the documentation over what requires to know + * and what additional elements you need. + * + * @access protected + * @param string $element + * @param mixed $value + * @return void + */ + protected function add($element, $value) + { + $_element = $this->createElement($element, $value); + $this->dimensionGroupElement->appendChild($_element); + } + + /** + * Sets the office code for this request. + * + * @access public + * @param int $office + * @return \PhpTwinfield\Request\DimensionGroup + */ + public function setOffice($office) + { + $this->add('office', $office); + return $this; + } + + /** + * Sets the code for this request. + * + * @access public + * @param string $code + * @return \PhpTwinfield\Request\DimensionGroup + */ + public function setCode($code) + { + $this->add('code', $code); + return $this; + } +} diff --git a/src/Request/DimensionType.php b/src/Request/DimensionType.php new file mode 100644 index 00000000..2e18a4ab --- /dev/null +++ b/src/Request/DimensionType.php @@ -0,0 +1,90 @@ + + * @version 0.0.1 + */ +class DimensionType extends DOMDocument +{ + /** + * Holds the element that all + * additional elements should be a child of. + * + * @access private + * @var DOMElement + */ + private $dimensionTypeElement; + + /** + * Creates the element and adds it to the property + * dimensionTypeElement and sets office and code if they are present. + * + * @access public + */ + public function __construct($office = null, $code = null) + { + parent::__construct(); + + $this->dimensionTypeElement = $this->createElement('dimensiontype'); + $this->appendChild($this->dimensionTypeElement); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } + + /** + * Adds additional elements to the dom element. + * + * See the documentation over what requires to know + * and what additional elements you need. + * + * @access protected + * @param string $element + * @param mixed $value + * @return void + */ + protected function add($element, $value) + { + $_element = $this->createElement($element, $value); + $this->dimensionTypeElement->appendChild($_element); + } + + /** + * Sets the office code for this request. + * + * @access public + * @param int $office + * @return \PhpTwinfield\Request\DimensionType + */ + public function setOffice($office) + { + $this->add('office', $office); + return $this; + } + + /** + * Sets the code for this request. + * + * @access public + * @param string $code + * @return \PhpTwinfield\Request\DimensionType + */ + public function setCode($code) + { + $this->add('code', $code); + return $this; + } +} diff --git a/src/Request/Read/Activity.php b/src/Request/Read/Activity.php new file mode 100644 index 00000000..cf504a8c --- /dev/null +++ b/src/Request/Read/Activity.php @@ -0,0 +1,39 @@ + + * @version 0.0.1 + */ +class Activity extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'dimensions'); + $this->add('dimtype', 'ACT'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Article.php b/src/Request/Read/Article.php index 84561c22..5fe60527 100644 --- a/src/Request/Read/Article.php +++ b/src/Request/Read/Article.php @@ -1,10 +1,11 @@ @@ -14,15 +15,17 @@ class Article extends Read { /** * Sets office and code if they are present. - * + * * @access public + * @param Office|null $office + * @param string $code */ - public function __construct($office = null, $code = null) + public function __construct(?Office $office = null, $code = null) { parent::__construct(); $this->add('type', 'article'); - + if (null !== $office) { $this->setOffice($office); } @@ -31,30 +34,4 @@ public function __construct($office = null, $code = null) $this->setCode($code); } } - - /** - * Sets the office code for this Article request. - * - * @access public - * @param int $office - * @return \PhpTwinfield\Request\Read\Article - */ - public function setOffice($office) - { - $this->add('office', $office); - return $this; - } - - /** - * Sets the code for this Article request. - * - * @access public - * @param string $code - * @return \PhpTwinfield\Request\Read\Article - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } } diff --git a/src/Request/Read/BrowseDefinition.php b/src/Request/Read/BrowseDefinition.php index 99e3a7de..47721b22 100644 --- a/src/Request/Read/BrowseDefinition.php +++ b/src/Request/Read/BrowseDefinition.php @@ -12,7 +12,7 @@ class BrowseDefinition extends Read * @param string $code * @param Office|null $office */ - public function __construct(string $code, Office $office = null) + public function __construct(string $code, ?Office $office = null) { parent::__construct(); @@ -26,30 +26,4 @@ public function __construct(string $code, Office $office = null) $this->setCode($code); } } - - /** - * Sets the office code for this BrowseData request. - * - * @access public - * @param Office $office - * @return BrowseDefinition - */ - public function setOffice(Office $office) - { - $this->add('office', $office->getCode()); - return $this; - } - - /** - * Sets the code for this BrowseData request. - * - * @access public - * @param string $code - * @return BrowseDefinition - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } } diff --git a/src/Request/Read/CostCenter.php b/src/Request/Read/CostCenter.php new file mode 100644 index 00000000..095c0c85 --- /dev/null +++ b/src/Request/Read/CostCenter.php @@ -0,0 +1,38 @@ + + * @version 0.0.1 + */ +class CostCenter extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'dimensions'); + $this->add('dimtype', 'KPL'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Currency.php b/src/Request/Read/Currency.php new file mode 100644 index 00000000..b43b0cbf --- /dev/null +++ b/src/Request/Read/Currency.php @@ -0,0 +1,37 @@ + + * @version 0.0.1 + */ +class Currency extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'currency'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Customer.php b/src/Request/Read/Customer.php index a7d827b2..8ff8327a 100644 --- a/src/Request/Read/Customer.php +++ b/src/Request/Read/Customer.php @@ -1,10 +1,12 @@ @@ -16,62 +18,24 @@ class Customer extends Read /** * Sets the to dimensions for the request and * sets the dimtype, office and code if they are present. - * + * * @access public + * @param Office|null $office + * @param string $code */ - public function __construct($office = null, $code = null, $dimType = 'DEB') + public function __construct(?Office $office = null, $code = null) { parent::__construct(); $this->add('type', 'dimensions'); - + $this->add('dimtype', 'DEB'); + if (null !== $office) { $this->setOffice($office); } - + if (null !== $code) { $this->setCode($code); } - - $this->setDimType($dimType); - } - - /** - * Sets the office code for this customer request. - * - * @access public - * @param int $office - * @return \PhpTwinfield\Request\Read\Customer - */ - public function setOffice($office) - { - $this->add('office', $office); - return $this; - } - - /** - * Sets the code for this customer request. - * - * @access public - * @param string $code - * @return \PhpTwinfield\Request\Read\Customer - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } - - /** - * Sets the dimtype for the request. - * - * @access public - * @param string $dimType - * @return \PhpTwinfield\Request\Read\Customer - */ - public function setDimType($dimType) - { - $this->add('dimtype', $dimType); - return $this; } } diff --git a/src/Request/Read/FixedAsset.php b/src/Request/Read/FixedAsset.php new file mode 100644 index 00000000..c1123e38 --- /dev/null +++ b/src/Request/Read/FixedAsset.php @@ -0,0 +1,38 @@ + + * @version 0.0.1 + */ +class FixedAsset extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'dimensions'); + $this->add('dimtype', 'AST'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/GeneralLedger.php b/src/Request/Read/GeneralLedger.php new file mode 100644 index 00000000..37539e85 --- /dev/null +++ b/src/Request/Read/GeneralLedger.php @@ -0,0 +1,41 @@ + + * @version 0.0.1 + */ +class GeneralLedger extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null, $dimType = null) + { + parent::__construct(); + + $this->add('type', 'dimensions'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + + if (null !== $dimType) { + $this->setDimType($dimType); + } + } +} diff --git a/src/Request/Read/Invoice.php b/src/Request/Read/Invoice.php index 27aec93a..07402a0a 100644 --- a/src/Request/Read/Invoice.php +++ b/src/Request/Read/Invoice.php @@ -1,84 +1,59 @@ - * @copyright (c) 2013, Pronamic + * @copyright (c) 2013, Pronamic * @version 0.0.1 */ class Invoice extends Read { /** * Sets the to salesinvoice for the request - * and sets the office, code and number if they + * and sets the office, code and invoice number if they * are present. - * + * * @access public - * @param int $office + * @param Office|null $office * @param string $code - * @param int $number + * @param int $invoiceNumber */ - public function __construct($office = null, $code = null, $number = null) + public function __construct(?Office $office = null, $code = null, $invoiceNumber = null) { parent::__construct(); $this->add('type', 'salesinvoice'); - + if (null !== $office) { $this->setOffice($office); } - + if (null !== $code) { $this->setCode($code); } - - if (null !== $number) { - $this->setNumber($number); - } - } - /** - * Sets the office code for this salesinvoice - * request. It is an optional field. - * - * @access public - * @param int $office - * @return \PhpTwinfield\Request\Read\Invoice - */ - public function setOffice($office) - { - $this->add('office', $office); - return $this; + if (null !== $invoiceNumber) { + $this->setInvoiceNumber($invoiceNumber); + } } - /** - * Sets the code for this salesinvoice request. + /** + * Sets the invoice number for this request. * * @access public - * @param string $code - * @return \PhpTwinfield\Request\Read\Invoice - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } - - /** - * Sets the invoicenumber for this request. - * - * @access public - * @param int $number + * @param string $invoiceNumber * @return \PhpTwinfield\Request\Read\Invoice */ - public function setNumber($number) + public function setInvoiceNumber($invoiceNumber) { - $this->add('invoicenumber', $number); + $this->add('invoicenumber', $invoiceNumber); return $this; } } diff --git a/src/Request/Read/Office.php b/src/Request/Read/Office.php new file mode 100644 index 00000000..07f73eaf --- /dev/null +++ b/src/Request/Read/Office.php @@ -0,0 +1,30 @@ + + * @version 0.0.1 + */ +class Office extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param string $code + */ + public function __construct($code = null) + { + parent::__construct(); + + $this->add('type', 'office'); + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Project.php b/src/Request/Read/Project.php new file mode 100644 index 00000000..1b3253da --- /dev/null +++ b/src/Request/Read/Project.php @@ -0,0 +1,38 @@ + + * @version 0.0.1 + */ +class Project extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'dimensions'); + $this->add('dimtype', 'PRJ'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Rate.php b/src/Request/Read/Rate.php new file mode 100644 index 00000000..e93b35e0 --- /dev/null +++ b/src/Request/Read/Rate.php @@ -0,0 +1,37 @@ + + * @version 0.0.1 + */ +class Rate extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'projectrate'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/Read.php b/src/Request/Read/Read.php index 31b8899c..c3648968 100644 --- a/src/Request/Read/Read.php +++ b/src/Request/Read/Read.php @@ -1,16 +1,18 @@ dom element are done through the add() * method. - * + * * @package PhpTwinfield * @subpackage Request\Read * @author Leon Rowland @@ -21,8 +23,8 @@ abstract class Read extends \DOMDocument { /** * Holds the element that all - * additional elements shoudl be a child of. - * + * additional elements should be a child of. + * * @access private * @var \DOMElement */ @@ -31,7 +33,7 @@ abstract class Read extends \DOMDocument /** * Creates the element and adds it to the property * readElement - * + * * @access public */ public function __construct() @@ -44,10 +46,10 @@ public function __construct() /** * Adds additional elements to the dom element. - * + * * See the documentation over what requires to know * and what additional elements you need. - * + * * @access protected * @param string $element * @param mixed $value @@ -58,4 +60,56 @@ protected function add($element, $value) $_element = $this->createElement($element, $value); $this->readElement->appendChild($_element); } + + /** + * Sets the office code for this request. + * + * @access public + * @param Office $office + * @return \PhpTwinfield\Request\Read\Read + */ + public function setOffice(Office $office) + { + $this->add('office', $office); + return $this; + } + + /** + * Sets the code for this request. + * + * @access public + * @param string $code + * @return \PhpTwinfield\Request\Read\Read + */ + public function setCode($code) + { + $this->add('code', $code); + return $this; + } + + /** + * Sets the dimtype for this request. + * + * @access public + * @param string $dimType + * @return \PhpTwinfield\Request\Read\Read + */ + public function setDimType($dimType) + { + $this->add('dimtype', $dimType); + return $this; + } + + /** + * Sets the number for this request. + * + * @access public + * @param string $number + * @return \PhpTwinfield\Request\Read\Read + */ + public function setNumber($number) + { + $this->add('number', $number); + return $this; + } } diff --git a/src/Request/Read/Supplier.php b/src/Request/Read/Supplier.php index 2abfc86a..a6ba3d96 100644 --- a/src/Request/Read/Supplier.php +++ b/src/Request/Read/Supplier.php @@ -1,10 +1,12 @@ @@ -15,63 +17,25 @@ class Supplier extends Read { /** * Sets the to dimensions for the request and - * sets the dimtype, office and code if they are present. - * + * sets the office and code if they are present. + * * @access public + * @param Office $office + * @param string $code */ - public function __construct($office = null, $code = null, $dimType = 'CRD') + public function __construct(?Office $office = null, $code = null) { parent::__construct(); $this->add('type', 'dimensions'); - + $this->add('dimtype', 'CRD'); + if (null !== $office) { $this->setOffice($office); } - + if (null !== $code) { $this->setCode($code); } - - $this->setDimType($dimType); - } - - /** - * Sets the office code for this customer request. - * - * @access public - * @param int $office - * @return $this - */ - public function setOffice($office) - { - $this->add('office', $office); - return $this; - } - - /** - * Sets the code for this customer request. - * - * @access public - * @param string $code - * @return $this - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } - - /** - * Sets the dimtype for the request. - * - * @access public - * @param string $dimType - * @return $this - */ - public function setDimType($dimType) - { - $this->add('dimtype', $dimType); - return $this; } } diff --git a/src/Request/Read/Transaction.php b/src/Request/Read/Transaction.php index 00bdbad7..5c224d05 100644 --- a/src/Request/Read/Transaction.php +++ b/src/Request/Read/Transaction.php @@ -6,7 +6,7 @@ /** * Used to request a specific transaction from a certain * office, code and number. - * + * * @package PhpTwinfield * @subpackage Request\Read * @author Leon Rowland @@ -18,67 +18,28 @@ class Transaction extends Read /** * Sets the to transaction for the request and * sets the office, code and number if they are present. - * + * * @access public - * @param int $office + * @param Office $office * @param string $code * @param int $number */ - public function __construct($office = null, $code = null, $number = null) + public function __construct(?Office $office = null, $code = null, $number = null) { parent::__construct(); - + $this->add('type', 'transaction'); - + if (null !== $office) { $this->setOffice($office); } - + if (null !== $code) { $this->setCode($code); } - + if (null !== $number) { $this->setNumber($number); } } - - /** - * Sets the office code for this transaction request. - * - * @access public - * @param Office $office - * @return \PhpTwinfield\Request\Read\Transaction - */ - public function setOffice(Office $office) - { - $this->add('office', $office->getCode()); - return $this; - } - - /** - * Sets the code for this transaction request. - * - * @access public - * @param string $code - * @return \PhpTwinfield\Request\Read\Transaction - */ - public function setCode($code) - { - $this->add('code', $code); - return $this; - } - - /** - * Sets the number for this transaction request - * - * @access public - * @param int $number - * @return \PhpTwinfield\Request\Read\Transaction - */ - public function setNumber($number) - { - $this->add('number', $number); - return $this; - } } diff --git a/src/Request/Read/User.php b/src/Request/Read/User.php new file mode 100644 index 00000000..7bbe7b20 --- /dev/null +++ b/src/Request/Read/User.php @@ -0,0 +1,37 @@ + + * @version 0.0.1 + */ +class User extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'user'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Request/Read/VatCode.php b/src/Request/Read/VatCode.php new file mode 100644 index 00000000..d8d3d0af --- /dev/null +++ b/src/Request/Read/VatCode.php @@ -0,0 +1,37 @@ + + * @version 0.0.1 + */ +class VatCode extends Read +{ + /** + * Sets office and code if they are present. + * + * @access public + * @param Office|null $office + * @param string $code + */ + public function __construct(?Office $office = null, $code = null) + { + parent::__construct(); + + $this->add('type', 'vat'); + + if (null !== $office) { + $this->setOffice($office); + } + + if (null !== $code) { + $this->setCode($code); + } + } +} diff --git a/src/Response/IndividualMappedResponse.php b/src/Response/IndividualMappedResponse.php index 127b7d3a..e9f68efd 100644 --- a/src/Response/IndividualMappedResponse.php +++ b/src/Response/IndividualMappedResponse.php @@ -69,4 +69,4 @@ public function getErrorMessages(): array { return $this->response->getErrorMessages(); } -} \ No newline at end of file +} diff --git a/src/Response/Response.php b/src/Response/Response.php index 43ea9c6e..accbdb8f 100644 --- a/src/Response/Response.php +++ b/src/Response/Response.php @@ -45,7 +45,7 @@ public static function fromString(string $xml) return new self($document); } - + public function __construct(\DOMDocument $responseDocument) { $this->responseDocument = $responseDocument; diff --git a/src/Response/ResponseException.php b/src/Response/ResponseException.php index 486b3c60..c1a12590 100644 --- a/src/Response/ResponseException.php +++ b/src/Response/ResponseException.php @@ -29,4 +29,4 @@ public function getReturnedObject() { return $this->returnedObject; } -} \ No newline at end of file +} diff --git a/src/SalesTransaction.php b/src/SalesTransaction.php index 1bc0d746..c86d7cac 100644 --- a/src/SalesTransaction.php +++ b/src/SalesTransaction.php @@ -2,63 +2,28 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionFields\DueDateField; -use PhpTwinfield\Transactions\TransactionFields\InvoiceNumberField; -use PhpTwinfield\Transactions\TransactionFields\PaymentReferenceField; -use PhpTwinfield\Transactions\TransactionLineFields\ThreeDimFields; +use PhpTwinfield\Fields\DueDateField; +use PhpTwinfield\Fields\InvoiceNumberField; +use PhpTwinfield\Fields\Transaction\InvoiceNumberRaiseWarningField; +use PhpTwinfield\Fields\Transaction\OriginReferenceField; +use PhpTwinfield\Fields\Transaction\PaymentReferenceField; -/** +/* * @link https://c3.twinfield.com/webservices/documentation/#/ApiReference/SalesTransactions */ class SalesTransaction extends BaseTransaction { use DueDateField; use InvoiceNumberField; + use InvoiceNumberRaiseWarningField; + use OriginReferenceField; use PaymentReferenceField; - use ThreeDimFields; - /** - * @var string|null The sales transaction origin reference (id). Provided in form of Guid. Read-only attribute. - * Sample: "f386393c-e4ba-439a-add4-3b366535d7bf". - */ - private $originReference; - - /** + /* * @return string */ public function getLineClassName(): string { return SalesTransactionLine::class; } - - /** - * @return string|null - */ - public function getOriginReference(): ?string - { - return $this->originReference; - } - - /** - * @param string|null $originReference - * @return $this - */ - public function setOriginReference(?string $originReference): SalesTransaction - { - $this->originReference = $originReference; - - return $this; - } - - /** - * When creating a new sales transaction, don't include this tag as the transaction number is determined by the - * system. When updating a sales transaction, the related transaction number should be provided. - * - * @param int|null $number - * @return $this - */ - public function setNumber(?int $number): BaseTransaction - { - return parent::setNumber($number); - } } diff --git a/src/SalesTransactionLine.php b/src/SalesTransactionLine.php index f33175be..1366e501 100644 --- a/src/SalesTransactionLine.php +++ b/src/SalesTransactionLine.php @@ -3,27 +3,38 @@ namespace PhpTwinfield; use Money\Money; -use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionFields\FreeTextFields; -use PhpTwinfield\Transactions\TransactionLineFields\PerformanceFields; -use PhpTwinfield\Transactions\TransactionLineFields\ValueOpenField; -use PhpTwinfield\Transactions\TransactionLineFields\VatTotalFields; +use PhpTwinfield\Enums\PerformanceType; +use PhpTwinfield\Enums\MatchStatus; +use PhpTwinfield\Fields\PerformanceDateField; +use PhpTwinfield\Fields\PerformanceTypeField; +use PhpTwinfield\Fields\Transaction\TransactionLine\BaselineField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceCountryField; +use PhpTwinfield\Fields\Transaction\TransactionLine\PerformanceVatNumberField; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueOpenField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatBaseTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatRepTotalField; +use PhpTwinfield\Fields\Transaction\TransactionLine\VatTotalField; use Webmozart\Assert\Assert; class SalesTransactionLine extends BaseTransactionLine { - use VatTotalFields; + use BaselineField; + use PerformanceCountryField; + use PerformanceDateField; + use PerformanceTypeField; + use PerformanceVatNumberField; use ValueOpenField; - use PerformanceFields; - use FreeTextFields; + use VatBaseTotalField; + use VatRepTotalField; + use VatTotalField; - /** + /* * @var SalesTransaction */ private $transaction; - /** + /* * @param SalesTransaction $object */ public function setTransaction($object): void @@ -33,7 +44,7 @@ public function setTransaction($object): void $this->transaction = $object; } - /** + /* * References the transaction this line belongs too. * * @return SalesTransaction @@ -43,35 +54,52 @@ public function getTransaction(): SalesTransaction return $this->transaction; } - /** - * If line type = total the accounts receivable balance account. When dim1 is omitted, by default the general ledger - * account will be taken as entered at the customer in Twinfield. - * - * If line type = detail the profit and loss account. + /* + * Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. * - * If line type = vat the VAT balance account. When an empty dim1 is entered, by default the general ledger account - * will be taken as entered at the VAT code in Twinfield. + * @param int|null $baseline + * @return $this + * @throws Exception + */ + public function setBaseline(?int $baseline): self + { + if (!$this->getLineType()->equals(LineType::VAT())) { + throw Exception::invalidFieldForLineType("baseline", $this); + } + + $this->baseline = $baseline; + + return $this; + } + + /* + * Only if line type is total. The amount still owed in base currency. Read-only attribute. * - * @param string|null $dim1 + * @param Money|null $baseValueOpen * @return $this + * @throws Exception */ - public function setDim1(?string $dim1): BaseTransactionLine + public function setBaseValueOpen(?Money $baseValueOpen): parent { - return parent::setDim1($dim1); + if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('basevalueopen', $this); + } + + return parent::setBaseValueOpen($baseValueOpen); } - /** + /* * If line type = total the account receivable. * * If line type = detail the cost center or empty. * * If line type = vat empty. * - * @param string|null $dim2 + * @param $dim2 * @return $this * @throws Exception */ - public function setDim2(?string $dim2): BaseTransactionLine + public function setDim2($dim2): parent { if ($dim2 !== null && $this->getLineType()->equals(LineType::VAT())) { throw Exception::invalidDimensionForLineType(2, $this); @@ -80,177 +108,247 @@ public function setDim2(?string $dim2): BaseTransactionLine return parent::setDim2($dim2); } - /** - * If line type = total - * - In case of a 'normal' sales transaction debit. - * - In case of a credit sales transaction credit. + /* + * If line type = total empty. + * + * If line type = detail the project or asset or empty. * - * If line type = detail or vat - * - In case of a 'normal' sales transaction credit. - * - In case of a credit sales transaction debit. + * If line type = empty. * - * @param DebitCredit $debitCredit + * @param $dim3 * @return $this + * @throws Exception */ - public function setDebitCredit(DebitCredit $debitCredit): BaseTransactionLine + public function setDim3($dim3): parent { - return parent::setDebitCredit($debitCredit); + if ($dim3 !== null && ($this->getLineType()->equals(LineType::TOTAL()) || $this->getLineType()->equals(LineType::VAT()))) { + throw Exception::invalidDimensionForLineType(3, $this); + } + + return parent::setDim3($dim3); } - /** - * If line type = total amount including VAT. + /* + * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction + * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. * - * If line type = detail amount without VAT. + * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing + * transaction type is a Purchase Transaction. * - * If line type = vat VAT amount. + * @return bool + */ + protected function isIncomingTransactionType(): bool + { + return true; + } + + /* + * Only if line type is total. The level of the matchable dimension. Read-only attribute. * - * @param Money $value + * @param int|null $matchLevel * @return $this + * @throws Exception */ - public function setValue(Money $value): BaseTransactionLine + public function setMatchLevel(?int $matchLevel): parent { - return parent::setValue($value); + if ($matchLevel !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('matchlevel', $this); + } + + return parent::setMatchLevel($matchLevel); } - /** - * Payment status of the sales transaction. If line type detail or vat always notmatchable. Read-only attribute. + /* + * Payment status of the transaction. If line type detail or vat always notmatchable. Read-only attribute. + * NOTE: The above statement from the Twinfield API documentation is incorrect as detail lines can also have other match statuses than notmatchable * - * @param string|null $matchStatus + * @param MatchStatus|null $matchStatus * @return $this * @throws Exception */ - public function setMatchStatus(?string $matchStatus): BaseTransactionLine + public function setMatchStatus(?MatchStatus $matchStatus): parent { - if ( - $matchStatus !== null && - in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) && - $matchStatus != self::MATCHSTATUS_NOTMATCHABLE - ) { + //if ($matchStatus !== null && in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { + if ($matchStatus !== null && in_array($this->getLineType(), [LineType::VAT()]) && $matchStatus != MatchStatus::NOTMATCHABLE()) { throw Exception::invalidMatchStatusForLineType($matchStatus, $this); } return parent::setMatchStatus($matchStatus); } - /** - * Only if line type is total. The level of the matchable dimension. Read-only attribute. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The performance type. * - * @param int|null $matchLevel + * @param PerformanceType|null $performanceType * @return $this * @throws Exception */ - public function setMatchLevel(?int $matchLevel): BaseTransactionLine + public function setPerformanceType(?PerformanceType $performanceType): self { - if ($matchLevel !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('matchLevel', $this); + if ($performanceType !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancetype', $this); } - return parent::setMatchLevel($matchLevel); + $this->performanceType = $performanceType; + + return $this; } - /** - * Only if line type is total. The amount still owed in base currency. Read-only attribute. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. The ISO country codes are used. If not added to the request, by default the country code of the customer will be taken. * - * @param Money|null $baseValueOpen + * @param Country|null $performanceCountry * @return $this * @throws Exception */ - public function setBaseValueOpen(?Money $baseValueOpen): BaseTransactionLine + public function setPerformanceCountry(?Country $performanceCountry): self { - if ($baseValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('baseValueOpen', $this); + if ($performanceCountry !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancecountry', $this); } - return parent::setBaseValueOpen($baseValueOpen); + $this->performanceCountry = $performanceCountry; + + return $this; } - /** - * If line type = detail the project or asset or empty. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code. If not added to the request, by default the VAT number of the customer will be taken. * - * @param string $dim3 + * @param string|null $performanceVatNumber * @return $this * @throws Exception */ - public function setProjectAsset(string $dim3) + public function setPerformanceVatNumber(?string $performanceVatNumber): self { - if (!$this->getLineType()->equals(LineType::DETAIL())) { - throw Exception::invalidDimensionForLineType(3, $this); + if ($performanceVatNumber !== null && $this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('performancevatnumber', $this); } - return $this->setDim3($dim3); + $this->performanceVatNumber = $performanceVatNumber; + + return $this; } - /** - * Only if line type is vat. Amount on which VAT was calculated in the currency of the sales transaction. + /* + * Only if line type is detail or vat. Mandatory in case of an ICT VAT code but only if performancetype is services. * - * @param Money|null $vatTurnover + * @param \DateTimeInterface|null $performanceDate * @return $this * @throws Exception */ - public function setVatTurnover(?Money $vatTurnover) + public function setPerformanceDate(?\DateTimeInterface $performanceDate): self { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType("vatturnover", $this); + if ($performanceDate !== null && (!$this->getPerformanceType()->equals(PerformanceType::SERVICES()) || $this->getLineType()->equals(LineType::TOTAL()))) { + throw Exception::invalidFieldForLineType('performancedate', $this); } - return parent::setVatTurnOver($vatTurnover); + + $this->performanceDate = $performanceDate; + + return $this; } - /** - * Only if line type is vat. Amount on which VAT was calculated in base currency. + /* + * Relation of the transaction. Only if line type is total. Read-only attribute. * - * @param Money|null $vatBaseTurnover + * @param int|null $relation * @return $this * @throws Exception */ - public function setVatBaseTurnover(?Money $vatBaseTurnover) + public function setRelation(?int $relation): parent { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType("vatbaseturnover", $this); + if ($relation !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('relation', $this); } - return parent::setVatBaseTurnover($vatBaseTurnover); + + return parent::setRelation($relation); } - /** - * Only if line type is vat. Amount on which VAT was calculated in reporting currency. + /* + * Only if line type is total. The amount still owed in reporting currency. Read-only attribute. * - * @param Money|null $vatRepTurnover + * @param Money|null $reValueOpen * @return $this * @throws Exception */ - public function setVatRepTurnover(?Money $vatRepTurnover) + public function setRepValueOpen(?Money $reValueOpen): parent { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType("vatrepturnover", $this); + if ($reValueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('repvalueopen', $this); } - return parent::setVatRepTurnover($vatRepTurnover); + + return parent::setRepValueOpen($reValueOpen); } - /** - * Only if line type is vat. The value of the baseline tag is a reference to the line ID of the VAT rate. + /* + * Only if line type is total. The amount still to be paid in the currency of the sales transaction. Read-only attribute. * - * @param int|null $baseline + * @param Money|null $valueOpen * @return $this * @throws Exception */ - public function setBaseline(?int $baseline) + public function setValueOpen(?Money $valueOpen): self { - if (!$this->getLineType()->equals(LineType::VAT())) { - throw Exception::invalidFieldForLineType("baseline", $this); + if ($valueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('valueopen', $this); } - return parent::setBaseline($baseline); + + $this->valueOpen = $valueOpen; + + return $this; } - /** - * Returns true if a positive amount in the TOTAL line means the amount is 'debit'. Examples of incoming transaction - * types are Sales Transactions, Electronic Bank Statements and Bank Transactions. + /* + * Only if line type is total. The total VAT amount in the currency of the sales transaction * - * Returns false if a positive amount in the TOTAL line means the amount is 'credit'. An example of an outgoing - * transaction type is a Purchase Transaction. + * @param Money|null $vatTotal + * @return $this + * @throws Exception + */ + public function setVatTotal(?Money $vatTotal): self + { + if ($vatTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vattotal', $this); + } + + $this->vatTotal = $vatTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in base currency. * - * @return bool + * @param Money|null $vatBaseTotal + * @return $this + * @throws Exception */ - protected function isIncomingTransactionType(): bool + public function setVatBaseTotal(?Money $vatBaseTotal): self { - return true; + if ($vatBaseTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatbasetotal', $this); + } + + $this->vatBaseTotal = $vatBaseTotal; + + return $this; + } + + /* + * Only if line type is total. The total VAT amount in reporting currency. + * + * @param Money|null $vatRepTotal + * @return $this + * @throws Exception + */ + public function setVatRepTotal(?Money $vatRepTotal): self + { + if ($vatRepTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { + throw Exception::invalidFieldForLineType('vatreptotal', $this); + } + + $this->vatRepTotal = $vatRepTotal; + + return $this; } } diff --git a/src/Secure/OpenIdConnectAuthentication.php b/src/Secure/OpenIdConnectAuthentication.php index 36ee7a3f..d60e438b 100644 --- a/src/Secure/OpenIdConnectAuthentication.php +++ b/src/Secure/OpenIdConnectAuthentication.php @@ -48,11 +48,13 @@ class OpenIdConnectAuthentication extends AuthenticatedConnection * Please note that for most calls an office is mandatory. If you do not supply it * you have to pass it with every request, or call setOffice. */ - public function __construct(OAuthProvider $provider, string $refreshToken, ?Office $office) + public function __construct(OAuthProvider $provider, string $refreshToken, ?Office $office, string $accessToken = null, string $cluster = null) { $this->provider = $provider; + $this->accessToken = $accessToken; $this->refreshToken = $refreshToken; $this->office = $office; + $this->cluster = $cluster; } public function setOffice(?Office $office) @@ -95,8 +97,10 @@ protected function login(): void $this->refreshToken(); } - $validationResult = $this->validateToken(); - $this->cluster = $validationResult["twf.clusterUrl"]; + if ($this->cluster === null) { + $validationResult = $this->validateToken(); + $this->cluster = $validationResult["twf.clusterUrl"]; + } } /** @@ -139,4 +143,4 @@ protected function refreshToken(): void $this->accessToken = $accessToken->getToken(); } -} \ No newline at end of file +} diff --git a/src/Secure/Provider/InvalidAccessTokenException.php b/src/Secure/Provider/InvalidAccessTokenException.php index 8134776f..e484e98f 100644 --- a/src/Secure/Provider/InvalidAccessTokenException.php +++ b/src/Secure/Provider/InvalidAccessTokenException.php @@ -4,4 +4,4 @@ class InvalidAccessTokenException extends OAuthException { -} \ No newline at end of file +} diff --git a/src/Secure/Provider/OAuthException.php b/src/Secure/Provider/OAuthException.php index 77188280..44999e38 100644 --- a/src/Secure/Provider/OAuthException.php +++ b/src/Secure/Provider/OAuthException.php @@ -4,4 +4,4 @@ class OAuthException extends \Exception { -} \ No newline at end of file +} diff --git a/src/Secure/Provider/ResourceOwner.php b/src/Secure/Provider/ResourceOwner.php index 6baf79f9..c4774789 100644 --- a/src/Secure/Provider/ResourceOwner.php +++ b/src/Secure/Provider/ResourceOwner.php @@ -31,4 +31,4 @@ public function toArray(): array { return $this->response; } -} \ No newline at end of file +} diff --git a/src/Secure/WebservicesAuthentication.php b/src/Secure/WebservicesAuthentication.php index eca9085c..3d725fc5 100644 --- a/src/Secure/WebservicesAuthentication.php +++ b/src/Secure/WebservicesAuthentication.php @@ -121,4 +121,4 @@ protected function getCluster(): string { return $this->cluster; } -} \ No newline at end of file +} diff --git a/src/Services/BaseService.php b/src/Services/BaseService.php index 8c424909..9391637d 100644 --- a/src/Services/BaseService.php +++ b/src/Services/BaseService.php @@ -41,4 +41,9 @@ public function __construct(string $wsdl = null, array $options = []) parent::__construct($wsdl, $options); } + + public function __call($func, $args) + { + return $this->__soapCall($func, $args); + } } diff --git a/src/Services/FinderService.php b/src/Services/FinderService.php index 1da663b6..8bcd3ae4 100644 --- a/src/Services/FinderService.php +++ b/src/Services/FinderService.php @@ -96,4 +96,4 @@ public function searchFinder( ] ); } -} \ No newline at end of file +} diff --git a/src/Services/ProcessXmlService.php b/src/Services/ProcessXmlService.php index f6204e5f..4a8e0e4f 100644 --- a/src/Services/ProcessXmlService.php +++ b/src/Services/ProcessXmlService.php @@ -37,7 +37,7 @@ public function chunk(array $items): array * * If there is an error in the response, an Exception is thrown, but it can also throw SoapFaults. * - * Note that you will probably have to chunk the objects into several documents if you want to send many objects. + * Note that you will probably have to chunk the objects into several documents if you want to send many objects. * * @param \DOMDocument $document * @return Response The response from the request @@ -86,4 +86,4 @@ public function mapAll(array $responses, string $individualTag, callable $mapCal return $mappedResponses; } -} \ No newline at end of file +} diff --git a/src/Supplier.php b/src/Supplier.php index 3ae9a054..120e8b41 100644 --- a/src/Supplier.php +++ b/src/Supplier.php @@ -2,347 +2,207 @@ namespace PhpTwinfield; -use PhpTwinfield\Transactions\TransactionFields\OfficeField; -use PhpTwinfield\Transactions\TransactionLineFields\VatCodeField; +use PhpTwinfield\Fields\BehaviourField; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\Dimensions\BeginPeriodField; +use PhpTwinfield\Fields\Dimensions\BeginYearField; +use PhpTwinfield\Fields\Dimensions\DimensionGroup\GroupField; +use PhpTwinfield\Fields\Dimensions\DimensionType\TypeField; +use PhpTwinfield\Fields\Dimensions\EndPeriodField; +use PhpTwinfield\Fields\Dimensions\EndYearField; +use PhpTwinfield\Fields\Dimensions\Level2\PaymentConditionDiscountDaysField; +use PhpTwinfield\Fields\Dimensions\Level2\PaymentConditionDiscountPercentageField; +use PhpTwinfield\Fields\Dimensions\Level2\RemittanceAdviceSendMailField; +use PhpTwinfield\Fields\Dimensions\Level2\RemittanceAdviceSendTypeField; +use PhpTwinfield\Fields\Dimensions\Level2\Supplier\BlockedAccountPaymentConditionsIncludeVatField; +use PhpTwinfield\Fields\Dimensions\Level2\Supplier\BlockedAccountPaymentConditionsPercentageField; +use PhpTwinfield\Fields\Dimensions\Level2\WebsiteField; +use PhpTwinfield\Fields\InUseField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; +use PhpTwinfield\Fields\TouchedField; +use PhpTwinfield\Fields\UIDField; /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Suppliers * @todo Add documentation and typehints to all properties. */ -class Supplier +class Supplier extends BaseObject implements HasCodeInterface { + use BeginPeriodField; + use BeginYearField; + use BehaviourField; + use BlockedAccountPaymentConditionsIncludeVatField; + use BlockedAccountPaymentConditionsPercentageField; + use CodeField; + use EndPeriodField; + use EndYearField; + use GroupField; + use InUseField; + use NameField; use OfficeField; - use VatCodeField; - - private $code; - private $UID; - private $status; - private $name; - - /** - * Dimension type of suppliers is CRD. - * - * @var string - */ - private $type = "CRD"; - - private $inUse; - private $behaviour; - private $touched; - private $beginPeriod; - private $beginYear; - private $endPeriod; - private $endYear; - private $website; - private $cocNumber; - private $vatNumber; - private $editDimensionName; - private $dueDays = 0; - private $payAvailable = false; - private $payCode; - private $eBilling = false; - private $eBillMail; - private $addresses = array(); - private $banks = array(); - private $groups; - - public function getCode() - { - return $this->code; - } - - public function setCode($code) - { - $this->code = $code; - return $this; - } - - public function getID() - { - trigger_error('getID is a deprecated method: Use getCode', E_USER_NOTICE); - return $this->getCode(); - } - - public function setID($ID) - { - trigger_error('setID is a deprecated method: Use setCode', E_USER_NOTICE); - return $this->setCode($ID); - } - - public function getUID() - { - return $this->UID; - } - - public function setUID($UID) - { - $this->UID = $UID; - return $this; - } - - public function getStatus() - { - return $this->status; - } - - public function setStatus($status) - { - $this->status = $status; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - return $this; - } - - public function getType() - { - return $this->type; - } - - public function setType($type) - { - $this->type = $type; - return $this; - } - - public function getInUse() - { - return $this->inUse; - } - - public function setInUse($inUse) - { - $this->inUse = $inUse; - return $this; - } - - public function getBehaviour() - { - return $this->behaviour; - } + use PaymentConditionDiscountDaysField; + use PaymentConditionDiscountPercentageField; + use RemittanceAdviceSendMailField; + use RemittanceAdviceSendTypeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + use WebsiteField; - public function setBehaviour($behaviour) - { - $this->behaviour = $behaviour; - return $this; - } + private $financials; - public function getTouched() - { - return $this->touched; - } + private $addresses = []; + private $banks = []; + private $postingRules = []; - public function setTouched($touched) + public function __construct() { - $this->touched = $touched; - return $this; - } + $this->setBeginPeriod(0); + $this->setBeginYear(0); + $this->setEndPeriod(0); + $this->setEndYear(0); + $this->setType(\PhpTwinfield\DimensionType::fromCode('CRD')); - public function getBeginPeriod() - { - return $this->beginPeriod; + $this->setFinancials(new SupplierFinancials); } - public function setBeginPeriod($beginPeriod) - { - $this->beginPeriod = $beginPeriod; - return $this; - } - - public function getBeginYear() - { - return $this->beginYear; - } - - public function setBeginYear($beginYear) - { - $this->beginYear = $beginYear; - return $this; - } - - public function getEndPeriod() - { - return $this->endPeriod; - } - - public function setEndPeriod($endPeriod) - { - $this->endPeriod = $endPeriod; - return $this; - } - - public function getEndYear() - { - return $this->endYear; - } + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); - public function setEndYear($endYear) - { - $this->endYear = $endYear; - return $this; + return $instance; } - public function getWebsite() + public function getFinancials(): SupplierFinancials { - return $this->website; + return $this->financials; } - public function setWebsite($website) + public function setFinancials(SupplierFinancials $financials) { - $this->website = $website; + $this->financials = $financials; return $this; } - public function getCocNumber() + public function getAddresses() { - trigger_error('setCocNumber is a deprecated method: get from SupplierAddress::field05', E_USER_NOTICE); - return $this->cocNumber; + return $this->addresses; } - public function setCocNumber($cocNumber) + public function addAddress(SupplierAddress $address) { - trigger_error('setCocNumber is a deprecated method: add to SupplierAddress::field05', E_USER_NOTICE); - $this->cocNumber = $cocNumber; + $this->addresses[] = $address; return $this; } - public function getVatNumber() - { - trigger_error('setVatNumber is a deprecated method: add to SupplierAddress::field04', E_USER_NOTICE); - return $this->vatNumber; - } - - public function setVatNumber($vatNumber) + public function removeAddress($index) { - trigger_error('setVatNumber is a deprecated method: get SupplierAddress::field04', E_USER_NOTICE); - $this->vatNumber = $vatNumber; - return $this; + if (array_key_exists($index, $this->addresses)) { + unset($this->addresses[$index]); + return true; + } else { + return false; + } } - public function getEditDimensionName() + public function removeAddressByID($id) { - return $this->editDimensionName; - } + $found = false; - public function setEditDimensionName($editDimensionName) - { - $this->editDimensionName = $editDimensionName; - return $this; - } + foreach ($this->addresses as $index => $address) { + if ($id == $address->getID()) { + unset($this->addresses[$index]); + $found = true; + } + } - public function getDueDays() - { - return $this->dueDays; - } + if ($found) { + return true; + } - public function setDueDays($dueDays) - { - $this->dueDays = $dueDays; - return $this; + return false; } - public function getPayAvailable(): bool + public function getBanks() { - return $this->payAvailable; + return $this->banks; } - public function setPayAvailable(bool $payAvailable): self + public function addBank(SupplierBank $bank) { - $this->payAvailable = $payAvailable; + $this->banks[] = $bank; return $this; } - public function getPayCode() - { - return $this->payCode; - } - - public function setPayCode($payCode) + public function removeBank($index) { - $this->payCode = $payCode; - return $this; + if (array_key_exists($index, $this->banks)) { + unset($this->banks[$index]); + return true; + } else { + return false; + } } - public function getEBilling(): bool + public function removeBankByID($id) { - return $this->eBilling; - } + $found = false; - public function setEBilling(bool $eBilling): self - { - $this->eBilling = $eBilling; - return $this; - } + foreach ($this->banks as $index => $bank) { + if ($id == $bank->getID()) { + unset($this->banks[$index]); + $found = true; + } + } - public function getEBillMail() - { - return $this->eBillMail; - } + if ($found) { + return true; + } - public function setEBillMail($eBillMail) - { - $this->eBillMail = $eBillMail; - return $this; + return false; } - public function getAddresses() + public function getPostingRules() { - return $this->addresses; + return $this->postingRules; } - public function addAddress(SupplierAddress $address) + public function addPostingRule(SupplierPostingRule $postingRule) { - $this->addresses[$address->getID()] = $address; + $this->postingRules[] = $postingRule; return $this; } - public function removeAddress($index) + public function removePostingRule($index) { - if (array_key_exists($index, $this->addresses)) { - unset($this->addresses[$index]); + if (array_key_exists($index, $this->postingRules)) { + unset($this->postingRules[$index]); return true; } else { return false; } } - public function getBanks() + public function removePostingRuleByID($id) { - return $this->banks; - } + $found = false; - public function addBank(SupplierBank $bank) - { - $this->banks[$bank->getID()] = $bank; - return $this; - } + foreach ($this->postingRules as $index => $postingRule) { + if ($id == $postingRule->getID()) { + unset($this->postingRules[$index]); + $found = true; + } + } - public function removeBank($index) - { - if (array_key_exists($index, $this->banks)) { - unset($this->banks[$index]); + if ($found) { return true; - } else { - return false; } - } - public function getGroups() - { - return $this->groups; - } - - public function setGroups($groups) - { - $this->groups = $groups; - return $this; + return false; } } diff --git a/src/SupplierAddress.php b/src/SupplierAddress.php index 84d2301d..8202089f 100644 --- a/src/SupplierAddress.php +++ b/src/SupplierAddress.php @@ -2,219 +2,43 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\Dimensions\Level2\CityField; +use PhpTwinfield\Fields\Dimensions\Level2\CountryField; +use PhpTwinfield\Fields\Dimensions\Level2\DefaultField; +use PhpTwinfield\Fields\Dimensions\Level2\Field1Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field2Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field3Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field4Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field5Field; +use PhpTwinfield\Fields\Dimensions\Level2\Field6Field; +use PhpTwinfield\Fields\Dimensions\Level2\PostcodeField; +use PhpTwinfield\Fields\Dimensions\Level2\TelefaxField; +use PhpTwinfield\Fields\Dimensions\Level2\TelephoneField; +use PhpTwinfield\Fields\Dimensions\Level2\TypeField; +use PhpTwinfield\Fields\EmailField; +use PhpTwinfield\Fields\IDField; +use PhpTwinfield\Fields\NameField; + /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Suppliers * @todo Add documentation and typehints to all properties. */ -class SupplierAddress +class SupplierAddress extends BaseObject { - private $ID; - private $type; - private $default; - private $name; - private $contact; - private $country; - private $city; - private $postcode; - private $telephone; - private $fax; - private $email; - private $field1; - private $field2; - private $field3; - private $field4; - private $field5; - private $field6; - - public function __construct() - { - $this->ID = uniqid(); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - public function getType() - { - return $this->type; - } - - public function setType($type) - { - $this->type = $type; - return $this; - } - - public function getDefault() - { - return $this->default; - } - - public function setDefault($default) - { - $this->default = $default; - return $this; - } - - public function getName() - { - return $this->name; - } - - public function setName($name) - { - $this->name = $name; - return $this; - } - - public function getContact() - { - return $this->contact; - } - - public function setContact($contact) - { - $this->contact = $contact; - return $this; - } - - public function getCountry() - { - return $this->country; - } - - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - public function getCity() - { - return $this->city; - } - - public function setCity($city) - { - $this->city = $city; - return $this; - } - - public function getPostcode() - { - return $this->postcode; - } - - public function setPostcode($postcode) - { - $this->postcode = $postcode; - return $this; - } - - public function getTelephone() - { - return $this->telephone; - } - - public function setTelephone($telephone) - { - $this->telephone = $telephone; - return $this; - } - - public function getFax() - { - return $this->fax; - } - - public function setFax($fax) - { - $this->fax = $fax; - return $this; - } - - public function getEmail() - { - return $this->email; - } - - public function setEmail($email) - { - $this->email = $email; - return $this; - } - - public function getField1() - { - return $this->field1; - } - - public function setField1($field1) - { - $this->field1 = $field1; - return $this; - } - - public function getField2() - { - return $this->field2; - } - - public function setField2($field2) - { - $this->field2 = $field2; - return $this; - } - - public function getField3() - { - return $this->field3; - } - - public function setField3($field3) - { - $this->field3 = $field3; - return $this; - } - - public function getField4() - { - return $this->field4; - } - - public function setField4($field4) - { - $this->field4 = $field4; - return $this; - } - - public function getField5() - { - return $this->field5; - } - - public function setField5($field5) - { - $this->field5 = $field5; - return $this; - } - - public function getField6() - { - return $this->field6; - } - - public function setField6($field6) - { - $this->field6 = $field6; - return $this; - } + use CityField; + use CountryField; + use DefaultField; + use EmailField; + use Field1Field; + use Field2Field; + use Field3Field; + use Field4Field; + use Field5Field; + use Field6Field; + use IDField; + use NameField; + use PostcodeField; + use TelefaxField; + use TelephoneField; + use TypeField; } diff --git a/src/SupplierBank.php b/src/SupplierBank.php index 02c1d145..1f9c3613 100644 --- a/src/SupplierBank.php +++ b/src/SupplierBank.php @@ -2,183 +2,41 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\Dimensions\Level2\AccountNumberField; +use PhpTwinfield\Fields\Dimensions\Level2\AddressField2Field; +use PhpTwinfield\Fields\Dimensions\Level2\AddressField3Field; +use PhpTwinfield\Fields\Dimensions\Level2\AscriptionField; +use PhpTwinfield\Fields\Dimensions\Level2\BankBlockedField; +use PhpTwinfield\Fields\Dimensions\Level2\BankNameField; +use PhpTwinfield\Fields\Dimensions\Level2\BicCodeField; +use PhpTwinfield\Fields\Dimensions\Level2\CityField; +use PhpTwinfield\Fields\Dimensions\Level2\CountryField; +use PhpTwinfield\Fields\Dimensions\Level2\DefaultField; +use PhpTwinfield\Fields\Dimensions\Level2\IbanField; +use PhpTwinfield\Fields\Dimensions\Level2\NatBicCodeField; +use PhpTwinfield\Fields\Dimensions\Level2\PostcodeField; +use PhpTwinfield\Fields\Dimensions\Level2\StateField; +use PhpTwinfield\Fields\IDField; + /** * @see https://c3.twinfield.com/webservices/documentation/#/ApiReference/Masters/Suppliers * @todo Add documentation and typehints to all properties. */ -class SupplierBank +class SupplierBank extends BaseObject { - private $ID; # integer Sequence number of the bank account line. - private $default; # true/false Is this the default bank account, only one default bank account is possible. - private $ascription; # string(40) Account holder. - private $accountnumber; # string(40) Account number. - private $addressField2; # string(128) Bank address. - private $addressField3; # string(128) Bank address number. - private $bankname; # string(40) Bank name. - private $biccode; # string(16) BIC code. - private $city; # string(40) City. - private $country; # string(2) Bank country code. The ISO country codes are used. - private $iban; # string(40) IBAN account number. - private $natbiccode; # string(20) National bank code. - private $postcode; # string(16) Postcode. - private $state; # string(40) State. - - public function __construct() - { - $this->ID = uniqid(); - } - - public function getID() - { - return $this->ID; - } - - public function setID($ID) - { - $this->ID = $ID; - return $this; - } - - public function getDefault() - { - return $this->default; - } - - public function setDefault($default) - { - $this->default = $default; - return $this; - } - - public function getAscription() - { - return $this->ascription; - } - - public function setAscription($ascription) - { - $this->ascription = $ascription; - return $this; - } - - public function getAccountnumber() - { - return $this->accountnumber; - } - - public function setAccountnumber($accountnumber) - { - $this->accountnumber = $accountnumber; - return $this; - } - - public function getAddressField2() - { - return $this->addressField2; - } - - public function setAddressField2($addressField2) - { - $this->addressField2 = $addressField2; - return $this; - } - - public function getAddressField3() - { - return $this->addressField3; - } - - public function setAddressField3($addressField3) - { - $this->addressField3 = $addressField3; - return $this; - } - - public function getBankname() - { - return $this->bankname; - } - - public function setBankname($bankname) - { - $this->bankname = $bankname; - return $this; - } - - public function getBiccode() - { - return $this->biccode; - } - - public function setBiccode($biccode) - { - $this->biccode = $biccode; - return $this; - } - - public function getCity() - { - return $this->city; - } - - public function setCity($city) - { - $this->city = $city; - return $this; - } - - public function getCountry() - { - return $this->country; - } - - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - public function getIban() - { - return $this->iban; - } - - public function setIban($iban) - { - $this->iban = $iban; - return $this; - } - - public function getNatbiccode() - { - return $this->natbiccode; - } - - public function setNatbiccode($natbiccode) - { - $this->natbiccode = $natbiccode; - return $this; - } - - public function getPostcode() - { - return $this->postcode; - } - - public function setPostcode($postcode) - { - $this->postcode = $postcode; - return $this; - } - - public function getState() - { - return $this->state; - } - - public function setState($state) - { - $this->state = $state; - return $this; - } + use AccountNumberField; + use AddressField2Field; + use AddressField3Field; + use AscriptionField; + use BankBlockedField; + use BankNameField; + use BicCodeField; + use CityField; + use CountryField; + use DefaultField; + use IbanField; + use IDField; + use NatBicCodeField; + use PostcodeField; + use StateField; } diff --git a/src/SupplierChildValidation.php b/src/SupplierChildValidation.php new file mode 100644 index 00000000..69dd5377 --- /dev/null +++ b/src/SupplierChildValidation.php @@ -0,0 +1,18 @@ +setAccountType(\PhpTwinfield\Enums\AccountType::INHERIT()); + $this->setDueDays(30); + $this->setMatchType(\PhpTwinfield\Enums\MatchType::CUSTOMERSUPPLIER()); + $this->setSubAnalyse(\PhpTwinfield\Enums\SubAnalyse::FALSE()); + $this->setSubstitutionLevel(1); + } + + public function getChildValidations() + { + return $this->childValidations; + } + + public function addChildValidation(SupplierChildValidation $childValidation) + { + $this->childValidations[] = $childValidation; + return $this; + } + + public function removeChildValidation($index) + { + if (array_key_exists($index, $this->childValidations)) { + unset($this->childValidations[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/SupplierLine.php b/src/SupplierLine.php new file mode 100644 index 00000000..c56a035d --- /dev/null +++ b/src/SupplierLine.php @@ -0,0 +1,32 @@ +lines; + } + + public function addLine(SupplierLine $line) + { + $this->lines[] = $line; + return $this; + } + + public function removeLine($index) + { + if (array_key_exists($index, $this->lines)) { + unset($this->lines[$index]); + return true; + } else { + return false; + } + } +} diff --git a/src/Transactions/TransactionLine.php b/src/TransactionLineInterface.php similarity index 53% rename from src/Transactions/TransactionLine.php rename to src/TransactionLineInterface.php index 4ebf3898..6a52df91 100644 --- a/src/Transactions/TransactionLine.php +++ b/src/TransactionLineInterface.php @@ -1,43 +1,26 @@ transaction; - } - - /** - * @param BankTransaction $object - */ - public function setTransaction($object): void - { - Assert::null($this->transaction, "Attempting to set a transaction while the transaction is already set."); - Assert::isInstanceOf($object, BankTransaction::class); - $this->transaction = $object; - } - - /** - * @return LineType - */ - final public function getLineType(): LineType - { - return $this->lineType; - } - - /** - * @param LineType $lineType - * @return $this - */ - final protected function setLineType(LineType $lineType) - { - $this->lineType = $lineType; - return $this; - } - - /** - * @return string - */ - public function getDescription(): ?string - { - return $this->description; - } - - /** - * @param string $description - * @return $this - */ - public function setDescription(string $description) - { - $this->description = $description; - return $this; - } - - /** - * @return null|Office - */ - public function getDestOffice(): ?Office - { - return $this->destOffice; - } - - /** - * Used for inter company transactions – here you define in which company the transaction line should be posted. - * - * @param Office $destOffice - * @return $this - */ - public function setDestOffice(Office $destOffice) - { - $this->destOffice = $destOffice; - return $this; - } - - public function getId(): ?int - { - return $this->id; - } - - /** - * @param int $id - * @return $this - */ - public function setId(int $id) - { - $this->id = $id; - return $this; - } - - public function getReference(): MatchReferenceInterface - { - $transaction = $this->getTransaction(); - - return new MatchReference( - $transaction->getOffice(), - $transaction->getCode(), - $transaction->getNumber(), - $this->getId() - ); - } - - protected function isIncomingTransactionType(): bool - { - return true; - } -} diff --git a/src/Transactions/BankTransactionLine/Detail.php b/src/Transactions/BankTransactionLine/Detail.php deleted file mode 100644 index 772784e8..00000000 --- a/src/Transactions/BankTransactionLine/Detail.php +++ /dev/null @@ -1,153 +0,0 @@ -vatValue = $vatValue; - - return $this; - } - - /** - * @param Money $vatBaseValue - * @return Detail - */ - public function setVatBaseValue(Money $vatBaseValue): Detail - { - $this->vatBaseValue = $vatBaseValue; - - return $this; - } - - /** - * @param Money $vatRepValue - * @return Detail - */ - public function setVatRepValue(Money $vatRepValue): Detail - { - $this->vatRepValue = $vatRepValue; - - return $this; - } - - /** - * VAT amount in base currency. - * - * @var Money|null - */ - private $vatBaseValue; - - /** - * VAT amount in reporting currency. - * - * @var Money|null - */ - private $vatRepValue; - - public function __construct() - { - $this->setLineType(LineType::DETAIL()); - } - - /** - * Set the customer or supplier balance account or profit and loss account. - * - * @param string $dim1 - * @return $this - */ - public function setAccount(string $dim1) - { - return $this->setDim1($dim1); - } - - /** - * Set the customer or supplier or the cost center or empty. - * - * @param string $dim2 - * @return $this - */ - public function setCustomerOrSupplierOrCostCenter(string $dim2) - { - return $this->setDim2($dim2); - } - - /** - * Set the project or asset or empty. - * - * @param string $dim3 - * @return $this - */ - public function setProjectOrAsset(string $dim3) - { - return $this->setDim3($dim3); - } - - /** - * Credit in case money is received and debit in case money is paid. - * - * @param DebitCredit $debitCredit - * @return Detail - */ - public function setDebitCredit(DebitCredit $debitCredit): self - { - return parent::setDebitCredit($debitCredit); - } - - /** - * Amount without VAT. - * - * @param Money $money - */ - public function setValue(Money $money): void - { - parent::setValue($money); - } - - - /** - * @return Money|null - */ - public function getVatValue(): ?Money - { - return $this->vatValue; - } - - /** - * @return Money|null - */ - public function getVatBaseValue(): ?Money - { - return $this->vatBaseValue; - } - - /** - * @return Money|null - */ - public function getVatRepValue(): ?Money - { - return $this->vatRepValue; - } -} \ No newline at end of file diff --git a/src/Transactions/BankTransactionLine/Total.php b/src/Transactions/BankTransactionLine/Total.php deleted file mode 100644 index 176312c0..00000000 --- a/src/Transactions/BankTransactionLine/Total.php +++ /dev/null @@ -1,115 +0,0 @@ -setLineType(LineType::TOTAL()); - } - - public function setBankBalanceAccount(string $dim1) - { - $this->setDim1($dim1); - } - - /** - * Based on the sum of the individual bank transaction lines. In case of a bank addition debit. In case of a bank - * withdrawal credit. - * - * @param DebitCredit $debitCredit - * @return $this - */ - public function setDebitCredit(DebitCredit $debitCredit) - { - return parent::setDebitCredit($debitCredit); - } - - /** - * Amount including VAT. - * - * @param Money $money - */ - public function setValue(Money $money): void - { - parent::setValue($money); - } - - /** - * @return Money|null - */ - public function getVatTotal(): ?Money - { - return $this->vatTotal; - } - - /** - * The total VAT amount in the currency of the bank transaction. - * - * @param Money $vatTotal - */ - public function setVatTotal(Money $vatTotal): void - { - $this->vatTotal = $vatTotal; - } - - /** - * @return Money|null - */ - public function getVatBaseTotal(): ?Money - { - return $this->vatBaseTotal; - } - - /** - * The total VAT amount in base currency. - * - * @param Money $vatBaseTotal - */ - public function setVatBaseTotal(Money $vatBaseTotal): void - { - $this->vatBaseTotal = $vatBaseTotal; - } - - /** - * @return Money|null - */ - public function getVatRepTotal(): ?Money - { - return $this->vatRepTotal; - } - - /** - * @param Money $vatRepTotal - */ - public function setVatRepTotal(Money $vatRepTotal): void - { - $this->vatRepTotal = $vatRepTotal; - } -} \ No newline at end of file diff --git a/src/Transactions/BankTransactionLine/Vat.php b/src/Transactions/BankTransactionLine/Vat.php deleted file mode 100644 index 23315220..00000000 --- a/src/Transactions/BankTransactionLine/Vat.php +++ /dev/null @@ -1,55 +0,0 @@ -setLineType(LineType::VAT()); - } - - /** - * Set the VAT balance account. When an empty dim1 is entered, by default the general ledger account will be taken - * as entered at the VAT code in Twinfield. - * - * @param string $dim1 - */ - public function setVatBalanceAccount(string $dim1) - { - $this->setDim1($dim1); - } - - /** - * Based on the sum of the vat amounts of the individual bank transaction lins. In case of a bank addition credit. - * In case of a bank withdrawal debit. - * - * @param DebitCredit $debitCredit - * @return Vat - */ - public function setDebitCredit(DebitCredit $debitCredit): self - { - return parent::setDebitCredit($debitCredit); - } - - /** - * VAT amount. - * - * @param Money $money - */ - public function setValue(Money $money): void - { - parent::setValue($money); - } -} \ No newline at end of file diff --git a/src/Transactions/Transaction.php b/src/Transactions/Transaction.php deleted file mode 100644 index 2fc1dafb..00000000 --- a/src/Transactions/Transaction.php +++ /dev/null @@ -1,7 +0,0 @@ -code = $code; - return $this; - } - - /** - * @return string|int|null - */ - public function getCode() - { - return $this->code; - } - - /** - * @param int $number - * @return $this - */ - public function setNumber(int $number) - { - $this->number = $number; - return $this; - } - - /** - * When creating a new transaction, don't include this tag as the transaction number is determined by the - * system. When updating a transaction, the related transaction number should be provided. - * - * @return int - */ - public function getNumber(): ?int - { - return $this->number; - } - - /** - * Get the booking reference. The booking reference uniquely identifies a booking. - * - * @return BookingReference - */ - public function getBookingReference(): BookingReference - { - return new BookingReference( - $this->office, - $this->code, - $this->number - ); - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionFields/DestinyField.php b/src/Transactions/TransactionFields/DestinyField.php deleted file mode 100644 index 35c224b1..00000000 --- a/src/Transactions/TransactionFields/DestinyField.php +++ /dev/null @@ -1,31 +0,0 @@ -destiny; - } - - /** - * @param Destiny $destiny - * @return $this - */ - public function setDestiny(Destiny $destiny): self - { - $this->destiny = $destiny; - - return $this; - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionFields/DueDateField.php b/src/Transactions/TransactionFields/DueDateField.php deleted file mode 100644 index 6b287647..00000000 --- a/src/Transactions/TransactionFields/DueDateField.php +++ /dev/null @@ -1,47 +0,0 @@ -dueDate; - } - - /** - * @param \DateTimeInterface $date - * @return $this - */ - public function setDueDate(\DateTimeInterface $date) - { - $this->dueDate = $date; - return $this; - } - - /** - * @param string $dateString - * @return $this - * @throws Exception - */ - public function setDueDateFromString(string $dateString) - { - return $this->setDueDate(Util::parseDate($dateString)); - } -} diff --git a/src/Transactions/TransactionFields/FreeTextFields.php b/src/Transactions/TransactionFields/FreeTextFields.php deleted file mode 100644 index d7b2968c..00000000 --- a/src/Transactions/TransactionFields/FreeTextFields.php +++ /dev/null @@ -1,85 +0,0 @@ -freetext1; - } - - /** - * @param null|string $freetext1 - * @return $this - */ - public function setFreetext1(?string $freetext1): self - { - $this->freetext1 = $freetext1; - - return $this; - } - - /** - * @return null|string - */ - public function getFreetext2(): ?string - { - return $this->freetext2; - } - - /** - * @param null|string $freetext2 - * @return $this - */ - public function setFreetext2(?string $freetext2): self - { - $this->freetext2 = $freetext2; - - return $this; - } - - /** - * @return null|string - */ - public function getFreetext3(): ?string - { - return $this->freetext3; - } - - /** - * @param null|string $freetext3 - * @return $this - */ - public function setFreetext3(?string $freetext3): self - { - $this->freetext3 = $freetext3; - - return $this; - } - -} \ No newline at end of file diff --git a/src/Transactions/TransactionFields/StartAndCloseValueFields.php b/src/Transactions/TransactionFields/StartAndCloseValueFields.php deleted file mode 100644 index 34ee10c4..00000000 --- a/src/Transactions/TransactionFields/StartAndCloseValueFields.php +++ /dev/null @@ -1,67 +0,0 @@ -currency; - } - - /** - * Set the currency. Can only be done when the start value is still 0. - * - * @param Currency $currency - * @return $this - */ - public function setCurrency(Currency $currency) - { - Assert::true($this->startvalue->isZero()); - $this->setStartvalue(new Money(0, $currency)); - - return $this; - } - - public function getStartvalue(): Money - { - return $this->startvalue; - } - - public function setStartvalue(Money $startvalue): void - { - $this->currency = $startvalue->getCurrency(); - $this->startvalue = $startvalue; - $this->closevalue = $startvalue; - } - - public function getClosevalue(): Money - { - return $this->closevalue ?? new Money(0, $this->getCurrency()); - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionFields/StatementNumberField.php b/src/Transactions/TransactionFields/StatementNumberField.php deleted file mode 100644 index 5d7ffb63..00000000 --- a/src/Transactions/TransactionFields/StatementNumberField.php +++ /dev/null @@ -1,30 +0,0 @@ -statementnumber; - } - - /** - * @param int $statementnumber - * @return $this - */ - public function setStatementnumber(int $statementnumber) - { - $this->statementnumber = $statementnumber; - return $this; - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionLineFields/DateField.php b/src/Transactions/TransactionLineFields/DateField.php deleted file mode 100644 index 2ea4c03a..00000000 --- a/src/Transactions/TransactionLineFields/DateField.php +++ /dev/null @@ -1,47 +0,0 @@ -date; - } - - /** - * @param \DateTimeInterface $date - * @return $this - */ - public function setDate(\DateTimeInterface $date) - { - $this->date = $date; - return $this; - } - - /** - * @param string $dateString - * @return $this - * @throws Exception - */ - public function setDateFromString(string $dateString) - { - return $this->setDate(Util::parseDate($dateString)); - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionLineFields/FourDimFields.php b/src/Transactions/TransactionLineFields/FourDimFields.php deleted file mode 100644 index b148fbee..00000000 --- a/src/Transactions/TransactionLineFields/FourDimFields.php +++ /dev/null @@ -1,28 +0,0 @@ -dim4; - } - - /** - * @param string $dim4 - * @return $this - */ - public function setDim4(string $dim4) - { - $this->dim4 = $dim4; - return $this; - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionLineFields/PerformanceFields.php b/src/Transactions/TransactionLineFields/PerformanceFields.php deleted file mode 100644 index edca4f0f..00000000 --- a/src/Transactions/TransactionLineFields/PerformanceFields.php +++ /dev/null @@ -1,144 +0,0 @@ -performanceType; - } - - /** - * @param PerformanceType|null $performanceType - * @return $this - * @throws Exception - */ - public function setPerformanceType(?PerformanceType $performanceType): self - { - if ( - $performanceType !== null && - !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) - ) { - throw Exception::invalidFieldForLineType('performanceType', $this); - } - - $this->performanceType = $performanceType; - - return $this; - } - - /** - * @return string|null - */ - public function getPerformanceCountry(): ?string - { - return $this->performanceCountry; - } - - /** - * @param string|null $performanceCountry - * @return $this - * @throws Exception - */ - public function setPerformanceCountry(?string $performanceCountry): self - { - if ( - $performanceCountry !== null && - !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) - ) { - throw Exception::invalidFieldForLineType('performanceCountry', $this); - } - - $this->performanceCountry = $performanceCountry; - - return $this; - } - - /** - * @return string|null - */ - public function getPerformanceVatNumber(): ?string - { - return $this->performanceVatNumber; - } - - /** - * @param string|null $performanceVatNumber - * @return $this - * @throws Exception - */ - public function setPerformanceVatNumber(?string $performanceVatNumber): self - { - if ( - $performanceVatNumber !== null && - !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) - ) { - throw Exception::invalidFieldForLineType('performanceVatNumber', $this); - } - - $this->performanceVatNumber = $performanceVatNumber; - - return $this; - } - - /** - * @return \DateTimeInterface|null - */ - public function getPerformanceDate(): ?\DateTimeInterface - { - return $this->performanceDate; - } - - /** - * @param \DateTimeInterface|null $performanceDate - * @return $this - * @throws Exception - */ - public function setPerformanceDate(?\DateTimeInterface $performanceDate): self - { - if ( - $performanceDate !== null && - !in_array($this->getLineType(), [LineType::DETAIL(), LineType::VAT()]) - ) { - throw Exception::invalidFieldForLineType('performanceDate', $this); - } - - $this->performanceDate = $performanceDate; - - return $this; - } -} diff --git a/src/Transactions/TransactionLineFields/PeriodField.php b/src/Transactions/TransactionLineFields/PeriodField.php deleted file mode 100644 index 13fe4357..00000000 --- a/src/Transactions/TransactionLineFields/PeriodField.php +++ /dev/null @@ -1,37 +0,0 @@ -period; - } - - /** - * @param string $period - * @return $this - */ - public function setPeriod(string $period): self - { - if (!preg_match("!\\d{4}/\\d{1,2}!", $period)) { - throw new \InvalidArgumentException("Period must be in YYYY/PP format (got: {$period}."); - } - - $this->period = $period; - - return $this; - } -} diff --git a/src/Transactions/TransactionLineFields/ThreeDimFields.php b/src/Transactions/TransactionLineFields/ThreeDimFields.php deleted file mode 100644 index 6b002614..00000000 --- a/src/Transactions/TransactionLineFields/ThreeDimFields.php +++ /dev/null @@ -1,66 +0,0 @@ -dim1; - } - - /** - * @param string|null $dim1 - * @return $this - */ - public function setDim1(?string $dim1) - { - $this->dim1 = $dim1; - return $this; - } - - final public function getDim2(): ?string - { - return $this->dim2; - } - - /** - * @param string|null $dim2 - * @return $this - */ - public function setDim2(?string $dim2) - { - $this->dim2 = $dim2; - return $this; - } - - final public function getDim3(): ?string - { - return $this->dim3; - } - - /** - * @param string|null $dim3 - * @return $this - */ - public function setDim3(?string $dim3) - { - $this->dim3 = $dim3; - return $this; - } -} diff --git a/src/Transactions/TransactionLineFields/ValueOpenField.php b/src/Transactions/TransactionLineFields/ValueOpenField.php deleted file mode 100644 index 1155b103..00000000 --- a/src/Transactions/TransactionLineFields/ValueOpenField.php +++ /dev/null @@ -1,43 +0,0 @@ -valueOpen; - } - - /** - * @param Money|null $valueOpen - * @return $this - * @throws Exception - */ - public function setValueOpen(?Money $valueOpen): self - { - if ($valueOpen !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('valueOpen', $this); - } - - $this->valueOpen = $valueOpen; - - return $this; - } -} diff --git a/src/Transactions/TransactionLineFields/VatCodeField.php b/src/Transactions/TransactionLineFields/VatCodeField.php deleted file mode 100644 index d2421d11..00000000 --- a/src/Transactions/TransactionLineFields/VatCodeField.php +++ /dev/null @@ -1,33 +0,0 @@ -vatCode = $vatCode; - - return $this; - } - - /** - * @return null|string - */ - public function getVatCode(): ?string - { - return $this->vatCode; - } -} \ No newline at end of file diff --git a/src/Transactions/TransactionLineFields/VatTotalFields.php b/src/Transactions/TransactionLineFields/VatTotalFields.php deleted file mode 100644 index f688a67e..00000000 --- a/src/Transactions/TransactionLineFields/VatTotalFields.php +++ /dev/null @@ -1,76 +0,0 @@ -vatTotal) ? $this->vatTotal->absolute() : null; - } - - /** - * @param Money|null $vatTotal - * @return $this - * @throws Exception - */ - public function setVatTotal(?Money $vatTotal): self - { - if ($vatTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('vatTotal', $this); - } - - $this->vatTotal = $vatTotal; - - return $this; - } - - /** - * @return Money|null - */ - public function getVatBaseTotal(): ?Money - { - return !empty($this->vatBaseTotal) ? $this->vatBaseTotal->absolute() : null; - } - - /** - * @param Money|null $vatBaseTotal - * @return $this - * @throws Exception - */ - public function setVatBaseTotal(?Money $vatBaseTotal): self - { - if ($vatBaseTotal !== null && !$this->getLineType()->equals(LineType::TOTAL())) { - throw Exception::invalidFieldForLineType('vatBaseTotal', $this); - } - - $this->vatBaseTotal = $vatBaseTotal; - - return $this; - } -} diff --git a/src/Transactions/TransactionLineFields/VatTurnoverFields.php b/src/Transactions/TransactionLineFields/VatTurnoverFields.php deleted file mode 100644 index 9b840455..00000000 --- a/src/Transactions/TransactionLineFields/VatTurnoverFields.php +++ /dev/null @@ -1,81 +0,0 @@ -vatTurnover; - } - - /** - * @param Money|null $vatTurnover - * @return $this - */ - public function setVatTurnover(?Money $vatTurnover) - { - $this->vatTurnover = $vatTurnover; - - return $this; - } - - /** - * @return Money|null - */ - public function getVatBaseTurnover(): ?Money - { - return $this->vatBaseTurnover; - } - - /** - * @param Money|null $vatBaseTurnover - * @return $this - */ - public function setVatBaseTurnover(?Money $vatBaseTurnover) - { - $this->vatBaseTurnover = $vatBaseTurnover; - - return $this; - } - - /** - * @return Money|null - */ - public function getVatRepTurnover(): ?Money - { - return $this->vatRepTurnover; - } - - /** - * @param Money|null $vatRepTurnover - * @return $this - */ - public function setVatRepTurnover(?Money $vatRepTurnover) - { - $this->vatRepTurnover = $vatRepTurnover; - - return $this; - } -} - diff --git a/src/User.php b/src/User.php index 55fd3f6c..c9248753 100644 --- a/src/User.php +++ b/src/User.php @@ -2,50 +2,64 @@ namespace PhpTwinfield; -class User -{ - /** - * @var string The code of the user. - */ - private $code; - - /** - * @var string The name of the user. - */ - private $name; - - /** - * @var string The short name of the user. - */ - private $shortName; - - public function getCode(): string - { - return $this->code; - } - - public function setCode(string $code): void - { - $this->code = $code; - } - - public function getName(): string - { - return $this->name; - } +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\CreatedField; +use PhpTwinfield\Fields\EmailField; +use PhpTwinfield\Fields\ModifiedField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; +use PhpTwinfield\Fields\TouchedField; +use PhpTwinfield\Fields\User\AcceptExtraCostField; +use PhpTwinfield\Fields\User\CultureField; +use PhpTwinfield\Fields\User\CultureNameField; +use PhpTwinfield\Fields\User\CultureNativeNameField; +use PhpTwinfield\Fields\User\DemoField; +use PhpTwinfield\Fields\User\DemoLockedField; +use PhpTwinfield\Fields\User\ExchangeQuotaField; +use PhpTwinfield\Fields\User\ExchangeQuotaLockedField; +use PhpTwinfield\Fields\User\FileManagerQuotaField; +use PhpTwinfield\Fields\User\FileManagerQuotaLockedField; +use PhpTwinfield\Fields\User\IsCurrentUserField; +use PhpTwinfield\Fields\User\LevelField; +use PhpTwinfield\Fields\User\PasswordField; +use PhpTwinfield\Fields\User\RoleField; +use PhpTwinfield\Fields\User\RoleLockedField; +use PhpTwinfield\Fields\User\TypeField; +use PhpTwinfield\Fields\User\TypeLockedField; - public function setName(string $name): void - { - $this->name = $name; - } +class User extends BaseObject implements HasCodeInterface +{ + use AcceptExtraCostField; + use CodeField; + use CreatedField; + use CultureField; + use CultureNameField; + use CultureNativeNameField; + use DemoField; + use DemoLockedField; + use EmailField; + use ExchangeQuotaField; + use ExchangeQuotaLockedField; + use FileManagerQuotaField; + use FileManagerQuotaLockedField; + use IsCurrentUserField; + use LevelField; + use ModifiedField; + use NameField; + use PasswordField; + use RoleField; + use RoleLockedField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use TypeLockedField; - public function getShortName(): string - { - return $this->shortName; - } + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); - public function setShortName(string $value): void - { - $this->shortName = $value; + return $instance; } } diff --git a/src/UserRole.php b/src/UserRole.php new file mode 100644 index 00000000..1ecfa5d6 --- /dev/null +++ b/src/UserRole.php @@ -0,0 +1,28 @@ + + */ +class UserRole extends BaseObject implements HasCodeInterface +{ + use CodeField; + use LevelField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/Util.php b/src/Util.php index de8e09c5..6f2260fe 100644 --- a/src/Util.php +++ b/src/Util.php @@ -11,15 +11,36 @@ final class Util { - public static function formatMoney(Money $money): string + /** + * Format a money object to string according to Twinfield specifications. + * + * @param Money|null $money + * @return string|null + */ + public static function formatMoney(?Money $money): ?string { + if ($money === null) { + return null; + } + $decimalformatter = new DecimalMoneyFormatter(new ISOCurrencies()); return $decimalformatter->format($money); } - public static function parseMoney(string $moneyString, Currency $currency): Money + /** + * Parse a money string and Currency object. + * + * @param string|null $moneyString + * @param Currency|null $currency + * @return Money|null + */ + public static function parseMoney(?string $moneyString, ?Currency $currency): ?Money { + if ($moneyString === null || $currency === null) { + return null; + } + $parser = new DecimalMoneyParser(new ISOCurrencies()); return $parser->parse($moneyString, $currency); } @@ -27,23 +48,31 @@ public static function parseMoney(string $moneyString, Currency $currency): Mone /** * Format a date according to Twinfield specifications. * - * @param \DateTimeInterface $date - * @return string + * @param \DateTimeInterface|null $date + * @return string|null */ - public static function formatDate(\DateTimeInterface $date): string + public static function formatDate(?\DateTimeInterface $date): ?string { + if ($date === null) { + return null; + } + return $date->format("Ymd"); } /** * Parse a date string from a Twinfield XML. * - * @param string $dateString - * @return \DateTimeImmutable + * @param string|null $dateString + * @return \DateTimeImmutable|null * @throws Exception */ - public static function parseDate(string $dateString): \DateTimeImmutable + public static function parseDate(?string $dateString): ?\DateTimeImmutable { + if ($dateString === null) { + return null; + } + $date = \DateTimeImmutable::createFromFormat("Ymd|", $dateString); if (false === $date) { @@ -53,15 +82,34 @@ public static function parseDate(string $dateString): \DateTimeImmutable return $date; } + /** + * Format a date time according to Twinfield specifications. + * + * @param \DateTimeInterface|null $datetime + * @return string|null + */ + public static function formatDateTime(?\DateTimeInterface $datetime): ?string + { + if ($datetime === null) { + return null; + } + + return $datetime->format("YmdHis"); + } + /** * Parse a date time string from a Twinfield XML. * - * @param string $dateString - * @return \DateTimeImmutable + * @param string|null $dateString + * @return \DateTimeImmutable|null * @throws Exception */ - public static function parseDateTime(string $dateString) + public static function parseDateTime(?string $dateString): ?\DateTimeImmutable { + if ($dateString === null) { + return null; + } + $date = \DateTimeImmutable::createFromFormat("YmdHis", $dateString); if (false === $date) { @@ -72,29 +120,42 @@ public static function parseDateTime(string $dateString) } /** - * @param bool $boolean - * @return string + * @param bool|null $boolean + * @return string|null */ - public static function formatBoolean(bool $boolean): string + public static function formatBoolean(?bool $boolean): ?string { + if ($boolean === null) { + return null; + } + return $boolean ? "true" : "false"; } /** - * @param string $input - * @return bool - * @throws Exception + * @param string|null $value + * @return bool|null + */ + public static function parseBoolean(?string $value): ?bool + { + if ($value === null) { + return null; + } + + return filter_var($value, FILTER_VALIDATE_BOOLEAN); + } + + /** + * @param HasCodeInterface|null $object + * @return string|null */ - public static function parseBoolean(string $input): bool + public static function objectToStr(?HasCodeInterface $object): ?string { - switch ($input) { - case "true": - return true; - case "false": - return false; + if ($object === null) { + return null; } - throw new Exception("Unknown boolean value \"{$input}\"."); + return $object->getCode(); } /** @@ -134,4 +195,4 @@ public static function getPrettyXml(\DOMDocument $document): string return $xml_string ?: ''; } -} \ No newline at end of file +} diff --git a/src/VatCode.php b/src/VatCode.php index 61051d2c..50e28362 100644 --- a/src/VatCode.php +++ b/src/VatCode.php @@ -2,40 +2,64 @@ namespace PhpTwinfield; +use PhpTwinfield\Fields\CodeField; +use PhpTwinfield\Fields\CreatedField; +use PhpTwinfield\Fields\ModifiedField; +use PhpTwinfield\Fields\NameField; +use PhpTwinfield\Fields\OfficeField; +use PhpTwinfield\Fields\ShortNameField; +use PhpTwinfield\Fields\StatusField; +use PhpTwinfield\Fields\TouchedField; +use PhpTwinfield\Fields\UIDField; +use PhpTwinfield\Fields\UserField; +use PhpTwinfield\Fields\VatCode\TypeField; + /** * Class VatCode * - * @author Emile Bons + * @author Emile Bons , extended by Yannick Aerssens */ -class VatCode +class VatCode extends BaseObject implements HasCodeInterface { - /** - * @var string The code of the VAT code. - */ - private $code; + use CodeField; + use CreatedField; + use ModifiedField; + use NameField; + use OfficeField; + use ShortNameField; + use StatusField; + use TouchedField; + use TypeField; + use UIDField; + use UserField; - /** - * @var string The name of the VAT code. - */ - private $name; + private $percentages = []; - public function getCode(): string - { - return $this->code; + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; } - public function setCode(string $code): void + public function getPercentages() { - $this->code = $code; + return $this->percentages; } - public function getName(): string + public function addPercentage(VatCodePercentage $percentage) { - return $this->name; + $this->percentages[] = $percentage; + return $this; } - public function setName(string $name): void + public function removePercentage($index) { - $this->name = $name; + if (array_key_exists($index, $this->percentages)) { + unset($this->percentages[$index]); + return true; + } else { + return false; + } } } diff --git a/src/VatCodeAccount.php b/src/VatCodeAccount.php new file mode 100644 index 00000000..3d51dd17 --- /dev/null +++ b/src/VatCodeAccount.php @@ -0,0 +1,24 @@ +accounts; + } + + public function addAccount(VatCodeAccount $account) + { + $this->accounts[] = $account; + return $this; + } + + public function removeAccount($index) + { + if (array_key_exists($index, $this->accounts)) { + unset($this->accounts[$index]); + return true; + } else { + return false; + } + } + + public function removeAccountByID($id) + { + $found = false; + + foreach ($this->accounts as $index => $account) { + if ($id == $account->getID()) { + unset($this->accounts[$index]); + $found = true; + } + } + + if ($found) { + return true; + } + + return false; + } +} diff --git a/src/VatGroup.php b/src/VatGroup.php new file mode 100644 index 00000000..bdaa4145 --- /dev/null +++ b/src/VatGroup.php @@ -0,0 +1,26 @@ + + */ +class VatGroup extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/src/VatGroupCountry.php b/src/VatGroupCountry.php new file mode 100644 index 00000000..13fa5809 --- /dev/null +++ b/src/VatGroupCountry.php @@ -0,0 +1,26 @@ + + */ +class VatGroupCountry extends BaseObject implements HasCodeInterface +{ + use CodeField; + use NameField; + use ShortNameField; + + public static function fromCode(string $code) { + $instance = new self; + $instance->setCode($code); + + return $instance; + } +} diff --git a/tests/IntegrationTests/BankTransactionIntegrationTest.php b/tests/IntegrationTests/BankTransactionIntegrationTest.php new file mode 100644 index 00000000..f7838eeb --- /dev/null +++ b/tests/IntegrationTests/BankTransactionIntegrationTest.php @@ -0,0 +1,197 @@ +transactionApiConnector = new TransactionApiConnector($this->connection); + } + + public function testGetBankTransactionWorks() + { + $response = Response::fromString(file_get_contents(__DIR__ . '/resources/bankTransactionGetResponse.xml')); + + $this->processXmlService + ->expects($this->once()) + ->method("sendDocument") + ->with($this->isInstanceOf(\PhpTwinfield\Request\Read\Transaction::class)) + ->willReturn($response); + + /** @var BankTransaction $bankTransaction */ + $bankTransaction = $this->transactionApiConnector->get(BankTransaction::class, 'BNK', '201300008', $this->office); + + $this->assertInstanceOf(BankTransaction::class, $bankTransaction); + $this->assertEquals(Destiny::TEMPORARY(), $bankTransaction->getDestiny()); + $this->assertNull($bankTransaction->getAutoBalanceVat()); + $this->assertSame(false, $bankTransaction->getRaiseWarning()); + $this->assertEquals(Office::fromCode('001'), $bankTransaction->getOffice()); + $this->assertSame('BNK', $bankTransaction->getCode()); + $this->assertSame(201300008, $bankTransaction->getNumber()); + $this->assertSame('2013/11', $bankTransaction->getPeriod()); + $this->assertEquals('EUR', Util::objectToStr($bankTransaction->getCurrency())); + $this->assertEquals(new DateTimeImmutable('2013-11-04'), $bankTransaction->getDate()); + $this->assertSame('import', $bankTransaction->getOrigin()); + $this->assertNull($bankTransaction->getFreeText1()); + $this->assertNull($bankTransaction->getFreeText2()); + $this->assertNull($bankTransaction->getFreeText3()); + $this->assertSame(4, $bankTransaction->getStatementNumber()); + $this->assertTrue(Money::EUR(97401)->equals($bankTransaction->getStartValue())); + $this->assertTrue(Money::EUR(140956)->equals($bankTransaction->getCloseValue())); + + /** @var BankTransactionLine[] $bankTransactionLines */ + $bankTransactionLines = $bankTransaction->getLines(); + $this->assertCount(2, $bankTransactionLines); + [$totalLine, $detailLine] = $bankTransactionLines; + + $this->assertEquals(LineType::TOTAL(), $totalLine->getLineType()); + $this->assertSame(1, $totalLine->getId()); + $this->assertSame('1001', Util::objectToStr($totalLine->getDim1())); + $this->assertEquals(DebitCredit::DEBIT(), $totalLine->getDebitCredit()); + $this->assertEquals(Money::EUR(43555), $totalLine->getValue()); + $this->assertEquals(Money::EUR(43555), $totalLine->getBaseValue()); + $this->assertSame(1.0, $totalLine->getRate()); + $this->assertEquals(Money::USD(65333), $totalLine->getRepValue()); + $this->assertSame(1.500000000, $totalLine->getRepRate()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('NOTMATCHABLE'), (string)$totalLine->getMatchStatus()); + $this->assertNull($totalLine->getMatchLevel()); + $this->assertNull($totalLine->getBaseValueOpen()); + $this->assertNull($totalLine->getVatCode()); + $this->assertNull($totalLine->getVatValue()); + $this->assertNull($totalLine->getVatTotal()); + $this->assertNull($totalLine->getVatBaseTotal()); + $this->assertNull($totalLine->getPerformanceType()); + $this->assertNull($totalLine->getPerformanceCountry()); + $this->assertNull($totalLine->getPerformanceVatNumber()); + $this->assertNull($totalLine->getPerformanceDate()); + + $this->assertEquals(LineType::DETAIL(), $detailLine->getLineType()); + $this->assertSame(2, $detailLine->getId()); + $this->assertSame('1300', Util::objectToStr($detailLine->getDim1())); + $this->assertSame('1000', Util::objectToStr($detailLine->getDim2())); + $this->assertEquals(DebitCredit::CREDIT(), $detailLine->getDebitCredit()); + $this->assertEquals(Money::EUR(43555), $detailLine->getValue()); + $this->assertEquals(Money::EUR(43555), $totalLine->getBaseValue()); + $this->assertSame(1.0, $totalLine->getRate()); + $this->assertEquals(Money::USD(65333), $totalLine->getRepValue()); + $this->assertSame(1.500000000, $totalLine->getRepRate()); + $this->assertSame('Invoice paid', $detailLine->getDescription()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('AVAILABLE'), (string)$detailLine->getMatchStatus()); + $this->assertSame(2, $detailLine->getMatchLevel()); + $this->assertEquals(Money::EUR(43555), $detailLine->getBaseValueOpen()); + $this->assertEquals(Money::USD(65333), $detailLine->getRepValue()); + $this->assertNull(Util::objectToStr($detailLine->getVatCode())); + $this->assertNull($detailLine->getVatValue()); + $this->assertNull($detailLine->getVatTotal()); + $this->assertNull($detailLine->getVatBaseTotal()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$detailLine->getPerformanceType()); + $this->assertNull(Util::objectToStr($detailLine->getPerformanceCountry())); + $this->assertNull($detailLine->getPerformanceVatNumber()); + $this->assertNull($detailLine->getPerformanceDate()); + } + + public function testSendBankTransactionWorks() + { + $bankTransaction = new BankTransaction(); + $bankTransaction + ->setOffice(Office::fromCode('001')) + ->setDestiny(Destiny::TEMPORARY()) + ->setRaiseWarning(false) + ->setCode('BNK') + ->setCurrency(Currency::fromCode('EUR')) + ->setDate(new DateTimeImmutable('2013-11-04')) + ->setStatementNumber(4) + ->setStartValue(Money::EUR(97401)); + + $totalLine = new BankTransactionLine(); + $totalLine + ->setLineType(LineType::TOTAL()) + ->setId('1') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1001')) + ->setValue(Money::EUR(43555)); + + $detailLine = new BankTransactionLine(); + $detailLine + ->setLineType(LineType::DETAIL()) + ->setId('2') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1300')) + ->setDim2(\PhpTwinfield\CostCenter::fromCode('1000')) + ->setValue(Money::EUR(43555)) + ->setDescription('Invoice paid'); + + $bankTransaction + ->addLine($totalLine) + ->addLine($detailLine); + + $this->processXmlService + ->expects($this->once()) + ->method("sendDocument") + ->with($this->isInstanceOf(TransactionsDocument::class)) + ->willReturnCallback(function (TransactionsDocument $transactionsDocument) { + $this->assertXmlStringEqualsXmlString( + file_get_contents(realpath(__DIR__ . '/resources/bankTransactionSendRequest.xml')), + $transactionsDocument->saveXML() + ); + + return $this->getSuccessfulResponse(); + }); + + $this->transactionApiConnector->send($bankTransaction); + } + + protected function getSuccessfulResponse(): Response + { + return Response::fromString( + ' +
+ 001 + BNK + EUR + 20131104 + 4 + 974.01 + 1409.56 + import + MARCEL + 2013/11 + 201300008 +
+
+
' + ); + } +} diff --git a/tests/IntegrationTests/BaseIntegrationTest.php b/tests/IntegrationTests/BaseIntegrationTest.php index 1d057088..df3a7461 100644 --- a/tests/IntegrationTests/BaseIntegrationTest.php +++ b/tests/IntegrationTests/BaseIntegrationTest.php @@ -2,6 +2,8 @@ namespace PhpTwinfield\IntegrationTests; +use PhpTwinfield\ApiConnectors\OfficeApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\Enums\Services; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; @@ -56,10 +58,19 @@ protected function setUp() throw new \InvalidArgumentException("Unknown service {$service->getValue()}"); }); + + $mockOfficeApiConnector = \Mockery::mock('overload:'.OfficeApiConnector::class)->makePartial(); + $mockOfficeApiConnector->shouldReceive('get')->andReturnUsing(function() { + $office = new Office; + $office->setResult(1); + $office->setBaseCurrency(Currency::fromCode('EUR')); + $office->setReportingCurrency(Currency::fromCode('USD')); + return $office; + }); } protected function getSuccessfulResponse(): Response { return Response::fromString(''); } -} \ No newline at end of file +} diff --git a/tests/IntegrationTests/BrowseDataApiConnectorTest.php b/tests/IntegrationTests/BrowseDataApiConnectorTest.php index 83dedc14..9301dd9c 100644 --- a/tests/IntegrationTests/BrowseDataApiConnectorTest.php +++ b/tests/IntegrationTests/BrowseDataApiConnectorTest.php @@ -7,6 +7,7 @@ use PhpTwinfield\BrowseDefinition; use PhpTwinfield\Enums\BrowseColumnOperator; use PhpTwinfield\Response\Response; +use PhpTwinfield\Util; class BrowseDataApiConnectorTest extends BaseIntegrationTest { @@ -37,7 +38,7 @@ public function testGetBrowseDefinition() $this->assertInstanceOf(BrowseDefinition::class, $browseDefinition); - $this->assertEquals('001', $browseDefinition->getOffice()->getCode()); + $this->assertEquals('001', Util::objectToStr($browseDefinition->getOffice())); $this->assertEquals('000', $browseDefinition->getCode()); $this->assertEquals('General ledger transactions', $browseDefinition->getName()); $this->assertEquals('General ledger transactions', $browseDefinition->getShortName()); @@ -207,7 +208,7 @@ public function testGetBrowseData() // Rows $row1 = $browseData->getRows()[0]; $this->assertCount(6, $browseData->getRows()); - $this->assertEquals('001', $row1->getOffice()->getCode()); + $this->assertEquals('001', Util::objectToStr($row1->getOffice())); $this->assertEquals('BNK', $row1->getCode()); $this->assertEquals('201300001', $row1->getNumber()); $this->assertEquals('2', $row1->getLine()); @@ -232,4 +233,4 @@ public function testGetBrowseData() $this->assertEquals(false, $cell7->isHideForUser()); $this->assertEquals(-121.00, $cell7->getValue()); } -} \ No newline at end of file +} diff --git a/tests/IntegrationTests/CashTransactionIntegrationTest.php b/tests/IntegrationTests/CashTransactionIntegrationTest.php index d6c4b11d..3ddc12f2 100644 --- a/tests/IntegrationTests/CashTransactionIntegrationTest.php +++ b/tests/IntegrationTests/CashTransactionIntegrationTest.php @@ -3,20 +3,20 @@ namespace PhpTwinfield\IntegrationTests; use DateTimeImmutable; -use Money\Currency; use Money\Money; use PhpTwinfield\ApiConnectors\TransactionApiConnector; use PhpTwinfield\CashTransaction; use PhpTwinfield\CashTransactionLine; +use PhpTwinfield\Currency; use PhpTwinfield\DomDocuments\TransactionsDocument; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Enums\LineType; +use PhpTwinfield\Enums\MatchStatus; use PhpTwinfield\Mappers\TransactionMapper; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; -use PhpTwinfield\SalesTransaction; -use PhpTwinfield\SalesTransactionLine; +use PhpTwinfield\Util; /** * @covers SalesTransaction @@ -54,21 +54,21 @@ public function testGetCashTransactionWorks() $this->assertInstanceOf(CashTransaction::class, $cashTransaction); $this->assertEquals(Destiny::TEMPORARY(), $cashTransaction->getDestiny()); - $this->assertNull($cashTransaction->isAutoBalanceVat()); + $this->assertNull($cashTransaction->getAutoBalanceVat()); $this->assertSame(false, $cashTransaction->getRaiseWarning()); $this->assertEquals(Office::fromCode('001'), $cashTransaction->getOffice()); $this->assertSame('CASH', $cashTransaction->getCode()); $this->assertSame(201300008, $cashTransaction->getNumber()); $this->assertSame('2013/11', $cashTransaction->getPeriod()); - $this->assertEquals(new Currency('EUR'), $cashTransaction->getCurrency()); + $this->assertEquals('EUR', Util::objectToStr($cashTransaction->getCurrency())); $this->assertEquals(new DateTimeImmutable('2013-11-04'), $cashTransaction->getDate()); $this->assertSame('import', $cashTransaction->getOrigin()); - $this->assertNull($cashTransaction->getFreetext1()); - $this->assertNull($cashTransaction->getFreetext2()); - $this->assertNull($cashTransaction->getFreetext3()); - $this->assertSame(4, $cashTransaction->getStatementnumber()); - $this->assertTrue(Money::EUR(97401)->equals($cashTransaction->getStartvalue())); - $this->assertTrue(Money::EUR(140956)->equals($cashTransaction->getClosevalue())); + $this->assertNull($cashTransaction->getFreeText1()); + $this->assertNull($cashTransaction->getFreeText2()); + $this->assertNull($cashTransaction->getFreeText3()); + $this->assertSame(4, $cashTransaction->getStatementNumber()); + $this->assertTrue(Money::EUR(97401)->equals($cashTransaction->getStartValue())); + $this->assertTrue(Money::EUR(140956)->equals($cashTransaction->getCloseValue())); /** @var CashTransactionLine[] $cashTransactionLines */ $cashTransactionLines = $cashTransaction->getLines(); @@ -77,14 +77,15 @@ public function testGetCashTransactionWorks() $this->assertEquals(LineType::TOTAL(), $totalLine->getLineType()); $this->assertSame(1, $totalLine->getId()); - $this->assertSame('1002', $totalLine->getDim1()); + $this->assertSame('1002', Util::objectToStr($totalLine->getDim1())); $this->assertEquals(DebitCredit::DEBIT(), $totalLine->getDebitCredit()); $this->assertEquals(Money::EUR(43555), $totalLine->getValue()); $this->assertEquals(Money::EUR(43555), $totalLine->getBaseValue()); $this->assertSame(1.0, $totalLine->getRate()); - $this->assertEquals(Money::EUR(65333), $totalLine->getRepValue()); + $this->assertEquals(Money::USD(65333), $totalLine->getRepValue()); $this->assertSame(1.500000000, $totalLine->getRepRate()); - $this->assertSame(CashTransactionLine::MATCHSTATUS_NOTMATCHABLE, $totalLine->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('NOTMATCHABLE'), (string)$totalLine->getMatchStatus()); $this->assertNull($totalLine->getMatchLevel()); $this->assertNull($totalLine->getBaseValueOpen()); $this->assertNull($totalLine->getVatCode()); @@ -98,26 +99,27 @@ public function testGetCashTransactionWorks() $this->assertEquals(LineType::DETAIL(), $detailLine->getLineType()); $this->assertSame(2, $detailLine->getId()); - $this->assertSame('1300', $detailLine->getDim1()); - $this->assertSame('1000', $detailLine->getDim2()); + $this->assertSame('1300', Util::objectToStr($detailLine->getDim1())); + $this->assertSame('1000', Util::objectToStr($detailLine->getDim2())); $this->assertEquals(DebitCredit::CREDIT(), $detailLine->getDebitCredit()); - $this->assertSame('11001770', $detailLine->getInvoiceNumber()); $this->assertEquals(Money::EUR(43555), $detailLine->getValue()); $this->assertEquals(Money::EUR(43555), $totalLine->getBaseValue()); $this->assertSame(1.0, $totalLine->getRate()); - $this->assertEquals(Money::EUR(65333), $totalLine->getRepValue()); + $this->assertEquals(Money::USD(65333), $totalLine->getRepValue()); $this->assertSame(1.500000000, $totalLine->getRepRate()); $this->assertSame('Invoice paid', $detailLine->getDescription()); - $this->assertSame(SalesTransactionLine::MATCHSTATUS_AVAILABLE, $detailLine->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('AVAILABLE'), (string)$detailLine->getMatchStatus()); $this->assertSame(2, $detailLine->getMatchLevel()); $this->assertEquals(Money::EUR(43555), $detailLine->getBaseValueOpen()); - $this->assertEquals(Money::EUR(65333), $detailLine->getRepValue()); - $this->assertNull($detailLine->getVatCode()); + $this->assertEquals(Money::USD(65333), $detailLine->getRepValue()); + $this->assertNull(Util::objectToStr($detailLine->getVatCode())); $this->assertNull($detailLine->getVatValue()); $this->assertNull($detailLine->getVatTotal()); $this->assertNull($detailLine->getVatBaseTotal()); - $this->assertNull($detailLine->getPerformanceType()); - $this->assertNull($detailLine->getPerformanceCountry()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$detailLine->getPerformanceType()); + $this->assertNull(Util::objectToStr($detailLine->getPerformanceCountry())); $this->assertNull($detailLine->getPerformanceVatNumber()); $this->assertNull($detailLine->getPerformanceDate()); } @@ -130,26 +132,25 @@ public function testSendCashTransactionWorks() ->setDestiny(Destiny::TEMPORARY()) ->setRaiseWarning(false) ->setCode('CASH') - ->setCurrency(new Currency('EUR')) + ->setCurrency(Currency::fromCode('EUR')) ->setDate(new DateTimeImmutable('2013-11-04')) - ->setStatementnumber(4) - ->setStartvalue(Money::EUR(97401)); + ->setStatementNumber(4) + ->setStartValue(Money::EUR(97401)); $totalLine = new CashTransactionLine(); $totalLine ->setLineType(LineType::TOTAL()) ->setId('1') - ->setDim1('1002') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1002')) ->setValue(Money::EUR(43555)); $detailLine = new CashTransactionLine(); $detailLine ->setLineType(LineType::DETAIL()) ->setId('2') - ->setDim1('1300') - ->setDim2('1000') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1300')) + ->setDim2(\PhpTwinfield\CostCenter::fromCode('1000')) ->setValue(Money::EUR(43555)) - ->setInvoiceNumber('11001770') ->setDescription('Invoice paid'); $cashTransaction diff --git a/tests/IntegrationTests/CustomerIntegrationTest.php b/tests/IntegrationTests/CustomerIntegrationTest.php index 07f0bbfc..e5c85191 100644 --- a/tests/IntegrationTests/CustomerIntegrationTest.php +++ b/tests/IntegrationTests/CustomerIntegrationTest.php @@ -3,14 +3,17 @@ namespace PhpTwinfield\IntegrationTests; use PhpTwinfield\ApiConnectors\CustomerApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\Customer; use PhpTwinfield\CustomerAddress; use PhpTwinfield\CustomerBank; use PhpTwinfield\CustomerCollectMandate; +use PhpTwinfield\CustomerFinancials; use PhpTwinfield\DomDocuments\CustomersDocument; use PhpTwinfield\Mappers\CustomerMapper; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; +use PhpTwinfield\Util; /** * @covers Customer @@ -18,6 +21,7 @@ * @covers CustomerBank * @covers CustomerCollectMandate * @covers CustomerCreditManagement + * @covers CustomerFinancials * @covers CustomersDocument * @covers CustomerMapper * @covers CustomerApiConnector @@ -47,23 +51,24 @@ public function testGetCustomerWorks() ->with($this->isInstanceOf(\PhpTwinfield\Request\Read\Customer::class)) ->willReturn($response); - $customer = $this->customerApiConnector->get('CODE', $this->office); + $customer = $this->customerApiConnector->get('CODE', Office::fromCode('001')); $this->assertInstanceOf(Customer::class, $customer); - $this->assertSame('001', $customer->getOffice()->getCode()); - $this->assertSame('DEB', $customer->getType()); + $this->assertSame('001', Util::objectToStr($customer->getOffice())); + $this->assertSame('DEB', Util::objectToStr($customer->getType())); $this->assertSame('Customer 0', $customer->getName()); $this->assertSame('http://www.example.com', $customer->getWebsite()); // Financials - $this->assertSame('30', $customer->getDueDays()); - $this->assertSame(true, $customer->getPayAvailable()); - $this->assertSame('SEPANLDD', $customer->getPayCode()); - $this->assertSame(false, $customer->getEBilling()); - $this->assertSame('VN', $customer->getVatCode()); + $financials = $customer->getFinancials(); + $this->assertSame(30, $financials->getDueDays()); + $this->assertSame(true, $financials->getPayAvailable()); + $this->assertSame('SEPANLDD', Util::objectToStr($financials->getPayCode())); + $this->assertSame(false, $financials->getEBilling()); + $this->assertSame('VN', Util::objectToStr($financials->getVatCode())); // Collect Mandate - $collectMandate = $customer->getCollectMandate(); + $collectMandate = $financials->getCollectMandate(); $this->assertSame('1', $collectMandate->getID()); $this->assertEquals(new \DateTimeImmutable('2018-06-04'), $collectMandate->getSignatureDate()); $this->assertEquals(new \DateTimeImmutable('2018-06-08'), $collectMandate->getFirstRunDate()); @@ -71,99 +76,99 @@ public function testGetCustomerWorks() // Addresses $addresses = $customer->getAddresses(); $this->assertCount(1, $addresses); - $this->assertArrayHasKey('1', $addresses); + $this->assertArrayHasKey(0, $addresses); /** @var CustomerAddress $address */ - $address = $addresses['1']; + $address = $addresses[0]; - $this->assertSame('1', $address->getID()); - $this->assertSame('invoice', $address->getType()); + $this->assertSame(1, $address->getID()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\AddressType'); + $this->assertSame($ReflectObject->getConstant('INVOICE'), (string)$address->getType()); $this->assertSame(true, $address->getDefault()); $this->assertSame('Customer 0', $address->getName()); - $this->assertSame('NL', $address->getCountry()); + $this->assertSame('NL', Util::objectToStr($address->getCountry())); $this->assertSame('Place', $address->getCity()); $this->assertSame('1000', $address->getPostcode()); $this->assertSame('010-123452000', $address->getTelephone()); - $this->assertSame('010-12342000', $address->getFax()); + $this->assertSame('010-12342000', $address->getTelefax()); $this->assertSame('info@example.com', $address->getEmail()); - $this->assertSame('', $address->getContact()); $this->assertSame('Customer 1', $address->getField1()); $this->assertSame('Streetname part 1 - 1', $address->getField2()); $this->assertSame('Streetname part 1 - 2', $address->getField3()); $this->assertSame('NL099887766B01', $address->getField4()); $this->assertSame('99887766', $address->getField5()); - $this->assertSame('', $address->getField6()); + $this->assertNull($address->getField6()); // Banks $banks = $customer->getBanks(); $this->assertCount(1, $banks); - $this->assertArrayHasKey('-1', $banks); + $this->assertArrayHasKey(0, $banks); /** @var CustomerBank $bank */ - $bank = $banks['-1']; + $bank = $banks[0]; - $this->assertSame('-1', $bank->getID()); + $this->assertSame(-1, $bank->getID()); $this->assertSame(true, $bank->getDefault()); $this->assertSame('Customer 1', $bank->getAscription()); - $this->assertSame('123456789', $bank->getAccountnumber()); - $this->assertSame('ABN Amro', $bank->getBankname()); - $this->assertSame('ABNANL2A', $bank->getBiccode()); + $this->assertSame('123456789', $bank->getAccountNumber()); + $this->assertSame('ABN Amro', $bank->getBankName()); + $this->assertSame('ABNANL2A', $bank->getBicCode()); $this->assertSame('Place', $bank->getCity()); - $this->assertSame('NL', $bank->getCountry()); + $this->assertSame('NL', Util::objectToStr($bank->getCountry())); $this->assertSame('NL02ABNA0123456789', $bank->getIban()); - $this->assertSame('', $bank->getNatbiccode()); - $this->assertSame('', $bank->getPostcode()); - $this->assertSame('', $bank->getState()); + $this->assertNull($bank->getNatBicCode()); + $this->assertNull($bank->getPostcode()); + $this->assertNull($bank->getState()); $this->assertNull($bank->getAddressField2()); $this->assertNull($bank->getAddressField3()); $this->assertSame('1097', $customer->getCode()); $this->assertSame('c5027760-476e-4081-85fb-351c983aea54', $customer->getUID()); - $this->assertSame('false', $customer->getInUse()); - $this->assertSame('normal', $customer->getBehaviour()); - $this->assertSame('0', $customer->getTouched()); - $this->assertSame('0', $customer->getBeginPeriod()); - $this->assertSame('0', $customer->getBeginYear()); - $this->assertSame('0', $customer->getEndPeriod()); - $this->assertSame('0', $customer->getEndYear()); - $this->assertSame('true', $customer->getEditDimensionName()); + $this->assertSame(false, $customer->getInUse()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\Behaviour'); + $this->assertSame($ReflectObject->getConstant('NORMAL'), (string)$customer->getBehaviour()); + $this->assertSame(0, $customer->getTouched()); + $this->assertSame(0, $customer->getBeginPeriod()); + $this->assertSame(0, $customer->getBeginYear()); + $this->assertSame(0, $customer->getEndPeriod()); + $this->assertSame(0, $customer->getEndYear()); // Creditmanagement $creditmanagement = $customer->getCreditManagement(); - $this->assertSame('', $creditmanagement->getResponsibleUser()); - $this->assertSame('0.00', $creditmanagement->getBaseCreditLimit()); - $this->assertSame(true, $creditmanagement->getSendReminder()); - $this->assertSame('', $creditmanagement->getReminderEmail()); + $this->assertNull(Util::objectToStr($creditmanagement->getResponsibleUser())); + $this->assertSame('0.00', Util::formatMoney($creditmanagement->getBaseCreditLimit())); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\SendReminder'); + $this->assertSame($ReflectObject->getConstant('TRUE'), (string)$creditmanagement->getSendReminder()); + $this->assertNull($creditmanagement->getReminderEmail()); $this->assertSame(false, $creditmanagement->getBlocked()); - $this->assertSame('', $creditmanagement->getFreeText1()); - $this->assertSame('', $creditmanagement->getFreeText2()); - $this->assertSame('', $creditmanagement->getFreeText3()); - $this->assertSame('', $creditmanagement->getComment()); + $this->assertNull($creditmanagement->getFreeText1()); + $this->assertNull($creditmanagement->getFreeText2()); + $this->assertNull($creditmanagement->getFreeText3()); + $this->assertNull($creditmanagement->getComment()); } public function testListAllCustomersWorks() { - $response = Response::fromString(file_get_contents(__DIR__ . '/resources/customerListResponse.xml')); + $response = (object)json_decode(file_get_contents(__DIR__ . '/resources/customerListResponse.json')); - $this->processXmlService + $this->finderService ->expects($this->once()) - ->method("sendDocument") - ->with($this->isInstanceOf(\PhpTwinfield\Request\Catalog\Dimension::class)) + ->method("searchFinder") ->willReturn($response); - $customers = $this->customerApiConnector->listAll($this->office); + $customers = $this->customerApiConnector->listAll(); $this->assertCount(3, $customers); - $this->assertArrayHasKey('D1000', $customers); - $this->assertSame('John Doe', $customers['D1000']['name']); + $this->assertSame('D1000', $customers[0]->getCode()); + $this->assertSame('John Doe', $customers[0]->getName()); - $this->assertArrayHasKey('D1001', $customers); - $this->assertSame('B. Terwel', $customers['D1001']['name']); + $this->assertSame('D1001', $customers[1]->getCode()); + $this->assertSame('B. Terwel', $customers[1]->getName()); - $this->assertArrayHasKey('D1002', $customers); - $this->assertSame('Hr E G H Küppers en/of MW M.J. Küppers-Veeneman', $customers['D1002']['name']); + $this->assertSame('D1002', $customers[2]->getCode()); + $this->assertSame('Hr E G H Küppers en/of MW M.J. Küppers-Veeneman', $customers[2]->getName()); } public function testSendCustomerWorks() @@ -171,20 +176,30 @@ public function testSendCustomerWorks() $customer = new Customer(); $customer->setOffice(Office::fromCode('001')); $customer->setName('Customer 0'); - $customer->setDueDays('30'); - $customer->setPayAvailable(true); - $customer->setPayCode('SEPANLDD'); + + $financials = new CustomerFinancials(); + $financials->setDueDays(30); + $financials->setPayAvailable(true); + $financials->setPayCode(\PhpTwinfield\PayCode::fromCode('SEPANLDD')); + + $collectMandate = new CustomerCollectMandate(); + $collectMandate->setID(1); + $collectMandate->setSignatureDate(Util::parseDate('20180604')); + $collectMandate->setFirstRunDate(Util::parseDate('20180608')); + $financials->setCollectMandate($collectMandate); + + $customer->setFinancials($financials); $address = new CustomerAddress(); - $address->setID('1'); - $address->setType('invoice'); + $address->setID(1); + $address->setType(\PhpTwinfield\Enums\AddressType::INVOICE()); $address->setDefault(true); $address->setName('Customer 0'); - $address->setCountry('NL'); + $address->setCountry(\PhpTwinfield\Country::fromCode('NL')); $address->setCity('Place'); $address->setPostcode('1000'); $address->setTelephone('010-123452000'); - $address->setFax('010-12342000'); + $address->setTelefax('010-12342000'); $address->setEmail('info@example.com'); $address->setField1('Customer 1'); $address->setField2('Streetname part 1 - 1'); @@ -194,25 +209,19 @@ public function testSendCustomerWorks() $bank = new CustomerBank(); $bank->setDefault(true); $bank->setAscription('Customer 1'); - $bank->setAccountnumber('123456789'); + $bank->setAccountNumber('123456789'); $bank->setAddressField2(''); $bank->setAddressField3(''); - $bank->setBankname('ABN Amro'); - $bank->setBiccode('ABNANL2A'); + $bank->setBankName('ABN Amro'); + $bank->setBicCode('ABNANL2A'); $bank->setCity('Place'); - $bank->setCountry('NL'); + $bank->setCountry(\PhpTwinfield\Country::fromCode('NL')); $bank->setIban('NL02ABNA0123456789'); - $bank->setNatbiccode(''); + $bank->setNatBicCode(''); $bank->setPostcode(''); $bank->setState(''); $customer->addBank($bank); - $collectMandate = new CustomerCollectMandate(); - $collectMandate->setID('1'); - $collectMandate->setSignatureDate(new \DateTimeImmutable('2018-06-04')); - $collectMandate->setFirstRunDate(new \DateTimeImmutable('2018-06-08')); - $customer->setCollectMandate($collectMandate); - $this->processXmlService ->expects($this->once()) ->method("sendDocument") diff --git a/tests/IntegrationTests/InvoiceIntegrationTest.php b/tests/IntegrationTests/InvoiceIntegrationTest.php index 225a7747..0231f15b 100644 --- a/tests/IntegrationTests/InvoiceIntegrationTest.php +++ b/tests/IntegrationTests/InvoiceIntegrationTest.php @@ -2,20 +2,27 @@ namespace PhpTwinfield\IntegrationTests; +use PhpTwinfield\ApiConnectors\ArticleApiConnector; use PhpTwinfield\ApiConnectors\InvoiceApiConnector; +use PhpTwinfield\ApiConnectors\InvoiceTypeApiConnector; +use PhpTwinfield\Article; use PhpTwinfield\Customer; +use PhpTwinfield\Currency; use PhpTwinfield\DomDocuments\InvoicesDocument; use PhpTwinfield\Invoice; use PhpTwinfield\InvoiceLine; use PhpTwinfield\InvoiceTotals; +use PhpTwinfield\InvoiceVatLine; use PhpTwinfield\Mappers\InvoiceMapper; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; +use PhpTwinfield\Util; /** * @covers Invoice * @covers InvoiceLine * @covers InvoiceTotals + * @covers InvoiceVatLine * @covers InvoicesDocument * @covers InvoiceMapper * @covers InvoiceApiConnector @@ -32,6 +39,25 @@ protected function setUp() parent::setUp(); $this->invoiceApiConnector = new InvoiceApiConnector($this->connection); + + $mockInvoiceTypeApiConnector = \Mockery::mock('overload:'.InvoiceTypeApiConnector::class)->makePartial(); + $mockInvoiceTypeApiConnector->shouldReceive('getInvoiceTypeVatType')->andReturnUsing(function() { + return 'exclusive'; + }); + + $mockArticleApiConnector = \Mockery::mock('overload:'.ArticleApiConnector::class)->makePartial(); + $mockArticleApiConnector->shouldReceive('get')->andReturnUsing(function() { + $article = new Article; + $article->setAllowChangeVatCode(true); + return $article; + }); + } + + protected function tearDown() + { + unset($mockInvoiceTypeApiConnector, $mockArticleApiConnector); + + \Mockery::close(); } public function testGetConceptInvoiceWorks() @@ -44,46 +70,59 @@ public function testGetConceptInvoiceWorks() ->with($this->isInstanceOf(\PhpTwinfield\Request\Read\Invoice::class)) ->willReturn($response); - $invoice = $this->invoiceApiConnector->get('FACTUUR', '5', $this->office); + $invoice = $this->invoiceApiConnector->get('FACTUUR', '5', Office::fromCode('001')); $this->assertInstanceOf(Invoice::class, $invoice); $this->assertEquals(Office::fromCode("11024"), $invoice->getOffice()); - $this->assertSame('FACTUUR', $invoice->getInvoiceType()); + $this->assertSame('FACTUUR', Util::objectToStr($invoice->getInvoiceType())); $this->assertSame('5', $invoice->getInvoiceNumber()); - $this->assertSame('20120831', $invoice->getInvoiceDate()); - $this->assertSame('BNK', $invoice->getBank()); - $this->assertSame('1', $invoice->getInvoiceAddressNumber()); - $this->assertSame('1', $invoice->getDeliverAddressNumber()); - $this->assertSame('1000', $invoice->getCustomer()->getCode()); - $this->assertSame('2012/8', $invoice->getPeriod()); - $this->assertSame('EUR', $invoice->getCurrency()); - $this->assertSame('concept', $invoice->getStatus()); - $this->assertSame('cash', $invoice->getPaymentMethod()); + $this->assertSame('20120831', Util::formatDate($invoice->getInvoiceDate())); + $this->assertSame('BNK', Util::objectToStr($invoice->getBank())); + $this->assertSame(1, $invoice->getInvoiceAddressNumber()); + $this->assertSame(1, $invoice->getDeliverAddressNumber()); + $this->assertSame('1000', Util::objectToStr($invoice->getCustomer())); + $this->assertSame('2012/08', $invoice->getPeriod()); + $this->assertSame('EUR', Util::objectToStr($invoice->getCurrency())); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\InvoiceStatus'); + $this->assertSame($ReflectObject->getConstant('CONCEPT'), (string)$invoice->getStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PaymentMethod'); + $this->assertSame($ReflectObject->getConstant('CASH'), (string)$invoice->getPaymentMethod()); + $this->assertSame('HEADER', $invoice->getHeaderText()); + $this->assertSame('FOOTER', $invoice->getFooterText()); $invoiceLines = $invoice->getLines(); $this->assertCount(1, $invoiceLines); - $this->assertArrayHasKey('1', $invoiceLines); + $this->assertArrayHasKey(0, $invoiceLines); /** @var InvoiceLine $invoiceLine */ - $invoiceLine = $invoiceLines['1']; - - $this->assertSame('1', $invoiceLine->getID()); - $this->assertSame('0', $invoiceLine->getArticle()); - $this->assertSame('118', $invoiceLine->getSubArticle()); - $this->assertSame('1', $invoiceLine->getQuantity()); - $this->assertSame('1', $invoiceLine->getUnits()); - $this->assertSame('true', $invoiceLine->getAllowDiscountOrPremium()); + $invoiceLine = $invoiceLines[0]; + + $this->assertSame(1, $invoiceLine->getID()); + $this->assertSame('0', Util::objectToStr($invoiceLine->getArticle())); + $this->assertSame('118', $invoiceLine->getSubArticleToString()); + $this->assertSame(1.0, $invoiceLine->getQuantity()); + $this->assertSame(1, $invoiceLine->getUnits()); + $this->assertSame(true, $invoiceLine->getAllowDiscountOrPremium()); $this->assertSame('CoalesceFunctioningOnImpatienceTShirt', $invoiceLine->getDescription()); - $this->assertSame('15.00', $invoiceLine->getValueExcl()); - $this->assertSame('0.00', $invoiceLine->getVatValue()); - $this->assertSame('15.00', $invoiceLine->getValueInc()); - $this->assertSame('15.00', $invoiceLine->getUnitsPriceExcl()); - $this->assertSame('8020', $invoiceLine->getDim1()); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getValueExcl())); + $this->assertSame('0.00', Util::formatMoney($invoiceLine->getVatValue())); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getValueInc())); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getUnitsPriceExcl())); + $this->assertSame('8020', Util::objectToStr($invoiceLine->getDim1())); - // TODO - Vat lines + $invoiceVatLines = $invoice->getVatLines(); + $this->assertCount(1, $invoiceVatLines); - $this->assertSame('15.00', $invoice->getTotals()->getValueInc()); - $this->assertSame('15.00', $invoice->getTotals()->getValueExcl()); + /** @var InvoiceVatLine $invoiceVatLine */ + $invoiceVatLine = current($invoiceVatLines); + + $this->assertSame('VN', Util::objectToStr($invoiceLine->getVatCode())); + $this->assertSame('0.00', Util::formatMoney($invoiceLine->getVatValue())); + $this->assertNull($invoiceLine->getPerformanceType()); + $this->assertNull($invoiceLine->getPerformanceDate()); + + $this->assertSame('15.00', Util::formatMoney($invoice->getTotals()->getValueInc())); + $this->assertSame('15.00', Util::formatMoney($invoice->getTotals()->getValueExcl())); $this->assertNull($invoice->getFinancialNumber()); $this->assertNull($invoice->getFinancialCode()); @@ -99,48 +138,61 @@ public function testGetFinalInvoiceWorks() ->with($this->isInstanceOf(\PhpTwinfield\Request\Read\Invoice::class)) ->willReturn($response); - $invoice = $this->invoiceApiConnector->get('FACTUUR', '5', $this->office); + $invoice = $this->invoiceApiConnector->get('FACTUUR', '5', Office::fromCode('001')); $this->assertInstanceOf(Invoice::class, $invoice); $this->assertEquals(Office::fromCode("11024"), $invoice->getOffice()); - $this->assertSame('FACTUUR', $invoice->getInvoiceType()); + $this->assertSame('FACTUUR', Util::objectToStr($invoice->getInvoiceType())); $this->assertSame('5', $invoice->getInvoiceNumber()); - $this->assertSame('20120831', $invoice->getInvoiceDate()); - $this->assertSame('BNK', $invoice->getBank()); - $this->assertSame('1', $invoice->getInvoiceAddressNumber()); - $this->assertSame('1', $invoice->getDeliverAddressNumber()); - $this->assertSame('1000', $invoice->getCustomer()->getCode()); - $this->assertSame('2012/8', $invoice->getPeriod()); - $this->assertSame('EUR', $invoice->getCurrency()); - $this->assertSame('final', $invoice->getStatus()); - $this->assertSame('cash', $invoice->getPaymentMethod()); + $this->assertSame('20120831', Util::formatDate($invoice->getInvoiceDate())); + $this->assertSame('BNK', Util::objectToStr($invoice->getBank())); + $this->assertSame(1, $invoice->getInvoiceAddressNumber()); + $this->assertSame(1, $invoice->getDeliverAddressNumber()); + $this->assertSame('1000', Util::objectToStr($invoice->getCustomer())); + $this->assertSame('2012/08', $invoice->getPeriod()); + $this->assertSame('EUR', Util::objectToStr($invoice->getCurrency())); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\InvoiceStatus'); + $this->assertSame($ReflectObject->getConstant('FINAL'), (string)$invoice->getStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PaymentMethod'); + $this->assertSame($ReflectObject->getConstant('CASH'), (string)$invoice->getPaymentMethod()); + $this->assertSame('HEADER', $invoice->getHeaderText()); + $this->assertSame('FOOTER', $invoice->getFooterText()); $invoiceLines = $invoice->getLines(); $this->assertCount(1, $invoiceLines); - $this->assertArrayHasKey('1', $invoiceLines); + $this->assertArrayHasKey(0, $invoiceLines); /** @var InvoiceLine $invoiceLine */ - $invoiceLine = $invoiceLines['1']; - - $this->assertSame('1', $invoiceLine->getID()); - $this->assertSame('0', $invoiceLine->getArticle()); - $this->assertSame('118', $invoiceLine->getSubArticle()); - $this->assertSame('1', $invoiceLine->getQuantity()); - $this->assertSame('1', $invoiceLine->getUnits()); - $this->assertSame('true', $invoiceLine->getAllowDiscountOrPremium()); + $invoiceLine = $invoiceLines[0]; + + $this->assertSame(1, $invoiceLine->getID()); + $this->assertSame('0', Util::objectToStr($invoiceLine->getArticle())); + $this->assertSame('118', $invoiceLine->getSubArticleToString()); + $this->assertSame(1.0, $invoiceLine->getQuantity()); + $this->assertSame(1, $invoiceLine->getUnits()); + $this->assertSame(true, $invoiceLine->getAllowDiscountOrPremium()); $this->assertSame('CoalesceFunctioningOnImpatienceTShirt', $invoiceLine->getDescription()); - $this->assertSame('15.00', $invoiceLine->getValueExcl()); - $this->assertSame('0.00', $invoiceLine->getVatValue()); - $this->assertSame('15.00', $invoiceLine->getValueInc()); - $this->assertSame('15.00', $invoiceLine->getUnitsPriceExcl()); - $this->assertSame('8020', $invoiceLine->getDim1()); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getValueExcl())); + $this->assertSame('0.00', Util::formatMoney($invoiceLine->getVatValue())); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getValueInc())); + $this->assertSame('15.00', Util::formatMoney($invoiceLine->getUnitsPriceExcl())); + $this->assertSame('8020', Util::objectToStr($invoiceLine->getDim1())); + + $invoiceVatLines = $invoice->getVatLines(); + $this->assertCount(1, $invoiceVatLines); - // TODO - Vat lines + /** @var InvoiceVatLine $invoiceVatLine */ + $invoiceVatLine = current($invoiceVatLines); - $this->assertSame('15.00', $invoice->getTotals()->getValueInc()); - $this->assertSame('15.00', $invoice->getTotals()->getValueExcl()); + $this->assertSame('VN', Util::objectToStr($invoiceLine->getVatCode())); + $this->assertSame('0.00', Util::formatMoney($invoiceLine->getVatValue())); + $this->assertNull($invoiceLine->getPerformanceType()); + $this->assertNull($invoiceLine->getPerformanceDate()); - $this->assertSame('123456789', $invoice->getFinancialNumber()); + $this->assertSame('15.00', Util::formatMoney($invoice->getTotals()->getValueInc())); + $this->assertSame('15.00', Util::formatMoney($invoice->getTotals()->getValueExcl())); + + $this->assertSame(123456789, $invoice->getFinancialNumber()); $this->assertSame('123456789', $invoice->getFinancialCode()); } @@ -151,39 +203,36 @@ public function testSendInvoiceWorks() $invoice = new Invoice(); $invoice->setOffice(Office::fromCode('11024')); - $invoice->setInvoiceType('FACTUUR'); + $invoice->setInvoiceType(\PhpTwinfield\InvoiceType::fromCode('FACTUUR')); $invoice->setInvoiceNumber('5'); - $invoice->setInvoiceDate('20120831'); - $invoice->setBank('BNK'); - $invoice->setInvoiceAddressNumber('1'); - $invoice->setDeliverAddressNumber('1'); + $invoice->setInvoiceDate(Util::parseDate('20120831')); + $invoice->setBank(\PhpTwinfield\CashBankBook::fromCode('BNK')); + $invoice->setInvoiceAddressNumber(1); + $invoice->setDeliverAddressNumber(1); $invoice->setCustomer($customer); - $invoice->setPeriod('2012/8'); - $invoice->setCurrency('EUR'); - $invoice->setStatus('concept'); - $invoice->setPaymentMethod('cash'); + $invoice->setPeriod('2012/08'); + $invoice->setCurrency(Currency::fromCode('EUR')); + $invoice->setStatus(\PhpTwinfield\Enums\InvoiceStatus::CONCEPT()); + $invoice->setPaymentMethod(\PhpTwinfield\Enums\PaymentMethod::CASH()); + $invoice->setHeaderText('HEADER'); + $invoice->setFooterText('FOOTER'); $invoiceLine = new InvoiceLine(); - $invoiceLine->setID('1'); - $invoiceLine->setArticle('4'); - $invoiceLine->setSubArticle('118'); - $invoiceLine->setQuantity('1'); - $invoiceLine->setUnits('1'); - $invoiceLine->setAllowDiscountOrPremium('true'); + $invoiceLine->setID(1); + $invoiceLine->setArticle(\PhpTwinfield\Article::fromCode('4')); + $invoiceLine->setSubArticle(\PhpTwinfield\ArticleLine::fromCode('118')); + $invoiceLine->setQuantity(1); + $invoiceLine->setUnits(1); + $invoiceLine->setAllowDiscountOrPremium(true); $invoiceLine->setDescription('CoalesceFunctioningOnImpatienceTShirt'); - $invoiceLine->setValueExcl('15.00'); - $invoiceLine->setVatValue('0.00'); - $invoiceLine->setValueInc('15.00'); - $invoiceLine->setUnitsPriceExcl('15.00'); - $invoiceLine->setDim1('8020'); - $invoiceLine->setVatCode('VN'); + $invoiceLine->setValueExcl(Util::parseMoney(15.00, new \Money\Currency('EUR'))); + $invoiceLine->setVatValue(Util::parseMoney(0.00, new \Money\Currency('EUR'))); + $invoiceLine->setValueInc(Util::parseMoney(15.00, new \Money\Currency('EUR'))); + $invoiceLine->setUnitsPriceExcl(Util::parseMoney(15.00, new \Money\Currency('EUR'))); + $invoiceLine->setDim1(\PhpTwinfield\GeneralLedger::fromCode('8020')); + $invoiceLine->setVatCode(\PhpTwinfield\VatCode::fromCode('VN')); $invoice->addLine($invoiceLine); - $totals = new InvoiceTotals(); - $totals->setValueExcl('15.00'); - $totals->setValueInc('15.00'); - $invoice->setTotals($totals); - $this->processXmlService ->expects($this->once()) ->method("sendDocument") diff --git a/tests/IntegrationTests/JournalTransactionIntegrationTest.php b/tests/IntegrationTests/JournalTransactionIntegrationTest.php index ee16f03c..61384e25 100644 --- a/tests/IntegrationTests/JournalTransactionIntegrationTest.php +++ b/tests/IntegrationTests/JournalTransactionIntegrationTest.php @@ -2,18 +2,20 @@ namespace PhpTwinfield\IntegrationTests; -use Money\Currency; use Money\Money; use PhpTwinfield\ApiConnectors\TransactionApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\DomDocuments\TransactionsDocument; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Enums\LineType; +use PhpTwinfield\Enums\MatchStatus; use PhpTwinfield\JournalTransaction; use PhpTwinfield\JournalTransactionLine; use PhpTwinfield\Mappers\TransactionMapper; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; +use PhpTwinfield\Util; /** * @covers JournalTransaction @@ -51,18 +53,18 @@ public function testGetJournalTransactionWorks() $this->assertInstanceOf(JournalTransaction::class, $journalTransaction); $this->assertEquals(Destiny::TEMPORARY(), $journalTransaction->getDestiny()); - $this->assertNull($journalTransaction->isAutoBalanceVat()); + $this->assertNull($journalTransaction->getAutoBalanceVat()); $this->assertNull($journalTransaction->getRaiseWarning()); $this->assertEquals(Office::fromCode('0-0-1-NL-001'), $journalTransaction->getOffice()); $this->assertSame('MEMO', $journalTransaction->getCode()); $this->assertSame(201300003, $journalTransaction->getNumber()); $this->assertSame('2013/11', $journalTransaction->getPeriod()); - $this->assertEquals(new Currency('EUR'), $journalTransaction->getCurrency()); + $this->assertEquals('EUR', Util::objectToStr($journalTransaction->getCurrency())); $this->assertEquals(new \DateTimeImmutable('2013-11-04'), $journalTransaction->getDate()); $this->assertSame('import', $journalTransaction->getOrigin()); - $this->assertNull($journalTransaction->getFreetext1()); - $this->assertNull($journalTransaction->getFreetext2()); - $this->assertNull($journalTransaction->getFreetext3()); + $this->assertNull($journalTransaction->getFreeText1()); + $this->assertNull($journalTransaction->getFreeText2()); + $this->assertNull($journalTransaction->getFreeText3()); $this->assertNull($journalTransaction->getRegime()); /** @var JournalTransactionLine[] $journalTransactionLines */ @@ -72,47 +74,49 @@ public function testGetJournalTransactionWorks() $this->assertEquals(LineType::DETAIL(), $detailLine1->getLineType()); $this->assertSame(1, $detailLine1->getId()); - $this->assertSame('4008', $detailLine1->getDim1()); - $this->assertNull($detailLine1->getDim2()); + $this->assertSame('4008', Util::objectToStr($detailLine1->getDim1())); + $this->assertNull(Util::objectToStr($detailLine1->getDim2())); $this->assertEquals(DebitCredit::DEBIT(), $detailLine1->getDebitCredit()); $this->assertEquals(Money::EUR(43555), $detailLine1->getValue()); $this->assertEquals(Money::EUR(43555), $detailLine1->getBaseValue()); $this->assertSame(1.0, $detailLine1->getRate()); - $this->assertEquals(Money::EUR(65333), $detailLine1->getRepValue()); + $this->assertEquals(Money::USD(65333), $detailLine1->getRepValue()); $this->assertSame(1.500000000, $detailLine1->getRepRate()); $this->assertNull($detailLine1->getDescription()); - $this->assertSame(JournalTransactionLine::MATCHSTATUS_NOTMATCHABLE, $detailLine1->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('NOTMATCHABLE'), (string)$detailLine1->getMatchStatus()); $this->assertNull($detailLine1->getMatchLevel()); $this->assertNull($detailLine1->getBaseValueOpen()); - $this->assertNull($detailLine1->getVatCode()); + $this->assertNull(Util::objectToStr($detailLine1->getVatCode())); $this->assertNull($detailLine1->getVatValue()); - $this->assertNull($detailLine1->getPerformanceType()); - $this->assertNull($detailLine1->getPerformanceCountry()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$detailLine1->getPerformanceType()); + $this->assertNull(Util::objectToStr($detailLine1->getPerformanceCountry())); $this->assertNull($detailLine1->getPerformanceVatNumber()); $this->assertNull($detailLine1->getPerformanceDate()); - $this->assertNull($detailLine1->getInvoiceNumber()); $this->assertEquals(LineType::DETAIL(), $detailLine2->getLineType()); $this->assertSame(2, $detailLine2->getId()); - $this->assertSame('1300', $detailLine2->getDim1()); - $this->assertSame('1000', $detailLine2->getDim2()); + $this->assertSame('1300', Util::objectToStr($detailLine2->getDim1())); + $this->assertSame('1000', Util::objectToStr($detailLine2->getDim2())); $this->assertEquals(DebitCredit::CREDIT(), $detailLine2->getDebitCredit()); $this->assertEquals(Money::EUR(43555), $detailLine2->getValue()); $this->assertEquals(Money::EUR(43555), $detailLine2->getBaseValue()); $this->assertSame(1.0, $detailLine2->getRate()); - $this->assertEquals(Money::EUR(65333), $detailLine2->getRepValue()); + $this->assertEquals(Money::USD(65333), $detailLine2->getRepValue()); $this->assertSame(1.500000000, $detailLine2->getRepRate()); $this->assertSame('Invoice paid', $detailLine2->getDescription()); - $this->assertSame(JournalTransactionLine::MATCHSTATUS_AVAILABLE, $detailLine2->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('AVAILABLE'), (string)$detailLine2->getMatchStatus()); $this->assertSame(2, $detailLine2->getMatchLevel()); $this->assertEquals(Money::EUR(43555), $detailLine2->getBaseValueOpen()); - $this->assertNull($detailLine2->getVatCode()); + $this->assertNull(Util::objectToStr($detailLine2->getVatCode())); $this->assertNull($detailLine2->getVatValue()); - $this->assertNull($detailLine2->getPerformanceType()); - $this->assertNull($detailLine2->getPerformanceCountry()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$detailLine2->getPerformanceType()); + $this->assertNull(Util::objectToStr($detailLine2->getPerformanceCountry())); $this->assertNull($detailLine2->getPerformanceVatNumber()); $this->assertNull($detailLine2->getPerformanceDate()); - $this->assertSame('11001770', $detailLine2->getInvoiceNumber()); } public function testSendJournalTransactionWorks() @@ -121,7 +125,7 @@ public function testSendJournalTransactionWorks() $journalTransaction ->setDestiny(Destiny::TEMPORARY()) ->setCode('MEMO') - ->setCurrency(new Currency('EUR')) + ->setCurrency(Currency::fromCode('EUR')) ->setDate(new \DateTimeImmutable('2013-11-04')) ->setOffice(Office::fromCode('001')); @@ -129,17 +133,16 @@ public function testSendJournalTransactionWorks() $detailLine1 ->setLineType(LineType::DETAIL()) ->setId('1') - ->setDim1('4008') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('4008')) ->setValue(Money::EUR(-43555)); $detailLine2 = new JournalTransactionLine(); $detailLine2 ->setLineType(LineType::DETAIL()) ->setId('2') - ->setDim1('1300') - ->setDim2('1000') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1300')) + ->setDim2(\PhpTwinfield\CostCenter::fromCode('1000')) ->setValue(Money::EUR(43555)) - ->setInvoiceNumber('11001770') ->setDescription('Invoice paid'); $journalTransaction diff --git a/tests/IntegrationTests/OfficeIntegrationTest.php b/tests/IntegrationTests/OfficeIntegrationTest.php index f35e08f3..160e7926 100644 --- a/tests/IntegrationTests/OfficeIntegrationTest.php +++ b/tests/IntegrationTests/OfficeIntegrationTest.php @@ -3,22 +3,78 @@ namespace PhpTwinfield\IntegrationTests; use PhpTwinfield\ApiConnectors\OfficeApiConnector; +use PhpTwinfield\Enums\Services; +use PhpTwinfield\Office; use PhpTwinfield\Response\Response; +use PhpTwinfield\Secure\AuthenticatedConnection; +use PhpTwinfield\Services\FinderService; +use PhpTwinfield\Services\ProcessXmlService; +use PHPUnit\Framework\TestCase; -class OfficeIntegrationTest extends BaseIntegrationTest +/** + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ +class OfficeIntegrationTest extends TestCase { /** * @var OfficeApiConnector|\PHPUnit_Framework_MockObject_MockObject */ private $officeApiConnector; + /** + * @var Office + */ + protected $office; + + /** + * @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject + */ + protected $connection; + + /** + * @var ProcessXmlService|\PHPUnit_Framework_MockObject_MockObject + */ + protected $processXmlService; + + /** + * @var FinderService|\PHPUnit_Framework_MockObject_MockObject + */ + protected $finderService; + protected function setUp() { parent::setUp(); + $this->office = new Office(); + $this->office->setCode("11024"); + + $this->processXmlService = $this->createPartialMock(ProcessXmlService::class, ['sendDocument']); + $this->finderService = $this->createPartialMock(FinderService::class, ['searchFinder']); + + $this->connection = $this->createMock(AuthenticatedConnection::class); + $this->connection->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturnCallback(function (Services $service) { + switch ($service->getValue()) { + case Services::PROCESSXML()->getValue(): + return $this->processXmlService; + + case Services::FINDER()->getValue(): + return $this->finderService; + } + + throw new \InvalidArgumentException("Unknown service {$service->getValue()}"); + }); + $this->officeApiConnector = new OfficeApiConnector($this->connection); } + protected function getSuccessfulResponse(): Response + { + return Response::fromString(''); + } + public function testListOfficesWithoutCompanyId() { $response = Response::fromString(file_get_contents(__DIR__ . '/resources/officeOauthGetResponse.xml')); @@ -38,4 +94,4 @@ public function testListOfficesWithoutCompanyId() $this->assertSame('010', $offices[1]->getCode()); $this->assertSame('More&Zo Holding', $offices[1]->getName()); } -} \ No newline at end of file +} diff --git a/tests/IntegrationTests/PurchaseTransactionIntegrationTest.php b/tests/IntegrationTests/PurchaseTransactionIntegrationTest.php index d93bc135..80fba92b 100644 --- a/tests/IntegrationTests/PurchaseTransactionIntegrationTest.php +++ b/tests/IntegrationTests/PurchaseTransactionIntegrationTest.php @@ -2,18 +2,20 @@ namespace PhpTwinfield\IntegrationTests; -use Money\Currency; use Money\Money; use PhpTwinfield\ApiConnectors\TransactionApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\DomDocuments\TransactionsDocument; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Enums\LineType; +use PhpTwinfield\Enums\MatchStatus; use PhpTwinfield\Mappers\TransactionMapper; use PhpTwinfield\Office; use PhpTwinfield\PurchaseTransaction; use PhpTwinfield\PurchaseTransactionLine; use PhpTwinfield\Response\Response; +use PhpTwinfield\Util; /** * @covers PurchaseTransaction @@ -50,18 +52,18 @@ public function testGetPurchaseTransactionWorks() $this->assertInstanceOf(PurchaseTransaction::class, $purchaseTransaction); $this->assertEquals(Destiny::TEMPORARY(), $purchaseTransaction->getDestiny()); - $this->assertNull($purchaseTransaction->isAutoBalanceVat()); + $this->assertNull($purchaseTransaction->getAutoBalanceVat()); $this->assertSame(false, $purchaseTransaction->getRaiseWarning()); $this->assertEquals(Office::fromCode('001'), $purchaseTransaction->getOffice()); $this->assertSame('INK', $purchaseTransaction->getCode()); $this->assertSame(201300021, $purchaseTransaction->getNumber()); $this->assertSame('2013/05', $purchaseTransaction->getPeriod()); - $this->assertEquals(new Currency('EUR'), $purchaseTransaction->getCurrency()); + $this->assertEquals('EUR', Util::objectToStr($purchaseTransaction->getCurrency())); $this->assertEquals(new \DateTimeImmutable('2013-05-02'), $purchaseTransaction->getDate()); $this->assertSame('import', $purchaseTransaction->getOrigin()); - $this->assertNull($purchaseTransaction->getFreetext1()); - $this->assertNull($purchaseTransaction->getFreetext2()); - $this->assertNull($purchaseTransaction->getFreetext3()); + $this->assertNull($purchaseTransaction->getFreeText1()); + $this->assertNull($purchaseTransaction->getFreeText2()); + $this->assertNull($purchaseTransaction->getFreeText3()); $this->assertEquals(new \DateTimeImmutable('2013-05-06'), $purchaseTransaction->getDueDate()); $this->assertSame('20130-5481', $purchaseTransaction->getInvoiceNumber()); $this->assertSame('+++100/0160/01495+++', $purchaseTransaction->getPaymentReference()); @@ -73,16 +75,17 @@ public function testGetPurchaseTransactionWorks() $this->assertEquals(LineType::TOTAL(), $totalLine->getLineType()); $this->assertSame(1, $totalLine->getId()); - $this->assertSame('1600', $totalLine->getDim1()); - $this->assertSame('2000', $totalLine->getDim2()); + $this->assertSame('1600', Util::objectToStr($totalLine->getDim1())); + $this->assertSame('2000', Util::objectToStr($totalLine->getDim2())); $this->assertEquals(DebitCredit::CREDIT(), $totalLine->getDebitCredit()); $this->assertEquals(Money::EUR(12100), $totalLine->getValue()); $this->assertEquals(Money::EUR(12100), $totalLine->getBaseValue()); $this->assertSame(1.0, $totalLine->getRate()); - $this->assertEquals(Money::EUR(15653), $totalLine->getRepValue()); + $this->assertEquals(Money::USD(15653), $totalLine->getRepValue()); $this->assertSame(1.293600000, $totalLine->getRepRate()); - $this->assertSame('', $totalLine->getDescription()); - $this->assertSame(PurchaseTransactionLine::MATCHSTATUS_AVAILABLE, $totalLine->getMatchStatus()); + $this->assertNull($totalLine->getDescription()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('AVAILABLE'), (string)$totalLine->getMatchStatus()); $this->assertSame(2, $totalLine->getMatchLevel()); $this->assertEquals(Money::EUR(12100), $totalLine->getBaseValueOpen()); $this->assertNull($totalLine->getVatCode()); @@ -93,19 +96,20 @@ public function testGetPurchaseTransactionWorks() $this->assertEquals(LineType::DETAIL(), $detailLine->getLineType()); $this->assertSame(2, $detailLine->getId()); - $this->assertSame('8020', $detailLine->getDim1()); - $this->assertNull($detailLine->getDim2()); + $this->assertSame('8020', Util::objectToStr($detailLine->getDim1())); + $this->assertNull(Util::objectToStr($detailLine->getDim2())); $this->assertEquals(DebitCredit::DEBIT(), $detailLine->getDebitCredit()); $this->assertEquals(Money::EUR(10000), $detailLine->getValue()); $this->assertEquals(Money::EUR(10000), $detailLine->getBaseValue()); $this->assertSame(1.0, $detailLine->getRate()); - $this->assertEquals(Money::EUR(12936), $detailLine->getRepValue()); + $this->assertEquals(Money::USD(12936), $detailLine->getRepValue()); $this->assertSame(1.293600000, $detailLine->getRepRate()); $this->assertSame('Outfit', $detailLine->getDescription()); - $this->assertSame(PurchaseTransactionLine::MATCHSTATUS_NOTMATCHABLE, $detailLine->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('NOTMATCHABLE'), (string)$detailLine->getMatchStatus()); $this->assertNull($detailLine->getMatchLevel()); $this->assertNull($detailLine->getBaseValueOpen()); - $this->assertSame('IH', $detailLine->getVatCode()); + $this->assertSame('IH', Util::objectToStr($detailLine->getVatCode())); $this->assertEquals(Money::EUR(2100), $detailLine->getVatValue()); $this->assertNull($detailLine->getVatTotal()); $this->assertNull($detailLine->getVatBaseTotal()); @@ -113,19 +117,19 @@ public function testGetPurchaseTransactionWorks() $this->assertEquals(LineType::VAT(), $vatLine->getLineType()); $this->assertSame(3, $vatLine->getId()); - $this->assertSame('1510', $vatLine->getDim1()); + $this->assertSame('1510', Util::objectToStr($vatLine->getDim1())); $this->assertNull($vatLine->getDim2()); $this->assertEquals(DebitCredit::DEBIT(), $vatLine->getDebitCredit()); $this->assertEquals(Money::EUR(2100), $vatLine->getValue()); $this->assertEquals(Money::EUR(2100), $vatLine->getBaseValue()); $this->assertSame(1.0, $vatLine->getRate()); - $this->assertEquals(Money::EUR(2717), $vatLine->getRepValue()); + $this->assertEquals(Money::USD(2717), $vatLine->getRepValue()); $this->assertSame(1.293600000, $vatLine->getRepRate()); $this->assertNull($vatLine->getDescription()); $this->assertNull($vatLine->getMatchStatus()); $this->assertNull($vatLine->getMatchLevel()); $this->assertNull($vatLine->getBaseValueOpen()); - $this->assertSame('IH', $vatLine->getVatCode()); + $this->assertSame('IH', Util::objectToStr($vatLine->getVatCode())); $this->assertNull($vatLine->getVatValue()); $this->assertNull($vatLine->getVatTotal()); $this->assertNull($vatLine->getVatBaseTotal()); @@ -139,7 +143,7 @@ public function testSendPurchaseTransactionWorks() ->setDestiny(Destiny::TEMPORARY()) ->setRaiseWarning(false) ->setCode('INK') - ->setCurrency(new Currency('EUR')) + ->setCurrency(Currency::fromCode('EUR')) ->setDate(new \DateTimeImmutable('2013-05-02')) ->setPeriod('2013/05') ->setInvoiceNumber('20130-5481') @@ -151,8 +155,8 @@ public function testSendPurchaseTransactionWorks() $totalLine ->setLineType(LineType::TOTAL()) ->setId('1') - ->setDim1('1600') - ->setDim2('2000') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1600')) + ->setDim2(\PhpTwinfield\CostCenter::fromCode('2000')) ->setValue(Money::EUR(12100)) ->setDescription(''); @@ -160,10 +164,10 @@ public function testSendPurchaseTransactionWorks() $detailLine ->setLineType(LineType::DETAIL()) ->setId('2') - ->setDim1('8020') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('8020')) ->setValue(Money::EUR(10000)) ->setDescription('Outfit') - ->setVatCode('IH'); + ->setVatCode(\PhpTwinfield\VatCode::fromCode('IH')); $purchaseTransaction ->addLine($totalLine) diff --git a/tests/IntegrationTests/SalesTransactionIntegrationTest.php b/tests/IntegrationTests/SalesTransactionIntegrationTest.php index 15f1121a..e923922d 100644 --- a/tests/IntegrationTests/SalesTransactionIntegrationTest.php +++ b/tests/IntegrationTests/SalesTransactionIntegrationTest.php @@ -2,18 +2,20 @@ namespace PhpTwinfield\IntegrationTests; -use Money\Currency; use Money\Money; use PhpTwinfield\ApiConnectors\TransactionApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\DomDocuments\TransactionsDocument; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Enums\LineType; +use PhpTwinfield\Enums\MatchStatus; use PhpTwinfield\Mappers\TransactionMapper; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; use PhpTwinfield\SalesTransaction; use PhpTwinfield\SalesTransactionLine; +use PhpTwinfield\Util; /** * @covers SalesTransaction @@ -50,22 +52,22 @@ public function testGetSalesTransactionWorks() $this->assertInstanceOf(SalesTransaction::class, $salesTransaction); $this->assertEquals(Destiny::TEMPORARY(), $salesTransaction->getDestiny()); - $this->assertNull($salesTransaction->isAutoBalanceVat()); + $this->assertNull($salesTransaction->getAutoBalanceVat()); $this->assertSame(false, $salesTransaction->getRaiseWarning()); $this->assertEquals(Office::fromCode('001'), $salesTransaction->getOffice()); $this->assertSame('SLS', $salesTransaction->getCode()); $this->assertSame(201300095, $salesTransaction->getNumber()); $this->assertSame('2013/05', $salesTransaction->getPeriod()); - $this->assertEquals(new Currency('EUR'), $salesTransaction->getCurrency()); + $this->assertEquals('EUR', Util::objectToStr($salesTransaction->getCurrency())); $this->assertEquals(new \DateTimeImmutable('2013-05-02'), $salesTransaction->getDate()); $this->assertSame('import', $salesTransaction->getOrigin()); - $this->assertNull($salesTransaction->getFreetext1()); - $this->assertNull($salesTransaction->getFreetext2()); - $this->assertNull($salesTransaction->getFreetext3()); + $this->assertNull($salesTransaction->getFreeText1()); + $this->assertNull($salesTransaction->getFreeText2()); + $this->assertNull($salesTransaction->getFreeText3()); $this->assertEquals(new \DateTimeImmutable('2013-05-06'), $salesTransaction->getDueDate()); $this->assertSame('20130-6000', $salesTransaction->getInvoiceNumber()); $this->assertSame('+++100/0160/01495+++', $salesTransaction->getPaymentReference()); - $this->assertSame('', $salesTransaction->getOriginReference()); + $this->assertNull($salesTransaction->getOriginReference()); /** @var SalesTransactionLine[] $salesTransactionLines */ $salesTransactionLines = $salesTransaction->getLines(); @@ -74,16 +76,17 @@ public function testGetSalesTransactionWorks() $this->assertEquals(LineType::TOTAL(), $totalLine->getLineType()); $this->assertSame(1, $totalLine->getId()); - $this->assertSame('1300', $totalLine->getDim1()); - $this->assertSame('1000', $totalLine->getDim2()); + $this->assertSame('1300', Util::objectToStr($totalLine->getDim1())); + $this->assertSame('1000', Util::objectToStr($totalLine->getDim2())); $this->assertEquals(DebitCredit::DEBIT(), $totalLine->getDebitCredit()); $this->assertEquals(Money::EUR(12100), $totalLine->getValue()); $this->assertEquals(Money::EUR(12100), $totalLine->getBaseValue()); $this->assertSame(1.0, $totalLine->getRate()); - $this->assertEquals(Money::EUR(15653), $totalLine->getRepValue()); + $this->assertEquals(Money::USD(15653), $totalLine->getRepValue()); $this->assertSame(1.293600000, $totalLine->getRepRate()); - $this->assertSame('', $totalLine->getDescription()); - $this->assertSame(SalesTransactionLine::MATCHSTATUS_AVAILABLE, $totalLine->getMatchStatus()); + $this->assertNull($totalLine->getDescription()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('AVAILABLE'), (string)$totalLine->getMatchStatus()); $this->assertSame(2, $totalLine->getMatchLevel()); $this->assertEquals(Money::EUR(12100), $totalLine->getBaseValueOpen()); $this->assertNull($totalLine->getVatCode()); @@ -98,49 +101,52 @@ public function testGetSalesTransactionWorks() $this->assertEquals(LineType::DETAIL(), $detailLine->getLineType()); $this->assertSame(2, $detailLine->getId()); - $this->assertSame('8020', $detailLine->getDim1()); - $this->assertNull($detailLine->getDim2()); + $this->assertSame('8020', Util::objectToStr($detailLine->getDim1())); + $this->assertNull(Util::objectToStr($detailLine->getDim2())); $this->assertEquals(DebitCredit::CREDIT(), $detailLine->getDebitCredit()); $this->assertEquals(Money::EUR(10000), $detailLine->getValue()); $this->assertEquals(Money::EUR(10000), $detailLine->getBaseValue()); $this->assertSame(1.0, $detailLine->getRate()); - $this->assertEquals(Money::EUR(12936), $detailLine->getRepValue()); + $this->assertEquals(Money::USD(12936), $detailLine->getRepValue()); $this->assertSame(1.293600000, $detailLine->getRepRate()); $this->assertSame('Outfit', $detailLine->getDescription()); - $this->assertSame(SalesTransactionLine::MATCHSTATUS_NOTMATCHABLE, $detailLine->getMatchStatus()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('NOTMATCHABLE'), (string)$detailLine->getMatchStatus()); $this->assertNull($detailLine->getMatchLevel()); $this->assertNull($detailLine->getBaseValueOpen()); - $this->assertSame('VH', $detailLine->getVatCode()); + $this->assertSame('VH', Util::objectToStr($detailLine->getVatCode())); $this->assertEquals(Money::EUR(2100), $detailLine->getVatValue()); $this->assertNull($detailLine->getVatTotal()); $this->assertNull($detailLine->getVatBaseTotal()); $this->assertNull($detailLine->getValueOpen()); - $this->assertNull($detailLine->getPerformanceType()); - $this->assertNull($detailLine->getPerformanceCountry()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$detailLine->getPerformanceType()); + $this->assertNull(Util::objectToStr($detailLine->getPerformanceCountry())); $this->assertNull($detailLine->getPerformanceVatNumber()); $this->assertNull($detailLine->getPerformanceDate()); $this->assertEquals(LineType::VAT(), $vatLine->getLineType()); $this->assertSame(3, $vatLine->getId()); - $this->assertSame('1530', $vatLine->getDim1()); + $this->assertSame('1530', Util::objectToStr($vatLine->getDim1())); $this->assertNull($vatLine->getDim2()); $this->assertEquals(DebitCredit::CREDIT(), $vatLine->getDebitCredit()); $this->assertEquals(Money::EUR(2100), $vatLine->getValue()); $this->assertEquals(Money::EUR(2100), $vatLine->getBaseValue()); $this->assertSame(1.0, $vatLine->getRate()); - $this->assertEquals(Money::EUR(2717), $vatLine->getRepValue()); + $this->assertEquals(Money::USD(2717), $vatLine->getRepValue()); $this->assertSame(1.293600000, $vatLine->getRepRate()); $this->assertNull($vatLine->getDescription()); $this->assertNull($vatLine->getMatchStatus()); $this->assertNull($vatLine->getMatchLevel()); $this->assertNull($vatLine->getBaseValueOpen()); - $this->assertSame('VH', $vatLine->getVatCode()); + $this->assertSame('VH', Util::objectToStr($vatLine->getVatCode())); $this->assertNull($vatLine->getVatValue()); $this->assertNull($vatLine->getVatTotal()); $this->assertNull($vatLine->getVatBaseTotal()); $this->assertNull($vatLine->getValueOpen()); - $this->assertNull($vatLine->getPerformanceType()); - $this->assertNull($vatLine->getPerformanceCountry()); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\PerformanceType'); + $this->assertSame($ReflectObject->getConstant('EMPTY'), (string)$vatLine->getPerformanceType()); + $this->assertNull(Util::objectToStr($vatLine->getPerformanceCountry())); $this->assertNull($vatLine->getPerformanceVatNumber()); $this->assertNull($vatLine->getPerformanceDate()); } @@ -152,7 +158,7 @@ public function testSendSalesTransactionWorks() ->setDestiny(Destiny::TEMPORARY()) ->setRaiseWarning(false) ->setCode('SLS') - ->setCurrency(new Currency('EUR')) + ->setCurrency(Currency::fromCode('EUR')) ->setDate(new \DateTimeImmutable('2013-05-02')) ->setPeriod('2013/05') ->setInvoiceNumber('20130-6000') @@ -164,8 +170,8 @@ public function testSendSalesTransactionWorks() $totalLine ->setLineType(LineType::TOTAL()) ->setId('1') - ->setDim1('1300') - ->setDim2('1000') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('1300')) + ->setDim2(\PhpTwinfield\CostCenter::fromCode('1000')) ->setValue(Money::EUR(12100)) ->setDescription(''); @@ -173,10 +179,10 @@ public function testSendSalesTransactionWorks() $detailLine ->setLineType(LineType::DETAIL()) ->setId('2') - ->setDim1('8020') + ->setDim1(\PhpTwinfield\GeneralLedger::fromCode('8020')) ->setValue(Money::EUR(10000)) ->setDescription('Outfit') - ->setVatCode('VH'); + ->setVatCode(\PhpTwinfield\VatCode::fromCode('VH')); $salesTransaction ->addLine($totalLine) diff --git a/tests/IntegrationTests/resources/bankTransactionGetResponse.xml b/tests/IntegrationTests/resources/bankTransactionGetResponse.xml new file mode 100644 index 00000000..a4330f87 --- /dev/null +++ b/tests/IntegrationTests/resources/bankTransactionGetResponse.xml @@ -0,0 +1,47 @@ + +
+ 001 + BNK + EUR + 20131104 + 4 + 974.01 + 1409.56 + import + MARCEL + 2013/11 + 201300008 +
+ + + 1001 + debit + 435.55 + 1 + 435.55 + 1.500000000 + 653.33 + notmatchable + + + 1300 + 1000 + credit + 435.55 + 11001770 + Invoice paid + 20131108 + 1 + 435.55 + 1.500000000 + 653.33 + + 2 + 2 + 435.55 + 435.55 + 653.33 + available + + +
diff --git a/tests/IntegrationTests/resources/bankTransactionSendRequest.xml b/tests/IntegrationTests/resources/bankTransactionSendRequest.xml new file mode 100644 index 00000000..be128c67 --- /dev/null +++ b/tests/IntegrationTests/resources/bankTransactionSendRequest.xml @@ -0,0 +1,27 @@ + + +
+ 001 + BNK + EUR + 20131104 + 4 + 974.01 + 1409.56 +
+ + + 1001 + debit + 435.55 + + + 1300 + 1000 + credit + 435.55 + Invoice paid + + +
+
diff --git a/tests/IntegrationTests/resources/cashTransactionGetResponse.xml b/tests/IntegrationTests/resources/cashTransactionGetResponse.xml index 232a3ed4..9cafc4e6 100644 --- a/tests/IntegrationTests/resources/cashTransactionGetResponse.xml +++ b/tests/IntegrationTests/resources/cashTransactionGetResponse.xml @@ -14,7 +14,7 @@ - 1002 + 1002 debit 435.55 1 @@ -24,8 +24,8 @@ notmatchable - 1300 - 1000 + 1300 + 1000 credit 435.55 11001770 diff --git a/tests/IntegrationTests/resources/cashTransactionSendRequest.xml b/tests/IntegrationTests/resources/cashTransactionSendRequest.xml index 14088409..b1fe1da8 100644 --- a/tests/IntegrationTests/resources/cashTransactionSendRequest.xml +++ b/tests/IntegrationTests/resources/cashTransactionSendRequest.xml @@ -1,10 +1,10 @@
+ 001 CASH EUR - 20131104 - 001 + 20131104 4 974.01 1409.56 @@ -20,7 +20,6 @@ 1000 credit 435.55 - 11001770 Invoice paid diff --git a/tests/IntegrationTests/resources/customerGetResponse.xml b/tests/IntegrationTests/resources/customerGetResponse.xml index 29aff77b..dccdd2cf 100644 --- a/tests/IntegrationTests/resources/customerGetResponse.xml +++ b/tests/IntegrationTests/resources/customerGetResponse.xml @@ -18,7 +18,7 @@ false 1 - 1300 + 1300 false diff --git a/tests/IntegrationTests/resources/customerListResponse.json b/tests/IntegrationTests/resources/customerListResponse.json new file mode 100644 index 00000000..4e019565 --- /dev/null +++ b/tests/IntegrationTests/resources/customerListResponse.json @@ -0,0 +1 @@ +{"SearchResult":{},"data":{"TotalRows":3,"Columns":{"string":["Code","Naam"]},"Items":{"ArrayOfString":[{"string":["D1000","John Doe"]},{"string":["D1001","B. Terwel"]},{"string":["D1002","Hr E G H Küppers en/of MW M.J. Küppers-Veeneman"]}]}}} diff --git a/tests/IntegrationTests/resources/customerListResponse.xml b/tests/IntegrationTests/resources/customerListResponse.xml deleted file mode 100644 index e4985032..00000000 --- a/tests/IntegrationTests/resources/customerListResponse.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - D1000 - D1001 - D1002 - DEB - diff --git a/tests/IntegrationTests/resources/customerSendRequest.xml b/tests/IntegrationTests/resources/customerSendRequest.xml index 64cf0c15..af5140f6 100644 --- a/tests/IntegrationTests/resources/customerSendRequest.xml +++ b/tests/IntegrationTests/resources/customerSendRequest.xml @@ -1,56 +1,88 @@ - - Customer 0 - DEB - 001 - - 30 - true - SEPANLDD - - false - - - 1 - 20180604 - 20180608 - - - -
- Customer 0 - - NL - Place - 1000 - 010-123452000 - 010-12342000 - info@example.com - Customer 1 - Streetname part 1 - 1 - Streetname part 1 - 2 - - - -
-
- - - Customer 1 - 123456789 - ABN Amro - ABNANL2A - Place - NL - NL02ABNA0123456789 - - - -
- - -
-
-
-
-
+ + 0 + 0 + 0 + 0 + Customer 0 + 001 + + DEB + + + core + 30 + + + + true + SEPANLDD + + + + 20180608 + 1 + 20180604 + + + + 0 + false + + + + + + + true + + + + + +
+ Place + NL + info@example.com + Customer 1 + Streetname part 1 - 1 + Streetname part 1 - 2 + + + + Customer 0 + 1000 + 010-12342000 + 010-123452000 +
+
+ + +
+ + +
+ Customer 1 + 123456789 + ABN Amro + ABNANL2A + Place + NL + NL02ABNA0123456789 + + + +
+
+ + + + + + + + + + +
+ diff --git a/tests/IntegrationTests/resources/invoiceConceptGetResponse.xml b/tests/IntegrationTests/resources/invoiceConceptGetResponse.xml index 2a490e88..64459c1f 100644 --- a/tests/IntegrationTests/resources/invoiceConceptGetResponse.xml +++ b/tests/IntegrationTests/resources/invoiceConceptGetResponse.xml @@ -10,12 +10,12 @@ 1 1 1000 - 2012/8 + 2012/08 EUR concept cash - - + HEADER + FOOTER
@@ -40,7 +40,8 @@ VN 0.00 - + + diff --git a/tests/IntegrationTests/resources/invoiceFinalGetResponse.xml b/tests/IntegrationTests/resources/invoiceFinalGetResponse.xml index 3fd4cf55..c672c4ec 100644 --- a/tests/IntegrationTests/resources/invoiceFinalGetResponse.xml +++ b/tests/IntegrationTests/resources/invoiceFinalGetResponse.xml @@ -10,12 +10,12 @@ 1 1 1000 - 2012/8 + 2012/08 EUR final cash - - + HEADER + FOOTER @@ -40,7 +40,8 @@ VN 0.00 - + + diff --git a/tests/IntegrationTests/resources/invoiceSendRequest.xml b/tests/IntegrationTests/resources/invoiceSendRequest.xml index 06ef0277..ebe088cf 100644 --- a/tests/IntegrationTests/resources/invoiceSendRequest.xml +++ b/tests/IntegrationTests/resources/invoiceSendRequest.xml @@ -2,28 +2,38 @@
+ BNK + EUR 1000 - 11024 - FACTUUR + 1 + + FOOTER + HEADER + 1 + 20120831 5 + FACTUUR + 11024 + cash + 2012/08 concept - EUR - 2012/8 - 20120831 - BNK - 1 - 1
- 1 + true
4
- 118 CoalesceFunctioningOnImpatienceTShirt - 15.00 + 8020 + + + + + + 1 + 118 1 + 15.00 VN - 8020
diff --git a/tests/IntegrationTests/resources/journalTransactionGetResponse.xml b/tests/IntegrationTests/resources/journalTransactionGetResponse.xml index 4753b51e..da7d8c50 100644 --- a/tests/IntegrationTests/resources/journalTransactionGetResponse.xml +++ b/tests/IntegrationTests/resources/journalTransactionGetResponse.xml @@ -11,7 +11,7 @@ - 4008 + 4008 debit 435.55 1 @@ -22,8 +22,8 @@ notmatchable - 1300 - 1000 + 1300 + 1000 credit 435.55 11001770 diff --git a/tests/IntegrationTests/resources/journalTransactionSendRequest.xml b/tests/IntegrationTests/resources/journalTransactionSendRequest.xml index 6b07a8b6..94a1e21d 100644 --- a/tests/IntegrationTests/resources/journalTransactionSendRequest.xml +++ b/tests/IntegrationTests/resources/journalTransactionSendRequest.xml @@ -1,10 +1,10 @@
+ 001 MEMO EUR - 20131104 - 001 + 20131104
@@ -17,7 +17,6 @@ 1000 credit 435.55 - 11001770 Invoice paid diff --git a/tests/IntegrationTests/resources/purchaseTransactionGetResponse.xml b/tests/IntegrationTests/resources/purchaseTransactionGetResponse.xml index f74d8f34..6efec89f 100644 --- a/tests/IntegrationTests/resources/purchaseTransactionGetResponse.xml +++ b/tests/IntegrationTests/resources/purchaseTransactionGetResponse.xml @@ -14,8 +14,8 @@ - 1600 - 2000 + 1600 + 2000 121.00 credit @@ -33,7 +33,7 @@ available - 8020 + 8020 100.00 debit Outfit @@ -47,7 +47,7 @@ notmatchable - 1510 + 1510 21.00 IH debit diff --git a/tests/IntegrationTests/resources/purchaseTransactionSendRequest.xml b/tests/IntegrationTests/resources/purchaseTransactionSendRequest.xml index 47ba4d38..d7dd5487 100644 --- a/tests/IntegrationTests/resources/purchaseTransactionSendRequest.xml +++ b/tests/IntegrationTests/resources/purchaseTransactionSendRequest.xml @@ -1,14 +1,14 @@
+ 001 INK - EUR - 20130502 2013/05 - 20130-5481 - +++100/0160/01495+++ - 001 + EUR + 20130502 20130506 + 20130-5481 + +++100/0160/01495+++
@@ -16,7 +16,6 @@ 2000 credit 121.00 - 8020 diff --git a/tests/IntegrationTests/resources/salesTransactionGetResponse.xml b/tests/IntegrationTests/resources/salesTransactionGetResponse.xml index bc7202e1..3abebbd3 100644 --- a/tests/IntegrationTests/resources/salesTransactionGetResponse.xml +++ b/tests/IntegrationTests/resources/salesTransactionGetResponse.xml @@ -15,8 +15,8 @@ - 1300 - 1000 + 1300 + 1000 121.00 debit @@ -34,7 +34,7 @@ available - 8020 + 8020 100.00 credit Outfit @@ -49,7 +49,7 @@ notmatchable - 1530 + 1530 21.00 VH credit diff --git a/tests/IntegrationTests/resources/salesTransactionSendRequest.xml b/tests/IntegrationTests/resources/salesTransactionSendRequest.xml index ae5107e3..cd013730 100644 --- a/tests/IntegrationTests/resources/salesTransactionSendRequest.xml +++ b/tests/IntegrationTests/resources/salesTransactionSendRequest.xml @@ -1,14 +1,14 @@
+ 001 SLS - EUR - 20130502 2013/05 - 20130-6000 - +++100/0160/01495+++ - 001 + EUR + 20130502 20130506 + 20130-6000 + +++100/0160/01495+++
@@ -16,7 +16,6 @@ 1000 debit 121.00 - 8020 diff --git a/tests/UnitTests/ApiConnectors/ActivityApiConnectorTest.php b/tests/UnitTests/ApiConnectors/ActivityApiConnectorTest.php new file mode 100644 index 00000000..180800d4 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/ActivityApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new ActivityApiConnector($connection); + } + + private function createActivity(): Activity + { + $activity = new Activity(); + return $activity; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/activity-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $activity = $this->createActivity(); + + $mapped = $this->apiConnector->send($activity); + + $this->assertInstanceOf(Activity::class, $mapped); + $this->assertEquals("A001", $mapped->getCode()); + $this->assertEquals("Test Activity", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/AssetMethodApiConnectorTest.php b/tests/UnitTests/ApiConnectors/AssetMethodApiConnectorTest.php new file mode 100644 index 00000000..8110a924 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/AssetMethodApiConnectorTest.php @@ -0,0 +1,78 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new AssetMethodApiConnector($connection); + } + + private function createAssetMethod(): AssetMethod + { + $assetMethod = new AssetMethod(); + $freeTexts = []; + + for ($i = 1; $i <=5; $i++) { + $freeTexts[$i] = new AssetMethodFreeText; + $freeTexts[$i]->setID($i) + ->setElementValue($i) + ->setType(\PhpTwinfield\Enums\FreeTextType::TEXT()); + $assetMethod->addFreeText($freeTexts[$i]); + } + + return $assetMethod; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/assetmethod-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $assetMethod = $this->createAssetMethod(); + + $mapped = $this->apiConnector->send($assetMethod); + + $this->assertInstanceOf(AssetMethod::class, $mapped); + $this->assertEquals("101", $mapped->getCode()); + $this->assertEquals("Inventaris", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/BankTransactionApiConnectorTest.php b/tests/UnitTests/ApiConnectors/BankTransactionApiConnectorTest.php deleted file mode 100644 index dd4f455c..00000000 --- a/tests/UnitTests/ApiConnectors/BankTransactionApiConnectorTest.php +++ /dev/null @@ -1,260 +0,0 @@ -processXmlService = $this->getMockBuilder(ProcessXmlService::class) - ->setMethods(["sendDocument"]) - ->disableOriginalConstructor() - ->getMock(); - - /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ - $connection = $this->createMock(AuthenticatedConnection::class); - $connection - ->expects($this->any()) - ->method("getAuthenticatedClient") - ->willReturn($this->processXmlService); - - $this->apiConnector = new BankTransactionApiConnector($connection); - $this->office = Office::fromCode("XXX101"); - } - - private function createBankTransaction(): BankTransaction - { - $banktransaction = new BankTransaction(); - $banktransaction->setDestiny(Destiny::TEMPORARY()); - $banktransaction->setOffice($this->office); - - return $banktransaction; - } - - public function testFailureResponseWithoutLineIdsThrowsResponseExceptionAndObjectCanStillBeExtracted() - { - $response = Response::fromString(file_get_contents( - __DIR__. "/resources/failed-response-without-line-ids.xml" - )); - - $this->processXmlService->expects($this->once()) - ->method("sendDocument") - ->willReturn($response); - - $mapped_responses = $this->apiConnector->sendAll([ - $this->createBankTransaction() - ]); - - self::assertCount(1, $mapped_responses); - - try { - $mapped_responses[0]->unwrap(); - - self::fail('Expected a ResponseException for a failed response'); - } catch (ResponseException $e) { - /** @var BankTransaction $bank_transaction */ - $bank_transaction = $e->getReturnedObject(); - - self::assertCount(2, $bank_transaction->getLines()); - - self::assertNull($bank_transaction->getLines()[0]->getId()); - self::assertNull($bank_transaction->getLines()[1]->getId()); - } - } - - public function testSendAllReturnsMappedObjects() - { - $response = Response::fromString(file_get_contents( - __DIR__."/resources/2-failed-and-1-successful-banktransactions.xml" - )); - - $this->processXmlService->expects($this->once()) - ->method("sendDocument") - ->willReturn($response); - - $responses = $this->apiConnector->sendAll([ - $this->createBankTransaction(), - $this->createBankTransaction(), - $this->createBankTransaction(), - ]); - - $this->assertCount(3, $responses); - - [$response1, $response2, $response3] = $responses; - - try { - $response1->unwrap(); - } catch (Exception $e) { - $this->assertEquals("De boeking is niet in balans. Er ontbreekt 0.01 debet.//De boeking balanceert niet in de basisvaluta. Er ontbreekt 0.01 debet.//De boeking balanceert niet in de rapportagevaluta. Er ontbreekt 0.01 debet.", $e->getMessage()); - } - - try { - $response2->unwrap(); - } catch (Exception $e) { - $this->assertEquals("De boeking is niet in balans. Er ontbreekt 0.01 debet.//De boeking balanceert niet in de basisvaluta. Er ontbreekt 0.01 debet.//De boeking balanceert niet in de rapportagevaluta. Er ontbreekt 0.01 debet.", $e->getMessage()); - } - - /** @var BankTransaction $banktransaction3 */ - $banktransaction3 = $response3->unwrap(); - - $this->assertEquals("BNK", $banktransaction3->getCode()); - $this->assertEquals("OFFICE001", $banktransaction3->getOffice()->getCode()); - $this->assertEquals("2017/08", $banktransaction3->getPeriod()); - $this->assertEquals(new Currency("EUR"), $banktransaction3->getCurrency()); - $this->assertEquals(Money::EUR(0), $banktransaction3->getStartvalue()); - $this->assertEquals(Money::EUR(0), $banktransaction3->getClosevalue()); - $this->assertEquals(0, $banktransaction3->getStatementnumber()); - $this->assertEquals("201700334", $banktransaction3->getNumber()); - - $lines = $banktransaction3->getLines(); - $this->assertCount(3, $lines); - - /** @var Total $line */ - $line = $lines[0]; - $this->assertEquals("1", $line->getId()); - $this->assertEquals(LineType::TOTAL(), $line->getLineType()); - $this->assertEquals("1100", $line->getDim1()); - $this->assertEquals("debit", $line->getDebitCredit()); - $this->assertEquals(Money::EUR(0), $line->getValue()); - $this->assertEquals("2017.123456", $line->getInvoiceNumber()); - $this->assertEquals("2017.123456", $line->getDescription()); - $this->assertEquals("2017.123456", $line->getComment()); - - /** @var Detail $line */ - $line = $lines[1]; - $this->assertEquals("2", $line->getId()); - $this->assertEquals(LineType::DETAIL(), $line->getLineType()); - $this->assertEquals("1800", $line->getDim1()); - $this->assertEquals("debit", $line->getDebitCredit()); - $this->assertEquals(Money::EUR(87), $line->getValue()); - $this->assertEquals("2017.123456", $line->getInvoiceNumber()); - $this->assertEquals("2017.123456", $line->getDescription()); - $this->assertEquals("2017.123456", $line->getComment()); - } - - public function testSendAllReturnsMappedObjectsAllLineTypes() - { - $response = Response::fromString(file_get_contents( - __DIR__."/resources/banktransaction-with-all-line-types.xml" - )); - - $this->processXmlService->expects($this->once()) - ->method("sendDocument") - ->willReturn($response); - - $responses = $this->apiConnector->sendAll([$this->createBankTransaction()]); - $this->assertCount(1, $responses); - $response = $responses[0]; - - /** @var BankTransaction $banktransaction */ - $banktransaction = $response->unwrap(); - - $this->assertEquals("BNK", $banktransaction->getCode()); - $this->assertEquals("OFFICE001", $banktransaction->getOffice()->getCode()); - $this->assertEquals("2017/09", $banktransaction->getPeriod()); - $this->assertEquals(new Currency("EUR"), $banktransaction->getCurrency()); - $this->assertEquals(Money::EUR(0), $banktransaction->getStartvalue()); - $this->assertEquals(Money::EUR(12100), $banktransaction->getClosevalue()); - $this->assertEquals(0, $banktransaction->getStatementnumber()); - $this->assertEquals("201700001", $banktransaction->getNumber()); - - $lines = $banktransaction->getLines(); - $this->assertCount(3, $lines); - - /** @var Total $line */ - $line = $lines[0]; - $this->assertEquals("1", $line->getId()); - $this->assertEquals(LineType::TOTAL(), $line->getLineType()); - $this->assertEquals("1100", $line->getDim1()); - $this->assertEquals("debit", $line->getDebitCredit()); - $this->assertEquals(Money::EUR(12100), $line->getValue()); - - /** @var Detail $line */ - $line = $lines[1]; - $this->assertEquals("2", $line->getId()); - $this->assertEquals(LineType::DETAIL(), $line->getLineType()); - $this->assertEquals("2200", $line->getDim1()); - $this->assertEquals("credit", $line->getDebitCredit()); - $this->assertEquals(Money::EUR(10000), $line->getValue()); - $this->assertEquals("My transaction", $line->getDescription()); - $this->assertEquals("VH", $line->getVatCode()); - $this->assertEquals(Money::EUR(2100), $line->getVatValue()); - $this->assertEquals(null, $line->getInvoiceNumber()); - $this->assertEquals(Money::EUR(2100), $line->getVatBaseValue()); - - /** @var Vat $line */ - $line = $lines[2]; - $this->assertEquals("3", $line->getId()); - $this->assertEquals(LineType::VAT(), $line->getLineType()); - $this->assertEquals("1502", $line->getDim1()); - $this->assertEquals("credit", $line->getDebitCredit()); - $this->assertEquals(Money::EUR(2100), $line->getValue()); - $this->assertEquals("VH", $line->getVatCode()); - $this->assertEquals(Money::EUR(10000), $line->getVatTurnover()); - $this->assertEquals(Money::EUR(10000), $line->getVatBaseTurnover()); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage De status van de boeking moet Concept zijn - */ - public function testDeleteThrowsWhenResponseContainsErrorMessages() - { - $bookingReference = new BookingReference(Office::fromCode("OFFICE001"), "BNK", 201700006); - - $this->processXmlService->expects($this->once()) - ->method("sendDocument") - ->willReturnCallback(function(\DOMDocument $document) { - - $this->assertXmlStringEqualsXmlString(' - OFFICE001 - BNK - 201700006 -', $document->saveXML()); - - return Response::fromString(' - - OFFICE001 - BNK - 201700006 -'); - }); - - $this->apiConnector->delete($bookingReference, "It was merely a test transaction & I no longer need it."); - } -} \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/BrowseDataApiConnectorTest.php b/tests/UnitTests/ApiConnectors/BrowseDataApiConnectorTest.php index 5bc87c16..584e4061 100644 --- a/tests/UnitTests/ApiConnectors/BrowseDataApiConnectorTest.php +++ b/tests/UnitTests/ApiConnectors/BrowseDataApiConnectorTest.php @@ -73,4 +73,4 @@ public function testFailureResponseForGetBrowseDataWithWrongSortFieldsObjects() $this->apiConnector->getBrowseData('001', $columns, $columns); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/ApiConnectors/CostCenterApiConnectorTest.php b/tests/UnitTests/ApiConnectors/CostCenterApiConnectorTest.php new file mode 100644 index 00000000..eb9b071e --- /dev/null +++ b/tests/UnitTests/ApiConnectors/CostCenterApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new CostCenterApiConnector($connection); + } + + private function createCostCenter(): CostCenter + { + $costCenter = new CostCenter(); + return $costCenter; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/costcenter-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $costCenter = $this->createCostCenter(); + + $mapped = $this->apiConnector->send($costCenter); + + $this->assertInstanceOf(CostCenter::class, $mapped); + $this->assertEquals("00001", $mapped->getCode()); + $this->assertEquals("Hoevelaken", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/CustomerApiConnectorTest.php b/tests/UnitTests/ApiConnectors/CustomerApiConnectorTest.php index 38fcd670..f50866bd 100644 --- a/tests/UnitTests/ApiConnectors/CustomerApiConnectorTest.php +++ b/tests/UnitTests/ApiConnectors/CustomerApiConnectorTest.php @@ -3,12 +3,19 @@ namespace PhpTwinfield\UnitTests; use PhpTwinfield\ApiConnectors\CustomerApiConnector; +use PhpTwinfield\ApiConnectors\OfficeApiConnector; +use PhpTwinfield\Currency; use PhpTwinfield\Customer; +use PhpTwinfield\Office; use PhpTwinfield\Response\Response; use PhpTwinfield\Secure\AuthenticatedConnection; use PhpTwinfield\Services\ProcessXmlService; use PHPUnit\Framework\TestCase; +/** + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ class CustomerApiConnectorTest extends TestCase { /** @@ -38,6 +45,15 @@ protected function setUp() ->willReturn($this->processXmlService); $this->apiConnector = new CustomerApiConnector($connection); + + $mockOfficeApiConnector = \Mockery::mock('overload:'.OfficeApiConnector::class)->makePartial(); + $mockOfficeApiConnector->shouldReceive('get')->andReturnUsing(function() { + $office = new Office; + $office->setResult(1); + $office->setBaseCurrency(Currency::fromCode('EUR')); + $office->setReportingCurrency(Currency::fromCode('USD')); + return $office; + }); } private function createCustomer(): Customer @@ -49,7 +65,7 @@ private function createCustomer(): Customer public function testSendAllReturnsMappedObjects() { $response = Response::fromString(file_get_contents( - __DIR__."/resources/customers-response.xml" + __DIR__."/resources/customer-response.xml" )); $this->processXmlService->expects($this->once()) @@ -63,6 +79,5 @@ public function testSendAllReturnsMappedObjects() $this->assertInstanceOf(Customer::class, $mapped); $this->assertEquals("D1001", $mapped->getCode()); $this->assertEquals("Hr E G H Küppers en/of MW M.J. Küppers-Veeneman", $mapped->getName()); - $this->assertEquals("BE", $mapped->getCountry()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/ApiConnectors/DimensionGroupApiConnectorTest.php b/tests/UnitTests/ApiConnectors/DimensionGroupApiConnectorTest.php new file mode 100644 index 00000000..3b0eceb4 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/DimensionGroupApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new DimensionGroupApiConnector($connection); + } + + private function createDimensionGroup(): DimensionGroup + { + $dimensionGroup = new DimensionGroup(); + return $dimensionGroup; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/dimensiongroup-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $dimensionGroup = $this->createDimensionGroup(); + + $mapped = $this->apiConnector->send($dimensionGroup); + + $this->assertInstanceOf(DimensionGroup::class, $mapped); + $this->assertEquals("TSTDIMGRP", $mapped->getCode()); + $this->assertEquals("Test Dimension Group", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/DimensionTypeApiConnectorTest.php b/tests/UnitTests/ApiConnectors/DimensionTypeApiConnectorTest.php new file mode 100644 index 00000000..bd074fe0 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/DimensionTypeApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new DimensionTypeApiConnector($connection); + } + + private function createDimensionType(): DimensionType + { + $dimensionType = new DimensionType(); + return $dimensionType; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/dimensiontype-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $dimensionType = $this->createDimensionType(); + + $mapped = $this->apiConnector->send($dimensionType); + + $this->assertInstanceOf(DimensionType::class, $mapped); + $this->assertEquals("DEB", $mapped->getCode()); + $this->assertEquals("Debiteuren", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/FixedAssetApiConnectorTest.php b/tests/UnitTests/ApiConnectors/FixedAssetApiConnectorTest.php new file mode 100644 index 00000000..0e332861 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/FixedAssetApiConnectorTest.php @@ -0,0 +1,83 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new FixedAssetApiConnector($connection); + + $mockOfficeApiConnector = \Mockery::mock('overload:'.OfficeApiConnector::class)->makePartial(); + $mockOfficeApiConnector->shouldReceive('get')->andReturnUsing(function() { + $office = new Office; + $office->setResult(1); + $office->setBaseCurrency(Currency::fromCode('EUR')); + $office->setReportingCurrency(Currency::fromCode('USD')); + return $office; + }); + } + + private function createFixedAsset(): FixedAsset + { + $fixedAsset = new FixedAsset(); + return $fixedAsset; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/fixedasset-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $fixedAsset = $this->createFixedAsset(); + + $mapped = $this->apiConnector->send($fixedAsset); + + $this->assertInstanceOf(FixedAsset::class, $mapped); + $this->assertEquals("60000", $mapped->getCode()); + $this->assertEquals("Afschrijving Computer", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/GeneralLedgerApiConnectorTest.php b/tests/UnitTests/ApiConnectors/GeneralLedgerApiConnectorTest.php new file mode 100644 index 00000000..1329bca9 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/GeneralLedgerApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new GeneralLedgerApiConnector($connection); + } + + private function createGeneralLedger(): GeneralLedger + { + $generalLedger = new GeneralLedger(); + return $generalLedger; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/generalledger-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $generalLedger = $this->createGeneralLedger(); + + $mapped = $this->apiConnector->send($generalLedger); + + $this->assertInstanceOf(GeneralLedger::class, $mapped); + $this->assertEquals("4004", $mapped->getCode()); + $this->assertEquals("Bonussen/gratificaties", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/InvoiceApiConnectorTest.php b/tests/UnitTests/ApiConnectors/InvoiceApiConnectorTest.php new file mode 100644 index 00000000..d340ee09 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/InvoiceApiConnectorTest.php @@ -0,0 +1,87 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new InvoiceApiConnector($connection); + + $mockInvoiceTypeApiConnector = \Mockery::mock('overload:'.InvoiceTypeApiConnector::class)->makePartial(); + $mockInvoiceTypeApiConnector->shouldReceive('getInvoiceTypeVatType')->andReturnUsing(function() { + return 'exclusive'; + }); + + $mockArticleApiConnector = \Mockery::mock('overload:'.ArticleApiConnector::class)->makePartial(); + $mockArticleApiConnector->shouldReceive('get')->andReturnUsing(function() { + $article = new Article; + $article->setAllowChangeVatCode(true); + return $article; + }); + } + + private function createInvoice(): Invoice + { + $invoice = new Invoice(); + return $invoice; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/invoice-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $invoice = $this->createInvoice(); + + $mapped = $this->apiConnector->send($invoice); + + $this->assertInstanceOf(Invoice::class, $mapped); + $this->assertEquals("10", $mapped->getInvoiceNumber()); + $this->assertEquals("20190410", Util::formatDate($mapped->getInvoiceDate())); + } +} diff --git a/tests/UnitTests/ApiConnectors/MatchesApiConnectorTest.php b/tests/UnitTests/ApiConnectors/MatchesApiConnectorTest.php index 821f2e5a..fd3b45c8 100644 --- a/tests/UnitTests/ApiConnectors/MatchesApiConnectorTest.php +++ b/tests/UnitTests/ApiConnectors/MatchesApiConnectorTest.php @@ -87,15 +87,15 @@ public function testSendAllReturnsMappedObjects() $this->assertCount(2, $lines); $line = $lines[0]; - $this->assertEquals("VRK", $line->getTranscode()); - $this->assertSame(201700103, $line->getTransnumber()); - $this->assertSame(1, $line->getTransline()); + $this->assertEquals("VRK", $line->getTransCode()); + $this->assertSame(201700103, $line->getTransNumber()); + $this->assertSame(1, $line->getTransLine()); $this->assertEquals(Money::EUR(526), $line->getMatchValue()); $line = $lines[1]; - $this->assertEquals("DUM2", $line->getTranscode()); - $this->assertSame(201700029, $line->getTransnumber()); - $this->assertSame(79, $line->getTransline()); + $this->assertEquals("DUM2", $line->getTransCode()); + $this->assertSame(201700029, $line->getTransNumber()); + $this->assertSame(79, $line->getTransLine()); $this->assertEquals(Money::EUR(-526), $line->getMatchValue()); /** @var MatchSet $matchSet */ @@ -113,15 +113,15 @@ public function testSendAllReturnsMappedObjects() $this->assertCount(2, $lines); $line = $lines[0]; - $this->assertEquals("VRK", $line->getTranscode()); - $this->assertSame(201700100, $line->getTransnumber()); - $this->assertSame(1, $line->getTransline()); + $this->assertEquals("VRK", $line->getTransCode()); + $this->assertSame(201700100, $line->getTransNumber()); + $this->assertSame(1, $line->getTransLine()); $this->assertEquals(Money::EUR(140), $line->getMatchValue()); $line = $lines[1]; - $this->assertEquals("DUM2", $line->getTranscode()); - $this->assertSame(201700029, $line->getTransnumber()); - $this->assertSame(64, $line->getTransline()); + $this->assertEquals("DUM2", $line->getTransCode()); + $this->assertSame(201700029, $line->getTransNumber()); + $this->assertSame(64, $line->getTransLine()); $this->assertEquals(Money::EUR(-140), $line->getMatchValue()); } } diff --git a/tests/UnitTests/ApiConnectors/ProjectApiConnectorTest.php b/tests/UnitTests/ApiConnectors/ProjectApiConnectorTest.php new file mode 100644 index 00000000..9d531398 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/ProjectApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new ProjectApiConnector($connection); + } + + private function createProject(): Project + { + $project = new Project(); + return $project; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/project-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $project = $this->createProject(); + + $mapped = $this->apiConnector->send($project); + + $this->assertInstanceOf(Project::class, $mapped); + $this->assertEquals("P0000", $mapped->getCode()); + $this->assertEquals("Project direct", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/RateApiConnectorTest.php b/tests/UnitTests/ApiConnectors/RateApiConnectorTest.php new file mode 100644 index 00000000..c1e01007 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/RateApiConnectorTest.php @@ -0,0 +1,71 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new RateApiConnector($connection); + } + + private function createRate(): Rate + { + $rate = new Rate(); + $rateChange = new RateRateChange(); + $rateChange->setID(2); + $rate->addRateChange($rateChange); + return $rate; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/rate-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $rate = $this->createRate(); + + $mapped = $this->apiConnector->send($rate); + + $this->assertInstanceOf(Rate::class, $mapped); + $this->assertEquals("DIRECT", $mapped->getCode()); + $this->assertEquals("Direct rate", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/SupplierApiConnectorTest.php b/tests/UnitTests/ApiConnectors/SupplierApiConnectorTest.php new file mode 100644 index 00000000..8fb73c1c --- /dev/null +++ b/tests/UnitTests/ApiConnectors/SupplierApiConnectorTest.php @@ -0,0 +1,67 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new SupplierApiConnector($connection); + } + + private function createSupplier(): Supplier + { + $supplier = new Supplier(); + return $supplier; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/supplier-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $supplier = $this->createSupplier(); + + $mapped = $this->apiConnector->send($supplier); + + $this->assertInstanceOf(Supplier::class, $mapped); + $this->assertEquals("2000", $mapped->getCode()); + $this->assertEquals("Smits", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/TransactionApiConnectorTest.php b/tests/UnitTests/ApiConnectors/TransactionApiConnectorTest.php index f60c099e..279ecfa6 100644 --- a/tests/UnitTests/ApiConnectors/TransactionApiConnectorTest.php +++ b/tests/UnitTests/ApiConnectors/TransactionApiConnectorTest.php @@ -2,17 +2,23 @@ namespace PhpTwinfield\UnitTests; -use Money\Currency; +use PhpTwinfield\ApiConnectors\OfficeApiConnector; use PhpTwinfield\ApiConnectors\TransactionApiConnector; use PhpTwinfield\BaseTransaction; +use PhpTwinfield\Currency; use PhpTwinfield\Enums\Destiny; use PhpTwinfield\Office; use PhpTwinfield\Response\Response; use PhpTwinfield\SalesTransaction; use PhpTwinfield\Secure\AuthenticatedConnection; use PhpTwinfield\Services\ProcessXmlService; +use PhpTwinfield\Util; use PHPUnit\Framework\TestCase; +/** + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ class TransactionApiConnectorTest extends TestCase { /** @@ -42,6 +48,15 @@ protected function setUp() ->willReturn($this->processXmlService); $this->apiConnector = new TransactionApiConnector($connection); + + $mockOfficeApiConnector = \Mockery::mock('overload:'.OfficeApiConnector::class)->makePartial(); + $mockOfficeApiConnector->shouldReceive('get')->andReturnUsing(function() { + $office = new Office; + $office->setResult(1); + $office->setBaseCurrency(Currency::fromCode('EUR')); + $office->setReportingCurrency(Currency::fromCode('USD')); + return $office; + }); } private function createTransaction(string $transactionClassName): BaseTransaction @@ -75,9 +90,9 @@ public function testSendReturnsMappedObjects() - 130000 + 130000 - Dxxxx + Dxxxx debit 100.00 @@ -95,9 +110,7 @@ public function testSendReturnsMappedObjects() available - 191000 - + 191000 credit 100.00 Outfit @@ -122,9 +135,9 @@ public function testSendReturnsMappedObjects() $mapped = $this->apiConnector->send($transaction); $this->assertEquals("VRK", $mapped->getCode()); - $this->assertEquals(new Currency("EUR"), $mapped->getCurrency()); + $this->assertEquals("EUR", Util::objectToStr($mapped->getCurrency())); $this->assertEquals("2017/09", $mapped->getPeriod()); $this->assertEquals("INV123458", $mapped->getInvoiceNumber()); $this->assertEquals(new \DateTimeImmutable("2017-09-01"), $mapped->getDate()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/ApiConnectors/VatCodeApiConnectorTest.php b/tests/UnitTests/ApiConnectors/VatCodeApiConnectorTest.php new file mode 100644 index 00000000..c5ac1b42 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/VatCodeApiConnectorTest.php @@ -0,0 +1,71 @@ +processXmlService = $this->getMockBuilder(ProcessXmlService::class) + ->setMethods(["sendDocument"]) + ->disableOriginalConstructor() + ->getMock(); + + /** @var AuthenticatedConnection|\PHPUnit_Framework_MockObject_MockObject $connection */ + $connection = $this->createMock(AuthenticatedConnection::class); + $connection + ->expects($this->any()) + ->method("getAuthenticatedClient") + ->willReturn($this->processXmlService); + + $this->apiConnector = new VatCodeApiConnector($connection); + } + + private function createVatCode(): VatCode + { + $vatCode = new VatCode(); + $vatCodePercentage = new VatCodePercentage(); + $vatCodePercentage->setDate(\PhpTwinfield\Util::parseDate('20121001')); + $vatCode->addPercentage($vatCodePercentage); + return $vatCode; + } + + public function testSendAllReturnsMappedObjects() + { + $response = Response::fromString(file_get_contents( + __DIR__."/resources/vatcode-response.xml" + )); + + $this->processXmlService->expects($this->once()) + ->method("sendDocument") + ->willReturn($response); + + $vatCode = $this->createVatCode(); + + $mapped = $this->apiConnector->send($vatCode); + + $this->assertInstanceOf(VatCode::class, $mapped); + $this->assertEquals("VH", $mapped->getCode()); + $this->assertEquals("VAT Sales High", $mapped->getName()); + } +} diff --git a/tests/UnitTests/ApiConnectors/resources/2-failed-and-1-successful-banktransactions.xml b/tests/UnitTests/ApiConnectors/resources/2-failed-and-1-successful-banktransactions.xml deleted file mode 100644 index 848ba3d8..00000000 --- a/tests/UnitTests/ApiConnectors/resources/2-failed-and-1-successful-banktransactions.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - -
- BNK - OFFICE001 - 2017/06 - 20170901 - EUR - 0.00 - 0.00 - import - CHUCK-NORRIS - generic - 0 -
- - - 1100 - credit - 0.01 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 0.01 - 1 - 0.01 - notmatchable - - - 1800 - credit - 12.90 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 12.90 - 1 - 12.90 - - notmatchable - - - 4700 - debit - 12.90 - 2017.123456 - Some description - Some comment - 1 - 12.90 - 1 - 12.90 - - notmatchable - - -
- -
- BNK - OFFICE001 - 2017/07 - 20170901 - EUR - 0.00 - 0.00 - import - CHUCK-NORRIS - generic - 0 -
- - - 1100 - credit - 0.01 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 0.01 - 1 - 0.01 - notmatchable - - - 1800 - credit - 5.15 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 5.15 - 1 - 5.15 - - notmatchable - - - 4700 - debit - 5.15 - 2017.123456 - Some other description - Some other comment - 1 - 5.15 - 1 - 5.15 - - notmatchable - - -
- -
- BNK - OFFICE001 - 2017/08 - 20170901 - EUR - 0.00 - 0.00 - import - CHUCK-NORRIS - generic - 0 - 201700334 -
- - - 1100 - debit - 0.00 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 0.00 - 1 - 0.00 - notmatchable - - - 1800 - debit - 0.87 - 2017.123456 - 2017.123456 - 2017.123456 - 1 - 0.87 - 1 - 0.87 - - notmatchable - - - 8000 - credit - 0.87 - 2017.123456 - Last description - Last comment - 1 - 0.87 - 1 - 0.87 - - notmatchable - - -
-
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/activity-response.xml b/tests/UnitTests/ApiConnectors/resources/activity-response.xml new file mode 100644 index 00000000..116f75d2 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/activity-response.xml @@ -0,0 +1,63 @@ + + + DEV1000 + ACT + A001 + 149e5dcb-8b37-446b-b865-f3928572618f + Test Activity + TstAct + falsenormal + 1 + 0 + 0 + 0 + 0 + + + + true + + notmatchable + inherit + false + 0 + 4 + false + none + + false + + 0 + + + + + false + + + A001 + + + + core + + PRJ + + + + ToFileManager + + + + + + + + + + true + + + + \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/article-response.xml b/tests/UnitTests/ApiConnectors/resources/article-response.xml new file mode 100644 index 00000000..6de9f20f --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/article-response.xml @@ -0,0 +1,36 @@ + +
+
+ DEV1000 + 9060 + normal + Test Article + TstArt + Test Article + Test Articles + VN + false + + false + false + true + true + true +
+ + + 0.00 + 0.00 + 1 + Test SubArticle + TstSubArt + 9060 + 9060 + + + + + + + +
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/assetmethod-response.xml b/tests/UnitTests/ApiConnectors/resources/assetmethod-response.xml new file mode 100644 index 00000000..d4103ae9 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/assetmethod-response.xml @@ -0,0 +1,36 @@ + + + DEV1000 + 101 + Inventaris + Inv + 20190426120347 + 20190501092003 + 10 + API000001 + 0 + 10 + from_purchase_date + linearpercentage + + + 0155 + + 0150 + + + + + + 4750 + + + + + 1 + 2 + 3 + 4 + 5 + + \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/banktransaction-with-all-line-types.xml b/tests/UnitTests/ApiConnectors/resources/banktransaction-with-all-line-types.xml deleted file mode 100644 index 7c03cb95..00000000 --- a/tests/UnitTests/ApiConnectors/resources/banktransaction-with-all-line-types.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - -
- BNK - OFFICE001 - 2017/09 - 20170901 - EUR - 0.00 - 121.00 - import - USER - generic - 0 - 201700001 -
- - - 1100 - debit - 121.00 - 1 - 121.00 - 1 - 121.00 - notmatchable - - - 2200 - credit - 100.00 - My transaction - VH - 21.00 - 1 - 100.00 - 1 - 100.00 - - - 21.00 - notmatchable - - - credit - 21.00 - VH - 1 - 21.00 - 1 - 21.00 - 1 - 100.00 - 100.00 - 1502 - notmatchable - - -
-
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/costcenter-response.xml b/tests/UnitTests/ApiConnectors/resources/costcenter-response.xml new file mode 100644 index 00000000..5e8782fe --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/costcenter-response.xml @@ -0,0 +1,50 @@ + + + DEV1000 + KPL + 00001 + 149e5dcb-8b37-446b-b865-f3928572618f + Hoevelaken + + false + normal + 0 + 0 + 0 + 0 + 0 + + + + true + + notmatchable + inherit + maybe + 0 + 2 + false + none + + false + + 0 + + + + + false + + + 00001 + + + + core + + + ToFileManager + + + + \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/customer-response.xml b/tests/UnitTests/ApiConnectors/resources/customer-response.xml new file mode 100644 index 00000000..d60118e8 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/customer-response.xml @@ -0,0 +1,80 @@ + + + D1001 + Hr E G H Küppers en/of MW M.J. Küppers-Veeneman + DEB + DEV1000 + +
+ + + BE + + + + + + + + + BE0123456789 + + +
+
+ 149e5dcb-8b37-446b-b865-f3928572618f + true + + normal + 4 + 0 + 0 + 0 + 0 + + + + true + + customersupplier + inherit + false + 30 + 2 + false + none + + false + + 1 + + 130000 + + + + + false + + + D1001 + + + + core + + 130000 + + + + + 0.00 + true + + false + + + + + + +
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/customers-response.xml b/tests/UnitTests/ApiConnectors/resources/customers-response.xml deleted file mode 100644 index c1e8ae7b..00000000 --- a/tests/UnitTests/ApiConnectors/resources/customers-response.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - D1001 - Hr E G H Küppers en/of MW M.J. Küppers-Veeneman - DEB - DEV1000 - -
- - - BE - - - - - - - - - BE0123456789 - - -
-
- 149e5dcb-8b37-446b-b865-f3928572618f - true - - normal - 4 - 0 - 0 - 0 - 0 - - - - true - - customersupplier - inherit - false - 30 - 2 - false - none - - false - - 1 - - 130000 - - - - - false - - - D1001 - - - - core - - 130000 - - - - - 0.00 - true - - false - - - - - - -
-
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/dimensiongroup-response.xml b/tests/UnitTests/ApiConnectors/resources/dimensiongroup-response.xml new file mode 100644 index 00000000..c839dd4c --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/dimensiongroup-response.xml @@ -0,0 +1,18 @@ + + + DEV1000 + TSTDIMGRP + Test Dimension Group + TstDimGrp + 35 + + + BAS + 0100 + + + BAS + 0105 + + + \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/dimensiontype-response.xml b/tests/UnitTests/ApiConnectors/resources/dimensiontype-response.xml new file mode 100644 index 00000000..a5f966ae --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/dimensiontype-response.xml @@ -0,0 +1,23 @@ + + + DEV1000 + DEB + Debiteuren + Debiteuren + 1[0-9][0-9][0-9] + 8 + + 2 + + 0 + 0 + +
+ Tav + Adres + Postadres + BTW nummer + KVK nummer + +
+
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/failed-response-without-line-ids.xml b/tests/UnitTests/ApiConnectors/resources/failed-response-without-line-ids.xml deleted file mode 100644 index 9e197dcd..00000000 --- a/tests/UnitTests/ApiConnectors/resources/failed-response-without-line-ids.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - -
- BNK_CODE_123 - 450 - 20170901 - 321 - EUR - 0.00 - 126.17 - import -
- - - 123456 - credit - 126.17 - - - 654321 - credit - 126.17 - description - comment - - -
-
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/fixedasset-response.xml b/tests/UnitTests/ApiConnectors/resources/fixedasset-response.xml new file mode 100644 index 00000000..113993d3 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/fixedasset-response.xml @@ -0,0 +1,68 @@ + + + DEV1000 + AST + 60000 + 149e5dcb-8b37-446b-b865-f3928572618f + Afschrijving Computer + + false + normal + 0 + 0 + 0 + 0 + 0 + + + + true + + notmatchable + inherit + false + 30 + 3 + false + none + + false + + 2 + 00001 + + + + false + + + 60000 + + + + core + + + ToFileManager + + + + + active + 500.00 + 0.00 + 100 + 2019/01 + 20180401 + + + + + + + + 0 + 10 + 2019/12 + + diff --git a/tests/UnitTests/ApiConnectors/resources/generalledger-response.xml b/tests/UnitTests/ApiConnectors/resources/generalledger-response.xml new file mode 100644 index 00000000..dc20cf53 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/generalledger-response.xml @@ -0,0 +1,53 @@ + + + DEV1000 + PNL + 4004 + 149e5dcb-8b37-446b-b865-f3928572618f + Bonussen/gratificaties + Bonussen/gratificati + false + normal + 0 + 0 + 0 + 0 + 0 + + + + true + + notmatchable + profitandloss + maybe + 0 + 1 + false + none + + false + + 0 + + + + + false + + + + + + + core + + KPL + + + + ToFileManager + + + + diff --git a/tests/UnitTests/ApiConnectors/resources/invoice-response.xml b/tests/UnitTests/ApiConnectors/resources/invoice-response.xml new file mode 100644 index 00000000..5e4e710e --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/invoice-response.xml @@ -0,0 +1,51 @@ + + +
+ DEV1000 + INVOICE + 10 + 20190410 + 20190510 + BNK + 1 + 1 + 1000 + 2019/4 + EUR + concept + cash + Headertext + Footertext +
+ + +
9060
+ 9060 + 1 + 1 + true + Afronding + 0.00 + 0.00 + 0.00 + 0.00 + + + + 9060 + EXP-BUI-EU +
+
+ + + EXP-BUI-EU + 0.00 + + + + + + 0.00 + 0.00 + +
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/project-response.xml b/tests/UnitTests/ApiConnectors/resources/project-response.xml new file mode 100644 index 00000000..6c501905 --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/project-response.xml @@ -0,0 +1,71 @@ + + + DEV1000 + PRJ + P0000 + 149e5dcb-8b37-446b-b865-f3928572618f + Project direct + Project directK + false + normal + 0 + 0 + 0 + 0 + 0 + + + + true + + matchable + inherit + maybe + 0 + 3 + false + none + + false + + 2 + 09999 + + + + false + + + P0000 + + + + core + + KPL + ACT + + + + ToFileManager + + + + + Project direct invoice description + + + + + + + + + + KILOMETERS + true + false + + + + \ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/rate-response.xml b/tests/UnitTests/ApiConnectors/resources/rate-response.xml new file mode 100644 index 00000000..6b9dc82a --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/rate-response.xml @@ -0,0 +1,22 @@ + + + DEV1000 + DIRECT + Direct rate + DirectK + 20161223182142 + 20161223182142 + 0 + SUPER + time + 60 + EUR + + + 20100101 + 20991231 + 60.0000 + 120.0000 + + + diff --git a/tests/UnitTests/ApiConnectors/resources/supplier-response.xml b/tests/UnitTests/ApiConnectors/resources/supplier-response.xml new file mode 100644 index 00000000..cfd908da --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/supplier-response.xml @@ -0,0 +1,116 @@ + + + DEV1000 + CRD + 2000 + 149e5dcb-8b37-446b-b865-f3928572618f + Smits + + true + normal + 6 + 0 + 0 + 0 + 0 + http://www.test.com + + + true + + customersupplier + inherit + false + 30 + 2 + true + paymentfile + SEPANLCT + false + + 1 + 1600 + L2000 + + IH + false + + + 2000 + + + + core + + 1600 + + + + ByEmail + test@test.nl + + +
+ BDRNAAM + NL + Utrecht + Postcode + Telefoon + Fax + test@test.com + + TAV + ADRESRGL1 + ADRESRGL2 + NL854800219B01 + KVK + +
+
+ + + Smits + 417164300 +
+ Testadres + 10 +
+ ABN + ABNANL2A + Utrecht + NL + NL91ABNA0417164300 + NL + 1234AB + Teststraat +
+
+ + + EUR + 100.00 + Test + + + + 0100 + 00001 + 60010 + 23 + # + Test + + + + + + + 14 + 10.00 + + + + 20.00 + true + +
\ No newline at end of file diff --git a/tests/UnitTests/ApiConnectors/resources/vatcode-response.xml b/tests/UnitTests/ApiConnectors/resources/vatcode-response.xml new file mode 100644 index 00000000..9967ae7f --- /dev/null +++ b/tests/UnitTests/ApiConnectors/resources/vatcode-response.xml @@ -0,0 +1,33 @@ + + + VH + VAT Sales High + VATSlsHigh + 149e5dcb-8b37-446b-b865-f3928572618f + 20041027101342 + 20190410185128 + 0 + TWINAPPS + sales + + + 20121001 + 21.000000000 + 20171016135323 + VAT Sales High + VATSlsHigh + SUPER + + + + + 1530 + NL + NL1A + 100.0 + vat + + + + + diff --git a/tests/UnitTests/BankTransactionLineUnitTest.php b/tests/UnitTests/BankTransactionLineUnitTest.php new file mode 100644 index 00000000..f7770482 --- /dev/null +++ b/tests/UnitTests/BankTransactionLineUnitTest.php @@ -0,0 +1,180 @@ +line = new BankTransactionLine(); + } + + public function testSetTransaction() + { + $bankTransaction = new BankTransaction(); + $this->line->setTransaction($bankTransaction); + + $this->assertEquals($bankTransaction, $this->line->getTransaction()); + } + + public function testCanNotSetDifferentTransaction() + { + $this->expectException(InvalidArgumentException::class); + + $transaction = new SalesTransaction(); + $this->line->setTransaction($transaction); + } + + public function testCanNotSetTransactionIfTransactionIsAlreadySet() + { + $this->expectException(InvalidArgumentException::class); + + $bankTransaction1 = new BankTransaction(); + $bankTransaction2 = new BankTransaction(); + $this->line->setTransaction($bankTransaction1); + $this->line->setTransaction($bankTransaction2); + } + + public function testSetDim2() + { + $this->line->setLineType(LineType::DETAIL()); + + $this->assertEquals($this->line, $this->line->setDim2(\PhpTwinfield\CostCenter::fromCode('test')), 'Fluid interface is expected'); + $this->assertSame('test', Util::objectToStr($this->line->getDim2())); + } + + public function testCanNotSetDim2IfLineTypeIsNotDetail() + { + $this->expectExceptionMessage('Dimension 2 is invalid for line class PhpTwinfield\BankTransactionLine and type \'vat\'.'); + + $this->line->setLineType(LineType::VAT()); + $this->line->setDim2('test'); + } + + public function testSetDim3() + { + $this->line->setLineType(LineType::DETAIL()); + + $this->assertEquals($this->line, $this->line->setDim3(\PhpTwinfield\Project::fromCode('test')), 'Fluid interface is expected'); + $this->assertSame('test', Util::objectToStr($this->line->getDim3())); + } + + public function testCanNotSetDim3IfLineTypeIsNotDetail() + { + $this->expectExceptionMessage('Dimension 3 is invalid for line class PhpTwinfield\BankTransactionLine and type \'vat\'.'); + + $this->line->setLineType(LineType::VAT()); + $this->line->setDim3('test'); + } + + public function testSetMatchStatus() + { + $this->line->setLineType(LineType::DETAIL()); + + $this->assertEquals($this->line, $this->line->setMatchStatus(MatchStatus::MATCHED()), 'Fluid interface is expected'); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('MATCHED'), (string)$this->line->getMatchStatus()); + } + + public function testCanNotSetMatchStatusOtherThanNotMatchableIfLineTypeIsNotDetail() + { + $this->expectExceptionMessage('Invalid match status \'matched\' for line class PhpTwinfield\BankTransactionLine and type \'vat\'.'); + + $this->line->setLineType(LineType::VAT()); + $this->line->setMatchStatus(MatchStatus::MATCHED()); + } + + public function testSetMatchLevel() + { + $this->line->setLineType(LineType::DETAIL()); + + $this->assertEquals($this->line, $this->line->setMatchLevel(1), 'Fluid interface is expected'); + $this->assertSame(1, $this->line->getMatchLevel()); + } + + public function testCanNotSetMatchLevelIfLineTypeIsNotDetail() + { + $this->expectExceptionMessage('Invalid field \'matchlevel\' for line class PhpTwinfield\BankTransactionLine and type \'vat\'.'); + + $this->line->setLineType(LineType::VAT()); + $this->line->setMatchLevel(1); + } + + public function testSetBaseValueOpen() + { + $this->line->setLineType(LineType::DETAIL()); + + $this->assertEquals($this->line, $this->line->setBaseValueOpen(Money::EUR(100)), 'Fluid interface is expected'); + $this->assertEquals(Money::EUR(100), $this->line->getBaseValueOpen()); + } + + public function testCanNotSetBaseValueOpenIfLineTypeIsNotDetail() + { + $this->expectExceptionMessage('Invalid field \'basevalueopen\' for line class PhpTwinfield\BankTransactionLine and type \'vat\'.'); + + $this->line->setLineType(LineType::VAT()); + $this->line->setBaseValueOpen(Money::EUR(100)); + } + + public function testSetVatTurnover() + { + $this->line->setLineType(LineType::VAT()); + + $this->assertEquals($this->line, $this->line->setVatTurnover(Money::EUR(100)), 'Fluid interface is expected'); + $this->assertEquals(Money::EUR(100), $this->line->getVatTurnover()); + } + + public function testCanNotSetVatTurnoverIfLineTypeIsNotVat() + { + $this->expectExceptionMessage('Invalid field \'vatturnover\' for line class PhpTwinfield\BankTransactionLine and type \'detail\'.'); + + $this->line->setLineType(LineType::DETAIL()); + $this->line->setVatTurnover(Money::EUR(100)); + } + + public function testSetVatBaseTurnover() + { + $this->line->setLineType(LineType::VAT()); + + $this->assertEquals($this->line, $this->line->setVatBaseTurnover(Money::EUR(100)), 'Fluid interface is expected'); + $this->assertEquals(Money::EUR(100), $this->line->getVatBaseTurnover()); + } + + public function testCanNotSetVatBaseTurnoverIfLineTypeIsNotVat() + { + $this->expectExceptionMessage('Invalid field \'vatbaseturnover\' for line class PhpTwinfield\BankTransactionLine and type \'detail\'.'); + + $this->line->setLineType(LineType::DETAIL()); + $this->line->setVatBaseTurnover(Money::EUR(100)); + } + + public function testSetVatRepTurnover() + { + $this->line->setLineType(LineType::VAT()); + + $this->assertEquals($this->line, $this->line->setVatRepTurnover(Money::EUR(100)), 'Fluid interface is expected'); + $this->assertEquals(Money::EUR(100), $this->line->getVatRepTurnover()); + } + + public function testCanNotSetVatRepTurnoverIfLineTypeIsNotVat() + { + $this->expectExceptionMessage('Invalid field \'vatrepturnover\' for line class PhpTwinfield\BankTransactionLine and type \'detail\'.'); + + $this->line->setLineType(LineType::DETAIL()); + $this->line->setVatRepTurnover(Money::EUR(100)); + } +} diff --git a/tests/UnitTests/BankTransactionUnitTest.php b/tests/UnitTests/BankTransactionUnitTest.php index 54b66017..a3a761d6 100644 --- a/tests/UnitTests/BankTransactionUnitTest.php +++ b/tests/UnitTests/BankTransactionUnitTest.php @@ -1,179 +1,90 @@ setOffice(Office::fromCode("XXX99999")); - $bank->setNumber("201300003"); - $bank->getNumber(); - $bank->setCode("MEMO"); - - $line = new Detail(); - $line->setId(1); - $line->setValue(Money::EUR(1)); - - $bank->addLine($line); - - $reference = $line->getReference(); - - $this->assertEquals(Office::fromCode("XXX99999"), $reference->getOffice()); - $this->assertEquals("201300003", $reference->getNumber()); - $this->assertEquals("1", $reference->getLineId()); - $this->assertEquals("MEMO", $reference->getCode()); - } - - public function testGetLineReturnsLinesInSameOrderButAlwaysWithTotalAtTheTop() - { - $total_line_count = 287; - - $bank_transaction = new BankTransaction(); - - for ($i = 1; $i < $total_line_count; $i++) { - $this->addDetailLineWithDescription($bank_transaction, (string)$i); - } - - $this->addTotalLineWithDescription($bank_transaction, '0'); - - self::assertLinesInOrderBasedOnDescription($bank_transaction, $total_line_count); - } - - private static function assertLinesInOrderBasedOnDescription( - BankTransaction $bank_transaction, - int $expected_line_count - ) { - $i = 0; - /** @var Base $line */ - foreach ($bank_transaction->getLines() as $line) { - self::assertSame( - $i, - (int)$line->getDescription(), - 'Expected line #' . $i . ', but got line #' . $line->getDescription() . - ' of type ' . $line->getLineType()->getValue() . '. Wrong order!' - ); - $i++; - } - - self::assertSame($expected_line_count, $i, 'Number of returned lines does not match number of added lines'); - } - - private function addTotalLineWithDescription(BankTransaction $bankTransaction, string $description): Total - { - $line = new Total(); - $line->setDescription($description); - $line->setValue(Money::EUR(0)); + /** + * @var BankTransaction + */ + private $bankTransaction; - $bankTransaction->addLine($line); - - return $line; - } - - private function addDetailLineWithDescription(BankTransaction $bankTransaction, string $description): Detail + protected function setUp() { - $line = new Detail(); - $line->setDescription($description); - $line->setValue(Money::EUR(0)); - - $bankTransaction->addLine($line); - - return $line; + $this->bankTransaction = new BankTransaction(); } - public function testGetLinesReturnsLinesInTheSameOrderAsTheyWereAdded() + public function testSetStartValue() { - $total_line_count = 300; + $this->bankTransaction->setCurrency(Currency::fromCode('EUR')); + $this->bankTransaction->setStartValue(Money::EUR(100)); - $bank_transaction = new BankTransaction(); - - $this->addTotalLineWithDescription($bank_transaction, '0'); - - for ($i = 1; $i < $total_line_count; $i++) { - $this->addDetailLineWithDescription($bank_transaction, (string)$i); - } - - self::assertLinesInOrderBasedOnDescription($bank_transaction, $total_line_count); + $this->assertEquals('EUR', Util::objectToStr($this->bankTransaction->getCurrency())); + $this->assertEquals(Money::EUR(100), $this->bankTransaction->getStartValue()); + $this->assertEquals(Money::EUR(100), $this->bankTransaction->getCloseValue()); } - public function testGetLinesReturnsEmptyArrayWhenNoLinesSet() + public function testSetCurrencyWithoutStartValue() { - $bank_transaction = new BankTransaction(); - - self::assertCount(0, $bank_transaction->getLines()); + $this->bankTransaction->setCurrency(Currency::fromCode('EUR')); + $this->assertEquals('EUR', Util::objectToStr($this->bankTransaction->getCurrency())); } - public function testGetLinesReturnsLinesInSameOrderWhenOnlyDetailsAdded() + public function testSetCurrencyWithZeroStartValue() { - $bank_transaction = new BankTransaction(); + $this->bankTransaction->setStartvalue(Money::EUR(0)); + $this->bankTransaction->setCurrency(Currency::fromCode('EUR')); - $this->addDetailLineWithDescription($bank_transaction, '0'); - $this->addDetailLineWithDescription($bank_transaction, '1'); - $this->addDetailLineWithDescription($bank_transaction, '2'); - - self::assertLinesInOrderBasedOnDescription($bank_transaction, 3); + $this->assertEquals('EUR', Util::objectToStr($this->bankTransaction->getCurrency())); } - public function testGetLinesReturnsOnlyTotalLineWhenOnlyTotalLineIsAdded() + public function testSetCurrencyWithStartValue() { - $bank_transaction = new BankTransaction(); - - $this->addTotalLineWithDescription($bank_transaction, '0'); + $this->expectException(InvalidArgumentException::class); - self::assertCount(1, $bank_transaction->getLines()); - self::assertTrue($bank_transaction->getLines()[0]->getLineType()->equals(LineType::TOTAL())); + $this->bankTransaction->setStartValue(Money::EUR(100)); + $this->bankTransaction->setCurrency(Currency::fromCode('EUR')); } - public function testAdding1TotalLineAnd499DetailLinesToABankTransactionWorks() + public function testAddLineWithWrongTransactionLine() { - $total_line_count = 500; - - $bank_transaction = new BankTransaction(); + $this->expectException(InvalidArgumentException::class); - $this->addTotalLineWithDescription($bank_transaction, '0'); - for ($i = 1; $i < $total_line_count; $i++) { - $this->addDetailLineWithDescription($bank_transaction, (string)$i); - } - - self::assertCount($total_line_count, $bank_transaction->getLines()); + $this->bankTransaction->setStartValue(Money::EUR(100)); + $this->bankTransaction->addLine(new SalesTransactionLine()); } - public function testAdding1TotalLineWith500DetailLinesToABankTransactionThrows() + public function testAddLineUpdatesCloseValue() { - $total_line_count = 501; - - $bank_transaction = new BankTransaction(); + $this->bankTransaction->setStartValue(Money::EUR(100)); - $this->addTotalLineWithDescription($bank_transaction, '0'); + $totalLine = new BankTransactionLine(); + $totalLine + ->setLineType(LineType::TOTAL()) + ->setValue(Money::EUR(0)); - $this->expectException(\InvalidArgumentException::class); - - for ($i = 1; $i < $total_line_count; $i++) { - $this->addDetailLineWithDescription($bank_transaction, (string)$i); - } - } - - public function testAddLineThrowsAndIgnoresWhenAddingASecondTotalLine() - { - $bank_transaction = new BankTransaction(); + $detailLine1 = new BankTransactionLine(); + $detailLine1 + ->setLineType(LineType::DETAIL()) + ->setValue(Money::EUR(43555)); - $this->addTotalLineWithDescription($bank_transaction, '0'); + $detailLine2 = new BankTransactionLine(); + $detailLine2 + ->setLineType(LineType::DETAIL()) + ->setValue(Money::EUR(-43455)); - try { - $this->addTotalLineWithDescription($bank_transaction, '0'); + $this->bankTransaction->addLine($totalLine); + $this->bankTransaction->addLine($detailLine1); + $this->bankTransaction->addLine($detailLine2); - self::fail('An exception should have been thrown when adding a second total line'); - } catch (\InvalidArgumentException $e) { - self::assertCount(1, $bank_transaction->getLines()); - } + $this->assertEquals(Money::EUR(200), $this->bankTransaction->getCloseValue()); } } diff --git a/tests/UnitTests/CashTransactionLineUnitTest.php b/tests/UnitTests/CashTransactionLineUnitTest.php index 1e10ce41..8bb00ddf 100644 --- a/tests/UnitTests/CashTransactionLineUnitTest.php +++ b/tests/UnitTests/CashTransactionLineUnitTest.php @@ -7,7 +7,9 @@ use PhpTwinfield\CashTransaction; use PhpTwinfield\CashTransactionLine; use PhpTwinfield\Enums\LineType; +use PhpTwinfield\Enums\MatchStatus; use PhpTwinfield\SalesTransaction; +use PhpTwinfield\Util; class CashTransactionLineUnitTest extends \PHPUnit\Framework\TestCase { @@ -51,8 +53,8 @@ public function testSetDim2() { $this->line->setLineType(LineType::DETAIL()); - $this->assertEquals($this->line, $this->line->setDim2('test'), 'Fluid interface is expected'); - $this->assertSame('test', $this->line->getDim2()); + $this->assertEquals($this->line, $this->line->setDim2(\PhpTwinfield\CostCenter::fromCode('test')), 'Fluid interface is expected'); + $this->assertSame('test', Util::objectToStr($this->line->getDim2())); } public function testCanNotSetDim2IfLineTypeIsNotDetail() @@ -67,8 +69,8 @@ public function testSetDim3() { $this->line->setLineType(LineType::DETAIL()); - $this->assertEquals($this->line, $this->line->setDim3('test'), 'Fluid interface is expected'); - $this->assertSame('test', $this->line->getDim3()); + $this->assertEquals($this->line, $this->line->setDim3(\PhpTwinfield\Project::fromCode('test')), 'Fluid interface is expected'); + $this->assertSame('test', Util::objectToStr($this->line->getDim3())); } public function testCanNotSetDim3IfLineTypeIsNotDetail() @@ -83,8 +85,9 @@ public function testSetMatchStatus() { $this->line->setLineType(LineType::DETAIL()); - $this->assertEquals($this->line, $this->line->setMatchStatus(CashTransactionLine::MATCHSTATUS_MATCHED), 'Fluid interface is expected'); - $this->assertSame(CashTransactionLine::MATCHSTATUS_MATCHED, $this->line->getMatchStatus()); + $this->assertEquals($this->line, $this->line->setMatchStatus(MatchStatus::MATCHED()), 'Fluid interface is expected'); + $ReflectObject = new \ReflectionClass('\PhpTwinfield\Enums\MatchStatus'); + $this->assertSame($ReflectObject->getConstant('MATCHED'), (string)$this->line->getMatchStatus()); } public function testCanNotSetMatchStatusOtherThanNotMatchableIfLineTypeIsNotDetail() @@ -92,7 +95,7 @@ public function testCanNotSetMatchStatusOtherThanNotMatchableIfLineTypeIsNotDeta $this->expectExceptionMessage('Invalid match status \'matched\' for line class PhpTwinfield\CashTransactionLine and type \'vat\'.'); $this->line->setLineType(LineType::VAT()); - $this->line->setMatchStatus(CashTransactionLine::MATCHSTATUS_MATCHED); + $this->line->setMatchStatus(MatchStatus::MATCHED()); } public function testSetMatchLevel() @@ -105,7 +108,7 @@ public function testSetMatchLevel() public function testCanNotSetMatchLevelIfLineTypeIsNotDetail() { - $this->expectExceptionMessage('Invalid field \'matchLevel\' for line class PhpTwinfield\CashTransactionLine and type \'vat\'.'); + $this->expectExceptionMessage('Invalid field \'matchlevel\' for line class PhpTwinfield\CashTransactionLine and type \'vat\'.'); $this->line->setLineType(LineType::VAT()); $this->line->setMatchLevel(1); @@ -121,7 +124,7 @@ public function testSetBaseValueOpen() public function testCanNotSetBaseValueOpenIfLineTypeIsNotDetail() { - $this->expectExceptionMessage('Invalid field \'baseValueOpen\' for line class PhpTwinfield\CashTransactionLine and type \'vat\'.'); + $this->expectExceptionMessage('Invalid field \'basevalueopen\' for line class PhpTwinfield\CashTransactionLine and type \'vat\'.'); $this->line->setLineType(LineType::VAT()); $this->line->setBaseValueOpen(Money::EUR(100)); @@ -174,20 +177,4 @@ public function testCanNotSetVatRepTurnoverIfLineTypeIsNotVat() $this->line->setLineType(LineType::DETAIL()); $this->line->setVatRepTurnover(Money::EUR(100)); } - - public function testSetInvoiceNumber() - { - $this->line->setLineType(LineType::DETAIL()); - - $this->assertEquals($this->line, $this->line->setInvoiceNumber('11001770'), 'Fluid interface is expected'); - $this->assertSame('11001770', $this->line->getInvoiceNumber()); - } - - public function testCanNotSetInvoiceNumberIfLineTypeIsNotDetail() - { - $this->expectExceptionMessage('Invalid field \'invoicenumber\' for line class PhpTwinfield\CashTransactionLine and type \'total\'.'); - - $this->line->setLineType(LineType::TOTAL()); - $this->line->setInvoiceNumber('11001770'); - } } diff --git a/tests/UnitTests/CashTransactionUnitTest.php b/tests/UnitTests/CashTransactionUnitTest.php index a3b5dcc3..7123e370 100644 --- a/tests/UnitTests/CashTransactionUnitTest.php +++ b/tests/UnitTests/CashTransactionUnitTest.php @@ -2,12 +2,13 @@ namespace PhpTwinfield\UnitTests; use InvalidArgumentException; -use Money\Currency; use Money\Money; use PhpTwinfield\CashTransaction; use PhpTwinfield\CashTransactionLine; +use PhpTwinfield\Currency; use PhpTwinfield\Enums\LineType; use PhpTwinfield\SalesTransactionLine; +use PhpTwinfield\Util; class CashTransactionUnitTest extends \PHPUnit\Framework\TestCase { @@ -23,46 +24,47 @@ protected function setUp() public function testSetStartValue() { - $this->cashTransaction->setStartvalue(Money::EUR(100)); + $this->cashTransaction->setCurrency(Currency::fromCode('EUR')); + $this->cashTransaction->setStartValue(Money::EUR(100)); - $this->assertEquals(new Currency('EUR'), $this->cashTransaction->getCurrency()); - $this->assertEquals(Money::EUR(100), $this->cashTransaction->getStartvalue()); - $this->assertEquals(Money::EUR(100), $this->cashTransaction->getClosevalue()); + $this->assertEquals('EUR', Util::objectToStr($this->cashTransaction->getCurrency())); + $this->assertEquals(Money::EUR(100), $this->cashTransaction->getStartValue()); + $this->assertEquals(Money::EUR(100), $this->cashTransaction->getCloseValue()); } public function testSetCurrencyWithoutStartValue() { - $this->cashTransaction->setCurrency(new Currency('EUR')); - $this->assertEquals(new Currency('EUR'), $this->cashTransaction->getCurrency()); + $this->cashTransaction->setCurrency(Currency::fromCode('EUR')); + $this->assertEquals('EUR', Util::objectToStr($this->cashTransaction->getCurrency())); } public function testSetCurrencyWithZeroStartValue() { $this->cashTransaction->setStartvalue(Money::EUR(0)); - $this->cashTransaction->setCurrency(new Currency('EUR')); + $this->cashTransaction->setCurrency(Currency::fromCode('EUR')); - $this->assertEquals(new Currency('EUR'), $this->cashTransaction->getCurrency()); + $this->assertEquals('EUR', Util::objectToStr($this->cashTransaction->getCurrency())); } public function testSetCurrencyWithStartValue() { $this->expectException(InvalidArgumentException::class); - $this->cashTransaction->setStartvalue(Money::EUR(100)); - $this->cashTransaction->setCurrency(new Currency('EUR')); + $this->cashTransaction->setStartValue(Money::EUR(100)); + $this->cashTransaction->setCurrency(Currency::fromCode('EUR')); } public function testAddLineWithWrongTransactionLine() { $this->expectException(InvalidArgumentException::class); - $this->cashTransaction->setStartvalue(Money::EUR(100)); + $this->cashTransaction->setStartValue(Money::EUR(100)); $this->cashTransaction->addLine(new SalesTransactionLine()); } public function testAddLineUpdatesCloseValue() { - $this->cashTransaction->setStartvalue(Money::EUR(100)); + $this->cashTransaction->setStartValue(Money::EUR(100)); $totalLine = new CashTransactionLine(); $totalLine @@ -83,6 +85,6 @@ public function testAddLineUpdatesCloseValue() $this->cashTransaction->addLine($detailLine1); $this->cashTransaction->addLine($detailLine2); - $this->assertEquals(Money::EUR(200), $this->cashTransaction->getClosevalue()); + $this->assertEquals(Money::EUR(200), $this->cashTransaction->getCloseValue()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/DomDocuments/BankTransactionDocumentUnitTest.php b/tests/UnitTests/DomDocuments/BankTransactionDocumentUnitTest.php deleted file mode 100644 index e732c29f..00000000 --- a/tests/UnitTests/DomDocuments/BankTransactionDocumentUnitTest.php +++ /dev/null @@ -1,113 +0,0 @@ -document = new BankTransactionDocument(); - } - - public function testXmlIsCreatedPerSpec() - { - $transaction = new BankTransaction(); - $transaction->setDestiny(Destiny::TEMPORARY()); - $transaction->setAutoBalanceVat(true); - $transaction->setOffice(Office::fromCode("DEV-10000")); - $transaction->setStartvalue(Money::EUR(0)); - - $line1 = new Total(); - $line1->setValue(Money::EUR(121)); - $line1->setId(38861); - $line1->setVatTotal(Money::EUR(21)); - $line1->setVatBaseTotal(Money::EUR(21)); - $line1->setVatRepTotal(Money::EUR(21)); - $line1->setComment("Round House Kicks & Beard Fists"); - - $line2 = new Detail(); - $line2->setValue(Money::EUR(100)); - $line2->setId(38862); - $line2->setVatValue(Money::EUR(100)); // Not sure? - $line2->setVatBaseValue(Money::EUR(100)); - $line2->setVatRepValue(Money::EUR(100)); - - $line3 = new Detail(); - $line3->setValue(Money::EUR(-100)); - $line3->setId(38863); - $line3->setDestOffice(Office::fromCode("DEV-11000")); - - $line4 = new Vat(); - $line4->setValue(Money::EUR(21)); - $line4->setId(38864); - - $transaction->setLines([$line1, $line2, $line3, $line4]); - - $line3->setComment( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse facilisis lobortis arcu in tincidunt. Mauris urna enim, commodo nec feugiat quis, pharetra vel sem. Etiam ullamcorper eleifend tellus non viverra. Nulla facilisi. Donec sed orci aliquam." - ); - - $this->document->addBankTransaction($transaction); - - $this->assertXmlStringEqualsXmlString( - << - - -
- DEV-10000 - EUR - 0.00 - 0.21 -
- - - debit - 1.21 - 0.21 - 0.21 - 0.21 - Round House Kicks & Beard Fists - - - credit - 1.00 - 1.00 - 1.00 - 1.00 - - - debit - 1.00 - DEV-11000 - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse facilisis lobortis arcu in tincidunt. Mauris urna enim, commodo nec feugiat quis, pharetra vel sem. Etiam ullamcorper eleifend tellus non viverra. Nulla facilisi. Donec sed orci aliquam. - - - credit - 0.21 - - -
-
-XML - , - $this->document->saveXML() - ); - } -} \ No newline at end of file diff --git a/tests/UnitTests/DomDocuments/CustomersDocumentUnitTest.php b/tests/UnitTests/DomDocuments/CustomerDocumentUnitTest.php similarity index 57% rename from tests/UnitTests/DomDocuments/CustomersDocumentUnitTest.php rename to tests/UnitTests/DomDocuments/CustomerDocumentUnitTest.php index 338fb12c..299173f6 100644 --- a/tests/UnitTests/DomDocuments/CustomersDocumentUnitTest.php +++ b/tests/UnitTests/DomDocuments/CustomerDocumentUnitTest.php @@ -6,11 +6,13 @@ use PhpTwinfield\CustomerAddress; use PhpTwinfield\CustomerBank; use PhpTwinfield\CustomerCreditManagement; +use PhpTwinfield\CustomerFinancials; use PhpTwinfield\DomDocuments\CustomersDocument; use PhpTwinfield\Office; +use PhpTwinfield\Util; use PHPUnit\Framework\TestCase; -class CustomersDocumentUnitTest extends TestCase +class CustomerDocumentUnitTest extends TestCase { /** * @var CustomersDocument @@ -31,37 +33,39 @@ public function testXmlIsCreatedPerSpec() $customer->setName('Chuck Norris'); $customer->setWebsite('http://example.org'); $customer->setOffice(Office::fromCode("DEV-10000")); - $customer->setStatus('active'); + $customer->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); - $customer->setDueDays(1); - $customer->setPayAvailable(true); - $customer->setPayCode('pay-code'); - $customer->setVatCode('vat-code'); - $customer->setEBilling(true); - $customer->setEBillMail('ebillingmail@mail.com'); + $financials = new CustomerFinancials(); + $financials->setDueDays(1); + $financials->setPayAvailable(true); + $financials->setPayCode(\PhpTwinfield\PayCode::fromCode('pay-code')); + $financials->setVatCode(\PhpTwinfield\VatCode::fromCode('vat-code')); + $financials->setEBilling(true); + $financials->setEBillMail('ebillingmail@mail.com'); + $customer->setFinancials($financials); $customer->setCreditManagement( (new CustomerCreditManagement()) - ->setResponsibleUser('responsible-user') - ->setBaseCreditLimit(50) - ->setSendReminder(true) + ->setResponsibleUser(\PhpTwinfield\User::fromCode('responsible-user')) + ->setBaseCreditLimit(Util::parseMoney(50, new \Money\Currency("EUR"))) + ->setSendReminder(\PhpTwinfield\Enums\SendReminder::TRUE()) ->setReminderEmail('reminderemail@mail.com') ->setBlocked(false) - ->setFreeText1('free1') + ->setFreeText1(true) ->setFreeText2('free2') ->setComment('comment comment') ); + $customer->addAddress( (new CustomerAddress()) ->setDefault(true) - ->setType('invoice') + ->setType(\PhpTwinfield\Enums\AddressType::INVOICE()) ->setName('My Address') - ->setContact('My Contact') - ->setCountry('nl') + ->setCountry(\PhpTwinfield\Country::fromCode('nl')) ->setCity('city') ->setPostcode('postal code') ->setTelephone('phone number') - ->setFax('fax number') + ->setTelefax('fax number') ->setEmail('email@mail.com') ->setField1('field 1') ->setField2('field 2') @@ -70,21 +74,22 @@ public function testXmlIsCreatedPerSpec() ->setField5('field 5') ->setField6('field 6') ); + $customer->addBank( (new CustomerBank()) ->setDefault(true) + ->setAddressField2('address 2') + ->setAddressField3('address 3') ->setAscription('ascriptor') - ->setAccountnumber('account number') - ->setBankname('bank name') - ->setBiccode('bic code') + ->setAccountNumber('account number') + ->setBankName('bank name') + ->setBicCode('bic code') ->setCity('city') - ->setCountry('nl') + ->setCountry(\PhpTwinfield\Country::fromCode('nl')) ->setIban('iban') - ->setNatbiccode('nat-bic') + ->setNatBicCode('nat-bic') ->setPostcode('postcode') ->setState('state') - ->setAddressField2('address 2') - ->setAddressField3('address 3') ); $this->document->addCustomer($customer); @@ -94,7 +99,7 @@ public function testXmlIsCreatedPerSpec() $customer->setName('Nuck Chorris'); $customer->setWebsite('http://example.org'); $customer->setOffice(Office::fromCode("DEV-00001")); - $customer->setStatus('deleted'); + $customer->setStatus(\PhpTwinfield\Enums\Status::DELETED()); $this->document->addCustomer($customer); @@ -103,38 +108,45 @@ public function testXmlIsCreatedPerSpec() + 0 + 0 D123456 + 0 + 0 Chuck Norris + DEV-10000 + DEB http://example.org - DEV-10000 + core 1 + true + ebillingmail@mail.com + true pay-code + vat-code - true - ebillingmail@mail.com - responsible-user - 50 - true - reminderemail@mail.com + 50.00 false - free1 - free2 comment comment + true + free2 + + reminderemail@mail.com + responsible-user + true + + +
- My Address - My Contact - nl city - postal code - phone number - fax number + nl email@mail.com field 1 field 2 @@ -142,10 +154,18 @@ public function testXmlIsCreatedPerSpec() field 4 field 5 field 6 + My Address + postal code + fax number + phone number
+
+ address 2 + address 3 +
ascriptor account number bank name @@ -156,19 +176,65 @@ public function testXmlIsCreatedPerSpec() nat-bic postcode state -
- address 2 - address 3 -
+ + + + + + + + + +
- D654321 - Nuck Chorris - DEB - http://example.org - DEV-00001 + 0 + 0 + D654321 + 0 + 0 + Nuck Chorris + DEV-00001 + + DEB + http://example.org + + core + 30 + + + + + + + + + + 0 + false + + + + + + + true + + + + + + + + + + + + + +
XML @@ -176,4 +242,4 @@ public function testXmlIsCreatedPerSpec() $this->document->saveXML() ); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/DomDocuments/ElectronicBankStatementDocumentUnitTest.php b/tests/UnitTests/DomDocuments/ElectronicBankStatementDocumentUnitTest.php index 09dd1606..06ffbb92 100644 --- a/tests/UnitTests/DomDocuments/ElectronicBankStatementDocumentUnitTest.php +++ b/tests/UnitTests/DomDocuments/ElectronicBankStatementDocumentUnitTest.php @@ -13,9 +13,9 @@ public function testDocumentationExampleCreatedSuccessfully() { $statement = new ElectronicBankStatement(); $statement->setIban("NL91ABNA0417164300"); - $statement->setStartvalue(Money::EUR(768)); + $statement->setStartValue(Money::EUR(768)); $statement->setDate(new \DateTimeImmutable("2013-11-08")); - $statement->setStatementnumber(2); + $statement->setStatementNumber(2); $transaction1 = new ElectronicBankStatementTransaction(); $transaction1->setType("N100"); @@ -66,8 +66,8 @@ public function testImportDuplicateIsSet() $statement = new ElectronicBankStatement(); $statement->setImportDuplicate(true); $statement->setDate(new \DateTimeImmutable("2017-11-30")); - $statement->setStartvalue(Money::EUR(0)); - $statement->setStatementnumber(236); + $statement->setStartValue(Money::EUR(0)); + $statement->setStatementNumber(236); $domdocument = new ElectronicBankStatementDocument(); $domdocument->addStatement($statement); @@ -96,8 +96,8 @@ public function testNegativeBalanceIsPossible() $statement = new ElectronicBankStatement(); $statement->setImportDuplicate(true); $statement->setDate(new \DateTimeImmutable("2017-11-30")); - $statement->setStartvalue(Money::EUR(-1)); - $statement->setStatementnumber(237); + $statement->setStartValue(Money::EUR(-1)); + $statement->setStatementNumber(237); $domdocument = new ElectronicBankStatementDocument(); $domdocument->addStatement($statement); @@ -118,4 +118,4 @@ public function testNegativeBalanceIsPossible() ,$domdocument->saveXML()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/DomDocuments/MatchDocumentUnitTest.php b/tests/UnitTests/DomDocuments/MatchDocumentUnitTest.php index 03c40c0f..e78138da 100644 --- a/tests/UnitTests/DomDocuments/MatchDocumentUnitTest.php +++ b/tests/UnitTests/DomDocuments/MatchDocumentUnitTest.php @@ -170,4 +170,4 @@ public function testDiscount() $matchdocument->saveXML() ); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/DomDocuments/SupplierDocumentUnitTest.php b/tests/UnitTests/DomDocuments/SupplierDocumentUnitTest.php new file mode 100644 index 00000000..58f7b1b5 --- /dev/null +++ b/tests/UnitTests/DomDocuments/SupplierDocumentUnitTest.php @@ -0,0 +1,205 @@ +document = new SuppliersDocument(); + } + + public function testXmlIsCreatedPerSpec() + { + $supplier = new Supplier(); + $supplier->setCode('D123456'); + $supplier->setName('Chuck Norris'); + $supplier->setWebsite('http://example.org'); + $supplier->setOffice(Office::fromCode("DEV-10000")); + $supplier->setStatus(\PhpTwinfield\Enums\Status::ACTIVE()); + + $financials = new SupplierFinancials(); + $financials->setDueDays(1); + $financials->setPayAvailable(true); + $financials->setPayCode(\PhpTwinfield\PayCode::fromCode('pay-code')); + $financials->setVatCode(\PhpTwinfield\VatCode::fromCode('vat-code')); + $supplier->setFinancials($financials); + + $supplier->addAddress( + (new SupplierAddress()) + ->setDefault(true) + ->setType(\PhpTwinfield\Enums\AddressType::INVOICE()) + ->setName('My Address') + ->setCountry(\PhpTwinfield\Country::fromCode('nl')) + ->setCity('city') + ->setPostcode('postal code') + ->setTelephone('phone number') + ->setTelefax('fax number') + ->setEmail('email@mail.com') + ->setField1('field 1') + ->setField2('field 2') + ->setField3('field 3') + ->setField4('field 4') + ->setField5('field 5') + ->setField6('field 6') + ); + + $supplier->addBank( + (new SupplierBank()) + ->setDefault(true) + ->setAddressField2('address 2') + ->setAddressField3('address 3') + ->setAscription('ascriptor') + ->setAccountNumber('account number') + ->setBankName('bank name') + ->setBicCode('bic code') + ->setCity('city') + ->setCountry(\PhpTwinfield\Country::fromCode('nl')) + ->setIban('iban') + ->setNatBicCode('nat-bic') + ->setPostcode('postcode') + ->setState('state') + ); + + $this->document->addSupplier($supplier); + + $supplier = new Supplier(); + $supplier->setCode('D654321'); + $supplier->setName('Nuck Chorris'); + $supplier->setWebsite('http://example.org'); + $supplier->setOffice(Office::fromCode("DEV-00001")); + $supplier->setStatus(\PhpTwinfield\Enums\Status::DELETED()); + + $this->document->addSupplier($supplier); + + $this->assertXmlStringEqualsXmlString( + << + + + 0 + 0 + D123456 + 0 + 0 + Chuck Norris + DEV-10000 + + CRD + http://example.org + + 1 + + true + pay-code + + + vat-code + + +
+ city + nl + email@mail.com + field 1 + field 2 + field 3 + field 4 + field 5 + field 6 + My Address + postal code + fax number + phone number +
+
+ + +
+ address 2 + address 3 +
+ ascriptor + account number + bank name + bic code + city + nl + iban + nat-bic + postcode + state +
+
+ + + + + + + + + + + + + + +
+ + 0 + 0 + D654321 + 0 + 0 + Nuck Chorris + DEV-00001 + + CRD + http://example.org + + 30 + + + + + + + + + + + + + + + + + + + + + + +
+XML + , + $this->document->saveXML() + ); + } +} diff --git a/tests/UnitTests/ElectronicBankStatementUnitTest.php b/tests/UnitTests/ElectronicBankStatementUnitTest.php index df0e8bab..a378208f 100644 --- a/tests/UnitTests/ElectronicBankStatementUnitTest.php +++ b/tests/UnitTests/ElectronicBankStatementUnitTest.php @@ -2,9 +2,10 @@ namespace PhpTwinfield\UnitTests; -use Money\Currency; use Money\Money; +use PhpTwinfield\Currency; use PhpTwinfield\ElectronicBankStatement; +use PhpTwinfield\Util; use PHPUnit\Framework\TestCase; class ElectronicBankStatementUnitTest extends TestCase @@ -15,9 +16,9 @@ class ElectronicBankStatementUnitTest extends TestCase public function testCanSetCurrencyManually() { $ebs = new ElectronicBankStatement(); - $ebs->setCurrency(new Currency("HUF")); + $ebs->setCurrency(Currency::fromCode("HUF")); - $this->assertEquals("HUF", $ebs->getCurrency()); + $this->assertEquals("HUF", Util::objectToStr($ebs->getCurrency())); } /** @@ -26,8 +27,8 @@ public function testCanSetCurrencyManually() public function testCannotChangeCurrencyOnceValueIsSet() { $ebs = new ElectronicBankStatement(); - $ebs->setStartvalue(Money::GBP(1)); + $ebs->setStartValue(Money::GBP(1)); - $ebs->setCurrency(new Currency("EUR")); + $ebs->setCurrency(Currency::fromCode("EUR")); } } diff --git a/tests/UnitTests/Transactions/TransactionLineFields/ValueFieldsUnitTest.php b/tests/UnitTests/Fields/Transaction/TransactionLine/ValueFieldsUnitTest.php similarity index 98% rename from tests/UnitTests/Transactions/TransactionLineFields/ValueFieldsUnitTest.php rename to tests/UnitTests/Fields/Transaction/TransactionLine/ValueFieldsUnitTest.php index 6ff22630..f5d0275b 100644 --- a/tests/UnitTests/Transactions/TransactionLineFields/ValueFieldsUnitTest.php +++ b/tests/UnitTests/Fields/Transaction/TransactionLine/ValueFieldsUnitTest.php @@ -3,11 +3,11 @@ use Money\Money; use PhpTwinfield\Enums\DebitCredit; use PhpTwinfield\Enums\LineType; -use PhpTwinfield\Transactions\TransactionLineFields\ValueFields; +use PhpTwinfield\Fields\Transaction\TransactionLine\ValueFields; use PHPUnit\Framework\TestCase; /** - * @covers \PhpTwinfield\Transactions\TransactionLineFields\ValueFields + * @covers \PhpTwinfield\Fields\Transaction\TransactionLine\ValueFields */ class ValueFieldsUnitTest extends TestCase { diff --git a/tests/UnitTests/Request/BrowseDataUnitTest.php b/tests/UnitTests/Request/BrowseDataUnitTest.php index 0ceda138..57caffa8 100644 --- a/tests/UnitTests/Request/BrowseDataUnitTest.php +++ b/tests/UnitTests/Request/BrowseDataUnitTest.php @@ -68,4 +68,4 @@ public function testFailureResponseForConstructorWithWrongSortFieldsObjects() new BrowseData('000', $columns, $columns); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/Request/MappedResponseCollectionUnitTest.php b/tests/UnitTests/Request/MappedResponseCollectionUnitTest.php index 89bc98c8..7803c53a 100644 --- a/tests/UnitTests/Request/MappedResponseCollectionUnitTest.php +++ b/tests/UnitTests/Request/MappedResponseCollectionUnitTest.php @@ -2,7 +2,7 @@ namespace PhpTwinfield\UnitTests; -use PhpTwinfield\ApiConnectors\BankTransactionApiConnector; +use PhpTwinfield\ApiConnectors\TransactionApiConnector; use PhpTwinfield\Response\Response; use PhpTwinfield\Services\ProcessXmlService; use PHPUnit\Framework\TestCase; @@ -10,7 +10,7 @@ class MappedResponseCollectionUnitTest extends TestCase { /** - * @var BankTransactionApiConnector + * @var TransactionApiConnector */ protected $apiConnector; @@ -54,4 +54,4 @@ public function createFakeResponse() "); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/SalesTransactionUnitTest.php b/tests/UnitTests/SalesTransactionUnitTest.php index 0267205e..1028ce62 100644 --- a/tests/UnitTests/SalesTransactionUnitTest.php +++ b/tests/UnitTests/SalesTransactionUnitTest.php @@ -87,4 +87,4 @@ private static function assertLinesInOrderBasedOnDescription( self::assertSame($expected_line_count, $i, 'Number of returned lines does not match number of added lines'); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/Secure/OpenIdConnectionAuthenticationTest.php b/tests/UnitTests/Secure/OpenIdConnectionAuthenticationTest.php index f43192bc..15f1e9b4 100644 --- a/tests/UnitTests/Secure/OpenIdConnectionAuthenticationTest.php +++ b/tests/UnitTests/Secure/OpenIdConnectionAuthenticationTest.php @@ -122,4 +122,4 @@ public function testInvalidTokenLogin() $this->assertEquals("someClusterUrl", $openIdConnect->getCluster()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/Secure/Provider/OAuthProviderTest.php b/tests/UnitTests/Secure/Provider/OAuthProviderTest.php index 93692643..6fe48bcb 100644 --- a/tests/UnitTests/Secure/Provider/OAuthProviderTest.php +++ b/tests/UnitTests/Secure/Provider/OAuthProviderTest.php @@ -146,4 +146,4 @@ public function testGetResourceOwnerDetails() $this->assertEquals("someId", $account->getId()); $this->assertEquals(["sub" => "someId", "twf.organisationId" => "someOrganisationId"], $account->toArray()); } -} \ No newline at end of file +} diff --git a/tests/UnitTests/Supplier/OfficeTest.php b/tests/UnitTests/Supplier/OfficeTest.php deleted file mode 100644 index 1501c1fe..00000000 --- a/tests/UnitTests/Supplier/OfficeTest.php +++ /dev/null @@ -1,56 +0,0 @@ -office = Office::fromCode('TEST-001'); - } - - /** - * @covers \PhpTwinfield\Supplier::setOffice() - * @todo Implement testSetOffice(). - */ - public function testSetOffice() - { - $customer = new Supplier; - - $customer->setOffice($this->office); - - $this->assertEquals($this->office, $customer->getOffice()); - - return $customer; - } - - /** - * Checks if the office field is correctly serialized - * - * @depends testSetOffice - */ - public function testSetOfficeAndSerializes(Supplier $customer) - { - $document = new SuppliersDocument; - - $document->addSupplier($customer); - - $xpath = new \DOMXPath($document); - - $this->assertEquals($xpath->query('/dimension/office')->item(0)->nodeValue, $this->office); - } -} diff --git a/usage.md b/usage.md new file mode 100644 index 00000000..e0c0b453 --- /dev/null +++ b/usage.md @@ -0,0 +1,377 @@ +# Usage + +## Authentication +You need to set up a `\PhpTwinfield\Secure\AuthenticatedConnection` class with your credentials. + +### Session Login +**:warning: Note that Twinfield has stated that session login is deprecated and will be removed. End of life date will be announced later. See https://c3.twinfield.com/webservices/documentation/#/ApiReference/Authentication/WebServices** + +When using basic username and password authentication, the `\PhpTwinfield\Secure\WebservicesAuthentication` class should be used, as follows: + +```php +$connection = new Secure\WebservicesAuthentication("username", "password", "organization"); +``` + +### OAuth2 +In order to use OAuth2 to authenticate with Twinfield, one should use the `\PhpTwinfield\Secure\Provider\OAuthProvider` to retrieve an `\League\OAuth2\Client\Token\AccessToken` object, and extract the refresh token from this object. Furthermore, it is required to set up a default `\PhpTwinfield\Office`, that will be used during requests to Twinfield. **Please note:** when a different office is specified when sending a request through one of the `ApiConnectors`, this Office will override the default. + +#### Request a client ID/Secret from Twinfield +Go to the [Twinfield web site](https://www.twinfield.nl/openid-connect-request/) in order to register your OpenID Connect / OAuth 2.0 client and get your Client ID and Secret. Fill in your personal information en pick the following: +* Flow: Authorization Code +* Consent: Your choice +* Redirect URL: The full URI where the following code is available on your domain/server +* Add more redirect URL's?: Your choice +* Post logout URL: Your choice, can be left blank +* Add more post logout URL's?: Your choice + +#### Grant Authorization and retrieve initial Access Token +See [Authorization Example](examples/Authorization.php) for a complete example. +Also see [RenewAuthorization Example](examples/RenewAuthorization.php) for a complete example on how/when to request users to renew their authorization. + +On loading a page containing the following code the user will be redirected to the Twinfield Login page. +After successful login and optionally consent (see above) the user will be redirected back to the page at which point the Access Token and Refresh Token can be retrieved. + +For more information, please refer to: https://github.com/thephpleague/oauth2-client#usage + +```php +$provider = new \PhpTwinfield\Secure\Provider\OAuthProvider([ + 'clientId' => 'someClientId', // The Client ID assigned to you by Twinfield + 'clientSecret' => 'someClientSecret', // The Client Secret assigned to you by Twinfield + 'redirectUri' => 'https://example.org/', // The full URL your filled in at Redirect URL when you requested your client ID +]); + +// If we don't have an authorization code then get one +if (!isset($_GET['code'])) { + //Optionally limit your scope if you don't require all. + $options = [ + 'scope' => ['twf.user','twf.organisation','twf.organisationUser','offline_access','openid'] + ]; + + $authorizationUrl = $provider->getAuthorizationUrl($options); + + // Get the state generated for you and store it to the session. + $_SESSION['oauth2state'] = $provider->getState(); + + // Redirect the user to the authorization URL. + header('Location: ' . $authorizationUrl); + exit; + +// Check given state against previously stored one to mitigate CSRF attack +} elseif (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) { + if (isset($_SESSION['oauth2state'])) { + unset($_SESSION['oauth2state']); + } + + exit('Invalid state'); +} else { + try { + // Try to get an access token using the authorization code grant. + $accessToken = $provider->getAccessToken('authorization_code', [ + 'code' => $_GET['code'] + ]); + + //Twinfield's Refresh Token is valid for 550 days. + //Remember to put in place functionality to request the user to renew their authorization. + //This can be done by requesting the user to reload this page and logging into Twinfield + //before the refresh token is invalidated after 550 days. + $refresh_expiry = strtotime(date('Ymd') . " +550 days"); + + //Save Refresh Token and Refresh Token Expiry Time to storage + $refreshTokenStorage = array(); + $refreshTokenStorage['refresh_token'] = $accessToken->getRefreshToken(); + $refreshTokenStorage['refresh_expiry'] = $refresh_expiry; + + SaveRefreshTokenToStore($refreshTokenStorage); + + //OPTIONAL: Save Access Token, Access Token Expiry Time and Cluster to storage + $validationUrl = "https://login.twinfield.com/auth/authentication/connect/accesstokenvalidation?token="; + $validationResult = @file_get_contents($validationUrl . urlencode($accessToken->getToken())); + + if ($validationResult !== false) { + $resultDecoded = \json_decode($validationResult, true); + $accessTokenStorage = array(); + $accessTokenStorage['access_token'] = $accessToken->getToken(); + $accessTokenStorage['access_expiry'] = $accessToken->getExpires(); + $accessTokenStorage['access_cluster'] = $resultDecoded["twf.clusterUrl"]; + SaveAccessTokenToStore($accessTokenStorage); + } + } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) { + // Failed to get the access token or user details. + exit($e->getMessage()); + } +} +``` + +#### Optionally: Store a valid access token and cluster through a scheduled task/cron job running in the background +See [RenewAccessToken Example](examples/RenewAccessToken.php) for a complete example. + +Running the following code every 60 minutes (or a bit less as Access Tokens are valid for exactly 60 minutes) will reduce connection time when working with the Api (by about 2 seconds). It will also reduce connection load on Twinfield when making more than 20-30 connections/day. + +```php +$refreshTokenStorage = retrieveRefreshTokenFromStore(); + +$provider = new OAuthProvider([ + 'clientId' => 'someClientId', + 'clientSecret' => 'someClientSecret', + 'redirectUri' => 'https://example.org/' +]); + +$accessToken = $provider->getAccessToken('refresh_token', [ + 'refresh_token' => $refreshTokenStorage['refresh_token'] +]); + +$validationUrl = "https://login.twinfield.com/auth/authentication/connect/accesstokenvalidation?token="; +$validationResult = @file_get_contents($validationUrl . urlencode($accessToken->getToken())); + +if ($validationResult !== false) { + $resultDecoded = \json_decode($validationResult, true); + + $tokenStorage = array(); + $tokenStorage['access_token'] = $accessToken->getToken(); + $tokenStorage['access_expiry'] = $accessToken->getExpires(); + $tokenStorage['access_cluster'] = $resultDecoded["twf.clusterUrl"]; + + SaveAccessTokenToStore($tokenStorage); +} +``` + +#### Connection +See [Connection Example](examples/Connection.php) for a complete example. + +Using the stored Refresh Token and optionally Access Token/Cluster, we can create an instance of the `\PhpTwinfield\Secure\OpenIdConnectAuthentication` class, as follows: + +```php +$provider = new OAuthProvider([ + 'clientId' => 'someClientId', + 'clientSecret' => 'someClientSecret', + 'redirectUri' => 'https://example.org/' +]); + +//Retrieve Refresh Token and Refresh Token Expiry Time from storage +$refreshTokenStorage = retrieveRefreshTokenFromStore(); + +//OPTIONAL: Retrieve Access Token, Access Token Expiry Time and Cluster from storage +$accessTokenStorage = retrieveAccessTokenFromStore(); + +$office = \PhpTwinfield\Office::fromCode("someOfficeCode"); + +if ($accessTokenStorage['access_expiry'] > time()) { + $connection = new \PhpTwinfield\Secure\OpenIdConnectAuthentication($provider, $refreshTokenStorage['refresh_token'], $office, $accessTokenStorage['access_token'], $accessTokenStorage['access_cluster']); +} else { + $connection = new \PhpTwinfield\Secure\OpenIdConnectAuthentication($provider, $refreshTokenStorage['refresh_token'], $office); +} +``` + +#### ApiConnector Configuration +The ApiConnector has a constructor second parameter that can be used to configure some aspects of its operation. + +The ApiOptions has the following methods signature: + + ```php +/** + * This will allow you to enforce the messages or the number of max retries. + * Passing null you will use the default values. + */ +public function __construct(?array $messages = null, ?int $maxRetries = null); +/** + * This will allow you to get all the exception messages + */ +public function getRetriableExceptionMessages(): array +/** + * This will allow you to replace the exception messages that should be retried + */ +public function setRetriableExceptionMessages(array $retriableExceptionMessages): ApiOptions +/** + * This will allow you to add new messages to the array of exception messages + */ +public function addMessages(array $messages): ApiOptions +/** + * This will allow you to get the number of max retries + */ +public function getMaxRetries(): int +/** + * This will allow you to set the number of max retries + */ +public function setMaxRetries(int $maxRetries): ApiOptions +``` + +:exclamation: All the *get* methods will return a new instance with the configuration you changed. + +##### Configuration Examples +Below are some examples on how to use the configuration object + + ```php +$connector = new BrowseDataApiConnector( + $connection, + new ApiOptions( + [ + "SSL: Connection reset by peer", + "Bad Gateway" + ], + 3 + ) +); +``` + +The example below will look for the default messages plus the "Bad Gateway" message. + + ```php +$options = new ApiOptions( + null, + 3 +); +$connector = new BrowseDataApiConnector( + $connection, + $options->addMessages(["Bad Gateway"]) +); +``` + +##### Configuration default values +| Attribute | Default Value | Description | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| Max retries | 3 | The number of retries that should happen before throwing an error. | +| Retriable exception messages | [
"SSL: Connection reset by peer",
"Your logon credentials are not valid anymore. Try to log on again."
] | The exception messages that should be match in order to retry automatically. | + +## Getting data from the API +See [Customer Example](examples/Customer.php) among others for a complete example. + +In order to communicate with the Twinfield API, you need to create an `ApiConnector` instance for the corresponding +resource and use the `get()` or `list()` method. + +The `ApiConnector` takes a `Secure\AuthenticatedConnection` object: + +An example: + +```php +$customerApiConnector = new ApiConnectors\CustomerApiConnector($connection); + +// Get one customer. +$office = Office::fromCode('office code'); +$customer = $customerApiConnector->get('1001', $office); + +// Get a list of all customers. +$customer = $customerApiConnector->listAll($office); +``` + +## Creating or updating objects +See [Customer Example](examples/Customer.php) among others for a complete example. + +If you want to create or update a customer or any other object, it's just as easy: + +```php +$customerApiConnector = new ApiConnectors\CustomerApiConnector($connection); + +// First, create the objects you want to send. +$customer = new Customer(); +$customer + ->setCode('1001') + ->setName('John Doe') + ->setOffice($office) + ->setEBilling(false); + +$customerAddress = new CustomerAddress(); +$customerAddress + ->setType('invoice') + ->setDefault(false) + ->setPostcode('1212 AB') + ->setCity('TestCity') + ->setCountry('NL') + ->setTelephone('010-12345') + ->setFax('010-1234') + ->setEmail('johndoe@example.com'); +$customer->addAddress($customerAddress); + +// And secondly, send it to Twinfield. +$customerApiConnector->send($customer); +``` + +You can also send multiple objects in one batch, chunking is handled automatically. + +## Browse data +See [BrowseData Example](examples/BrowseData.php) for a complete example. + +In order to get financial data out of Twinfield like general ledger transactions, sales invoices, and so on, you can use the the browse data functionality. +More information about the browse data functionality in Twinfield can be found in the [documentation](https://c3.twinfield.com/webservices/documentation/#/ApiReference/Request/BrowseData). + +### Browse definition + +You can retrieve the browse definition of a browse code as follows. +You don't need to retrieve the browse definition for getting the browse data. It's only for viewing the browse definition of a browse code to know exactly which columns are available. + +```php +$browseDataApiConnector = new BrowseDataApiConnector($connection); +$browseDefinition = $browseDataApiConnector->getBrowseDefinition('000'); +``` + +### Browse fields + +You can retrieve the browse fields as follows. +You don't need to retrieve the browse fields for getting the browse data. It's only for viewing the definitions of all browse fields so you now what you can expect when retrieving browse data. + +```php +$browseDataApiConnector = new BrowseDataApiConnector($connection); +$browseFields = $browseDataApiConnector->getBrowseFields(); +``` + +### Browse data + +You can retrieve browse data of a browse code as follows. + +```php +$browseDataApiConnector = new BrowseDataApiConnector($connection); + +// First, create the columns that you want to retrieve (see the browse definition for which columns are available) +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.head.yearperiod') + ->setLabel('Period') + ->setVisible(true) + ->setAsk(true) + ->setOperator(Enums\BrowseColumnOperator::BETWEEN()) + ->setFrom('2013/01') + ->setTo('2013/12'); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.head.code') + ->setLabel('Transaction type') + ->setVisible(true); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.head.shortname') + ->setLabel('Name') + ->setVisible(true); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.head.number') + ->setLabel('Trans. no.') + ->setVisible(true); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.line.dim1') + ->setLabel('General ledger') + ->setVisible(true) + ->setAsk(true) + ->setOperator(Enums\BrowseColumnOperator::BETWEEN()) + ->setFrom('1300') + ->setTo('1300'); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.head.curcode') + ->setLabel('Currency') + ->setVisible(true); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.line.valuesigned') + ->setLabel('Value') + ->setVisible(true); + +$columns[] = (new BrowseColumn()) + ->setField('fin.trs.line.description') + ->setLabel('Description') + ->setVisible(true); + +// Second, create sort fields +$sortFields[] = new BrowseSortField('fin.trs.head.code'); + +// Get the browse data +$browseData = $browseDataApiConnector->getBrowseData('000', $columns, $sortFields); +``` \ No newline at end of file