Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add projects create/update. #121

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/ApiConnectors/ProjectApiConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace PhpTwinfield\ApiConnectors;

use PhpTwinfield\DomDocuments\ProjectDocument;
use PhpTwinfield\Exception;
use PhpTwinfield\Mappers\ProjectMapper;
use PhpTwinfield\Project;
use PhpTwinfield\Response\MappedResponseCollection;
use PhpTwinfield\Response\Response;
use Webmozart\Assert\Assert;

/**
* A facade to make interaction with the Twinfield service easier when trying to retrieve or set information about
* Transactions.
*
* @author Jelle Roorda <[email protected]>
*/
class ProjectApiConnector extends BaseApiConnector
{
/**
* @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) {
$projectDocument = new ProjectDocument;

foreach ($chunk as $project) {
$projectDocument->addProject($project);
}

$responses[] = $this->sendXmlDocument($projectDocument);

}

return $this->getProcessXmlService()->mapAll(
$responses,
"dimension",
function (Response $subresponse): Project {
return ProjectMapper::map($subresponse);
}
);
}
}
130 changes: 130 additions & 0 deletions src/DomDocuments/ProjectDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace PhpTwinfield\DomDocuments;

use PhpTwinfield\Project;

class ProjectDocument extends BaseDocument
{
/**
* The root tag, e.g.
*
* @return string
*/
protected function getRootTagName(): string
{
return 'dimension';
}

/**
* Turns a passed Project class into the required markup for interacting
* with Twinfield.
*
* This method doesn't return anything, instead just adds the transaction
* to this DOMDocument instance for submission usage.
*
* @param Project $project
*/
public function addProject(Project $project)
{
$office = $project->getOffice();

// Transaction->status
$this->rootElement->setAttribute('status', $project->getStatus());

// Transaction > Office
if(!is_null($office)) {
$officeElement = $this->createNodeWithTextContent('office', $office->getCode());
$this->rootElement->appendChild($officeElement);
}

// Transaction > Type
$typeElement = $this->createNodeWithTextContent('type', 'PRJ');
$this->rootElement->appendChild($typeElement);

// Transaction > Code
if(!is_null($project->getCode())) {
$codeElement = $this->createNodeWithTextContent('code', $project->getCode());
$this->rootElement->appendChild($codeElement);
}

// Transaction > Name
$nameElement = $this->createNodeWithTextContent('name', $project->getName());
$this->rootElement->appendChild($nameElement);

// Transaction > Short name
$shortNameElement = $this->createNodeWithTextContent('shortname', $project->getShortName());
$this->rootElement->appendChild($shortNameElement);

// Transaction > Projects
$projectsElement = $this->createElement('projects');

// Transaction > Projects > Invoice description
if(!is_null($project->getInvoiceDescription())) {
$invoiceDescriptionElement = $this->createNodeWithTextContent('invoicedescription',
$project->getInvoiceDescription());
$projectsElement->appendChild($invoiceDescriptionElement);
}

// Transaction > Projects > authoriser
// Todo: set the attributes on the authoriser element
$authoriserElement = $this->createNodeWithTextContent('authoriser', $project->getAuthoriser());
$projectsElement->appendChild($authoriserElement);

// Transaction > Projects > customer
// Todo: set the attributes on the customer element
$customerElement = $this->createNodeWithTextContent('customer', $project->getCustomer());
$projectsElement->appendChild($customerElement);

// Transaction > Projects > billable
// Todo: set the attributes on the billable element
$billableElement = $this->createNodeWithTextContent('billable', $project->getBillable());
$projectsElement->appendChild($billableElement);

// Transaction > Projects > rate
// Todo: set the attributes on the rate element
if(!is_null($project->getRate())) {
$rateElement = $this->createNodeWithTextContent('rate', $project->getRate());
$projectsElement->appendChild($rateElement);
}

// Transaction > Projects > Quantities
if(!is_null($project->getQuantities())) {
$projectsElement->appendChild($this->createQuantityElement($project));
}
}

/**
* @param Project $project
* @return \DOMElement
*/
private function createQuantityElement(Project $project): \DOMElement
{
$quantityTags = [
'label',
'rate',
'billable',
'mandatory',
];

$quantitiesElement = $this->createElement('quantities');

foreach ($project->getQuantities() as $quantity) {
// Create quantity tags
foreach ($quantityTags as $tag) {
// Get value
$getter = 'get' . ucfirst($tag);
$value = $quantity->{$getter}();
if(is_bool($value)) {
$value = ($value) ? 'true' : 'false';
}

$tagElement = $this->createNodeWithTextContent($tag, $value);
$quantitiesElement->appendChild($tagElement);
}
}

return $quantitiesElement;
}

}
17 changes: 17 additions & 0 deletions src/Enums/ProjectStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace PhpTwinfield\Enums;

use MyCLabs\Enum\Enum;

/**
* @method static ProjectStatus ACTIVE()
* @method static ProjectStatus DELETED()
* @method static ProjectStatus HIDE()
*/
class ProjectStatus extends Enum
{
protected const ACTIVE = "active";
protected const DELETED = "deleted";
protected const HIDE = "hide";
}
30 changes: 30 additions & 0 deletions src/Fields/BehaviourField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace PhpTwinfield\Fields;

trait BehaviourField
{
use BehaviourField;

private $behaviour;

/**
* READONLY attribute
* Get the behaviour attribute
* @return mixed
*/
public function getBehaviour()
{
return $this->behaviour;
}

/**
* READONLY attribute
* Set the behaviour attribute
* @param mixed $behaviour
*/
public function setBehaviour($behaviour): void
{
$this->behaviour = $behaviour;
}
}
28 changes: 28 additions & 0 deletions src/Fields/InUseField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace PhpTwinfield\Fields;

trait InUseField
{
private $inuse;

/**
* READONLY attribute
* Get the inuse attribute
* @return mixed
*/
public function getInuse()
{
return $this->inuse;
}

/**
* READONLY attribute
* Set the inuse attribute
* @param mixed $inuse
*/
public function setInuse($inuse): void
{
$this->inuse = $inuse;
}
}
28 changes: 28 additions & 0 deletions src/Fields/TouchedField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace PhpTwinfield\Fields;

trait TouchedField
{
private $touched;

/**
* READONLY attribute
* Get the touched attribute
* @return mixed
*/
public function getTouched()
{
return $this->touched;
}

/**
* READONLY attribute
* Set the touched attribute
* @param int $touched
*/
public function setTouched(int $touched): void
{
$this->touched = $touched;
}
}
28 changes: 28 additions & 0 deletions src/Fields/UIDField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace PhpTwinfield\Fields;

trait UIDField
{
private $UID;

/**
* READONLY attribute
* Get the UID attribute
* @return mixed
*/
public function getUID()
{
return $this->UID;
}

/**
* READONLY attribute
* Set the UID attribute
* @param mixed $UID
*/
public function setUID($UID): void
{
$this->UID = $UID;
}
}
Loading