diff --git a/local/modules/FedEx/Config/config.xml b/local/modules/FedEx/Config/config.xml
new file mode 100755
index 00000000..d5ba94b7
--- /dev/null
+++ b/local/modules/FedEx/Config/config.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/local/modules/FedEx/Config/module.xml b/local/modules/FedEx/Config/module.xml
new file mode 100755
index 00000000..43bff63c
--- /dev/null
+++ b/local/modules/FedEx/Config/module.xml
@@ -0,0 +1,18 @@
+
+
+ FedEx\FedEx
+
+ FedEx delivery
+
+
+ Livraison par FedEx
+
+ 1.0.0
+
+ Laurent LE CORRE
+ laurent@thecoredev.fr
+
+ delivery
+ 1.0.0
+ alpha
+
diff --git a/local/modules/FedEx/Config/routing.xml b/local/modules/FedEx/Config/routing.xml
new file mode 100755
index 00000000..30263c8c
--- /dev/null
+++ b/local/modules/FedEx/Config/routing.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ FedEx\Controller\EditPrices::editprices
+
+
+
+ FedEx\Controller\Configuration::editConfiguration
+
+
diff --git a/local/modules/FedEx/Controller/Configuration.php b/local/modules/FedEx/Controller/Configuration.php
new file mode 100755
index 00000000..3a4ea94b
--- /dev/null
+++ b/local/modules/FedEx/Controller/Configuration.php
@@ -0,0 +1,67 @@
+
+ */
+class Configuration extends BaseAdminController
+{
+ public function editConfiguration()
+ {
+ if (null !== $response = $this->checkAuth(
+ AdminResources::MODULE,
+ [FedEx::DOMAIN_NAME],
+ AccessManager::UPDATE
+ )) {
+ return $response;
+ }
+
+ $form = $this->createForm('fedex.configuration');
+ $error_message = null;
+
+ try {
+ $validateForm = $this->validateForm($form);
+ $data = $validateForm->getData();
+
+ FedEx::setConfigValue(
+ FedExConfigValue::TRACKING_URL,
+ $data["tracking_url"]
+ );
+
+ return $this->redirectToConfigurationPage();
+
+ } catch (FormValidationException $e) {
+ $error_message = $this->createStandardFormValidationErrorMessage($e);
+ }
+
+ if (null !== $error_message) {
+ $this->setupFormErrorContext(
+ 'configuration',
+ $error_message,
+ $form
+ );
+ $response = $this->render("module-configure", ['module_code' => 'FedEx']);
+ }
+ return $response;
+ }
+
+ /**
+ * Redirect to the configuration page
+ */
+ protected function redirectToConfigurationPage()
+ {
+ return RedirectResponse::create(URL::getInstance()->absoluteUrl('/admin/module/fedex'));
+ }
+}
diff --git a/local/modules/FedEx/Controller/EditPrices.php b/local/modules/FedEx/Controller/EditPrices.php
new file mode 100755
index 00000000..8c6b5d09
--- /dev/null
+++ b/local/modules/FedEx/Controller/EditPrices.php
@@ -0,0 +1,74 @@
+
+ */
+class EditPrices extends BaseAdminController
+{
+ public function editprices()
+ {
+ // Get data & treat
+ $post = $this->getRequest();
+ $operation = $post->get('operation');
+ $area = $post->get('area');
+ $weight = $post->get('weight');
+ $price = $post->get('price');
+
+ if (preg_match("#^add|delete$#", $operation) &&
+ preg_match("#^\d+$#", $area) &&
+ preg_match("#^\d+\.?\d*$#", $weight)
+ ) {
+ // check if area exists in db
+ $exists = AreaQuery::create()
+ ->findPK($area);
+ if ($exists !== null) {
+
+ if (null !== $data = FedEx::getConfigValue(FedExConfigValue::PRICES, null)) {
+ $json_data = json_decode(
+ $data,
+ true
+ );
+ }
+ if ((float) $weight > 0 && $operation == "add"
+ && preg_match("#\d+\.?\d*#", $price)) {
+ $json_data[$area]['slices'][$weight] = $price;
+ } elseif ($operation == "delete") {
+ if (isset($json_data[$area]['slices'][$weight])) {
+ unset($json_data[$area]['slices'][$weight]);
+ }
+ } else {
+ throw new \Exception("Weight must be superior to 0");
+ }
+ ksort($json_data[$area]['slices']);
+
+ FedEx::setConfigValue(FedExConfigValue::PRICES, json_encode($json_data));
+
+ } else {
+ throw new \Exception("Area not found");
+ }
+ } else {
+ throw new \ErrorException("Arguments are missing or invalid");
+ }
+
+ return $this->redirectToConfigurationPage();
+ }
+
+ /**
+ * Redirect to the configuration page
+ */
+ protected function redirectToConfigurationPage()
+ {
+ return RedirectResponse::create(URL::getInstance()->absoluteUrl('/admin/module/fedex'));
+ }
+}
diff --git a/local/modules/FedEx/FedEx.php b/local/modules/FedEx/FedEx.php
new file mode 100755
index 00000000..6e192bb8
--- /dev/null
+++ b/local/modules/FedEx/FedEx.php
@@ -0,0 +1,163 @@
+insertSql(null, array(__DIR__ . '/Config/thelia.sql'));
+ }
+
+
+ public function isValidDelivery(Country $country, State $state = null)
+ {
+ if (0 == self::getConfigValue(FedExConfigValue::ENABLED, 1)) {
+ return false;
+ }
+
+ if (null !== $area = $this->getAreaForCountry($country, $state)) {
+ $areaId = $area->getId();
+
+ $prices = self::getPrices();
+
+ /* Check if FedEx delivers the area */
+ if (isset($prices[$areaId]) && isset($prices[$areaId]["slices"])) {
+ // Yes ! Check if the cart weight is below slice limit
+ $areaPrices = $prices[$areaId]["slices"];
+ ksort($areaPrices);
+
+ /* Check cart weight is below the maximum weight */
+ end($areaPrices);
+ $maxWeight = key($areaPrices);
+
+ $cartWeight = $this->getRequest()->getSession()->getSessionCart($this->getDispatcher())->getWeight();
+
+ if ($cartWeight <= $maxWeight) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $areaId
+ * @param $weight
+ *
+ * @return mixed
+ * @throws \Thelia\Exception\OrderException
+ */
+ public static function getPostageAmount($areaId, $weight)
+ {
+ $prices = self::getPrices();
+
+ /* check if FedEx delivers the asked area */
+ if (!isset($prices[$areaId]) || !isset($prices[$areaId]["slices"])) {
+ throw new DeliveryException(
+ Translator::getInstance()->trans(
+ "FedEx delivery unavailable for the delivery country",
+ [],
+ self::DOMAIN_NAME
+ )
+ );
+ }
+
+ $areaPrices = $prices[$areaId]["slices"];
+ ksort($areaPrices);
+
+ /* Check cart weight is below the maximum weight */
+ end($areaPrices);
+ $maxWeight = key($areaPrices);
+ if ($weight > $maxWeight) {
+ throw new DeliveryException(
+ Translator::getInstance()->trans(
+ "FedEx delivery unavailable for this cart weight (%weight kg)",
+ array("%weight" => $weight),
+ self::DOMAIN_NAME
+ )
+ );
+ }
+
+ $postage = current($areaPrices);
+
+ while (prev($areaPrices)) {
+ if ($weight > key($areaPrices)) {
+ break;
+ }
+
+ $postage = current($areaPrices);
+ }
+
+ return $postage;
+ }
+
+ /**
+ *
+ * calculate and return delivery price
+ *
+ * @param Country $country
+ * @param State $state
+ * @return mixed
+ */
+ public function getPostage(Country $country, State $state = null)
+ {
+ $cartWeight = $this->getRequest()->getSession()->getSessionCart($this->getDispatcher())->getWeight();
+
+ $postage = self::getPostageAmount(
+ $this->getAreaForCountry($country, $state)->getId(),
+ $cartWeight
+ );
+
+ return $postage;
+ }
+
+ public function update($currentVersion, $newVersion, ConnectionInterface $con = null)
+ {
+ $uploadDir = __DIR__ . '/Config/prices.json';
+
+// $database = new Database($con);
+// $tableExists = $database->execute("SHOW TABLES LIKE 'FedEx_freeshipping'")->rowCount();
+// if (FedEx::getConfigValue(FedExConfigValue::FREE_SHIPPING, null) == null && $tableExists) {
+// $result = $database->execute('SELECT active FROM FedEx_freeshipping WHERE id=1')->fetch()["active"];
+// FedEx::setConfigValue(FedExConfigValue::FREE_SHIPPING, $result);
+// $database->execute("DROP TABLE `FedEx_freeshipping`");
+// }
+
+ if (is_readable($uploadDir) && FedEx::getConfigValue(FedExConfigValue::PRICES, null) == null) {
+ FedEx::setConfigValue(FedExConfigValue::PRICES, file_get_contents($uploadDir));
+ }
+ }
+}
diff --git a/local/modules/FedEx/Form/Configuration.php b/local/modules/FedEx/Form/Configuration.php
new file mode 100644
index 00000000..5cd3d2cf
--- /dev/null
+++ b/local/modules/FedEx/Form/Configuration.php
@@ -0,0 +1,31 @@
+
+ */
+class Configuration extends BaseForm
+{
+ protected function buildForm()
+ {
+ $this->formBuilder
+ ->add(
+ FedEx::TRACKING_URL,
+ 'text',
+ [
+ 'label' => $this->translator->trans('FedEx parcel tracking URL', [], FedEx::DOMAIN_NAME),
+ 'label_attr' => [
+ 'help' => $this->translator->trans('This is the parcel tracking URL for FedEx.', [], FedEx::DOMAIN_NAME)
+ ]
+ ]
+ );
+ }
+}
diff --git a/local/modules/FedEx/Hook/HookManager.php b/local/modules/FedEx/Hook/HookManager.php
new file mode 100644
index 00000000..36a0d853
--- /dev/null
+++ b/local/modules/FedEx/Hook/HookManager.php
@@ -0,0 +1,21 @@
+
+ */
+class HookManager extends BaseHook
+{
+ public function onModuleConfiguration(HookRenderEvent $event)
+ {
+ $module_id = self::getModule()->getModuleId();
+
+ $event->add($this->render("module_configuration.html", ['module_id' => $module_id]));
+ }
+}
diff --git a/local/modules/FedEx/I18n/backOffice/default/en_US.php b/local/modules/FedEx/I18n/backOffice/default/en_US.php
new file mode 100644
index 00000000..d5ecf96c
--- /dev/null
+++ b/local/modules/FedEx/I18n/backOffice/default/en_US.php
@@ -0,0 +1,34 @@
+ '*If you choose this option, the exported orders would not be available on this page anymore',
+ 'Actions' => 'Actions',
+ 'An error occured' => 'An error occured',
+ 'Area : ' => 'Area : ',
+ 'Cancel' => 'Cancel',
+ 'FedEx Module allows to send your products all around the world with FedEx.' => 'FedEx Module allows to send your products all around the world with FedEx.',
+ 'Create' => 'Create',
+ 'Create a new price slice' => 'Create a new price slice',
+ 'Create a price slice' => 'Create a price slice',
+ 'Date' => 'Date',
+ 'Delete' => 'Delete',
+ 'Delete a price slice' => 'Delete a price slice',
+ 'Delete this price slice' => 'Delete this price slice',
+ 'Do not change' => 'Do not change',
+ 'Do you really want to delete this slice ?' => 'Do you really want to delete this slice ?',
+ 'Edit' => 'Edit',
+ 'Edit a price slice' => 'Edit a price slice',
+ 'Edit this price slice' => 'Edit this price slice',
+ 'FedEx parcel tracking URL' => 'FedEx URL for parcel tracking',
+ 'Please change the access rights' => 'Please change the access rights',
+ 'Price (€)' => 'Price (€)',
+ 'Price slices' => 'Price slices',
+ 'Processing' => 'Processing',
+ 'REF' => 'REF',
+ 'Sent' => 'Sent',
+ 'This is the parcel tracking URL for FedEx.' => 'This is the parcel tracking URL for FedEx.',
+ 'Total taxed amount' => 'Total taxed amount',
+ 'Weight up to ... (kg)' => 'Weight up to ... (kg)',
+ 'Number of packages' => 'Number of packages',
+ 'Packages weight' => 'Packages weight'
+);
diff --git a/local/modules/FedEx/I18n/backOffice/default/fr_FR.php b/local/modules/FedEx/I18n/backOffice/default/fr_FR.php
new file mode 100644
index 00000000..95102b7f
--- /dev/null
+++ b/local/modules/FedEx/I18n/backOffice/default/fr_FR.php
@@ -0,0 +1,35 @@
+ '* Si vous choisissez cette option, les commandes exportées ne seront plus affichée sur cette page.',
+ 'Actions' => 'Actions',
+ 'An error occured' => 'Une erreur est survenue',
+ 'Area : ' => 'Zone de livraison : ',
+ 'Cancel' => 'Annuler',
+ 'FedEx Module allows to send your products all around the world with FedEx.' => 'FedEx vous permet d’expédier vos colis dans le monde entier avec FedEx',
+ 'Create' => 'Créer',
+ 'Create a new price slice' => 'Créer une nouvelle tranche de prix',
+ 'Create a price slice' => 'Créer une tranche de prix',
+ 'Customer' => 'Client',
+ 'Date' => 'Date',
+ 'Delete' => 'Supprimer',
+ 'Delete a price slice' => 'Supprimer une tranche de prix',
+ 'Delete this price slice' => 'Supprimer cette tranche de prix',
+ 'Do not change' => 'Ne pas modifier',
+ 'Do you really want to delete this slice ?' => 'Confirmez-vous la suppression de cette tranche de prix',
+ 'Edit' => 'Modifier',
+ 'Edit a price slice' => 'Modifier une tranche de prix',
+ 'Edit this price slice' => 'Modifier cette tranche de prix',
+ 'FedEx parcel tracking URL' => 'URL de suivi des colis FedEx',
+ 'Number of packages' => 'Nombre de colis',
+ 'Packages weight' => 'Poids des colis',
+ 'Please change the access rights' => 'Merci de modifier les droits d\'accès',
+ 'Price (€)' => 'Prix (€)',
+ 'Price slices' => 'Prix et poids',
+ 'Processing' => 'Traitement',
+ 'REF' => 'REF',
+ 'Sent' => 'Envoyée',
+ 'This is the parcel tracking URL for FedEx.' => 'Il s\'agit de l\'URL fournie par FedEx afin de suivre les expéditions de ses colis.',
+ 'Total taxed amount' => 'Total TTC',
+ 'Weight up to ... (kg)' => 'Jusqu\'au poids (Kg)',
+];
diff --git a/local/modules/FedEx/I18n/en_US.php b/local/modules/FedEx/I18n/en_US.php
new file mode 100644
index 00000000..fc14b0c2
--- /dev/null
+++ b/local/modules/FedEx/I18n/en_US.php
@@ -0,0 +1,11 @@
+ 'Can\'t read Config directory',
+ 'Can\'t read file' => 'Can\'t read file',
+ 'Can\'t write Config directory' => 'Can\'t write Config directory',
+ 'Can\'t write file' => 'Can\'t write file',
+ 'FedEx delivery unavailable for the delivery country' => 'FedEx delivery unavailable for the delivery country',
+ 'FedEx delivery unavailable for this cart weight (%weight kg)' => 'FedEx delivery unavailable for this cart weight (%weight kg)',
+ 'select a valid status' => 'Select a valid order status',
+);
diff --git a/local/modules/FedEx/I18n/fr_FR.php b/local/modules/FedEx/I18n/fr_FR.php
new file mode 100644
index 00000000..f7986712
--- /dev/null
+++ b/local/modules/FedEx/I18n/fr_FR.php
@@ -0,0 +1,11 @@
+ 'Le dossier Config ne peut être lu',
+ 'Can\'t read file' => 'Le fichier suivant ne peut être lu',
+ 'Can\'t write Config directory' => 'Le dossier Config ne peut être écrit',
+ 'Can\'t write file' => 'Le fichier suivant ne peut être écrit',
+ 'FedEx delivery unavailable for the delivery country' => 'La livraison par FedEx n\'est pas disponible dans ce pays',
+ 'FedEx delivery unavailable for this cart weight (%weight kg)' => 'La livraison par FedEx n\'est pas disponible pour un panier de %weight Kg',
+ 'select a valid status' => 'Choisissez un statut de commande valide.',
+];
diff --git a/local/modules/FedEx/Listener/SendMail.php b/local/modules/FedEx/Listener/SendMail.php
new file mode 100755
index 00000000..a8e4860d
--- /dev/null
+++ b/local/modules/FedEx/Listener/SendMail.php
@@ -0,0 +1,92 @@
+
+ */
+class SendMail implements EventSubscriberInterface
+{
+ protected $parser;
+ protected $mailer;
+
+ public function __construct(ParserInterface $parser, MailerFactory $mailer)
+ {
+ $this->parser = $parser;
+ $this->mailer = $mailer;
+ }
+
+ public function updateStatus(OrderEvent $event)
+ {
+ $order = $event->getOrder();
+ $FedEx = new FedEx();
+
+ if ($order->isSent() && $order->getDeliveryModuleId() == $FedEx->getModuleModel()->getId()) {
+ $contact_email = ConfigQuery::getStoreEmail();
+
+ if ($contact_email) {
+ $order = $event->getOrder();
+ $customer = $order->getCustomer();
+
+ $this->mailer->sendEmailToCustomer(
+ 'mail_FedEx',
+ $customer,
+ [
+ 'customer_id' => $customer->getId(),
+ 'order_ref' => $order->getRef(),
+ 'order_date' => $order->getCreatedAt(),
+ 'update_date' => $order->getUpdatedAt(),
+ 'package' => $order->getDeliveryRef()
+ ]
+ );
+
+ Tlog::getInstance()->debug("FedEx shipping message sent to customer ".$customer->getEmail());
+ } else {
+ $customer = $order->getCustomer();
+ Tlog::getInstance()->debug("FedEx shipping message no contact email customer_id", $customer->getId());
+ }
+ }
+ }
+
+ /**
+ * Returns an array of event names this subscriber wants to listen to.
+ *
+ * The array keys are event names and the value can be:
+ *
+ * * The method name to call (priority defaults to 0)
+ * * An array composed of the method name to call and the priority
+ * * An array of arrays composed of the method names to call and respective
+ * priorities, or 0 if unset
+ *
+ * For instance:
+ *
+ * * array('eventName' => 'methodName')
+ * * array('eventName' => array('methodName', $priority))
+ * * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
+ *
+ * @return array The event names to listen to
+ *
+ * @api
+ */
+ public static function getSubscribedEvents()
+ {
+ return array(
+ TheliaEvents::ORDER_UPDATE_STATUS => array("updateStatus", 128)
+ );
+ }
+}
diff --git a/local/modules/FedEx/Loop/CheckRightsLoop.php b/local/modules/FedEx/Loop/CheckRightsLoop.php
new file mode 100755
index 00000000..3f3738c2
--- /dev/null
+++ b/local/modules/FedEx/Loop/CheckRightsLoop.php
@@ -0,0 +1,91 @@
+
+ */
+class CheckRightsLoop extends BaseLoop implements ArraySearchLoopInterface
+{
+ protected function getArgDefinitions()
+ {
+ return new ArgumentCollection();
+ }
+
+ public function buildArray()
+ {
+ $ret = array();
+ $dir = __DIR__."/../Config/";
+ if (!is_readable($dir)) {
+
+ $ret[] = array(
+ "ERRMES"=>Translator::getInstance()->trans(
+ "Can't read Config directory",
+ [],
+ FedEx::DOMAIN_NAME
+ ),
+ "ERRFILE"=>""
+ );
+ }
+ if (!is_writable($dir)) {
+ $ret[] = array(
+ "ERRMES"=>Translator::getInstance()->trans(
+ "Can't write Config directory",
+ [],
+ FedEx::DOMAIN_NAME
+ ),
+ "ERRFILE"=>""
+ );
+
+ }
+ if ($handle = opendir($dir)) {
+ while (false !== ($file = readdir($handle))) {
+ if (strlen($file) > 5 && substr($file, -5) === ".json") {
+ if (!is_readable($dir.$file)) {
+
+ $ret[] = array(
+ "ERRMES"=>Translator::getInstance()->trans(
+ "Can't read file",
+ [],
+ FedEx::DOMAIN_NAME
+ ),
+ "ERRFILE"=>"FedEx/Config/".$file
+ );
+ }
+ if (!is_writable($dir.$file)) {
+ $ret[] = array(
+ "ERRMES"=>Translator::getInstance()->trans(
+ "Can't write file",
+ [],
+ FedEx::DOMAIN_NAME
+ ),
+ "ERRFILE"=>"FedEx/Config/".$file
+ );
+
+ }
+ }
+ }
+ }
+ return $ret;
+ }
+ public function parseResults(LoopResult $loopResult)
+ {
+ foreach ($loopResult->getResultDataCollection() as $arr) {
+ $loopResultRow = new LoopResultRow();
+ $loopResultRow->set("ERRMES", $arr["ERRMES"])
+ ->set("ERRFILE", $arr["ERRFILE"]);
+ $loopResult->addRow($loopResultRow);
+ }
+ return $loopResult;
+ }
+}
diff --git a/local/modules/FedEx/Loop/NotSendLoop.php b/local/modules/FedEx/Loop/NotSendLoop.php
new file mode 100644
index 00000000..8d51e786
--- /dev/null
+++ b/local/modules/FedEx/Loop/NotSendLoop.php
@@ -0,0 +1,64 @@
+
+ */
+class NotSendLoop extends Order
+{
+ /**
+ *
+ * define all args used in your loop
+ *
+ *
+ * example :
+ *
+ * public function getArgDefinitions()
+ * {
+ * return new ArgumentCollection(
+ * Argument::createIntListTypeArgument('id'),
+ * new Argument(
+ * 'ref',
+ * new TypeCollection(
+ * new Type\AlphaNumStringListType()
+ * )
+ * ),
+ * Argument::createIntListTypeArgument('category'),
+ * Argument::createBooleanTypeArgument('new'),
+ * Argument::createBooleanTypeArgument('promo'),
+ * Argument::createFloatTypeArgument('min_price'),
+ * Argument::createFloatTypeArgument('max_price'),
+ * Argument::createIntTypeArgument('min_stock'),
+ * Argument::createFloatTypeArgument('min_weight'),
+ * Argument::createFloatTypeArgument('max_weight'),
+ * Argument::createBooleanTypeArgument('current'),
+ *
+ * );
+ * }
+ *
+ * @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection
+ */
+ public function getArgDefinitions()
+ {
+ return new ArgumentCollection(Argument::createBooleanTypeArgument('with_prev_next_info', false));
+ }
+
+ /**
+ * this method returns a Propel ModelCriteria
+ *
+ * @return \Propel\Runtime\ActiveQuery\ModelCriteria
+ */
+ public function buildModelCriteria()
+ {
+ return FedExQuery::getOrders();
+ }
+}
diff --git a/local/modules/FedEx/Loop/Price.php b/local/modules/FedEx/Loop/Price.php
new file mode 100755
index 00000000..fae96efa
--- /dev/null
+++ b/local/modules/FedEx/Loop/Price.php
@@ -0,0 +1,63 @@
+
+ */
+class Price extends BaseLoop implements ArraySearchLoopInterface
+{
+ /* set countable to false since we need to preserve keys */
+ protected $countable = false;
+
+ /**
+ * @return ArgumentCollection
+ */
+ protected function getArgDefinitions()
+ {
+ return new ArgumentCollection(
+ Argument::createIntTypeArgument('area', null, true)
+ );
+ }
+
+ public function buildArray()
+ {
+ $area = $this->getArea();
+ $prices = FedEx::getPrices();
+
+ if (!isset($prices[$area]) || !isset($prices[$area]["slices"])) {
+ return array();
+ }
+
+ $areaPrices = $prices[$area]["slices"];
+ ksort($areaPrices);
+
+ return $areaPrices;
+ }
+
+ public function parseResults(LoopResult $loopResult)
+ {
+ foreach ($loopResult->getResultDataCollection() as $maxWeight => $price) {
+ $loopResultRow = new LoopResultRow();
+ $loopResultRow->set("MAX_WEIGHT", $maxWeight)
+ ->set("PRICE", $price);
+
+ $loopResult->addRow($loopResultRow);
+ }
+ return $loopResult;
+ }
+}
diff --git a/local/modules/FedEx/Model/Config/Base/FedExConfigValue.php b/local/modules/FedEx/Model/Config/Base/FedExConfigValue.php
new file mode 100644
index 00000000..0a97e214
--- /dev/null
+++ b/local/modules/FedEx/Model/Config/Base/FedExConfigValue.php
@@ -0,0 +1,9 @@
+
+ */
+class FedExQuery
+{
+ /**
+ * @return OrderQuery
+ */
+ public static function getOrders()
+ {
+ $status = OrderStatusQuery::create()
+ ->filterByCode(
+ array(
+ OrderStatus::CODE_PAID,
+ OrderStatus::CODE_PROCESSING,
+ ),
+ Criteria::IN
+ )
+ ->find()
+ ->toArray("code");
+
+ $query = OrderQuery::create()
+ ->filterByDeliveryModuleId((new FedEx())->getModuleModel()->getId())
+ ->filterByStatusId(
+ array(
+ $status[OrderStatus::CODE_PAID]['Id'],
+ $status[OrderStatus::CODE_PROCESSING]['Id']),
+ Criteria::IN
+ );
+
+ return $query;
+ }
+}
diff --git a/local/modules/FedEx/templates/backOffice/default/assets/js/module-configuration-js.html b/local/modules/FedEx/templates/backOffice/default/assets/js/module-configuration-js.html
new file mode 100644
index 00000000..bfc91a30
--- /dev/null
+++ b/local/modules/FedEx/templates/backOffice/default/assets/js/module-configuration-js.html
@@ -0,0 +1,38 @@
+{javascripts file="assets/js/bootstrap-switch/bootstrap-switch.js"}
+
+{/javascripts}
+
+
\ No newline at end of file
diff --git a/local/modules/FedEx/templates/backOffice/default/module_configuration.html b/local/modules/FedEx/templates/backOffice/default/module_configuration.html
new file mode 100755
index 00000000..ade518ed
--- /dev/null
+++ b/local/modules/FedEx/templates/backOffice/default/module_configuration.html
@@ -0,0 +1,175 @@
+
+
+ {loop name="checkrights.fedex" type="fedex.check.rights"}
+
+
{$ERRMES} {$ERRFILE} | {intl d='fedex.bo.default' l="Please change the access rights"}.
+
+ {/loop}
+
+
+{elseloop rel="checkrights.fedex"}
+
+
+
{intl d='fedex.bo.default' l="FedEx Module allows to send your products all around the world with FedEx."}
+
+
+
+
+
+
+
+ {form name="fedex.configuration"}
+
+ {/form}
+
+
+
+
+
+{/elseloop}