Rajout d'un module pour gérer la TVA intracommunautaire

This commit is contained in:
2020-04-09 13:01:34 +02:00
parent c46b44924b
commit 49011d2df8
379 changed files with 2702 additions and 5197 deletions

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<config xmlns="http://thelia.net/schema/dic/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<services>
<service id="customervatnumber.services" class="CustomerVatNumber\EventListeners\CustomerVatNumberEventListener">
<argument id="request" type="service"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>
<hooks>
<hook id="customervatnumber.hook" class="CustomerVatNumber\Hook\CustomerVatNumberHook">
<tag name="hook.event_listener" event="register.form-bottom" type="front" method="addFormFieldInput" />
<tag name="hook.event_listener" event="account-update.form-bottom" type="front" method="addFormFieldInput" />
<tag name="hook.event_listener" event="register.after-javascript-include" type="front" method="onRegisterAddJs" />
<tag name="hook.event_listener" event="account-update.after-javascript-include" type="front" method="onFrontUpdateAddJs" />
<tag name="hook.event_listener" event="account.javascript-initialization" type="front" method="onFrontCustomerAccountJs" />
<tag name="hook.event_listener" event="customer.create-form" type="back" method="onBackCreate" />
<tag name="hook.event_listener" event="customer-edit.bottom" type="back" method="onBackUpdate" />
<tag name="hook.event_listener" event="customers.js" type="back" method="onBackCreateAddJs" />
<tag name="hook.event_listener" event="customer.edit-js" type="back" method="onBackUpdateAddJs" />
<tag name="hook.event_listener" event="invoice.information" type="pdf" method="invoiceInformation" />
</hook>
</hooks>
<loops>
<loop name="customer-vat-number" class="CustomerVatNumber\Loop\CustomerVatNumberLoop" />
</loops>
</config>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="http://thelia.net/schema/dic/module"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/module http://thelia.net/schema/dic/module/module-2_2.xsd">
<fullnamespace>CustomerVatNumber\CustomerVatNumber</fullnamespace>
<descriptive locale="en_US">
<title>Add a VAT number to your customer information</title>
</descriptive>
<descriptive locale="fr_FR">
<title>Ajoute le numéro de TVA Intracommunautaire aux informations client</title>
</descriptive>
<languages>
<language>en_US</language>
<language>fr_FR</language>
</languages>
<version>1.0.0</version>
<authors>
<author>
<name>Franck Allimant</name>
<company>CQFDev</company>
<email>thelia@cqfdev.fr</email>
<website>www.cqfdev.fr</website>
</author>
</authors>
<type>classic</type>
<thelia>2.3.0</thelia>
<stability>other</stability>
</module>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
</routes>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<database defaultIdMethod="native" name="thelia" >
<table name="customer_vat_number" namespace="CustomerVatNumber\Model">
<column name="id" primaryKey="true" required="true" type="INTEGER" />
<column name="vat_number" required="true" type="VARCHAR" length="64" />
<foreign-key foreignTable="customer" name="fk_customer_vat_number_customer_id" onDelete="CASCADE" onUpdate="CASCADE">
<reference foreign="id" local="id" />
</foreign-key>
</table>
<external-schema filename="local/config/schema.xml" referenceOnly="true" />
</database>

View File

@@ -0,0 +1,25 @@
# This is a fix for InnoDB in MySQL >= 4.1.x
# It "suspends judgement" for fkey relationships until are tables are set.
SET FOREIGN_KEY_CHECKS = 0;
-- ---------------------------------------------------------------------
-- customer_vat_number
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `customer_vat_number`;
CREATE TABLE `customer_vat_number`
(
`id` INTEGER NOT NULL,
`vat_number` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_customer_vat_number_customer_id`
FOREIGN KEY (`id`)
REFERENCES `customer` (`id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=InnoDB;
# This restores the fkey checks, after having unset them earlier
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,42 @@
<?php
/*************************************************************************************/
/* Copyright (c) Franck Allimant, CQFDev */
/* email : thelia@cqfdev.fr */
/* web : http://www.cqfdev.fr */
/* */
/* For the full copyright and license information, please view the LICENSE */
/* file that was distributed with this source code. */
/*************************************************************************************/
/**
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
* Date: 04/07/2019 23:21
*/
namespace CustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery;
use Propel\Runtime\Connection\ConnectionInterface;
use Thelia\Install\Database;
use Thelia\Module\BaseModule;
/**
* Class CustomerVatNumber
* @package CustomerVatNumber
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CustomerVatNumber extends BaseModule
{
/** @var string */
const DOMAIN_NAME = 'customervatnumber';
public function postActivation(ConnectionInterface $con = null)
{
try {
CustomerVatNumberQuery::create()->findOne();
} catch (\Exception $ex) {
$database = new Database($con);
$database->insertSql(null, [__DIR__ . "/Config/thelia.sql"]);
}
}
}

View File

@@ -0,0 +1,158 @@
<?php
/*************************************************************************************/
/* Copyright (c) Franck Allimant, CQFDev */
/* email : thelia@cqfdev.fr */
/* web : http://www.cqfdev.fr */
/* */
/* For the full copyright and license information, please view the LICENSE */
/* file that was distributed with this source code. */
/*************************************************************************************/
/**
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
* Date: 04/07/2019 23:14
*/
namespace CustomerVatNumber\EventListeners;
use CustomerVatNumber\CustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\TheliaFormEvent;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
/**
* Class CustomerVatNumberEventListener
* @package CustomerVatNumber\EventListeners
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CustomerVatNumberEventListener implements EventSubscriberInterface
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public static function getSubscribedEvents()
{
return [
// En front
TheliaEvents::FORM_AFTER_BUILD . '.thelia_customer_create' => ['vatNumberInput', 128],
TheliaEvents::AFTER_CREATECUSTOMER => ['processVatNumber', 128],
TheliaEvents::FORM_AFTER_BUILD . '.thelia_customer_profile_update' => ['vatNumberInput', 128],
TheliaEvents::CUSTOMER_UPDATEPROFILE => ['processVatNumber', 128],
// Dans le BO
TheliaEvents::FORM_AFTER_BUILD . '.thelia_customer_update' => ['vatNumberInput', 128],
TheliaEvents::CUSTOMER_UPDATEACCOUNT => ['processVatNumber', 128]
];
}
/**
* Add form field input in customer update and create forms
* @param TheliaFormEvent $event
*/
public function vatNumberInput(TheliaFormEvent $event)
{
if ($this->request->fromApi() === false) {
$data = $event->getForm()->getFormBuilder()->getData();
$customerVatNumber = null;
if (!empty($data['id'])) {
$customerVatNumber = CustomerVatNumberQuery::create()
->findOneById($data['id']);
}
$event->getForm()->getFormBuilder()
->add(
'vat_number',
'text',
[
'label' => Translator::getInstance()->trans("VAT Number", [], CustomerVatNumber::DOMAIN_NAME),
'required' => false,
'constraints' => [
new Callback([
"methods" => [
[$this, "checkVatNumber"],
],
]),
],
'data' => ($customerVatNumber !== null) ? $customerVatNumber->getVatNumber() : '',
'attr' => [
],
'label_attr' => [
'help' => Translator::getInstance()->trans("Please enter a valid VAT number.", [], CustomerVatNumber::DOMAIN_NAME),
'placeholder' => Translator::getInstance()->trans("VAT Number", [], CustomerVatNumber::DOMAIN_NAME),
]
]
);
}
}
public function checkVatNumber($value, ExecutionContextInterface $context)
{
// @see https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s21.html
static $vatNumberRegexp = "/^((AT)?U[0-9]{8}|(BE)?0[0-9]{9}|(BG)?[0-9]{9,10}|(CY)?[0-9]{8}L|(CZ)?[0-9]{8,10}|(DE)?[0-9]{9}|(DK)?[0-9]{8}|(EE)?[0-9]{9}|(EL|GR)?[0-9]{9}|(ES)?[0-9A-Z][0-9]{7}[0-9A-Z]|(FI)?[0-9]{8}|(FR)?[0-9A-Z]{2}[0-9]{9}|(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3})|(HU)?[0-9]{8}|(IE)?[0-9]S[0-9]{5}L|(IT)?[0-9]{11}|(LT)?([0-9]{9}|[0-9]{12})|(LU)?[0-9]{8}|(LV)?[0-9]{11}|(MT)?[0-9]{8}|(NL)?[0-9]{9}B[0-9]{2}|(PL)?[0-9]{10}|(PT)?[0-9]{9}|(RO)?[0-9]{2,10}|(SE)?[0-9]{12}|(SI)?[0-9]{8}|(SK)?[0-9]{10})$/";
$value = preg_replace("/[^A-Z0-9]/", "", strtoupper($value));
if (! empty($value)) {
if (! preg_match($vatNumberRegexp, $value)) {
$context->addViolation(
Translator::getInstance()->trans('Please enter a valid VAT number.', [], CustomerVatNumber::DOMAIN_NAME)
);
}
}
}
/**
* Process the customer VAT number.
*
* @param CustomerEvent $event
* @throws \Propel\Runtime\Exception\PropelException
*/
public function processVatNumber(CustomerEvent $event)
{
if ($this->request->fromApi() === false) {
// Utilise le principe NON DOCUMENTE qui dit que si une form bindée à un event trouve
// un champ absent de l'event, elle le rend accessible à travers une méthode magique.
// (cf. ActionEvent::bindForm())
$vatNumber = $event->vat_number;
if (null === $vatNumber) {
$vatNumber = $this->getVatNumberFromRequest('thelia_customer_profile_update');
}
if (null === $vatNumber) {
$vatNumber = $this->getVatNumberFromRequest('thelia_customer_create');
}
if (null !== $vatNumber) {
if (null === $customerVatNumber = CustomerVatNumberQuery::create()->findOneById($event->getCustomer()->getId())) {
// Create a new birth date
$customerVatNumber = (new \CustomerVatNumber\Model\CustomerVatNumber())
->setId($event->getCustomer()->getId());
}
$customerVatNumber
->setVatNumber($vatNumber)
->save();
}
}
}
protected function getVatNumberFromRequest($formName)
{
$data = $this->request->get($formName, []);
return isset($data['vat_number']) ? $data['vat_number'] : null;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/*************************************************************************************/
/* Copyright (c) Franck Allimant, CQFDev */
/* email : thelia@cqfdev.fr */
/* web : http://www.cqfdev.fr */
/* */
/* For the full copyright and license information, please view the LICENSE */
/* file that was distributed with this source code. */
/*************************************************************************************/
/**
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
* Date: 04/07/2019 23:20
*/
namespace CustomerVatNumber\Hook;
use CustomerVatNumber\CustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery;
use Thelia\Core\Event\Hook\HookRenderBlockEvent;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
use Thelia\Core\Translation\Translator;
use Thelia\Model\OrderQuery;
/**
* Class CustomerVatNumberHook
* @package CustomerVatNumber\Hook
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CustomerVatNumberHook extends BaseHook
{
public function addFormFieldInput(HookRenderEvent $event)
{
$event->add($this->render('customer-vat-input.html'));
}
public function onRegisterAddJs(HookRenderEvent $event)
{
$event->add($this->render('assets/js/register-move-vat-number-input.html'));
}
public function onFrontUpdateAddJs(HookRenderEvent $event)
{
$event->add($this->render('assets/js/update-move-vat-number-input.html'));
}
public function onFrontCustomerAccountJs(HookRenderEvent $event)
{
$event->add(
$this->render(
'assets/js/account-display-customer-vat-number.html',
[ 'customer_id' => $this->getCustomer()->getId() ]
)
);
}
public function onBackCreate(HookRenderEvent $event)
{
$event->add(
$this->render(
'customer-vat-input.html',
[
'custVatFormName' => 'thelia.admin.customer.create'
]
)
);
}
public function onBackUpdate(HookRenderEvent $event)
{
$event->add(
$this->render(
'customer-vat-input.html',
[
'custVatFormName' => 'thelia.admin.customer.update'
]
)
);
}
public function onBackCreateAddJs(HookRenderEvent $event)
{
$event->add($this->render('assets/js/create-customer-move-vat-number-input.html'));
}
public function onBackUpdateAddJs(HookRenderEvent $event)
{
$event->add($this->render('assets/js/update-customer-move-vat-number-input.html'));
}
public function invoiceInformation(HookRenderBlockEvent $event)
{
if (null !== $order = OrderQuery::create()->findPk($event->getArgument('order'))) {
if (null !== $cv = CustomerVatNumberQuery::create()->findOneById($order->getCustomerId())) {
$vatNumber = $cv->getVatNumber();
if (! empty($vatNumber)) {
$event->add([
'title' => Translator::getInstance()->trans("Your VAT Number", [], CustomerVatNumber::DOMAIN_NAME),
'value' => $vatNumber
]);
}
}
}
}
}

View File

@@ -0,0 +1,4 @@
<?php
return array(
// 'an english string' => 'The displayed english string',
);

View File

@@ -0,0 +1,7 @@
<?php
return array(
'Please enter a valid VAT number.' => 'Si vous êtres un professionnel, indiquez votre N° de TVA Intracommunautaire',
'VAT Number' => 'N° de TVA Intracommunautaire',
'Your VAT Number' => 'Votre N° de TVA',
);

View File

@@ -0,0 +1,6 @@
<?php
return array(
'You have not entered your VAT number.' => 'Vous n\'avez pas indiqué de N° de TVA Intracommunautaire.',
'Your VAT number: %vat' => 'Votre N° de TVA Intracommunautaire: %vat',
);

View File

@@ -0,0 +1,81 @@
<?php
/*************************************************************************************/
/* Copyright (c) Franck Allimant, CQFDev */
/* email : thelia@cqfdev.fr */
/* web : http://www.cqfdev.fr */
/* */
/* For the full copyright and license information, please view the LICENSE */
/* file that was distributed with this source code. */
/*************************************************************************************/
/**
* Created by Franck Allimant, CQFDev <franck@cqfdev.fr>
* Date: 04/07/2019 23:15
*/
namespace CustomerVatNumber\Loop;
use CustomerVatNumber\Model\CustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Element\PropelSearchLoopInterface;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
/**
* Class CustomerVatNumberLoop
* @package CustomerVatNumber\Loop
* @author Franck Allimant <franck@cqfdev.fr>
* @method int getCustomerId()
*/
class CustomerVatNumberLoop extends BaseLoop implements PropelSearchLoopInterface
{
/**
* @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntTypeArgument('customer_id', null, true)
);
}
/**
* this method returns a Propel ModelCriteria
*
* @return \Propel\Runtime\ActiveQuery\ModelCriteria
*/
public function buildModelCriteria()
{
$query = CustomerVatNumberQuery::create();
if (null !== $id = $this->getCustomerId()) {
$query->filterById($id);
}
return $query;
}
/**
* @param LoopResult $loopResult
*
* @return LoopResult
*/
public function parseResults(LoopResult $loopResult)
{
/** @var CustomerVatNumber $customerVatNumber */
foreach ($loopResult->getResultDataCollection() as $customerVatNumber) {
$loopResultRow = new LoopResultRow($customerVatNumber);
$loopResultRow
->set("CUSTOMER_ID", $customerVatNumber->getId())
->set("VAT_NUMBER", $customerVatNumber->getVatNumber());
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,462 @@
<?php
namespace CustomerVatNumber\Model\Base;
use \Exception;
use \PDO;
use CustomerVatNumber\Model\CustomerVatNumber as ChildCustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery as ChildCustomerVatNumberQuery;
use CustomerVatNumber\Model\Map\CustomerVatNumberTableMap;
use Propel\Runtime\Propel;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Propel\Runtime\ActiveQuery\ModelJoin;
use Propel\Runtime\Collection\Collection;
use Propel\Runtime\Collection\ObjectCollection;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Exception\PropelException;
use Thelia\Model\Customer;
/**
* Base class that represents a query for the 'customer_vat_number' table.
*
*
*
* @method ChildCustomerVatNumberQuery orderById($order = Criteria::ASC) Order by the id column
* @method ChildCustomerVatNumberQuery orderByVatNumber($order = Criteria::ASC) Order by the vat_number column
*
* @method ChildCustomerVatNumberQuery groupById() Group by the id column
* @method ChildCustomerVatNumberQuery groupByVatNumber() Group by the vat_number column
*
* @method ChildCustomerVatNumberQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method ChildCustomerVatNumberQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
* @method ChildCustomerVatNumberQuery innerJoin($relation) Adds a INNER JOIN clause to the query
*
* @method ChildCustomerVatNumberQuery leftJoinCustomer($relationAlias = null) Adds a LEFT JOIN clause to the query using the Customer relation
* @method ChildCustomerVatNumberQuery rightJoinCustomer($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Customer relation
* @method ChildCustomerVatNumberQuery innerJoinCustomer($relationAlias = null) Adds a INNER JOIN clause to the query using the Customer relation
*
* @method ChildCustomerVatNumber findOne(ConnectionInterface $con = null) Return the first ChildCustomerVatNumber matching the query
* @method ChildCustomerVatNumber findOneOrCreate(ConnectionInterface $con = null) Return the first ChildCustomerVatNumber matching the query, or a new ChildCustomerVatNumber object populated from the query conditions when no match is found
*
* @method ChildCustomerVatNumber findOneById(int $id) Return the first ChildCustomerVatNumber filtered by the id column
* @method ChildCustomerVatNumber findOneByVatNumber(string $vat_number) Return the first ChildCustomerVatNumber filtered by the vat_number column
*
* @method array findById(int $id) Return ChildCustomerVatNumber objects filtered by the id column
* @method array findByVatNumber(string $vat_number) Return ChildCustomerVatNumber objects filtered by the vat_number column
*
*/
abstract class CustomerVatNumberQuery extends ModelCriteria
{
/**
* Initializes internal state of \CustomerVatNumber\Model\Base\CustomerVatNumberQuery object.
*
* @param string $dbName The database name
* @param string $modelName The phpName of a model, e.g. 'Book'
* @param string $modelAlias The alias for the model in this query, e.g. 'b'
*/
public function __construct($dbName = 'thelia', $modelName = '\\CustomerVatNumber\\Model\\CustomerVatNumber', $modelAlias = null)
{
parent::__construct($dbName, $modelName, $modelAlias);
}
/**
* Returns a new ChildCustomerVatNumberQuery object.
*
* @param string $modelAlias The alias of a model in the query
* @param Criteria $criteria Optional Criteria to build the query from
*
* @return ChildCustomerVatNumberQuery
*/
public static function create($modelAlias = null, $criteria = null)
{
if ($criteria instanceof \CustomerVatNumber\Model\CustomerVatNumberQuery) {
return $criteria;
}
$query = new \CustomerVatNumber\Model\CustomerVatNumberQuery();
if (null !== $modelAlias) {
$query->setModelAlias($modelAlias);
}
if ($criteria instanceof Criteria) {
$query->mergeWith($criteria);
}
return $query;
}
/**
* Find object by primary key.
* Propel uses the instance pool to skip the database if the object exists.
* Go fast if the query is untouched.
*
* <code>
* $obj = $c->findPk(12, $con);
* </code>
*
* @param mixed $key Primary key to use for the query
* @param ConnectionInterface $con an optional connection object
*
* @return ChildCustomerVatNumber|array|mixed the result, formatted by the current formatter
*/
public function findPk($key, $con = null)
{
if ($key === null) {
return null;
}
if ((null !== ($obj = CustomerVatNumberTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) {
// the object is already in the instance pool
return $obj;
}
if ($con === null) {
$con = Propel::getServiceContainer()->getReadConnection(CustomerVatNumberTableMap::DATABASE_NAME);
}
$this->basePreSelect($con);
if ($this->formatter || $this->modelAlias || $this->with || $this->select
|| $this->selectColumns || $this->asColumns || $this->selectModifiers
|| $this->map || $this->having || $this->joins) {
return $this->findPkComplex($key, $con);
} else {
return $this->findPkSimple($key, $con);
}
}
/**
* Find object by primary key using raw SQL to go fast.
* Bypass doSelect() and the object formatter by using generated code.
*
* @param mixed $key Primary key to use for the query
* @param ConnectionInterface $con A connection object
*
* @return ChildCustomerVatNumber A model object, or null if the key is not found
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT ID, VAT_NUMBER FROM customer_vat_number WHERE ID = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
$stmt->execute();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e);
}
$obj = null;
if ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
$obj = new ChildCustomerVatNumber();
$obj->hydrate($row);
CustomerVatNumberTableMap::addInstanceToPool($obj, (string) $key);
}
$stmt->closeCursor();
return $obj;
}
/**
* Find object by primary key.
*
* @param mixed $key Primary key to use for the query
* @param ConnectionInterface $con A connection object
*
* @return ChildCustomerVatNumber|array|mixed the result, formatted by the current formatter
*/
protected function findPkComplex($key, $con)
{
// As the query uses a PK condition, no limit(1) is necessary.
$criteria = $this->isKeepQuery() ? clone $this : $this;
$dataFetcher = $criteria
->filterByPrimaryKey($key)
->doSelect($con);
return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher);
}
/**
* Find objects by primary key
* <code>
* $objs = $c->findPks(array(12, 56, 832), $con);
* </code>
* @param array $keys Primary keys to use for the query
* @param ConnectionInterface $con an optional connection object
*
* @return ObjectCollection|array|mixed the list of results, formatted by the current formatter
*/
public function findPks($keys, $con = null)
{
if (null === $con) {
$con = Propel::getServiceContainer()->getReadConnection($this->getDbName());
}
$this->basePreSelect($con);
$criteria = $this->isKeepQuery() ? clone $this : $this;
$dataFetcher = $criteria
->filterByPrimaryKeys($keys)
->doSelect($con);
return $criteria->getFormatter()->init($criteria)->format($dataFetcher);
}
/**
* Filter the query by primary key
*
* @param mixed $key Primary key to use for the query
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function filterByPrimaryKey($key)
{
return $this->addUsingAlias(CustomerVatNumberTableMap::ID, $key, Criteria::EQUAL);
}
/**
* Filter the query by a list of primary keys
*
* @param array $keys The list of primary key to use for the query
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function filterByPrimaryKeys($keys)
{
return $this->addUsingAlias(CustomerVatNumberTableMap::ID, $keys, Criteria::IN);
}
/**
* Filter the query on the id column
*
* Example usage:
* <code>
* $query->filterById(1234); // WHERE id = 1234
* $query->filterById(array(12, 34)); // WHERE id IN (12, 34)
* $query->filterById(array('min' => 12)); // WHERE id > 12
* </code>
*
* @see filterByCustomer()
*
* @param mixed $id The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function filterById($id = null, $comparison = null)
{
if (is_array($id)) {
$useMinMax = false;
if (isset($id['min'])) {
$this->addUsingAlias(CustomerVatNumberTableMap::ID, $id['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($id['max'])) {
$this->addUsingAlias(CustomerVatNumberTableMap::ID, $id['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CustomerVatNumberTableMap::ID, $id, $comparison);
}
/**
* Filter the query on the vat_number column
*
* Example usage:
* <code>
* $query->filterByVatNumber('fooValue'); // WHERE vat_number = 'fooValue'
* $query->filterByVatNumber('%fooValue%'); // WHERE vat_number LIKE '%fooValue%'
* </code>
*
* @param string $vatNumber The value to use as filter.
* Accepts wildcards (* and % trigger a LIKE)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function filterByVatNumber($vatNumber = null, $comparison = null)
{
if (null === $comparison) {
if (is_array($vatNumber)) {
$comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $vatNumber)) {
$vatNumber = str_replace('*', '%', $vatNumber);
$comparison = Criteria::LIKE;
}
}
return $this->addUsingAlias(CustomerVatNumberTableMap::VAT_NUMBER, $vatNumber, $comparison);
}
/**
* Filter the query by a related \Thelia\Model\Customer object
*
* @param \Thelia\Model\Customer|ObjectCollection $customer The related object(s) to use as filter
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function filterByCustomer($customer, $comparison = null)
{
if ($customer instanceof \Thelia\Model\Customer) {
return $this
->addUsingAlias(CustomerVatNumberTableMap::ID, $customer->getId(), $comparison);
} elseif ($customer instanceof ObjectCollection) {
if (null === $comparison) {
$comparison = Criteria::IN;
}
return $this
->addUsingAlias(CustomerVatNumberTableMap::ID, $customer->toKeyValue('PrimaryKey', 'Id'), $comparison);
} else {
throw new PropelException('filterByCustomer() only accepts arguments of type \Thelia\Model\Customer or Collection');
}
}
/**
* Adds a JOIN clause to the query using the Customer relation
*
* @param string $relationAlias optional alias for the relation
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function joinCustomer($relationAlias = null, $joinType = Criteria::INNER_JOIN)
{
$tableMap = $this->getTableMap();
$relationMap = $tableMap->getRelation('Customer');
// create a ModelJoin object for this join
$join = new ModelJoin();
$join->setJoinType($joinType);
$join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias);
if ($previousJoin = $this->getPreviousJoin()) {
$join->setPreviousJoin($previousJoin);
}
// add the ModelJoin to the current object
if ($relationAlias) {
$this->addAlias($relationAlias, $relationMap->getRightTable()->getName());
$this->addJoinObject($join, $relationAlias);
} else {
$this->addJoinObject($join, 'Customer');
}
return $this;
}
/**
* Use the Customer relation Customer object
*
* @see useQuery()
*
* @param string $relationAlias optional alias for the relation,
* to be used as main alias in the secondary query
* @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'
*
* @return \Thelia\Model\CustomerQuery A secondary query class using the current class as primary query
*/
public function useCustomerQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN)
{
return $this
->joinCustomer($relationAlias, $joinType)
->useQuery($relationAlias ? $relationAlias : 'Customer', '\Thelia\Model\CustomerQuery');
}
/**
* Exclude object from result
*
* @param ChildCustomerVatNumber $customerVatNumber Object to remove from the list of results
*
* @return ChildCustomerVatNumberQuery The current query, for fluid interface
*/
public function prune($customerVatNumber = null)
{
if ($customerVatNumber) {
$this->addUsingAlias(CustomerVatNumberTableMap::ID, $customerVatNumber->getId(), Criteria::NOT_EQUAL);
}
return $this;
}
/**
* Deletes all rows from the customer_vat_number table.
*
* @param ConnectionInterface $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver).
*/
public function doDeleteAll(ConnectionInterface $con = null)
{
if (null === $con) {
$con = Propel::getServiceContainer()->getWriteConnection(CustomerVatNumberTableMap::DATABASE_NAME);
}
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
$affectedRows += parent::doDeleteAll($con);
// Because this db requires some delete cascade/set null emulation, we have to
// clear the cached instance *after* the emulation has happened (since
// instances get re-added by the select statement contained therein).
CustomerVatNumberTableMap::clearInstancePool();
CustomerVatNumberTableMap::clearRelatedInstancePool();
$con->commit();
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
return $affectedRows;
}
/**
* Performs a DELETE on the database, given a ChildCustomerVatNumber or Criteria object OR a primary key value.
*
* @param mixed $values Criteria or ChildCustomerVatNumber object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param ConnectionInterface $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public function delete(ConnectionInterface $con = null)
{
if (null === $con) {
$con = Propel::getServiceContainer()->getWriteConnection(CustomerVatNumberTableMap::DATABASE_NAME);
}
$criteria = $this;
// Set the correct dbName
$criteria->setDbName(CustomerVatNumberTableMap::DATABASE_NAME);
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
CustomerVatNumberTableMap::removeInstanceFromPool($criteria);
$affectedRows += ModelCriteria::delete($con);
CustomerVatNumberTableMap::clearRelatedInstancePool();
$con->commit();
return $affectedRows;
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
}
} // CustomerVatNumberQuery

View File

@@ -0,0 +1,10 @@
<?php
namespace CustomerVatNumber\Model;
use CustomerVatNumber\Model\Base\CustomerVatNumber as BaseCustomerVatNumber;
class CustomerVatNumber extends BaseCustomerVatNumber
{
}

View File

@@ -0,0 +1,21 @@
<?php
namespace CustomerVatNumber\Model;
use CustomerVatNumber\Model\Base\CustomerVatNumberQuery as BaseCustomerVatNumberQuery;
/**
* Skeleton subclass for performing query and update operations on the 'customer_vat_number' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
*/
class CustomerVatNumberQuery extends BaseCustomerVatNumberQuery
{
} // CustomerVatNumberQuery

View File

@@ -0,0 +1,407 @@
<?php
namespace CustomerVatNumber\Model\Map;
use CustomerVatNumber\Model\CustomerVatNumber;
use CustomerVatNumber\Model\CustomerVatNumberQuery;
use Propel\Runtime\Propel;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\InstancePoolTrait;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\DataFetcher\DataFetcherInterface;
use Propel\Runtime\Exception\PropelException;
use Propel\Runtime\Map\RelationMap;
use Propel\Runtime\Map\TableMap;
use Propel\Runtime\Map\TableMapTrait;
/**
* This class defines the structure of the 'customer_vat_number' table.
*
*
*
* This map class is used by Propel to do runtime db structure discovery.
* For example, the createSelectSql() method checks the type of a given column used in an
* ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
* (i.e. if it's a text column type).
*
*/
class CustomerVatNumberTableMap extends TableMap
{
use InstancePoolTrait;
use TableMapTrait;
/**
* The (dot-path) name of this class
*/
const CLASS_NAME = 'CustomerVatNumber.Model.Map.CustomerVatNumberTableMap';
/**
* The default database name for this class
*/
const DATABASE_NAME = 'thelia';
/**
* The table name for this class
*/
const TABLE_NAME = 'customer_vat_number';
/**
* The related Propel class for this table
*/
const OM_CLASS = '\\CustomerVatNumber\\Model\\CustomerVatNumber';
/**
* A class that can be returned by this tableMap
*/
const CLASS_DEFAULT = 'CustomerVatNumber.Model.CustomerVatNumber';
/**
* The total number of columns
*/
const NUM_COLUMNS = 2;
/**
* The number of lazy-loaded columns
*/
const NUM_LAZY_LOAD_COLUMNS = 0;
/**
* The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS)
*/
const NUM_HYDRATE_COLUMNS = 2;
/**
* the column name for the ID field
*/
const ID = 'customer_vat_number.ID';
/**
* the column name for the VAT_NUMBER field
*/
const VAT_NUMBER = 'customer_vat_number.VAT_NUMBER';
/**
* The default string format for model objects of the related table
*/
const DEFAULT_STRING_FORMAT = 'YAML';
/**
* holds an array of fieldnames
*
* first dimension keys are the type constants
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
self::TYPE_PHPNAME => array('Id', 'VatNumber', ),
self::TYPE_STUDLYPHPNAME => array('id', 'vatNumber', ),
self::TYPE_COLNAME => array(CustomerVatNumberTableMap::ID, CustomerVatNumberTableMap::VAT_NUMBER, ),
self::TYPE_RAW_COLNAME => array('ID', 'VAT_NUMBER', ),
self::TYPE_FIELDNAME => array('id', 'vat_number', ),
self::TYPE_NUM => array(0, 1, )
);
/**
* holds an array of keys for quick access to the fieldnames array
*
* first dimension keys are the type constants
* e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
self::TYPE_PHPNAME => array('Id' => 0, 'VatNumber' => 1, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'vatNumber' => 1, ),
self::TYPE_COLNAME => array(CustomerVatNumberTableMap::ID => 0, CustomerVatNumberTableMap::VAT_NUMBER => 1, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'VAT_NUMBER' => 1, ),
self::TYPE_FIELDNAME => array('id' => 0, 'vat_number' => 1, ),
self::TYPE_NUM => array(0, 1, )
);
/**
* Initialize the table attributes and columns
* Relations are not initialized by this method since they are lazy loaded
*
* @return void
* @throws PropelException
*/
public function initialize()
{
// attributes
$this->setName('customer_vat_number');
$this->setPhpName('CustomerVatNumber');
$this->setClassName('\\CustomerVatNumber\\Model\\CustomerVatNumber');
$this->setPackage('CustomerVatNumber.Model');
$this->setUseIdGenerator(false);
// columns
$this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'customer', 'ID', true, null, null);
$this->addColumn('VAT_NUMBER', 'VatNumber', 'VARCHAR', true, 255, null);
} // initialize()
/**
* Build the RelationMap objects for this table relationships
*/
public function buildRelations()
{
$this->addRelation('Customer', '\\Thelia\\Model\\Customer', RelationMap::MANY_TO_ONE, array('id' => 'id', ), 'CASCADE', 'CASCADE');
} // buildRelations()
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param array $row resultset row.
* @param int $offset The 0-based offset for reading from the resultset row.
* @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME
* TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM
*/
public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM)
{
// If the PK cannot be derived from the row, return NULL.
if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) {
return null;
}
return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)];
}
/**
* Retrieves the primary key from the DB resultset row
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, an array of the primary key columns will be returned.
*
* @param array $row resultset row.
* @param int $offset The 0-based offset for reading from the resultset row.
* @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME
* TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM
*
* @return mixed The primary key of the row
*/
public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM)
{
return (int) $row[
$indexType == TableMap::TYPE_NUM
? 0 + $offset
: self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)
];
}
/**
* The class that the tableMap will make instances of.
*
* If $withPrefix is true, the returned path
* uses a dot-path notation which is translated into a path
* relative to a location on the PHP include_path.
* (e.g. path.to.MyClass -> 'path/to/MyClass.php')
*
* @param boolean $withPrefix Whether or not to return the path with the class name
* @return string path.to.ClassName
*/
public static function getOMClass($withPrefix = true)
{
return $withPrefix ? CustomerVatNumberTableMap::CLASS_DEFAULT : CustomerVatNumberTableMap::OM_CLASS;
}
/**
* Populates an object of the default type or an object that inherit from the default.
*
* @param array $row row returned by DataFetcher->fetch().
* @param int $offset The 0-based offset for reading from the resultset row.
* @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType().
One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME
* TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM.
*
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return array (CustomerVatNumber object, last column rank)
*/
public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM)
{
$key = CustomerVatNumberTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType);
if (null !== ($obj = CustomerVatNumberTableMap::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, $offset, true); // rehydrate
$col = $offset + CustomerVatNumberTableMap::NUM_HYDRATE_COLUMNS;
} else {
$cls = CustomerVatNumberTableMap::OM_CLASS;
$obj = new $cls();
$col = $obj->hydrate($row, $offset, false, $indexType);
CustomerVatNumberTableMap::addInstanceToPool($obj, $key);
}
return array($obj, $col);
}
/**
* The returned array will contain objects of the default type or
* objects that inherit from the default.
*
* @param DataFetcherInterface $dataFetcher
* @return array
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(DataFetcherInterface $dataFetcher)
{
$results = array();
// set the class once to avoid overhead in the loop
$cls = static::getOMClass(false);
// populate the object(s)
while ($row = $dataFetcher->fetch()) {
$key = CustomerVatNumberTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType());
if (null !== ($obj = CustomerVatNumberTableMap::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, 0, true); // rehydrate
$results[] = $obj;
} else {
$obj = new $cls();
$obj->hydrate($row);
$results[] = $obj;
CustomerVatNumberTableMap::addInstanceToPool($obj, $key);
} // if key exists
}
return $results;
}
/**
* Add all the columns needed to create a new object.
*
* Note: any columns that were marked with lazyLoad="true" in the
* XML schema will not be added to the select list and only loaded
* on demand.
*
* @param Criteria $criteria object containing the columns to add.
* @param string $alias optional table alias
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function addSelectColumns(Criteria $criteria, $alias = null)
{
if (null === $alias) {
$criteria->addSelectColumn(CustomerVatNumberTableMap::ID);
$criteria->addSelectColumn(CustomerVatNumberTableMap::VAT_NUMBER);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.VAT_NUMBER');
}
}
/**
* Returns the TableMap related to this object.
* This method is not needed for general use but a specific application could have a need.
* @return TableMap
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getTableMap()
{
return Propel::getServiceContainer()->getDatabaseMap(CustomerVatNumberTableMap::DATABASE_NAME)->getTable(CustomerVatNumberTableMap::TABLE_NAME);
}
/**
* Add a TableMap instance to the database for this tableMap class.
*/
public static function buildTableMap()
{
$dbMap = Propel::getServiceContainer()->getDatabaseMap(CustomerVatNumberTableMap::DATABASE_NAME);
if (!$dbMap->hasTable(CustomerVatNumberTableMap::TABLE_NAME)) {
$dbMap->addTableObject(new CustomerVatNumberTableMap());
}
}
/**
* Performs a DELETE on the database, given a CustomerVatNumber or Criteria object OR a primary key value.
*
* @param mixed $values Criteria or CustomerVatNumber object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param ConnectionInterface $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doDelete($values, ConnectionInterface $con = null)
{
if (null === $con) {
$con = Propel::getServiceContainer()->getWriteConnection(CustomerVatNumberTableMap::DATABASE_NAME);
}
if ($values instanceof Criteria) {
// rename for clarity
$criteria = $values;
} elseif ($values instanceof \CustomerVatNumber\Model\CustomerVatNumber) { // it's a model object
// create criteria based on pk values
$criteria = $values->buildPkeyCriteria();
} else { // it's a primary key, or an array of pks
$criteria = new Criteria(CustomerVatNumberTableMap::DATABASE_NAME);
$criteria->add(CustomerVatNumberTableMap::ID, (array) $values, Criteria::IN);
}
$query = CustomerVatNumberQuery::create()->mergeWith($criteria);
if ($values instanceof Criteria) { CustomerVatNumberTableMap::clearInstancePool();
} elseif (!is_object($values)) { // it's a primary key, or an array of pks
foreach ((array) $values as $singleval) { CustomerVatNumberTableMap::removeInstanceFromPool($singleval);
}
}
return $query->delete($con);
}
/**
* Deletes all rows from the customer_vat_number table.
*
* @param ConnectionInterface $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver).
*/
public static function doDeleteAll(ConnectionInterface $con = null)
{
return CustomerVatNumberQuery::create()->doDeleteAll($con);
}
/**
* Performs an INSERT on the database, given a CustomerVatNumber or Criteria object.
*
* @param mixed $criteria Criteria or CustomerVatNumber object containing data that is used to create the INSERT statement.
* @param ConnectionInterface $con the ConnectionInterface connection to use
* @return mixed The new primary key.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doInsert($criteria, ConnectionInterface $con = null)
{
if (null === $con) {
$con = Propel::getServiceContainer()->getWriteConnection(CustomerVatNumberTableMap::DATABASE_NAME);
}
if ($criteria instanceof Criteria) {
$criteria = clone $criteria; // rename for clarity
} else {
$criteria = $criteria->buildCriteria(); // build Criteria from CustomerVatNumber object
}
// Set the correct dbName
$query = CustomerVatNumberQuery::create()->mergeWith($criteria);
try {
// use transaction because $criteria could contain info
// for more than one table (I guess, conceivably)
$con->beginTransaction();
$pk = $query->doInsert($con);
$con->commit();
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
return $pk;
}
} // CustomerVatNumberTableMap
// This is the static code needed to register the TableMap for this table with the main Propel class.
//
CustomerVatNumberTableMap::buildTableMap();

View File

@@ -0,0 +1,26 @@
# Customer Vat Number
Ce module permet à vos clients d'indiquer leur N° de TVA intracommunautaire au moment de la création de leur compte, ou
lors de la modification de leur profil. Le numéro indiqué par le client est vérifié via une expression régulière pour
s'assurer que son format est valide (voir https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s21.html)
Vous pouvez aussi modifier ou indiquer cette information dans la fiche du client dans le back-office.
Une boucle simple permet de récupérer le N° de TVA d'un client :
```
{loop type="customer-vat-number" name="vat" customer_id=<a customer ID>}
VAT Number : {$VAT_NUMBER}
{/loop}
```
## Intégration
Le module utilise des hooks pour s'intégrer en front-office, en back-office et dans la facture PDF. Il n'y a rien de
particulier à faire.
Attention : en front-office et en back-office, pour cause de manque de hooks, les champs de saisie et d'affichage
sont injectés dans le DOM en Javascript. Si vous modifiez la structure du DOM des pages `register.html`, `account-update.html`
et `account.html` et qu'elle devient différente du template pâr défaut, veillez à adapter le code JS qui injecte le HTML.
Idem pour le back-office dans les pages customers.html et customer-edit.html.

View File

@@ -0,0 +1,11 @@
{
"name": "cqfdev/customer-vat-number-module",
"license": "LGPL-3.0+",
"type": "thelia-module",
"require": {
"thelia/installer": "~1.1"
},
"extra": {
"installer-name": "CustomerVatNumber"
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace CustomerBirthDate\Hook;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
/**
* Class CustomerBirthDateHook
* @package CustomerBirthDate\Hook
* @author Etienne Perriere - OpenStudio <eperriere@openstudio.fr>
*/
class CustomerBirthDateHook extends BaseHook
{
public function addFormFieldInput(HookRenderEvent $event)
{
$event->add($this->render('customer-vat-input.html'));
}
}

View File

@@ -0,0 +1,5 @@
<script>
$(function() {
$('input#lastname').parent().after($('.group-vat-number').removeClass('hidden'));
});
</script>

View File

@@ -0,0 +1,5 @@
<script>
$(function() {
$('input#email').parent().after($('.group-vat-number').removeClass('hidden'));
});
</script>

View File

@@ -0,0 +1,5 @@
<div class="group-vat-number hidden">
{form name=$custVatFormName}
{render_form_field field="vat_number"}
{/form}
</div>

View File

@@ -0,0 +1,15 @@
{loop type="customer-vat-number" name="customer-vat" customer_id=$customer_id}
<div class="vat-number hidden">
<p>
{if $VAT_NUMBER}
{intl l="Your VAT number: %vat" d='customervatnumber.fo.default' vat=$VAT_NUMBER}
{else}
{intl l="You have not entered your VAT number." d='customervatnumber.fo.default'}
{/if}</p>
</div>
<script>
$(function() {
$('.list-info').after($('.vat-number').removeClass('hidden'));
});
</script>
{/loop}

View File

@@ -0,0 +1,3 @@
<script>
$('fieldset#register-info div.panel-body').append($('.group-vat-number').removeClass('hidden'));
</script>

View File

@@ -0,0 +1,3 @@
<script>
$('fieldset#register-info div.panel-body').append($('.group-vat-number').removeClass('hidden'));
</script>

View File

@@ -0,0 +1,14 @@
{form_field field='vat_number'}
<div class="form-group group-vat-number hidden {if $error}has-error{/if}">
<label class="control-label col-sm-3" for="{$label_attr.for}">{$label}{if $required} <span class="required">*</span>{/if}</label>
<div class="control-input col-sm-5">
<input type="text" name="{$name}" id="{$label_attr.for}" class="form-control" maxlength="255" placeholder="{$label_attr.placeholder}" value="{$value}" {if $required} aria-required="true" required{/if}{if !isset($error_focus) && $error} autofocus{/if}>
{if $error}
<span class="help-block">{$message}</span>
{assign var="error_focus" value="true"}
{else}
<span class="help-block">{$label_attr.help}</span>
{/if}
</div>
</div>
{/form_field}