Add dynamical prices editing in Colissimo

modified:   local/modules/Colissimo/AdminIncludes/module_configuration.html
	modified:   local/modules/Colissimo/Colissimo.php
	modified:   local/modules/Colissimo/Config/config.xml
	modified:   local/modules/Colissimo/Config/module.xml
	modified:   local/modules/Colissimo/Config/prices.json
	new file:   local/modules/Colissimo/Config/routing.xml
	modified:   local/modules/Colissimo/Config/thelia.sql
	new file:   local/modules/Colissimo/Controller/EditPrices.php
	new file:   local/modules/Colissimo/I18n/en_US.php
	new file:   local/modules/Colissimo/I18n/fr_FR.php
	modified:   local/modules/Colissimo/Listener/SendMail.php
	new file:   local/modules/Colissimo/Loop/CheckRightsLoop.php
	modified:   local/modules/Colissimo/Loop/Price.php
	modified:   local/modules/Colissimo/documentation/TarifsAvril2013.pdf
	modified:   local/modules/Colissimo/documentation/readme.txt
This commit is contained in:
Benjamin Perche
2014-02-19 09:51:22 +01:00
parent 5caa55c345
commit d00bc84cd5
15 changed files with 310 additions and 183 deletions

View File

@@ -1,3 +1,13 @@
<div class="row">
<!-- Errors -->
{loop name="checkrights.colissimo" type="colissimo.check.rights"}
<div class="alert alert-danger">
<p>{$ERRMES} {$ERRFILE} | {intl l="Please change the access rights"}.</p>
</div>
{/loop}
</div>
{elseloop rel="checkrights.colissimo"}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
@@ -5,22 +15,35 @@
<p>{intl l="Colissimo Module allows to send your products all around the world with La Poste."}</p> <p>{intl l="Colissimo Module allows to send your products all around the world with La Poste."}</p>
</div> </div>
<div class="alert alert-danger">
<p>{intl l="Prices are not dynamically editable yet."}</p>
<p>{intl l="Prices below can be edited in local/modules/Colissimo/Config/prices.json file."}</p>
</div>
<div class="general-block-decorator"> <div class="general-block-decorator">
{* -- Add price slice confirmation dialog ----------------------------------- *}
{loop type="area" name="list area" backend_context=true} {loop type="area" name="list area" backend_context=true}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "price_slice_create_dialog_{$ID}"
dialog_title = {intl l="Create a price slice"}
dialog_body = "<input type=\"hidden\" name=\"operation\" value=\"add\"/>
<input type=\"hidden\" name=\"area\" value=\"{$ID}\" />
<label for=\"weight_{$ID}\">{intl l="Weight up to ... (kg)"}</label></label>
<input type=\"number\" id=\"weight_{$ID}\" name=\"weight\" value=\"1\" class=\"form-control\" pattern=\"\\d+\\.?\\d*\" required/>
<label for=\"price_{$ID}\">{intl l="Price (€)"}</label></label>
<input type=\"number\" id=\"price_{$ID}\" name=\"price\" value=\"1\" class=\"form-control\" pattern=\"\\d+\\.?\\d*\" required/>"
form_action="{url path="/admin/module/colissimo/prices"}"
dialog_ok_label = {intl l="Create"}
dialog_cancel_label = {intl l="Cancel"}
}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned"> <table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix"> <caption class="clearfix">
{intl l="Area : "}{$NAME} {intl l="Area : "}{$NAME}
{loop type="auth" name="can_create" role="ADMIN" module="colissimo" access="CREATE"} {loop type="auth" name="can_create" role="ADMIN" module="colissimo" access="CREATE"}
<a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new price slice'}" href="#price_slice_create_dialog" data-toggle="modal"> <a class="btn btn-default btn-primary pull-right" title="{intl l='Create a new price slice'}" href="#price_slice_create_dialog_{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-plus"></span> <span class="glyphicon glyphicon-plus"></span>
</a> </a>
{/loop} {/loop}
</caption> </caption>
<thead> <thead>
@@ -31,19 +54,56 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{loop type="colissimo" name="colissimo" area=$ID} {loop type="colissimo" name="colissimo" area=$ID}
<tr> {* -- EDIT price slice confirmation dialog ----------------------------------- *}
<td>{$MAX_WEIGHT}</td> {include
<td>{$PRICE}</td> file = "includes/generic-confirm-dialog.html"
<td>
<div class="btn-group"> dialog_id = "price_slice_edit_dialog_{$ID}_{$MAX_WEIGHT|replace:'.':'-'}"
{loop type="auth" name="can_change" role="ADMIN" module="colissimo" access="UPDATE"} dialog_title = {intl l="Edit a price slice"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this price slice'}" href="#price_slice_delete_dialog" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a> dialog_message = "<input type=\"hidden\" name=\"operation\" value=\"add\"/>
{/loop} <input type=\"hidden\" name=\"area\" value=\"{$ID}\"/>
</div> <input type=\"hidden\" name=\"weight\" value=\"{$MAX_WEIGHT}\"/>
</td> <label for=\"price_edit_{$ID}_{$MAX_WEIGHT}\">{intl l='Price (€)'}</label>
</tr> <input type=\"number\" id=\"price_edit_{$ID}_{$MAX_WEIGHT}\" class=\"form-control\" name=\"price\" value=\"{$PRICE}\" pattern=\"\\d+\\.?\\d*\" required/>"
{/loop}
form_action="{url path="/admin/module/colissimo/prices"}"
dialog_ok_label = {intl l="Edit"}
dialog_cancel_label = {intl l="Cancel"}
}
{* -- Delete price slice confirmation dialog ----------------------------------- *}
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "price_slice_delete_dialog_{$ID}_{$MAX_WEIGHT|replace:'.':'-'}"
dialog_title = {intl l="Delete a price slice"}
dialog_message = "<input type=\"hidden\" name=\"operation\" value=\"delete\"/>
<input type=\"hidden\" name=\"area\" value=\"{$ID}\"/>
<input type=\"hidden\" name=\"weight\" value=\"{$MAX_WEIGHT}\"/>
{intl l="Do you really want to delete this slice ?"}"
form_action="{url path="/admin/module/colissimo/prices"}"
dialog_ok_label = {intl l="Delete"}
dialog_cancel_label = {intl l="Cancel"}
}
<tr>
<td>{$MAX_WEIGHT}</td>
<td>{$PRICE}</td>
<td>
<div class="btn-group">
{loop type="auth" name="can_change" role="ADMIN" module="colissimo" access="UPDATE"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this price slice'}" href="#price_slice_edit_dialog_{$ID}_{$MAX_WEIGHT|replace:'.':'-'}" data-toggle="modal">
<span class="glyphicon glyphicon-edit"></span>
</a>
<a class="btn btn-default btn-xs" title="{intl l='Delete this price slice'}" href="#price_slice_delete_dialog_{$ID}_{$MAX_WEIGHT|replace:'.':'-'}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
</tbody> </tbody>
</table> </table>
</div> </div>
@@ -53,35 +113,4 @@
</div> </div>
</div> </div>
{/elseloop}
{* -- Add price slice confirmation dialog ----------------------------------- *}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "price_slice_create_dialog"
dialog_title = {intl l="Create a price slice"}
dialog_body = "Not available yet."
dialog_ok_label = {intl l="Create"}
dialog_cancel_label = {intl l="Cancel"}
}
{* -- Delete price slice confirmation dialog ----------------------------------- *}
{include
file = "includes/generic-confirm-dialog.html"
dialog_id = "price_slice_delete_dialog"
dialog_title = {intl l="Delete a price slice"}
dialog_message = "Not available yet."
dialog_ok_label = {intl l="Delete"}
dialog_cancel_label = {intl l="Cancel"}
}
<script type="text/javascript">
jQuery(function($) {
})
</script>

4
local/modules/Colissimo/Colissimo.php Normal file → Executable file
View File

@@ -39,12 +39,12 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface
private static $prices = null; private static $prices = null;
const JSON_PRICE_RESOURCE = "prices.json"; const JSON_PRICE_RESOURCE = "/Config/prices.json";
public static function getPrices() public static function getPrices()
{ {
if(null === self::$prices) { if(null === self::$prices) {
self::$prices = json_decode(file_get_contents(sprintf('%s/Config/%s', __DIR__, self::JSON_PRICE_RESOURCE)), true); self::$prices = json_decode(file_get_contents(sprintf('%s%s', __DIR__, self::JSON_PRICE_RESOURCE)), true);
} }
return self::$prices; return self::$prices;

1
local/modules/Colissimo/Config/config.xml Normal file → Executable file
View File

@@ -6,6 +6,7 @@
<loops> <loops>
<loop class="Colissimo\Loop\Price" name="colissimo"/> <loop class="Colissimo\Loop\Price" name="colissimo"/>
<loop class="Colissimo\Loop\CheckRightsLoop" name="colissimo.check.rights" />
</loops> </loops>
<forms> <forms>

0
local/modules/Colissimo/Config/module.xml Normal file → Executable file
View File

129
local/modules/Colissimo/Config/prices.json Normal file → Executable file
View File

@@ -1,128 +1 @@
{ {"1":{"_info":"area 1 : France","slices":{"0.25":"5.23","0.5":5.8,"0.75":6.56,"1":7.13,"2":8.08,"3":9.22,"5":11.31,"7":13.4,"10":16.53,"15":19.14,"30":26.93}},"2":{"_info":"area 2 : A Zone - Union Europ\u00e9enne et Suisse","slices":{"1":15.34,"2":16.96,"3":20.47,"4":23.99,"5":27.5,"6":31.02,"7":34.53,"8":38.05,"9":41.56,"10":45.08,"15":51.92,"20":58.76,"25":65.6,"30":72.44}},"3":{"_info":"area 3 : B Zone - Pays de l\u2019Europe de l\u2019Est (hors Union Europ\u00e9enne), Norv\u00e8ge, Maghreb","slices":{"1":18.81,"2":20.62,"3":24.94,"4":29.26,"5":33.58,"6":37.91,"7":42.23,"8":46.55,"9":50.87,"10":55.2,"15":65.08,"20":74.96}},"4":{"_info":"area 4 : C Zone - Pays d\u2019Afrique hors Maghreb, Canada, Etats-Unis, Proche et Moyen Orient","slices":{"1":22.04,"2":29.55,"3":38.86,"4":48.17,"5":57.48,"6":66.79,"7":76.1,"8":85.41,"9":94.72,"10":104.03,"15":126.92,"20":149.82}},"5":{"_info":"area 5 : D Zone - Autres destinations","slices":{"1":25.08,"2":37.72,"3":50.26,"4":62.8,"5":75.34,"6":87.88,"7":100.42,"8":112.96,"9":125.5,"10":138.04,"15":162.74,"20":187.44}},"6":{"_info":"area 6 : France OM1","slices":{"0.5":8.27,"1":12.49,"2":17.05,"3":21.61,"4":26.17,"5":30.73,"6":35.29,"7":39.85,"8":44.41,"9":48.97,"10":53.53,"15":76.33,"20":99.13,"25":121.93,"30":144.73}},"7":{"_info":"area 7 : France OM2","slices":{"0.5":9.88,"1":14.92,"2":26.32,"3":37.72,"4":49.12,"5":60.52,"6":71.92,"7":83.32,"8":94.72,"9":106.12,"10":117.52,"15":174.52,"20":231.52,"25":288.52,"30":345.52}}}
"1": {
"_info": "area 1 : France",
"slices": {
"0.25": 5.23,
"0.5": 5.8,
"0.75": 6.56,
"1": 7.13,
"2": 8.08,
"3": 9.22,
"5": 11.31,
"7": 13.4,
"10": 16.53,
"15": 19.14,
"30": 26.93
}
},
"2": {
"_info": "area 2 : A Zone - Union Européenne et Suisse",
"slices": {
"1": 15.34,
"2": 16.96,
"3": 20.47,
"4": 23.99,
"5": 27.5,
"6": 31.02,
"7": 34.53,
"8": 38.05,
"9": 41.56,
"10": 45.08,
"15": 51.92,
"20": 58.76,
"25": 65.6,
"30": 72.44
}
},
"3": {
"_info": "area 3 : B Zone - Pays de lEurope de lEst (hors Union Européenne), Norvège, Maghreb",
"slices": {
"1": 18.81,
"2": 20.62,
"3": 24.94,
"4": 29.26,
"5": 33.58,
"6": 37.91,
"7": 42.23,
"8": 46.55,
"9": 50.87,
"10": 55.2,
"15": 65.08,
"20": 74.96
}
},
"4": {
"_info": "area 4 : C Zone - Pays dAfrique hors Maghreb, Canada, Etats-Unis, Proche et Moyen Orient",
"slices": {
"1": 22.04,
"2": 29.55,
"3": 38.86,
"4": 48.17,
"5": 57.48,
"6": 66.79,
"7": 76.1,
"8": 85.41,
"9": 94.72,
"10": 104.03,
"15": 126.92,
"20": 149.82
}
},
"5": {
"_info": "area 5 : D Zone - Autres destinations",
"slices": {
"1": 25.08,
"2": 37.72,
"3": 50.26,
"4": 62.8,
"5": 75.34,
"6": 87.88,
"7": 100.42,
"8": 112.96,
"9": 125.5,
"10": 138.04,
"15": 162.74,
"20": 187.44
}
},
"6": {
"_info": "area 6 : France OM1",
"slices": {
"0.5": 8.27,
"1": 12.49,
"2": 17.05,
"3": 21.61,
"4": 26.17,
"5": 30.73,
"6": 35.29,
"7": 39.85,
"8": 44.41,
"9": 48.97,
"10": 53.53,
"15": 76.33,
"20": 99.13,
"25": 121.93,
"30": 144.73
}
},
"7": {
"_info": "area 7 : France OM2",
"slices": {
"0.5": 9.88,
"1": 14.92,
"2": 26.32,
"3": 37.72,
"4": 49.12,
"5": 60.52,
"6": 71.92,
"7": 83.32,
"8": 94.72,
"9": 106.12,
"10": 117.52,
"15": 174.52,
"20": 231.52,
"25": 288.52,
"30": 345.52
}
}
}

View File

@@ -0,0 +1,10 @@
<?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">
<route id="icirelais.edit.prices" path="/admin/module/colissimo/prices" methods="post">
<default key="_controller">Colissimo\Controller\EditPrices::editprices</default>
</route>
</routes>

0
local/modules/Colissimo/Config/thelia.sql Normal file → Executable file
View File

View File

@@ -0,0 +1,90 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Colissimo\Controller;
use Colissimo\Colissimo;
use Thelia\Model\AreaQuery;
use Thelia\Controller\Admin\BaseAdminController;
/**
* Class EditPrices
* @package Colissimo\Controller
* @author Thelia <info@thelia.net>
*/
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) {
$json_path= __DIR__."/../".Colissimo::JSON_PRICE_RESOURCE;
if (is_readable($json_path)) {
$json_data = json_decode(file_get_contents($json_path),true);
} elseif(!file_exists($json_path)) {
$json_data = array();
} else {
throw new \Exception("Can't read Colissimo".Colissimo::JSON_PRICE_RESOURCE.". Please change the rights on the file.");
}
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']);
if ((file_exists($json_path) ?is_writable($json_path):is_writable(__DIR__."/../"))) {
$file = fopen($json_path, 'w');
fwrite($file, json_encode($json_data));;
fclose($file);
} else {
throw new \Exception("Can't write Colissimo".Colissimo::JSON_PRICE_RESOURCE.". Please change the rights on the file.");
}
} else {
throw new \Exception("Area not found");
}
} else {
throw new \ErrorException("Arguments are missing or invalid");
}
return $this->redirectToRoute("admin.module.configure",array(),
array ( 'module_code'=>"Colissimo",
'_controller' => 'Thelia\\Controller\\Admin\\ModuleController::configureAction'));
}
}

View File

@@ -0,0 +1,21 @@
<?php
return array(
'Can\'t read Config directory'=>'Can\'t read Config directory',
'Can\'t write Config directory'=>'Can\'t write Config directory',
'Can\'t read file'=>'Can\'t read file',
'Can\'t write file'=>'Can\'t write file',
'Please change the access rights'=>'Please change the access rights',
'Colissimo Module allows to send your products all around the world with La Poste.'=>'Colissimo Module allows to send your products all around the world with La Poste.',
'Create a price slice'=>'Create a price slice',
'Weight up to ... (kg)'=>'Weight up to ... (kg)',
'Price ('=>'Price (',
'Create'=>'Create',
'Cancel'=>'Cancel',
'Area '=>'Area ',
'Actions'=>'Actions',
'Edit a price slice'=>'Edit a price slice',
'Edit'=>'Edit',
'Delete a price slice'=>'Delete a price slice',
'Do you really want to delete this slice '=>'Do you really want to delete this slice ',
'Delete'=>'Delete',
);

View File

@@ -0,0 +1,21 @@
<?php
return array(
'Can\'t read Config directory'=>'Le dossier Config ne peut être lu',
'Can\'t write Config directory'=>'Le dossier Config ne peut être écrit',
'Can\'t read file'=>'Le fichier suivant ne peut être lu',
'Can\'t write file'=>'Le fichier suivant ne peut être écrit',
'Please change the access rights'=>'Veuillez changer les droits d\'accès',
'Colissimo Module allows to send your products all around the world with La Poste.'=>'Le module Colissimo vous permet d\'envoyer des colis dans le monde entier avec La Poste.',
'Create a price slice' => 'Créer une tranche de prix',
'Weight up to ... (kg)'=>'Poids ... (kg)',
'Price (€)'=>'Prix (€)',
'Create'=>'Créer',
'Cancel'=>'Annuler',
'Area : '=>'Zone de livraison : ',
'Actions'=>'Actions',
'Edit'=>'Modifer',
'Edit a price slice' => 'Modifier une tranche de prix',
'Delete a price slice' => 'Supprimer une tranche de prix',
'Do you really want to delete this slice ?'=>'Voulez-vous réellement supprimer cette tranche de prix ?',
'Delete'=>'Supprimer',
);

0
local/modules/Colissimo/Listener/SendMail.php Normal file → Executable file
View File

View File

@@ -0,0 +1,82 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Colissimo\Loop;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\ArraySearchLoopInterface;
use Thelia\Core\Translation\Translator;
/**
* Class CheckRightsLoop
* @package Colissimo\Looop
* @author Thelia <info@thelia.net>
*/
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"), "ERRFILE"=>"");
}
if (!is_writable($dir)) {
$ret[] = array("ERRMES"=>Translator::getInstance()->trans("Can't write Config directory"), "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"), "ERRFILE"=>"Colissimo/Config/".$file);
}
if (!is_writable($dir.$file)) {
$ret[] = array("ERRMES"=>Translator::getInstance()->trans("Can't write file"), "ERRFILE"=>"Colissimo/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;
}
}

0
local/modules/Colissimo/Loop/Price.php Normal file → Executable file
View File

View File

0
local/modules/Colissimo/documentation/readme.txt Normal file → Executable file
View File