Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: eea771de7d
...
compare: 7e492b47d6
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 17 files changed
  • 1 commit comment
  • 2 contributors
Commits on Mar 31, 2012
@inspiran inspiran Merge pull request #2 from beeldspraak/master
Added createPartnerAddress, updatePartner and deletePartner, updated createPartner.
03a6f95
@wjzijderveld wjzijderveld Fixed Address, Updated managers 7e492b4
View
39 DependencyInjection/Configuration.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Vespolina\PartnerBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+/**
+ * This is the class that validates and merges configuration from your app/config files
+ *
+ * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
+ */
+class Configuration implements ConfigurationInterface
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function getConfigTreeBuilder()
+ {
+ $treeBuilder = new TreeBuilder();
+ $rootNode = $treeBuilder->root('vespolina_partner');
+
+ $rootNode
+ ->children()
+ ->scalarNode('db_driver')->defaultValue('mongodb')->end()
+ ->arrayNode('classMapping')
+ ->children()
+ ->scalarNode('partner')->end()
+ ->scalarNode('partnerContact')->end()
+ ->scalarNode('partnerAddress')->end()
+ ->scalarNode('partnerPersonalDetails')->end()
+ ->scalarNode('partnerOrganisationDetails')->end()
+ ->end()
+ ->end()
+ ->end();
+
+ return $treeBuilder;
+ }
+}
View
39 DependencyInjection/VespolinaPartnerExtension.php
@@ -9,6 +9,8 @@
namespace Vespolina\PartnerBundle\DependencyInjection;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
@@ -19,10 +21,43 @@ class VespolinaPartnerExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
+ $processor = new Processor();
+ $configuration = new Configuration();
+ $config = $processor->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
- foreach (array('mongodb') as $basename) {
- $loader->load(sprintf('%s.xml', $basename));
+ if (!in_array(strtolower($config['db_driver']), array('mongodb'))) {
+ throw new \InvalidArgumentException(sprintf('Invalid db driver "%s".', $config['db_driver']));
+ }
+ $loader->load(sprintf('%s.xml', $config['db_driver']));
+
+ if (isset($config['classMapping']) && is_array($config['classMapping']))
+ $this->configureClassMapping($container, $config['classMapping']);
+ }
+
+ protected function configureClassMapping(ContainerBuilder $container, array $classMapping)
+ {
+ foreach ($classMapping as $name => $class) {
+ if (!class_exists($class))
+ throw new InvalidConfigurationException(sprintf("Class '%s' not found for model '%s'", $class, $name));
+
+ switch ($name) {
+ case 'partner':
+ $container->setParameter('vespolina_partner.model.partner.class', $class);
+ break;
+ case 'partnerContact':
+ $container->setParameter('vespolina_partner.model.partner_contact.class', $class);
+ break;
+ case 'partnerAddress':
+ $container->setParameter('vespolina_partner.model.partner_address.class', $class);
+ break;
+ case 'partnerPersonalDetails':
+ $container->setParameter('vespolina_partner.model.partner_personal_details.class', $class);
+ break;
+ case 'partnerOrganisationDetails':
+ $container->setParameter('vespolina_partner.model.partner_organisation_details.class', $class);
+ break;
+ }
}
}
}
View
11 Document/PartnerManager.php
@@ -22,11 +22,18 @@ class PartnerManager extends BasePartnerManager
*/
protected $dm;
- public function __construct(DocumentManager $dm, $partnerClass, $partnerAddressClass, array $partnerRoles)
+ /**
+ * Constructor to setup the partner manager
+ *
+ * @param DocumentManager $dm - Doctrine ODM DocumentManager
+ * @param array $classMapping - mapping for the partner class and his embedded classes
+ * @param array $partnerRoles - array with available partner roles
+ */
+ public function __construct(DocumentManager $dm, array $classMapping, array $partnerRoles)
{
$this->dm = $dm;
- parent::__construct($partnerClass, $partnerAddressClass, $partnerRoles);
+ parent::__construct($classMapping, $partnerRoles);
}
/**
View
35 Model/Address.php
@@ -9,13 +9,34 @@
class Address implements AddressInterface
{
- private $street;
- private $number;
- private $numbersuffix;
- private $zipcode;
- private $city;
- private $state;
- private $country;
+ const BOTH = 'BOTH';
+ const INVOICE = 'INVOICE';
+ const DELIVERY = 'DELIVERY';
+
+ protected $type;
+ protected $street;
+ protected $number;
+ protected $numbersuffix;
+ protected $zipcode;
+ protected $city;
+ protected $state;
+ protected $country;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+ }
/**
* {@inheritdoc}
View
12 Model/AddressInterface.php
@@ -10,6 +10,18 @@
interface AddressInterface
{
/**
+ * Get address type
+ * @return string
+ */
+ function getType();
+
+ /**
+ * Set type of address - e.g. invoice or delivery
+ * @param string $type
+ */
+ function setType($type);
+
+ /**
* Get street
*/
function getStreet();
View
33 Model/Contact.php
@@ -9,13 +9,28 @@
class Contact implements ContactInterface
{
+ protected $name;
protected $email;
protected $phone;
/**
- * The email of the contact
- *
- * @return string
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function getEmail()
{
@@ -23,9 +38,7 @@ public function getEmail()
}
/**
- * Sets the email of the contact
- *
- * @param string $email
+ * {@inheritdoc}
*/
public function setEmail($email)
{
@@ -33,9 +46,7 @@ public function setEmail($email)
}
/**
- * The primary phonenumer of the contact
- *
- * @return string
+ * {@inheritdoc}
*/
public function getPhone()
{
@@ -43,9 +54,7 @@ public function getPhone()
}
/**
- * Sets the primary phonenumber of the contact
- *
- * @param string $phone
+ * {@inheritdoc}
*/
public function setPhone($phone)
{
View
14 Model/ContactInterface.php
@@ -10,6 +10,20 @@
interface ContactInterface
{
/**
+ * Sets the name of the contact
+ *
+ * @param string $name
+ */
+ function setName($name);
+
+ /**
+ * The name of the contact
+ *
+ * @return string
+ */
+ function getName();
+
+ /**
* Sets the contacts phone number
*
* @param string $phone
View
1  Model/Partner.php
@@ -32,7 +32,6 @@ class Partner implements PartnerInterface
protected $currency;
protected $language;
protected $paymentTerms;
- protected $paymentType;
protected $addresses;
protected $primaryContact;
protected $personalDetails;
View
76 Model/PartnerManager.php
@@ -8,6 +8,8 @@
namespace Vespolina\PartnerBundle\Model;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
/**
* PartnerManager - handles partner creation, updating, deletion, etc
*
@@ -15,14 +17,47 @@
*/
abstract class PartnerManager implements PartnerManagerInterface
{
- protected $partnerClass;
- protected $partnerAddressClass;
+ /**
+ * Configurable partner classes
+ * @var string
+ */
+ protected $partnerClass,
+ $partnerAddressClass,
+ $partnerContactClass,
+ $partnerPersonalDetailsClass;
+
+ /**
+ * Array with available partnerRoles
+ * @var array $partnerRoles
+ */
protected $partnerRoles;
- public function __construct($partnerClass, $partnerAddressClass, array $partnerRoles)
+ /**
+ * Constructor to setup the partner manager
+ *
+ * @param array $classMapping - mapping for the partner class and his embedded classes
+ * @param array $partnerRoles - array with available partner roles
+ */
+ public function __construct(array $classMapping, array $partnerRoles)
{
- $this->partnerClass = $partnerClass;
- $this->partnerAddressClass = $partnerAddressClass;
+ $missingClasses = array();
+ foreach (array('', 'Address', 'Contact', 'PersonalDetails', 'OrganisationDetails') as $class) {
+ $class = 'partner' . $class . 'Class';
+ if (isset($classMapping[$class])) {
+
+ if (!class_exists($classMapping[$class]))
+ throw new InvalidConfigurationException(sprintf("Class '%s' not found as '%s'", $classMapping[$class], $class));
+
+ $this->{$class} = $classMapping[$class];
+ continue;
+ }
+ $missingClasses[] = $class;
+ }
+
+ if (count($missingClasses)) {
+ throw new InvalidConfigurationException(sprintf("The following partner classes are missing from configuration: %s", join(', ', $missingClasses)));
+ }
+
$this->partnerRoles = $partnerRoles;
}
@@ -49,11 +84,42 @@ public function createPartner($role = Partner::ROLE_CUSTOMER, $type = Partner::I
public function createPartnerAddress()
{
$address = new $this->partnerAddressClass;
+ $address->setType(Address::BOTH);
return $address;
}
/**
+ * {@inheritdoc}
+ */
+ public function createPartnerContact()
+ {
+ $contact = new $this->partnerContactClass;
+
+ return $contact;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createPartnerPersonalDetails()
+ {
+ $personalDetails = new $this->partnerPersonalDetailsClass;
+
+ return $personalDetails;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createPartnerOrganisationDetails()
+ {
+ $organisationDetails = new $this->partnerOrganisationDetailsClass;
+
+ return $organisationDetails;
+ }
+
+ /**
* Returns if the given Role is valid.
* @param string $role
*/
View
20 Model/PartnerManagerInterface.php
@@ -34,12 +34,30 @@ function updatePartner(PartnerInterface $partner, $andFlush = true);
function deletePartner(PartnerInterface $partner, $andFlush = true);
/**
- * Creates and returns a new PartnerAddress
+ * Creates and returns a new Partner Address
* @return Vespolina\PartnerBundle\Model\AddressInterface
*/
function createPartnerAddress();
/**
+ * Creates and returns a new Partner Contact
+ * @return Vespolina\PartnerBundle\Model\ContactInterface
+ */
+ function createPartnerContact();
+
+ /**
+ * Creates and returns new Partner Personal Details
+ * @return Vespolina\PartnerBundle\Model\PersonalDetailsInterface
+ */
+ function createPartnerPersonalDetails();
+
+ /**
+ * Creates and returns new Partner Organisation Details
+ * @return Vespolina\PartnerBundle\Model\OrganisationDetailsInterface
+ */
+ function createPartnerOrganisationDetails();
+
+ /**
* Returns a single partner with given partnerId
* @param string $partnerId
* @return Vespolina\PartnerBundle\Model\PartnerInterface or null when no result found
View
8 README.md
@@ -2,3 +2,11 @@ VespolinaPartnerBundle
======================
The Vespolina PartnerBundle is meant to manage all actions done with your customers, clients, suppliers and so more.
+
+
+TODO list
+-------------------------
+
+* Write some usecases to determine what functionality is needed for B2C B2B etc.
+* Write documentation
+* what else comes to mind
View
1  Resources/config/doctrine/BaseAddress.mongodb.xml
@@ -6,6 +6,7 @@
<mapped-superclass name="Vespolina\PartnerBundle\Document\BaseAddress">
+ <field name="type" fieldName="type" type="string" />
<field name="street" fieldName="street" type="string" />
<field name="number" fieldName="number" type="int" />
<field name="numbersuffix" fieldName="numbersuffix" type="string" />
View
12 Resources/config/mongodb.xml
@@ -7,14 +7,22 @@
<parameters>
<parameter key="vespolina_partner.partner_manager.class">Vespolina\PartnerBundle\Document\PartnerManager</parameter>
<parameter key="vespolina_partner.model.partner.class">Vespolina\PartnerBundle\Document\Partner</parameter>
+ <parameter key="vespolina_partner.model.partner_contact.class">Vespolina\PartnerBundle\Document\Contact</parameter>
<parameter key="vespolina_partner.model.partner_address.class">Vespolina\PartnerBundle\Document\Address</parameter>
+ <parameter key="vespolina_partner.model.partner_personal_details.class">Vespolina\PartnerBundle\Document\PersonalDetails</parameter>
+ <parameter key="vespolina_partner.model.partner_organisation_details.class">Vespolina\PartnerBundle\Document\OrganisationDetails</parameter>
</parameters>
<services>
<service id="vespolina_partner.partner_manager" class="%vespolina_partner.partner_manager.class%">
<argument type="service" id="doctrine.odm.mongodb.default_document_manager" />
- <argument>%vespolina_partner.model.partner.class%</argument>
- <argument>%vespolina_partner.model.partner_address.class%</argument>
+ <argument type="collection">
+ <argument key="partnerClass">%vespolina_partner.model.partner.class%</argument>
+ <argument key="partnerContactClass">%vespolina_partner.model.partner_contact.class%</argument>
+ <argument key="partnerAddressClass">%vespolina_partner.model.partner_address.class%</argument>
+ <argument key="partnerPersonalDetailsClass">%vespolina_partner.model.partner_personal_details.class%</argument>
+ <argument key="partnerOrganisationDetailsClass">%vespolina_partner.model.partner_organisation_details.class%</argument>
+ </argument>
<argument type="collection">
<argument>ROLE_CUSTOMER</argument>
<argument>ROLE_EMPLOYEE</argument>
View
91 Tests/Document/PartnerManagerTest.php
@@ -8,6 +8,8 @@
namespace Vespolina\PartnerBundle\Tests\Document;
+use Vespolina\PartnerBundle\Model\Address;
+
use Doctrine\Bundle\MongoDBBundle\Mapping\Driver\XmlDriver;
use Vespolina\PartnerBundle\Model\Partner;
@@ -72,18 +74,99 @@ public function testUpdatePartner()
$this->assertTrue($this->partnerMgr->findOneByPartnerId('testUpdatePartner') instanceOf PartnerInterface);
}
+ public function testFullFeateredPartner()
+ {
+ $partner = $this->partnerMgr->createPartner();
+ $partner->setPartnerId('PartnerId003');
+ $partner->setName('PartnerName');
+ $partner->setPartnerSince(new \DateTime('2012-03-01'));
+ $partner->setCurrency('EUR');
+ $partner->setLanguage('nl_NL');
+ $partner->setPaymentTerms('PartnerPaysWhenHeLikes');
+
+ $address = $this->partnerMgr->createPartnerAddress();
+ $address->setType(Address::INVOICE);
+ $address->setStreet('AddressStreet');
+ $address->setNumber(42);
+ $address->setNumberSuffix('A');
+ $address->setZipcode('1234AA');
+ $address->setCity('Rotterdam');
+ $address->setState('Zuid-Holland');
+ $address->setCountry('The Netherlands');
+
+ $partner->addAddress($address);
+
+ $contact = $this->partnerMgr->createPartnerContact();
+ $contact->setName('PartnerContactName');
+ $contact->setEmail('contact@example.org');
+ $contact->setPhone('0810-555-12345');
+
+ $partner->setPrimaryContact($contact);
+
+ $personalDetails = $this->partnerMgr->createPartnerPersonalDetails();
+ $personalDetails->setNationalIdentificationNumber('1234567890');
+
+ $partner->setPersonalDetails($personalDetails);
+
+ $this->partnerMgr->updatePartner($partner);
+
+ unset($partner);
+
+ $partner = $this->partnerMgr->findOneByPartnerId('PartnerId003');
+ $this->assertTrue($partner instanceOf PartnerInterface);
+
+ // details
+ $this->assertEquals('PartnerName', $partner->getName());
+ $this->assertEquals(new \DateTime('2012-03-01'), $partner->getPartnerSince());
+ $this->assertEquals('EUR', $partner->getCurrency());
+ $this->assertEquals('nl_NL', $partner->getLanguage());
+ $this->assertEquals('PartnerPaysWhenHeLikes', $partner->getPaymentTerms());
+
+ // address
+ $addresses = $partner->getAddresses();
+ $this->assertEquals(1, count($addresses));
+ $this->assertEquals('AddressStreet', $addresses[0]->getStreet());
+ $this->assertSame(42, $addresses[0]->getNumber());
+ $this->assertEquals('A', $addresses[0]->getNumberSuffix());
+ $this->assertEquals('1234AA', $addresses[0]->getZipcode());
+ $this->assertEquals('Rotterdam', $addresses[0]->getCity());
+ $this->assertEquals('Zuid-Holland', $addresses[0]->getState());
+ $this->assertEquals('The Netherlands', $addresses[0]->getCountry());
+
+ // primary contact
+ $contact = $partner->getPrimaryContact();
+ $this->assertEquals('PartnerContactName', $contact->getName());
+ $this->assertEquals('contact@example.org', $contact->getEmail());
+ $this->assertEquals('0810-555-12345', $contact->getPhone());
+
+ // personal details
+ $details = $partner->getPersonalDetails();
+ $this->assertEquals('1234567890', $details->getNationalIdentificationNumber());
+ }
+
+ public function testCustomField()
+ {
+ $partner = $this->partnerMgr->createPartner();
+ $partner->setDateOfBirth(new \DateTime('1987-02-12'));
+
+ $this->assertEquals(new \DateTime('1987-02-12'), $partner->getDateOfBirth());
+ }
public function setup()
{
$this->dm = self::createTestDocumentManager();
- $path = realpath(__DIR__.'/../') . '/Resources/config/doctrine';
- $xmlDriver = new XmlDriver(array($path => 'Vespolina\PartnerBundle\Tests\Fixtures\Document'));
+ $xmlDriver = new XmlDriver(array(realpath(__DIR__.'/../') . '/Resources/config/doctrine' => 'Vespolina\PartnerBundle\Tests\Fixtures\Document'));
$xmlDriver->setFileExtension('.mongodb.xml');
$this->dm->getConfiguration()->setMetadataDriverImpl($xmlDriver);
$this->partnerMgr = new PartnerManager(
$this->dm,
- 'Vespolina\PartnerBundle\Tests\Fixtures\Document\Partner',
- 'Vespolina\PartnerBundle\Tests\Fixtures\Document\Address',
+ array(
+ 'partnerClass' => 'Vespolina\PartnerBundle\Tests\Fixtures\Document\Partner',
+ 'partnerAddressClass' => 'Vespolina\PartnerBundle\Document\Address',
+ 'partnerContactClass' => 'Vespolina\PartnerBundle\Document\Contact',
+ 'partnerPersonalDetailsClass' => 'Vespolina\PartnerBundle\Document\PersonalDetails',
+ 'partnerOrganisationDetailsClass' => 'Vespolina\PartnerBundle\Document\OrganisationDetails',
+ ),
array(
Partner::ROLE_CUSTOMER,
Partner::ROLE_EMPLOYEE,
View
10 Tests/Fixtures/Document/Partner.php
@@ -11,5 +11,15 @@
class Partner extends BasePartner
{
+ protected $dateOfBirth;
+ public function getDateOfBirth()
+ {
+ return $this->dateOfBirth;
+ }
+
+ public function setDateOfBirth(\DateTime $dateOfBirth)
+ {
+ $this->dateOfBirth = $dateOfBirth;
+ }
}
View
13 Tests/PartnerTestCommon.php
@@ -36,7 +36,18 @@ public function getKernel(array $options = array())
public function getManager()
{
if (!$this->manager) {
- $this->manager = $this->getMockForAbstractClass('Vespolina\PartnerBundle\Model\PartnerManager', array('Vespolina\PartnerBundle\Model\Partner', 'Vespolina\PartnerBundle\Model\Address', array(Partner::ROLE_CUSTOMER)));
+ $this->manager = $this->getMockForAbstractClass('Vespolina\PartnerBundle\Model\PartnerManager',
+ array(
+ array(
+ 'partnerClass' => 'Vespolina\PartnerBundle\Model\Partner',
+ 'partnerAddressClass' => 'Vespolina\PartnerBundle\Model\Address',
+ 'partnerContactClass' => 'Vespolina\PartnerBundle\Model\Contact',
+ 'partnerPersonalDetailsClass' => 'Vespolina\PartnerBundle\Model\PersonalDetails',
+ 'partnerOrganisationDetailsClass' => 'Vespolina\PartnerBundle\Model\OrganisationDetails',
+ ),
+ array(Partner::ROLE_CUSTOMER)
+ )
+ );
}
return $this->manager;
View
2  Tests/Resources/config/doctrine/Partner.mongodb.xml
@@ -6,6 +6,8 @@
<document name="Vespolina\PartnerBundle\Tests\Fixtures\Document\Partner" collection="vespolina_test_partners">
<field name="id" id="true" />
+
+ <field name="dateOfBirth" type="date" />
</document>
</doctrine-mongo-mapping>

Showing you all comments on commits in this comparison.

@inspiran

Both? Does not make much sense

Don't forget you have many more types. eg. billing address, deliver from, deliver to , ...

Something went wrong with that request. Please try again.