Premiers écrans sur module PointRetrait

This commit is contained in:
2021-02-26 21:10:10 +01:00
parent 86d849a059
commit 1276d9bf3d
34 changed files with 1200 additions and 100 deletions

View File

@@ -21,7 +21,6 @@
<hooks>
<hook id="lps.admin.hook" class="LivraisonParSecteurs\Hook\AdminHook">
<tag name="hook.event_listener" event="main.in-top-menu-items" type="back" method="onMainTopMenuTools" />
<!-- <tag name="hook.event_listener" event="module.configuration" type="back" method="onModuleConfig" />-->
<tag name="hook.event_listener" event="order-edit.bill-delivery-address" type="back" method="displayDeliveryDate" />
<tag name="hook.event_listener" event="home.block" type="back" method="displayScheduledDeliveries" />
<argument type="service" id="thelia.securityContext"/>

View File

@@ -0,0 +1,2 @@
# Sqlfile -> Database map
thelia.sql=thelia

View File

@@ -0,0 +1,72 @@
# 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;
-- ---------------------------------------------------------------------
-- lps_area
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `lps_area`;
CREATE TABLE `lps_area`
(
`id` INTEGER NOT NULL,
`title` VARCHAR(50) NOT NULL,
`active` TINYINT DEFAULT 1 NOT NULL,
`price` FLOAT DEFAULT 0 NOT NULL,
`minimum_amount` FLOAT DEFAULT 15 NOT NULL,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- ---------------------------------------------------------------------
-- lps_area_city
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `lps_area_city`;
CREATE TABLE `lps_area_city`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`id_area` INTEGER NOT NULL,
`zipcode` VARCHAR(10) NOT NULL,
`title` VARCHAR(50) NOT NULL,
`latitude` DOUBLE,
`longitude` DOUBLE,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),
INDEX `fi_area_area_city` (`id_area`),
CONSTRAINT `fk_area_area_city`
FOREIGN KEY (`id_area`)
REFERENCES `lps_area` (`id`)
ON DELETE CASCADE
) ENGINE=InnoDB;
-- ---------------------------------------------------------------------
-- lps_area_schedule
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `lps_area_schedule`;
CREATE TABLE `lps_area_schedule`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`id_area` INTEGER NOT NULL,
`day` INTEGER NOT NULL,
`begin_time` TIME NOT NULL,
`end_time` TIME NOT NULL,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),
INDEX `fi_area_area_schedule` (`id_area`),
CONSTRAINT `fk_area_area_schedule`
FOREIGN KEY (`id_area`)
REFERENCES `lps_area` (`id`)
ON DELETE CASCADE
) ENGINE=InnoDB;
# This restores the fkey checks, after having unset them earlier
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -26,6 +26,15 @@ class GeneralForm extends BaseForm
"required" => true,
"constraints" => [new Constraints\NotBlank()]
])
->add(
"title",
"text",
[
"required" => true,
"constraints" => [new Constraints\NotBlank(), new Constraints\NotNull()],
"label" => $this->translator->trans('Area name', [], LivraisonParSecteurs::DOMAIN_NAME),
"label_attr" => ['for' => 'title']
])
->add(
"price",
"number",

View File

@@ -87,7 +87,7 @@ class AdminHook extends BaseHook
"id" => "block-scheduled-deliveries",
"title" => $this->trans("Scheduled deliveries", [], LivraisonParSecteurs::DOMAIN_NAME),
"content" => $content,
"class" => "col-md-8"
"class" => "col-md-6"
]);
}
}

View File

@@ -26,7 +26,7 @@ return array(
'General' => 'Général',
'Home delivery cost' => 'Frais de livraison à domicile',
'Message info minimum de commande' => 'Un panier d\'un montant minimum de %montant € est nécessaire pour pouvoir bénéficier de la livraison à domicile.',
'Minimum amount' => 'Montant minimum de commande',
'Minimum amount' => 'Minimum de commande',
'Modify a delivery day' => 'Modifier un jour de livraison',
'Module name' => 'Livraison à domicile',
'My areas' => 'Mes secteurs de livraison',
@@ -42,12 +42,12 @@ return array(
'There is no order to deliver' => 'Aucune commande à livrer à domicile',
'There is no schedule for this area' => 'Aucune livraison actuellement sur ce secteur',
'Title of config view' => 'Livraison à domicile - Configuration',
'Zipcode' => 'Code postal',
'Monday' => 'Lundi',
'Zipcode' => 'Code postal', 'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'Dimanche',
);

View File

@@ -7,7 +7,6 @@ use LivraisonParSecteurs\Model\LpsAreaCityQuery;
use LivraisonParSecteurs\Model\LpsAreaQuery;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Propel;
use Symfony\Component\Form\FormError;
use Thelia\Core\Translation\Translator;
use Thelia\Install\Database;
use Thelia\Model\AddressQuery;
@@ -82,7 +81,6 @@ class LivraisonParSecteurs extends AbstractDeliveryModule
}
}
}
$isValid = true;
return $isValid;
}

View File

@@ -1,4 +1,4 @@
{extends file="admin-layout.tpl"}
mais{extends file="admin-layout.tpl"}
{block name="no-return-functions"}
{$admin_current_location = 'module'}

View File

@@ -1,4 +1,10 @@
{form name='lps-area-general-update'}
<style>
.etroit { width: 80px !important; }
.large { width: 250px !important; }
</style>
<div class="form-container">
{if $form_error}
@@ -24,6 +30,18 @@
<div class="row form-inline">
<div class="col-md-3">
{form_field form=$form field="title"}
<div class="form-group">
<label class="control-label" for="{$label_attr.for}">
{intl l=$label d='livraisonparsecteurs'}
</label>
<input type="text" id="{$label_attr.for}" class="form-control large" name="{$name}" value="{$TITLE}" {if $required}required{/if} />&nbsp
</div>
{form_error form=$form field="title"}{$message}{/form_error}
{/form_field}
</div>
<div class="col-md-2">
{form_field form=$form field="active"}
<div class="form-group">
<label class="control-label" for="{$label_attr.for}">
@@ -40,7 +58,7 @@
{/form_field}
</div>
<div class="col-md-3">
<div class="col-md-2">
{form_field form=$form field="price"}
<div class="form-group form-inline">
<label class="control-label" for="{$label_attr.for}">
@@ -48,7 +66,7 @@
{if $required}<span class="required">*</span>{/if}
</label>
<input type="text" id="{$label_attr.for}" class="form-control" name="{$name}" value="{$PRICE}" {if $required}required{/if} />&nbsp;
<input type="text" id="{$label_attr.for}" class="form-control etroit" name="{$name}" value="{$PRICE}" {if $required}required{/if} />&nbsp;
</div>
{form_error form=$form field="price"}{$message}{/form_error}
{/form_field}
@@ -62,14 +80,12 @@
{if $required}<span class="required">*</span>{/if}
</label>
<input type="text" id="{$label_attr.for}" class="form-control" name="{$name}" value="{$MINIMUM_AMOUNT}" {if $required}required{/if} />&nbsp;
<input type="text" id="{$label_attr.for}" class="form-control etroit" name="{$name}" value="{$MINIMUM_AMOUNT}" {if $required}required{/if} />&nbsp;
</div>
{form_error form=$form field="minimum_amount"}{$message}{/form_error}
{/form_field}
</div>
<div class="col-md-2">&nbsp;</div>
</div>
</form>
{/loop}

View File

@@ -16,7 +16,6 @@
</style>
{loop type="auth" name="can_view" role="ADMIN" module="HookAdminHome" access="VIEW"}
<div class="scheduled-deliveries-list">
<table class="table table-striped">
<thead>
@@ -28,7 +27,7 @@
<th>{intl l="Area" d="livraisonparsecteurs"}</th>
</thead>
<tbody>
{loop name="deliveries-loop" type="scheduled_deliveries" order="date"}
{loop name="deliveries-loop" type="scheduled_deliveries" domicile_ou_retrait="domicile" only_future="true" order="date"}
{if $DELTA <= 7}
{assign var=path value="{image file='/assets/img/flag-green.png'}"}
{assign var=alt value='Drapeau vert'}
@@ -84,4 +83,3 @@
<span class="nb-commandes">Total :&nbsp;&nbsp;<b>{$nbCommandes}</b>&nbsp;&nbsp;commande(s)</span>
</div>
{/loop}

View File

@@ -1,9 +1,10 @@
<database defaultIdMethod="native" name="thelia" namespace="PlanificationLivraison\Model">
<table name="order_delivery_schedule">
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" />
<column name="id" autoIncrement="true" primaryKey="true" required="true" type="INTEGER" />
<column name="order_id" type="INTEGER" />
<column name="delivery_address_id" required="true" type="INTEGER" />
<column name="delivery_address_id" required="false" type="INTEGER" />
<column name="delivery_place_id" required="false" type="INTEGER" />
<column name="schedule_id" required="true" type="INTEGER" />
<column name="due_delivery_time_start" required="true" type="TIMESTAMP" />
@@ -15,6 +16,9 @@
<foreign-key foreignTable="order_address" name="fk_order_delivery_address_id">
<reference foreign="id" local="delivery_address_id" />
</foreign-key>
<foreign-key foreignTable="pdr_places" name="fk_order_delivery_place_id">
<reference foreign="id" local="delivery_place_id" />
</foreign-key>
<foreign-key foreignTable="lps_area_schedule" name="fk_order_delivery_schedule_id">
<reference foreign="id" local="schedule_id" />
</foreign-key>
@@ -22,5 +26,6 @@
</table>
<external-schema filename="local/config/schema.xml" referenceOnly="true" />
<external-schema filename="local/modules/LivraisonParSecteurs/Config/schema.xml" referenceOnly="true" />
<external-schema filename="local/modules/PointRetrait/Config/schema.xml" referenceOnly="true" />
</database>

View File

@@ -13,13 +13,15 @@ CREATE TABLE `order_delivery_schedule`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`order_id` INTEGER,
`delivery_address_id` INTEGER NOT NULL,
`delivery_address_id` INTEGER,
`delivery_place_id` INTEGER,
`schedule_id` INTEGER NOT NULL,
`due_delivery_time_start` DATETIME NOT NULL,
`due_delivery_time_end` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `fi_order_delivery_schedule_order_id` (`order_id`),
INDEX `fi_order_delivery_address_id` (`delivery_address_id`),
INDEX `fi_order_delivery_place_id` (`delivery_place_id`),
INDEX `fi_order_delivery_schedule_id` (`schedule_id`),
CONSTRAINT `fk_order_delivery_schedule_order_id`
FOREIGN KEY (`order_id`)
@@ -27,6 +29,9 @@ CREATE TABLE `order_delivery_schedule`
CONSTRAINT `fk_order_delivery_address_id`
FOREIGN KEY (`delivery_address_id`)
REFERENCES `order_address` (`id`),
CONSTRAINT `fk_order_delivery_place_id`
FOREIGN KEY (`delivery_place_id`)
REFERENCES `pdr_places` (`id`),
CONSTRAINT `fk_order_delivery_schedule_id`
FOREIGN KEY (`schedule_id`)
REFERENCES `lps_area_schedule` (`id`)

View File

@@ -4,6 +4,7 @@ namespace PlanificationLivraison\Loop;
use DateTime;
use PlanificationLivraison\Model\OrderDeliveryScheduleQuery;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
@@ -17,9 +18,12 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
*/
class ScheduledDeliveriesLoop extends BaseLoop implements PropelSearchLoopInterface
{
public $countable = true;
const DOMICILE = "domicile";
const RETRAIT = "retrait";
public $countable = true;
/**
* @param LoopResult $loopResult
*
@@ -35,22 +39,30 @@ class ScheduledDeliveriesLoop extends BaseLoop implements PropelSearchLoopInterf
$loopResultRow
->set("ORDER_ID", $deliveries->getOrderId())
->set("ADDRESS_ID", $deliveries->getDeliveryAddressId())
->set("PLACE_ID", $deliveries->getDeliveryPlaceId())
->set("SCHEDULE_ID", $deliveries->getScheduleId())
->set("START_DATE", $deliveries->getDueDeliveryTimeStart())
->set("END_DATE", $deliveries->getDueDeliveryTimeEnd())
->set("DELTA", $delta->days)
->set("SCHEDULE_ID", $deliveries->getScheduleId())
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
/**
* @inheritdoc
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createEnumListTypeArgument('domicile_ou_retrait', [
self::DOMICILE,
self::RETRAIT
], self::DOMICILE),
Argument::createBooleanTypeArgument('only_future', true),
Argument::createEnumListTypeArgument('order', [
'date',
'date-reverse'
@@ -64,9 +76,35 @@ class ScheduledDeliveriesLoop extends BaseLoop implements PropelSearchLoopInterf
public function buildModelCriteria()
{
$deliveries = OrderDeliveryScheduleQuery::create();
$deliveries->filterByDueDeliveryTimeStart(array('min' => time()))->find();
return $deliveries->orderByDueDeliveryTimeStart();
foreach ($this->getDomicileOuRetrait() as $parametre) {
switch ($parametre) {
case self::DOMICILE:
$deliveries->filterByDeliveryAddressId(null, Criteria::NOT_EQUAL);
break;
case self::RETRAIT:
$deliveries->filterByDeliveryPlaceId(null, Criteria::NOT_EQUAL);
break;
}
}
if ($this->getOnlyFuture())
$deliveries->filterByDueDeliveryTimeStart(array('min' => time()))->find();
else
$deliveries->filterByDueDeliveryTimeStart(array('max' => time()))->find();
foreach ($this->getOrder() as $parametre) {
switch ($parametre) {
case 'date':
$deliveries->orderByDueDeliveryTimeStart(Criteria::ASC);
break;
case 'date-reverse':
$deliveries->orderByDueDeliveryTimeStart(Criteria::DESC);
break;
}
}
return $deliveries;
}
}

View File

@@ -4,31 +4,21 @@
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">
<hooks>
<hook id="pdr.admin.hook" class="PointRetrait\Hook\AdminHook">
<tag name="hook.event_listener" event="home.block" type="back" method="displayScheduledWithdrawals" />
<tag name="hook.event_listener" event="main.in-top-menu-items" type="back" method="onMainTopMenuTools" />
<argument type="service" id="thelia.securityContext"/>
</hook>
</hooks>
<loops>
<!-- sample definition
<loop name="MySuperLoop" class="PointRetrait\Loop\MySuperLoop" />
-->
<loop name="pdr_places" class="PointRetrait\Loop\GeneralLoop"/>
<loop name="pdr_schedule" class="PointRetrait\Loop\ScheduleLoop"/>
</loops>
<forms>
<!--
<form name="MyFormName" class="PointRetrait\Form\MySuperForm" />
-->
<form name="pdr-place-main-update" class="PointRetrait\Form\MainForm"/>
</forms>
<!--
<services>
</services>
-->
<!--
<hooks>
<hook id="pointretrait.hook" class="PointRetrait\Hook\MySuperHook">
<tag name="hook.event_listener" event="main.body.bottom" type="front|back|pdf|email" method="onMainBodyBottom" />
</hook>
</hooks>
-->
</config>

View File

@@ -4,28 +4,17 @@
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">
<!--
if a /admin/module/pointretrait/ route is provided, a "Configuration" button will be displayed
for the module in the module list. Clicking this button will invoke this route.
<route id="my_route_id" path="/admin/module/pointretrait">
<default key="_controller">PointRetrait\Full\Class\Name\Of\YourConfigurationController::methodName</default>
<route id="pointretrait.places.list" path="/admin/module/PointRetrait">
<default key="_controller">PointRetrait\Controller\backOffice\ListController::viewAction</default>
</route>
<route id="pointretrait.toggle.active" path="/admin/module/PointRetrait/toggle-online/{id}" methods="post">
<default key="_controller">PointRetrait\Controller\backOffice\ListController::toggleActive</default>
<requirement key="id">\d+</requirement>
</route>
<route id="my_route_id" path="/admin/module/pointretrait/route-name">
<default key="_controller">PointRetrait\Full\Class\Name\Of\YourAdminController::methodName</default>
<route id="pointretrait.place.view" path="/admin/module/PointRetrait/edit" methods="get">
<default key="_controller">PointRetrait\Controller\backOffice\PlaceController::viewPlace</default>
</route>
<route id="my_route_id" path="/my/route/name">
<default key="_controller">PointRetrait\Full\Class\Name\Of\YourOtherController::methodName</default>
</route>
...add as many routes as required.
<route>
...
</route>
-->
</routes>

View File

@@ -2,24 +2,34 @@
<database defaultIdMethod="native" name="thelia"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../core/vendor/thelia/propel/resources/xsd/database.xsd" >
<!--
See propel documentation on http://propelorm.org for all information about schema file
<table name="product_rel" namespace="PointRetrait\Model">
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" />
<column defaultValue="0" name="visible" required="true" type="TINYINT" />
<column defaultValue="0" name="position" required="true" type="INTEGER" />
<column name="title" size="255" type="VARCHAR" />
<column name="description" type="CLOB" />
<column name="chapo" type="LONGVARCHAR" />
<column name="postscriptum" type="LONGVARCHAR" />
<foreign-key foreignTable="product" name="fk_product_id" onDelete="CASCADE" onUpdate="RESTRICT">
<reference foreign="id" local="product_id" />
</foreign-key>
<behavior name="timestampable" />
<behavior name="i18n">
<parameter name="i18n_columns" value="title, description, chapo, postscriptum" />
</behavior>
<table name="pdr_places" namespace="PointRetrait\Model">
<column name="id" autoIncrement="true" primaryKey="true" required="true" type="INTEGER" />
<column name="title" required="true" size="50" type="VARCHAR" />
<column name="active" required="true" type="TINYINT" defaultValue="1" />
<column name="price" required="true" type="FLOAT" defaultValue="0" />
<column name="minimum_amount" required="true" type="FLOAT" defaultValue="0" />
<column name="latitude" required="false" type="DOUBLE" />
<column name="longitude" required="false" type="DOUBLE" />
<column name="address1" size="255" type="VARCHAR" required="true"/>
<column name="address2" size="255" type="VARCHAR"/>
<column name="address3" size="255" type="VARCHAR"/>
<column name="zipcode" required="true" size="10" type="VARCHAR"/>
<column name="city" required="true" size="255" type="VARCHAR"/>
</table>
-->
<table name="pdr_schedule" namespace="PointRetrait\Model">
<column autoIncrement="true" name="id" primaryKey="true" required="true" type="INTEGER" />
<column name="id_place" required="true" type="INTEGER" />
<column name="day" required="true" type="INTEGER" />
<column name="begin_time" required="true" type="TIME" />
<column name="end_time" required="true" type="TIME" />
<foreign-key foreignTable="pdr_places" name="fk_places_schedule" onDelete="CASCADE">
<reference foreign="id" local="id_place"/>
</foreign-key>
</table>
</database>

View File

@@ -0,0 +1,2 @@
# Sqlfile -> Database map
thelia.sql=thelia

View File

@@ -0,0 +1,51 @@
# 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;
-- ---------------------------------------------------------------------
-- pdr_places
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `pdr_places`;
CREATE TABLE `pdr_places`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(50) NOT NULL,
`active` TINYINT DEFAULT 1 NOT NULL,
`price` FLOAT DEFAULT 0 NOT NULL,
`minimum_amount` FLOAT DEFAULT 0 NOT NULL,
`latitude` DOUBLE,
`longitude` DOUBLE,
`address1` VARCHAR(255) NOT NULL,
`address2` VARCHAR(255),
`address3` VARCHAR(255),
`zipcode` VARCHAR(10) NOT NULL,
`city` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- ---------------------------------------------------------------------
-- pdr_schedule
-- ---------------------------------------------------------------------
DROP TABLE IF EXISTS `pdr_schedule`;
CREATE TABLE `pdr_schedule`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`id_place` INTEGER NOT NULL,
`day` INTEGER NOT NULL,
`begin_time` TIME NOT NULL,
`end_time` TIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `fi_places_schedule` (`id_place`),
CONSTRAINT `fk_places_schedule`
FOREIGN KEY (`id_place`)
REFERENCES `pdr_places` (`id`)
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,86 @@
<?php
namespace PointRetrait\Form;
use PointRetrait\PointRetrait;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
use Thelia\Form\BaseForm;
/**
* Class MainForm
* @package PointRetrait\Form
*/
class MainForm extends BaseForm
{
/**
* @inheritDoc
*/
protected function buildForm()
{
$this->formBuilder
->add(
"place_id",
"integer",
[
"required" => true,
"constraints" => [new Constraints\NotBlank()]
])
->add(
"title",
"text",
[
"required" => true,
"constraints" => [new Constraints\NotBlank(), new Constraints\NotNull()],
"label" => $this->translator->trans('Place', [], PointRetrait::DOMAIN_NAME),
"label_attr" => ['for' => 'title']
])
->add(
"price",
"number",
[
"required" => true,
"constraints" => [new GreaterThanOrEqual(["value" => 0])],
"label" => $this->translator->trans('Withdrawal price', [], PointRetrait::DOMAIN_NAME),
"label_attr" => ['for' => 'price']
])
->add(
"minimum_amount",
"number",
[
"required" => true,
"constraints" => [new GreaterThanOrEqual(["value" => 0])],
"label" => $this->translator->trans('Minimum amount', [], PointRetrait::DOMAIN_NAME),
"label_attr" => ['for' => 'minimum_amount']
])
->add("latitude", "number", [
"label" => $this->translator->trans("Latitude", [], PointRetrait::MESSAGE_DOMAIN),
"label_attr" => ["for" => "latitude"],
"required" => false
])
->add("longitude", "number", [
"label" => $this->translator->trans("Longitude", [], PointRetrait::MESSAGE_DOMAIN),
"label_attr" => ["for" => "longitude"],
"required" => false
])
->add(
"active",
"number",
[
"required" => true,
"constraints" => [new Constraints\NotBlank()],
"label" => $this->translator->trans('Active', [], PointRetrait::DOMAIN_NAME),
"label_attr" => ['for' => 'active']
]
);
}
/**
* @inheritDoc
*/
public function getName()
{
return "pdr-place-main-update";
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace PointRetrait\Hook;
use PointRetrait\PointRetrait;
use Thelia\Core\Event\Hook\HookRenderBlockEvent;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\SecurityContext;
/**
* Class AdminHook
*/
class AdminHook extends BaseHook
{
protected $securityContext;
public function __construct(SecurityContext $securityContext)
{
$this->securityContext = $securityContext;
}
public function onMainTopMenuTools(HookRenderEvent $event)
{
$isGranted = $this->securityContext->isGranted(
["ADMIN"],
[],
[PointRetrait::getModuleCode()],
[AccessManager::VIEW]
);
if ($isGranted) {
$event->add($this->render("menu-hook.html", $event->getArguments()));
}
}
/* Pour afficher la liste des retraits en Point Retrait prévus dans la page d'accueil backOffice */
public function displayScheduledWithdrawals(HookRenderBlockEvent $event)
{
$content = trim($this->render("scheduled-withdrawals.html"));
if (!empty($content)) {
$event->add([
"id" => "block-scheduled-withdrawals",
"title" => $this->trans("Scheduled withdrawals", [], PointRetrait::DOMAIN_NAME),
"content" => $content,
"class" => "col-md-6"
]);
}
}
}

View File

@@ -1,4 +1,29 @@
<?php
return array(
// 'an english string' => 'La traduction française de la chaine',
);
'Active' => 'Actif',
'Delivery delay' => 'Délai avant retrait',
'Edit a place' => 'Modifier un lieu de retrait',
'Location set' => 'Coordonnées GPS présentes ?',
'Main' => 'Généralités',
'Minimum amount' => 'Minimum de commande',
'Module name' => 'Point de Retrait AuxBieauxLegumes',
'My places' => 'Point de retrait AuxBieauxLegumes',
'My withdrawal places' => 'Mes points de retrait AuxBieauxLegumes',
'Order number' => 'N° de commande',
'Place' => 'Lieu de retrait',
'Schedule' => 'Horaires de retrait',
'Scheduled date' => 'Date de retrait prévue',
'Scheduled withdrawals' => 'Commandes à retirer en Point Retrait',
'Title of config view' => 'Point retrait AuxBieauxLegumes - Configuration',
'There is no order to withdraw' => 'Aucune commande à retirer en Point Retrait',
'Withdrawal days' => 'Jours de retrait',
'Withdrawal price' => 'Coût du retrait',
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'Dimanche',
'' => '',
);

View File

@@ -0,0 +1,89 @@
<?php
namespace PointRetrait\Loop;
use PointRetrait\Model\PdrPlacesQuery;
use PointRetrait\Model\PdrScheduleQuery;
use PointRetrait\PointRetrait;
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 GeneralLoop
* @package LivraisonParSecteurs\Loop
*/
class GeneralLoop extends BaseLoop implements PropelSearchLoopInterface
{
public $countable = false;
public $timestampable = false;
public $versionable = false;
/**
* @param LoopResult $loopResult
*
* @return LoopResult
*/
public function parseResults(LoopResult $loopResult)
{
foreach ($loopResult->getResultDataCollection() as $places) {
$loopResultRow = new LoopResultRow($places);
$schedule = PdrScheduleQuery::create()->findById($places->getId());
$deliveryDays = "";
foreach ($schedule as $day) {
$deliveryDays .= PointRetrait::getDayLabel($day->getDay()) . ', ';
}
$deliveryDays = substr($deliveryDays, 0, strlen($deliveryDays)-2);
$loopResultRow
->set("ID", $places->getId())
->set("TITLE", $places->getTitle())
->set("ACTIVE", $places->getActive())
->set("PRICE", $places->getPrice())
->set("MINIMUM_AMOUNT", $places->getMinimumAmount())
->set("DELIVERY_DAYS", $deliveryDays)
->set("LATITUDE", $places->getLatitude())
->set("LONGITUDE", $places->getLongitude())
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
/**
* @inheritdoc
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
Argument::createIntListTypeArgument('active')
);
}
/**
* @inheritdoc
*/
public function buildModelCriteria()
{
$places = PdrPlacesQuery::create();
/* Filtrage éventuel */
if (null != $id = $this->getId()) {
$places->filterById($id);
}
if (null != $active = $this->getActive()) {
$places->filterByActive($active);
}
return $places->orderByTitle();
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace PointRetrait\Loop;
use PointRetrait\Model\PdrScheduleQuery;
use PointRetrait\PointRetrait;
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 ScheduleLoop
* @package PointRetrait\Loop
*/
class ScheduleLoop extends BaseLoop implements PropelSearchLoopInterface
{
public $countable = false;
public $timestampable = false;
public $versionable = false;
/**
* @param LoopResult $loopResult
*
* @return LoopResult
*/
public function parseResults(LoopResult $loopResult)
{
foreach ($loopResult->getResultDataCollection() as $pdr_schedule) {
$loopResultRow = new LoopResultRow($pdr_schedule);
$loopResultRow
->set("ID", $pdr_schedule->getId())
->set("PLACE_ID", $pdr_schedule->getIdArea())
->set("DAY", $pdr_schedule->getDay())
->set("DAY_LABEL", PointRetrait::getDayLabel($pdr_schedule->getDay()))
->set("BEGIN", $pdr_schedule->getBeginTime())
->set("END", $pdr_schedule->getEndTime())
;
$loopResult->addRow($loopResultRow);
}
return $loopResult;
}
/**
* @inheritdoc
*/
protected function getArgDefinitions()
{
return new ArgumentCollection(
Argument::createIntListTypeArgument('id'),
Argument::createIntListTypeArgument('place_id')
);
}
/**
* @inheritdoc
*/
public function buildModelCriteria()
{
$places = PdrScheduleQuery::create();
if (null != $id = $this->getId()) {
$places->filterById($id);
}
if (null != $id = $this->getPlaceId()) {
$places->filterByIdPlace($id);
}
return $places->orderByDay()->orderByBeginTime();
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PointRetrait\Model;
use PointRetrait\Model\Base\PdrPlaces as BasePdrPlaces;
/**
* Skeleton subclass for representing a row from the 'pdr_places' 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 PdrPlaces extends BasePdrPlaces
{
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PointRetrait\Model;
use PointRetrait\Model\Base\PdrPlacesQuery as BasePdrPlacesQuery;
/**
* Skeleton subclass for performing query and update operations on the 'pdr_places' 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 PdrPlacesQuery extends BasePdrPlacesQuery
{
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PointRetrait\Model;
use PointRetrait\Model\Base\PdrSchedule as BasePdrSchedule;
/**
* Skeleton subclass for representing a row from the 'pdr_schedule' 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 PdrSchedule extends BasePdrSchedule
{
}

View File

@@ -0,0 +1,20 @@
<?php
namespace PointRetrait\Model;
use PointRetrait\Model\Base\PdrScheduleQuery as BasePdrScheduleQuery;
/**
* Skeleton subclass for performing query and update operations on the 'pdr_schedule' 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 PdrScheduleQuery extends BasePdrScheduleQuery
{
}

View File

@@ -1,28 +1,98 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace PointRetrait;
use Thelia\Module\BaseModule;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Propel;
use Thelia\Core\Translation\Translator;
use Thelia\Install\Database;
use Thelia\Model\Country;
use Thelia\Model\OrderPostage;
use Thelia\Module\AbstractDeliveryModule;
use Thelia\Module\Exception\DeliveryException;
class PointRetrait extends BaseModule
class PointRetrait extends AbstractDeliveryModule
{
/** @var string */
const DOMAIN_NAME = 'pointretrait';
const MESSAGE_DOMAIN = 'pointretrait';
/*
* You may now override BaseModuleInterface methods, such as:
* install, destroy, preActivation, postActivation, preDeactivation, postDeactivation
*
* Have fun !
/**
* @param ConnectionInterface|null $con
*/
public function postActivation(ConnectionInterface $con = null)
{
$database = new Database($con->getWrappedConnection());
$database->insertSql(null, array(__DIR__ . '/Config/thelia.sql'));
}
/**
* This method is called by the Delivery loop, to check if the current module has to be displayed to the customer.
* Override it to implements your delivery rules/
*
* If you return true, the delivery method will de displayed to the customer
* If you return false, the delivery method will not be displayed
*
* @param Country $country the country to deliver to.
*
* @return boolean
*/
public function isValidDelivery(Country $country)
{
return true;
}
/**
* Calculate and return delivery price in the shop's default currency
*
* @param Country $country the country to deliver to.
*
* @return OrderPostage|float the delivery price
* @throws DeliveryException if the postage price cannot be calculated.
*/
public function getPostage(Country $country)
{
if (! $this->isValidDelivery($country)) {
throw new DeliveryException(
Translator::getInstance()->trans("This module cannot be used on the current cart.")
);
}
$price = 0;
$con = Propel::getConnection();
// $currentAddressId = $this->getRequest()->getSession()->getOrder()->getChoosenDeliveryAddress();
// if (!empty($currentAddressId)) {
// $zipcode = AddressQuery::create()->filterById($currentAddressId)->findOne($con)->getZipcode();
// $areaId = LpsAreaCityQuery::create()->findOneByZipcode($zipcode)->getIdArea();
// $price = LpsAreaQuery::create()->findOneById($areaId)->getPrice();
// }
return $price;
}
static public function getDayLabel($int)
{
$translator = Translator::getInstance();
$days = [
$translator->trans("Monday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Tuesday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Wednesday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Thursday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Friday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Saturday", [], PointRetrait::MESSAGE_DOMAIN),
$translator->trans("Sunday", [], PointRetrait::MESSAGE_DOMAIN)
];
if ($int === null)
return $days;
else
return $days[$int];
}
}

View File

@@ -0,0 +1,151 @@
<style>
.etroit { width: 80px !important; }
.large { width: 250px !important; }
.custom-map-control-button {
appearance: button;
background-color: #fff;
border: 0;
border-radius: 2px;
box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
cursor: pointer;
margin: 10px;
padding: 0 0.5em;
height: 40px;
font: 400 18px Roboto, Arial, sans-serif;
overflow: hidden;
}
.custom-map-control-button:hover {
background: #ebebeb;
}
.locationMap {
height:600px;
width:100%;
margin-top: 20px;
}
.city-remove {
height: 30px !important;
}
.pin {
height: 25px;
margin-left: 12px;
}
.legende {
margin-top: 25px;
text-align: center;
font-style: italic;
}
</style>
{form name='pdr-place-main-update'}
<div class="form-container">
{if $form_error}
<div class="alert alert-danger">{$form_error_message}</div>
{/if}
{loop name="places" type="pdr_places" id="$place_id"}
<form action="{url path='/admin/module/PointRetrait/edit' place_id={$place_id}}" method="POST" class="clearfix" {form_enctype form=$form}>
{form_hidden_fields form=$form}
{include
file = "includes/inner-form-toolbar.html"
hide_flags = true
hide_submit_buttons = false
page_url = "{url path='/admin/module/PointRetrait/edit' place_id=$place_id}"
close_url = "{url path='/admin/module/PointRetrait'}"
current_tab = "main"
}
{form_field form=$form field="place_id"}
<input type="hidden" name="{$name}" value="{$place_id}"/>
{/form_field}
<div class="row form-inline">
<div class="row">
<div class="col-md-3">
{form_field form=$form field="title"}
<div class="form-group">
<label class="control-label" for="{$label_attr.for}">
{intl l=$label d='pointretrait'}
</label>
<input type="text" id="{$label_attr.for}" class="form-control large" name="{$name}" value="{$TITLE}" {if $required}required{/if} />&nbsp
</div>
{form_error form=$form field="title"}{$message}{/form_error}
{/form_field}
</div>
<div class="col-md-2">
{form_field form=$form field="active"}
<div class="form-group">
<label class="control-label" for="{$label_attr.for}">
{intl l=$label d="pointretrait"}
</label>
<div class="make-switch switch-small toggle-active" data-id="{$ID}" data-on="success"
data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>"
data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" class="link" {if $ACTIVE == 1}checked="checked"{/if}>
</div>
<input type="hidden" id="{$label_attr.for}" name="{$name}" value="{$ACTIVE}"/>
</div>
{/form_field}
</div>
<div class="col-md-2">
{form_field form=$form field="price"}
<div class="form-group form-inline">
<label class="control-label" for="{$label_attr.for}">
{intl l=$label d="pointretrait"}
{if $required}<span class="required">*</span>{/if}
</label>
<input type="text" id="{$label_attr.for}" class="form-control etroit" name="{$name}" value="{$PRICE}" {if $required}required{/if} />&nbsp;
</div>
{form_error form=$form field="price"}{$message}{/form_error}
{/form_field}
</div>
<div class="col-md-3">
{form_field form=$form field="minimum_amount"}
<div class="form-group form-inline">
<label class="control-label" for="{$label_attr.for}">
{intl l=$label d="pointretrait"}
{if $required}<span class="required">*</span>{/if}
</label>
<input type="text" id="{$label_attr.for}" class="form-control etroit" name="{$name}" value="{$MINIMUM_AMOUNT}" {if $required}required{/if} />&nbsp;
</div>
{form_error form=$form field="minimum_amount"}{$message}{/form_error}
{/form_field}
</div>
<div class="col-md-2">
{form_field form=$form field="latitude"}
<input type="hidden" value="{$LATITUDE}" id="{$label_attr.for}" name="{$name}">
{/form_field}
{form_field form=$form field="longitude"}
<input type="hidden" value="{$LONGITUDE}" id="{$label_attr.for}" name="{$name}">
{/form_field}
</div>
</div>
<div class="row">
<div class="col-md-12">
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBb07YA_unrh5w821I1xHxbeYb5KCF_WaM&callback=initMap&libraries=&v=weekly" async></script>
<div id="map" class="locationMap"></div>
</div>
</div>
</div>
</form>
{/loop}
</div>
{/form}

View File

@@ -0,0 +1,32 @@
<script>
let map;
function initMap() {
var opt = {
center: new google.maps.LatLng($("#latitude").val(), $("#longitude").val()),
zoom: 15,
streetViewControl: true,
mapTypeControl: false
};
map = new google.maps.Map(document.getElementById("map"), opt);
var markerOpts = {
title: $(document.getElementById("title")).val(),
position: opt.center,
draggable: true,
map: map
};
displayPlace();
}
function displayPlace() {
var marker = new google.maps.Marker({
position: new google.maps.LatLng($("#latitude").val(), $("#longitude").val()),
map: map,
title: $(document.getElementById("title")).val()
});
}
</script>

View File

@@ -0,0 +1,3 @@
<li class="{if $admin_current_location == 'pointretrait'}active{/if}" id="pointretrait">
<a title="{intl l='Module name' d='pointretrait'}" href="{url path='/admin/module/PointRetrait'}" ><span class="glyphicon glyphicon-pushpin"></span> {intl l='Module name' d='pointretrait'}</a>
</li>

View File

@@ -0,0 +1,79 @@
{extends file="admin-layout.tpl"}
{block name="page-title"}{intl l='My places' d="pointretrait"}{/block}
{block name="check-access"}update{/block}
{block name="check-module"}PointRetrait{/block}
{block name="after-bootstrap-css"}
<link rel="stylesheet"
href="{stylesheet file='assets/js/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css'}">
{/block}
{block name="main-content"}
<div id="wrapper" class="container">
{assign "place_id" $smarty.get.place_id}
<div class="general-block-decorator">
<div class="title title-without-tabs">
{intl l="Edit a place" d="pointretrait"}&nbsp;: <b>{loop name="places" type="pdr_places" id={$place_id}}{$TITLE}{/loop}</b>
</div>
<ul class="nav nav-tabs" id="tabbed-menu">
{loop name="auth-general" type="auth" role="ADMIN" resource="admin" access="VIEW" module="PointRetrait"}
<li class="active"><a href="#main" data-toggle="tab">{intl l="Main" d="pointretrait"}</a></li>
{/loop}
{loop name="auth-schedule" type="auth" role="ADMIN" resource="admin.schedule" access="VIEW" module="PointRetrait"}
<li><a href="#schedule" data-toggle="tab">{intl l="Schedule" d="pointretrait"}</a></li>
{/loop}
</ul>
<div class="tab-content">
{loop name="auth-general-tab" type="auth" role="ADMIN" resource="admin" access="VIEW" module="PointRetrait"}
<div class="tab-pane fade in active" id="general">
{include file="includes/main.html"}
</div>
{/loop}
{loop name="auth-schedule-tab" type="auth" role="ADMIN" resource="admin.schedule" access="VIEW" module="PointRetrait"}
<div class="tab-pane fade" id="schedule">
{*
{include file="includes/schedule.html"}
*}
</div>
{/loop}
</div>
</div>
</div>
{*
{include file="modal/schedule-modal.html"}
*}
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/moment-with-locales.min.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
<script>
$(function() {
$(".toggle-active").on('switch-change', function (event, data) {
$("#active").val(data['value'] ? 1 : 0);
});
var hash = location.hash.slice(1);
if (!hash) hash = "main";
$('#tabbed-menu a[href="#' + hash + '"]').tab('show');
});
</script>
{/javascripts}
{include file="js/main-js.html"}
{*
{include file="js/schedule-js.html"}
*}
{/block}

View File

@@ -0,0 +1,94 @@
mais{extends file="admin-layout.tpl"}
{block name="no-return-functions"}
{$admin_current_location = 'module'}
{/block}
{block name="page-title"}{intl l='Title of config view' d='pointretrait'}{/block}
{block name="check-resource"}admin.module{/block}
{block name="check-access"}view{/block}
{block name="check-module"}PointRetrait{/block}
{block name="main-content"}
<div id="wrapper" class="container">
{if $general_error}
<div class="alert alert-danger">
{$general_error}
</div>
{/if}
<div class="general-block-decorator">
<div class="table-responsive">
<table class="table table-striped table-condensed" id="areas-table">
<caption class="clearfix">
{intl l='My withdrawal places' d='pointretrait'}
</caption>
<thead>
<tr>
<th>{intl l="Place" d='pointretrait'}</th>
<th class="col-md-1">{intl l="Active" d='pointretrait'}</th>
<th>{intl l="Withdrawal price" d='pointretrait'}</th>
<th>{intl l="Minimum amount" d='pointretrait'}</th>
<th>{intl l="Withdrawal days" d='pointretrait'}</th>
<th>{intl l="Location set" d='pointretrait'}</th>
<th class="col-md-1">&nbsp;</th>
</tr>
</thead>
<tbody>
{loop name="places" type="pdr_places"}
<tr>
<td><a href="{url path='/admin/module/PointRetrait/edit' place_id=$ID}">{$TITLE}</a></td>
<td>
<div class="make-switch switch-small toggle-visible" data-id="{$ID}" data-on="success"
data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>"
data-off-label="<i class='glyphicon glyphicon-remove'></i>">
<input type="checkbox" class="link" {if $ACTIVE == 1}checked="checked"{/if}>
</div>
</td>
<td>{$PRICE} €</td>
<td>{$MINIMUM_AMOUNT} €</td>
<td>{$DELIVERY_DAYS}{if $DELIVERY_DAYS eq ''}<i>{intl l="There is no schedule for this place" d='pointretrait'}</i>{/if}</td>
<td>{if $LATITUDE != ''}Oui{else}Non{/if}</td>
<td class="actions">
<div class="btn-group" role="group">
<a class="btn btn-info btn-responsive" title="{intl l='Edit this place'}" href="{url path='/admin/module/PointRetrait/edit' place_id=$ID}">
<i class="glyphicon glyphicon-edit"></i>
</a>
<a class="btn btn-danger btn-responsive place-delete" title="{intl l='Delete this place'}" data-target="#place-delete" data-toggle="modal" data-id="{$ID}">
<i class="glyphicon glyphicon-trash"></i>
</a>
</div>
</td>
</tr>
{/loop}
</tbody>
</table>
</div>
</div>
</div>
{/block}
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
<script>
$(function() {
$('a.area-delete').click(function(ev) {
$('#area_delete_id').val($(this).data('id'));
});
$(".toggle-visible").on('switch-change', function (event, data) {
$.ajax({
method: "POST",
url: "{url path='admin/module/PointRetrait/toggle-online/'}" + $(this).data('id')
});
});
});
</script>
{/javascripts}
{/block}

View File

@@ -0,0 +1,75 @@
<style>
#block-scheduled-deliveries > div.scheduled-deliveries-list > table > thead > tr > th,
#block-scheduled-deliveries > div.scheduled-deliveries-list > table > tbody > tr > td {
text-align: center;
}
.nb-commandes {
font-size: 14px;
margin-left: 30px;
}
.nb-commandes b {
color: orange;
font-weight: bold;
}
</style>
<div class="scheduled-withdrawal-list">
<table class="table table-striped">
<thead>
<th>&nbsp;</th>
<th>{intl l="Order number" d="pointretrait"}</th>
<th>{intl l="Scheduled date" d="pointretrait"}</th>
<th>{intl l="Delivery delay" d="pointretrait"}</th>
<th>{intl l="Place" d="pointretrait"}</th>
</thead>
<tbody>
{loop name="deliveries-loop" type="scheduled_deliveries" domicile_ou_retrait="retrait" only_future="true" order="date"}
{if $DELTA <= 7}
{assign var=path value="{image file='/assets/img/flag-green.png'}"}
{assign var=alt value='Drapeau vert'}
{/if}
{if $DELTA <= 4}
{assign var=path value="{image file='/assets/img/flag-orange.png'}"}
{assign var=alt value='Drapeau orange'}
{/if}
{if $DELTA <= 1}
{assign var=path value="{image file='/assets/img/flag-red.png'}"}
{assign var=alt value='Drapeau rouge'}
{/if}
{assign var=title value="{$DELTA} jour(s) de délai"}
{loop name="order-loop" type="order" id={$ORDER_ID} customer="*"}
{loop type="customer" name="customer-loop" current="false" id=$CUSTOMER}
{assign var=client value="$FIRSTNAME $LASTNAME"}
{/loop}
{/loop}
<tr>
<td><img src={$path} alt="{$alt}" title="{$title}" style="margin-left: 30px; width:25px"></td>
<td><a href="/admin/order/update/{$ORDER_ID}" target="_blank" title="Client : {$client}">{$ORDER_ID}</a></td>
<td>
{format_date date=$START_DATE format="d/m/Y"} entre {format_date date=$START_DATE format="H\hi"} et {format_date date=$END_DATE format="H\hi"}
</td>
<td>{$DELTA} jour(s)</td>
<td>Point de retrait</td>
</tr>
{if $LOOP_COUNT == $LOOP_TOTAL}{assign var=nbCommandes value=$LOOP_TOTAL}{/if}
{/loop}
{elseloop rel="deliveries-loop"}
<tr>
<td colspan="1000">
<div class="alert alert-info">
{intl l="There is no order to withdraw" d="pointretrait"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
<span class="nb-commandes">Total :&nbsp;&nbsp;<b>{$nbCommandes}</b>&nbsp;&nbsp;commande(s)</span>
</div>