Skip to content

Commit c5cdcce

Browse files
author
Jelle Roorda
committed
Add projects create/update. Extend BaseMapper.
1 parent bc65761 commit c5cdcce

11 files changed

+999
-1
lines changed
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace PhpTwinfield\ApiConnectors;
4+
5+
use PhpTwinfield\DomDocuments\ProjectDocument;
6+
use PhpTwinfield\Exception;
7+
use PhpTwinfield\Mappers\ProjectMapper;
8+
use PhpTwinfield\Project;
9+
use PhpTwinfield\Response\MappedResponseCollection;
10+
use PhpTwinfield\Response\Response;
11+
use Webmozart\Assert\Assert;
12+
13+
/**
14+
* A facade to make interaction with the Twinfield service easier when trying to retrieve or set information about
15+
* Transactions.
16+
*
17+
* @author Jelle Roorda <[email protected]>
18+
*/
19+
class ProjectApiConnector extends BaseApiConnector
20+
{
21+
/**
22+
* @param Project $project
23+
* @return Project
24+
* @throws Exception
25+
*/
26+
public function send(Project $project): Project
27+
{
28+
foreach ($this->sendAll([$project]) as $each) {
29+
return $each->unwrap();
30+
}
31+
}
32+
33+
/**
34+
*
35+
* @param Project[] $projects
36+
* @return MappedResponseCollection
37+
* @throws Exception
38+
*/
39+
public function sendAll(array $projects): MappedResponseCollection
40+
{
41+
Assert::allIsInstanceOf($projects, Project::class);
42+
43+
/** @var Response[] $responses */
44+
$responses = [];
45+
46+
foreach ($this->getProcessXmlService()->chunk($projects) as $chunk) {
47+
$projectDocument = new ProjectDocument;
48+
49+
foreach ($chunk as $project) {
50+
$projectDocument->addProject($project);
51+
}
52+
53+
$responses[] = $this->sendXmlDocument($projectDocument);
54+
55+
}
56+
57+
return $this->getProcessXmlService()->mapAll(
58+
$responses,
59+
"dimension",
60+
function (Response $subresponse): Project {
61+
return ProjectMapper::map($subresponse);
62+
}
63+
);
64+
}
65+
}

src/DomDocuments/ProjectDocument.php

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace PhpTwinfield\DomDocuments;
4+
5+
use PhpTwinfield\Project;
6+
7+
class ProjectDocument extends BaseDocument
8+
{
9+
/**
10+
* The root tag, e.g.
11+
*
12+
* @return string
13+
*/
14+
protected function getRootTagName(): string
15+
{
16+
return 'dimension';
17+
}
18+
19+
/**
20+
* Turns a passed Project class into the required markup for interacting
21+
* with Twinfield.
22+
*
23+
* This method doesn't return anything, instead just adds the transaction
24+
* to this DOMDocument instance for submission usage.
25+
*
26+
* @param Project $project
27+
*/
28+
public function addProject(Project $project)
29+
{
30+
$office = $project->getOffice();
31+
32+
// Transaction->status
33+
$this->rootElement->setAttribute('status', $project->getStatus());
34+
35+
// Transaction > Office
36+
if(!is_null($office)) {
37+
$officeElement = $this->createNodeWithTextContent('office', $office->getCode());
38+
$this->rootElement->appendChild($officeElement);
39+
}
40+
41+
// Transaction > Type
42+
$typeElement = $this->createNodeWithTextContent('type', 'PRJ');
43+
$this->rootElement->appendChild($typeElement);
44+
45+
// Transaction > Code
46+
if(!is_null($project->getCode())) {
47+
$codeElement = $this->createNodeWithTextContent('code', $project->getCode());
48+
$this->rootElement->appendChild($codeElement);
49+
}
50+
51+
// Transaction > Name
52+
$nameElement = $this->createNodeWithTextContent('name', $project->getName());
53+
$this->rootElement->appendChild($nameElement);
54+
55+
// Transaction > Short name
56+
$shortNameElement = $this->createNodeWithTextContent('shortname', $project->getShortName());
57+
$this->rootElement->appendChild($shortNameElement);
58+
59+
// Transaction > Projects
60+
$projectsElement = $this->createElement('projects');
61+
62+
// Transaction > Projects > Invoice description
63+
if(!is_null($project->getInvoiceDescription())) {
64+
$invoiceDescriptionElement = $this->createNodeWithTextContent('invoicedescription',
65+
$project->getInvoiceDescription());
66+
$projectsElement->appendChild($invoiceDescriptionElement);
67+
}
68+
69+
// Transaction > Projects > authoriser
70+
// Todo: set the attributes on the authoriser element
71+
$authoriserElement = $this->createNodeWithTextContent('authoriser', $project->getAuthoriser());
72+
$projectsElement->appendChild($authoriserElement);
73+
74+
// Transaction > Projects > customer
75+
// Todo: set the attributes on the customer element
76+
$customerElement = $this->createNodeWithTextContent('customer', $project->getCustomer());
77+
$projectsElement->appendChild($customerElement);
78+
79+
// Transaction > Projects > billable
80+
// Todo: set the attributes on the billable element
81+
$billableElement = $this->createNodeWithTextContent('billable', $project->getBillable());
82+
$projectsElement->appendChild($billableElement);
83+
84+
// Transaction > Projects > rate
85+
// Todo: set the attributes on the rate element
86+
if(!is_null($project->getRate())) {
87+
$rateElement = $this->createNodeWithTextContent('rate', $project->getRate());
88+
$projectsElement->appendChild($rateElement);
89+
}
90+
91+
// Transaction > Projects > Quantities
92+
if(!is_null($project->getQuantities())) {
93+
$projectsElement->appendChild($this->createQuantityElement($project));
94+
}
95+
}
96+
97+
/**
98+
* @param Project $project
99+
* @return \DOMElement
100+
*/
101+
private function createQuantityElement(Project $project): \DOMElement
102+
{
103+
$quantityTags = [
104+
'label',
105+
'rate',
106+
'billable',
107+
'mandatory',
108+
];
109+
110+
$quantitiesElement = $this->createElement('quantities');
111+
112+
foreach ($project->getQuantities() as $quantity) {
113+
// Create quantity tags
114+
foreach ($quantityTags as $tag) {
115+
// Get value
116+
$getter = 'get' . ucfirst($tag);
117+
$value = $quantity->{$getter}();
118+
if(is_bool($value)) {
119+
$value = ($value) ? 'true' : 'false';
120+
}
121+
122+
$tagElement = $this->createNodeWithTextContent($tag, $value);
123+
$quantitiesElement->appendChild($tagElement);
124+
}
125+
}
126+
127+
return $quantitiesElement;
128+
}
129+
130+
}

src/Enums/ProjectStatus.php

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace PhpTwinfield\Enums;
4+
5+
use MyCLabs\Enum\Enum;
6+
7+
/**
8+
* @method static ProjectStatus ACTIVE()
9+
* @method static ProjectStatus DELETED()
10+
* @method static ProjectStatus HIDE()
11+
*/
12+
class ProjectStatus extends Enum
13+
{
14+
protected const ACTIVE = "active";
15+
protected const DELETED = "deleted";
16+
protected const HIDE = "hide";
17+
}

src/Fields/BehaviourField.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace PhpTwinfield\Fields;
4+
5+
trait BehaviourField
6+
{
7+
use BehaviourField;
8+
9+
private $behaviour;
10+
11+
/**
12+
* READONLY attribute
13+
* Get the behaviour attribute
14+
* @return mixed
15+
*/
16+
public function getBehaviour()
17+
{
18+
return $this->behaviour;
19+
}
20+
21+
/**
22+
* READONLY attribute
23+
* Set the behaviour attribute
24+
* @param mixed $behaviour
25+
*/
26+
public function setBehaviour($behaviour): void
27+
{
28+
$this->behaviour = $behaviour;
29+
}
30+
}

src/Fields/InUseField.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace PhpTwinfield\Fields;
4+
5+
trait InUseField
6+
{
7+
private $inuse;
8+
9+
/**
10+
* READONLY attribute
11+
* Get the inuse attribute
12+
* @return mixed
13+
*/
14+
public function getInuse()
15+
{
16+
return $this->inuse;
17+
}
18+
19+
/**
20+
* READONLY attribute
21+
* Set the inuse attribute
22+
* @param mixed $inuse
23+
*/
24+
public function setInuse($inuse): void
25+
{
26+
$this->inuse = $inuse;
27+
}
28+
}

src/Fields/TouchedField.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace PhpTwinfield\Fields;
4+
5+
trait TouchedField
6+
{
7+
private $touched;
8+
9+
/**
10+
* READONLY attribute
11+
* Get the touched attribute
12+
* @return mixed
13+
*/
14+
public function getTouched()
15+
{
16+
return $this->touched;
17+
}
18+
19+
/**
20+
* READONLY attribute
21+
* Set the touched attribute
22+
* @param int $touched
23+
*/
24+
public function setTouched(int $touched): void
25+
{
26+
$this->touched = $touched;
27+
}
28+
}

src/Fields/UIDField.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace PhpTwinfield\Fields;
4+
5+
trait UIDField
6+
{
7+
private $UID;
8+
9+
/**
10+
* READONLY attribute
11+
* Get the UID attribute
12+
* @return mixed
13+
*/
14+
public function getUID()
15+
{
16+
return $this->UID;
17+
}
18+
19+
/**
20+
* READONLY attribute
21+
* Set the UID attribute
22+
* @param mixed $UID
23+
*/
24+
public function setUID($UID): void
25+
{
26+
$this->UID = $UID;
27+
}
28+
}

0 commit comments

Comments
 (0)