Compare commits

..
11 Commits
Author SHA1 Message Date
pvincent 089f137636 tagged as 1.8.1 2021-08-26 17:11:58 +04:00
pvincent 0426a175aa App.log 2021-08-26 17:11:16 +04:00
pvincent 59b7c48a89 tagged as 1.8.0 2021-08-25 22:23:45 +04:00
pvincent d13c85be61 force semver 2021-08-25 22:23:28 +04:00
pvincent 2714f44b44 README 2021-08-25 22:21:59 +04:00
pvincent 04cb4343ad semver 2021-08-25 22:20:29 +04:00
pvincent e94c4eae67 App.log for DEBUG 2021-08-25 22:17:03 +04:00
pvincent 47abd95962 tagged as 1.7.3 2021-08-25 19:23:35 +04:00
pvincent c346584d46 change readme 2021-08-25 19:23:20 +04:00
cagettepei.lxd bbeea934e4 tagged as 1.7.2 2021-08-25 19:10:48 +04:00
cagettepei.lxd 3c8a2507d9 no package-lock.json 2021-08-25 19:10:35 +04:00
10 changed files with 1028 additions and 7202 deletions
+2 -4
View File
@@ -1,7 +1,7 @@
*.n *.n
*.php *.php
config.xml config.xml
/package-lock.json package-lock.json
www/plugin/* www/plugin/*
tmp/* tmp/*
*node_modules* *node_modules*
@@ -30,10 +30,8 @@ www/file/*
www/js/app.js www/js/app.js
www/js/libs.js www/js/libs.js
www/css/.sass-cache www/css/.sass-cache
www/css/*.css www/css/*.css
!www/css/bootstrap.min.css !www/css/bootstrap.min.css
config-dev.xml
/package-lock.json
+1 -1
View File
@@ -1 +1 @@
1.7.1 1.8.1
+1
View File
@@ -74,6 +74,7 @@ templates:
@make LANG=fr ctemplates @make LANG=fr ctemplates
msgfmt www/lang/texts_fr.po -o www/lang/texts_fr.mo msgfmt www/lang/texts_fr.po -o www/lang/texts_fr.mo
chown www-data:www-data -R www chown www-data:www-data -R www
chown www-data:www-data -R lang
ctemplates: ctemplates:
(cd lang/$(LANG)/tpl; temploc2 -macros macros.mtt -output ../tmp/ *.mtt */*.mtt */*/*.mtt) (cd lang/$(LANG)/tpl; temploc2 -macros macros.mtt -output ../tmp/ *.mtt */*.mtt */*/*.mtt)
+3 -1
View File
@@ -9,7 +9,7 @@ j'ai repris sur la base d'un existant pour adapter au marché local réunionnais
## INSTALL FROM SCRATCH (debian-buster) ## INSTALL FROM SCRATCH (debian-buster)
* apt install -y curl * apt install -y curl
* curl -sL https://deb.nodesource.com/setup_8.x | bash - * curl -L https://deb.nodesource.com/setup_8.x | bash -
* apt install -y nodejs=8.17.0-1nodesource1 * apt install -y nodejs=8.17.0-1nodesource1
* apt install -y sudo haxe apache2 make git imagemagick gettext libapache2-mod-neko mariadb-server * apt install -y sudo haxe apache2 make git imagemagick gettext libapache2-mod-neko mariadb-server
* mysql -u root <<EOF * mysql -u root <<EOF
@@ -28,6 +28,8 @@ EOF
ServerName cagettepei ServerName cagettepei
DirectoryIndex index.n DirectoryIndex index.n
DocumentRoot /var/www/cagettepei/www/ DocumentRoot /var/www/cagettepei/www/
</VirtualHost> </VirtualHost>
``` ```
* sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf * sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
-6188
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -47,5 +47,5 @@
"bugs": { "bugs": {
"url": "https://github.com/bablukid/cagette/issues" "url": "https://github.com/bablukid/cagette/issues"
}, },
"version": "1.7.1" "version": "1.8.1"
} }
+64 -68
View File
@@ -3,28 +3,26 @@ import thx.semver.Version;
import Common; import Common;
class App extends sugoi.BaseApp { class App extends sugoi.BaseApp {
public static var current:App = null;
public static var current : App = null; public static var t:sugoi.i18n.translator.ITranslator;
public static var t : sugoi.i18n.translator.ITranslator;
public static var config = sugoi.BaseApp.config; public static var config = sugoi.BaseApp.config;
public var eventDispatcher :hxevents.Dispatcher<Event>; public var eventDispatcher:hxevents.Dispatcher<Event>;
public var plugins : Array<sugoi.plugin.IPlugIn>; public var plugins:Array<sugoi.plugin.IPlugIn>;
/** /**
* Version management * Version management
* @doc https://github.com/fponticelli/thx.semver * @doc https://github.com/fponticelli/thx.semver
*/ */
//public static var VERSION = ([0,9,2] : Version).withPre("july"); // public static var VERSION = ([0,9,2] : Version).withPre("july");
//public static var VERSION = ([0,9,2] : Version).withPre(MyMacros.getGitShortSHA(), MyMacros.getGitCommitDate()); // public static var VERSION = ([0,9,2] : Version).withPre(MyMacros.getGitShortSHA(), MyMacros.getGitCommitDate());
public static var VERSION = "cagette-péi " + MyMacros.getGitCommitDate(); public static var VERSION = "cagette-péi " + MyMacros.getGitCommitDate();
public function new(){ public function new() {
super(); super();
} }
public static function main() { public static function main() {
App.t = sugoi.form.Form.translator = new sugoi.i18n.translator.TMap(getTranslationArray(), "fr"); App.t = sugoi.form.Form.translator = new sugoi.i18n.translator.TMap(getTranslationArray(), "fr");
sugoi.BaseApp.main(); sugoi.BaseApp.main();
} }
@@ -35,58 +33,59 @@ class App extends sugoi.BaseApp {
override public function mainLoop() { override public function mainLoop() {
eventDispatcher = new hxevents.Dispatcher<Event>(); eventDispatcher = new hxevents.Dispatcher<Event>();
plugins = []; plugins = [];
//internal plugins // internal plugins
plugins.push(new plugin.Tutorial()); plugins.push(new plugin.Tutorial());
//optionnal plugins // optionnal plugins
#if plugins #if plugins
plugins.push( new hosted.HostedPlugIn() ); plugins.push(new hosted.HostedPlugIn());
plugins.push( new pro.ProPlugIn() ); plugins.push(new pro.ProPlugIn());
plugins.push( new connector.ConnectorPlugIn() ); plugins.push(new connector.ConnectorPlugIn());
plugins.push( new pro.LemonwayEC() ); plugins.push(new pro.LemonwayEC());
plugins.push( new who.WhoPlugIn() ); plugins.push(new who.WhoPlugIn());
#end #end
super.mainLoop(); super.mainLoop();
} }
public function getCurrentGroup(){ public function getCurrentGroup() {
if (session == null) return null; if (session == null)
if (session.data == null ) return null; return null;
if (session.data == null)
return null;
var a = session.data.amapId; var a = session.data.amapId;
if (a == null) { if (a == null) {
return null; return null;
}else { } else {
return db.Amap.manager.get(a,false); return db.Amap.manager.get(a, false);
} }
} }
override function beforeDispatch() { override function beforeDispatch() {
// send "current page" event
//send "current page" event event(Page(this.uri));
event( Page(this.uri) );
super.beforeDispatch(); super.beforeDispatch();
} }
public function getPlugin(name:String):sugoi.plugin.IPlugIn { public function getPlugin(name:String):sugoi.plugin.IPlugIn {
for (p in plugins) { for (p in plugins) {
if (p.getName() == name) return p; if (p.getName() == name)
return p;
} }
return null; return null;
} }
public static function log(t:Dynamic) { public static function log(t:Dynamic, ?infos:haxe.PosInfos) {
if(App.config.DEBUG) { // if (App.config.DEBUG) {
neko.Web.logMessage(Std.string(t)); //write in Apache error log // neko.Web.logMessage(Std.string(t)); // write in Apache error log
#if weblog // }
Weblog.log(t); //write en Weblog console (https://lib.haxe.org/p/weblog/) neko.Web.logMessage('[${infos.fileName}:${infos.lineNumber} ${infos.className}#${infos.methodName}] ' + Std.string(t));
#end
}
} }
public function event(e:Event) { public function event(e:Event) {
if(e==null) return null; if (e == null)
return null;
this.eventDispatcher.dispatch(e); this.eventDispatcher.dispatch(e);
return e; return e;
} }
@@ -95,16 +94,16 @@ class App extends sugoi.BaseApp {
* Translate DB objects fields in forms * Translate DB objects fields in forms
*/ */
public static function getTranslationArray() { public static function getTranslationArray() {
//var t = sugoi.i18n.Locale.texts; // var t = sugoi.i18n.Locale.texts;
var out = new Map<String,String>(); var out = new Map<String, String>();
//out.set("firstName", t._("First name") ); // out.set("firstName", t._("First name") );
//out.set("lastName", t._("Last name")); // out.set("lastName", t._("Last name"));
out.set("firstName2", "Prénom du conjoint"); out.set("firstName2", "Prénom du conjoint");
out.set("lastName2", "Nom du conjoint"); out.set("lastName2", "Nom du conjoint");
out.set("email2", "e-mail du conjoint"); out.set("email2", "e-mail du conjoint");
//out.set("pass", t._("Password") ); // out.set("pass", t._("Password") );
//out.set("address1", t._("address") ); // out.set("address1", t._("address") );
//out.set("address2", t._("address") ); // out.set("address2", t._("address") );
out.set("zipCode", "code postal"); out.set("zipCode", "code postal");
out.set("city", "commune"); out.set("city", "commune");
out.set("phone", "téléphone"); out.set("phone", "téléphone");
@@ -231,25 +230,22 @@ class App extends sugoi.BaseApp {
} }
public static function getMailer():sugoi.mail.IMailer { public static function getMailer():sugoi.mail.IMailer {
var mailer:sugoi.mail.IMailer = new sugoi.mail.BufferedMailer();
var mailer : sugoi.mail.IMailer = new sugoi.mail.BufferedMailer(); if (App.config.DEBUG) {
// Dev env : emails are written to tmp folder
if(App.config.DEBUG){
//Dev env : emails are written to tmp folder
mailer = new sugoi.mail.DebugMailer(); mailer = new sugoi.mail.DebugMailer();
}else{ } else {
if (sugoi.db.Variable.get("mailer") == null) {
if (sugoi.db.Variable.get("mailer") == null){
var msg = sugoi.i18n.Locale.texts._("Please configure the email settings in a <href='/admin/emails'>this section</a>"); var msg = sugoi.i18n.Locale.texts._("Please configure the email settings in a <href='/admin/emails'>this section</a>");
throw sugoi.ControllerAction.ErrorAction("/",msg); throw sugoi.ControllerAction.ErrorAction("/", msg);
} }
if (sugoi.db.Variable.get("mailer") == "mandrill"){ if (sugoi.db.Variable.get("mailer") == "mandrill") {
//Buffered emails with Mandrill // Buffered emails with Mandrill
untyped mailer.defineFinalMailer("mandrill"); untyped mailer.defineFinalMailer("mandrill");
}else{ } else {
//Buffered emails with SMTP // Buffered emails with SMTP
untyped mailer.defineFinalMailer("smtp"); untyped mailer.defineFinalMailer("smtp");
} }
} }
@@ -259,24 +255,27 @@ class App extends sugoi.BaseApp {
/** /**
* Send an email * Send an email
*/ */
public static function sendMail(m:sugoi.mail.Mail, ?group:db.Amap, ?listId:String, ?sender:db.User){ public static function sendMail(m:sugoi.mail.Mail, ?group:db.Amap, ?listId:String, ?sender:db.User) {
if (group == null)
if (group == null) group = App.current.user == null ? null:App.current.user.getAmap(); group = App.current.user == null ? null : App.current.user.getAmap();
current.event(SendEmail(m)); current.event(SendEmail(m));
var params = group==null ? null : {remoteId:group.id}; var params = group == null ? null : {remoteId: group.id};
getMailer().send(m,params,function(o){});
App.log('about to send email with subject=<${m.getSubject()}> ...');
getMailer().send(m, params, function(o) {});
App.log('email from=<${m.getSender().email}>, subject=<${m.getSubject()}> successfully sent');
} }
public static function quickMail(to:String, subject:String, html:String,?group:db.Amap){ public static function quickMail(to:String, subject:String, html:String, ?group:db.Amap) {
App.log('quickMail subject=$subject');
var e = new sugoi.mail.Mail(); var e = new sugoi.mail.Mail();
e.setSubject(subject); e.setSubject(subject);
e.setRecipient(to); e.setRecipient(to);
e.setSender(App.config.get("default_email"),"Cagette.net"); e.setSender(App.config.get("default_email"), "Cagette.net");
var html = App.current.processTemplate("mail/message.mtt", {text:html,group:group}); var html = App.current.processTemplate("mail/message.mtt", {text: html, group: group});
e.setHtmlBody(html); e.setHtmlBody(html);
App.sendMail(e); App.sendMail(e);
} }
@@ -287,21 +286,18 @@ class App extends sugoi.BaseApp {
* @param ctx * @param ctx
*/ */
public function processTemplate(tpl:String, ctx:Dynamic):String { public function processTemplate(tpl:String, ctx:Dynamic):String {
Reflect.setField(ctx, 'HOST', App.config.HOST); Reflect.setField(ctx, 'HOST', App.config.HOST);
Reflect.setField(ctx, 'hDate', App.current.view.hDate); Reflect.setField(ctx, 'hDate', App.current.view.hDate);
//i18n functions // i18n functions
ctx._ = App.current.view._; ctx._ = App.current.view._;
ctx.__ = App.current.view.__; ctx.__ = App.current.view.__;
var tpl = loadTemplate(tpl); var tpl = loadTemplate(tpl);
var html = tpl.execute(ctx); var html = tpl.execute(ctx);
#if php #if php
if ( html.substr(0, 4) == "null") html = html.substr(4); if (html.substr(0, 4) == "null")
html = html.substr(4);
#end #end
return html; return html;
} }
} }
File diff suppressed because it is too large Load Diff
+180 -166
View File
@@ -1,48 +1,43 @@
package controller; package controller;
import sugoi.db.Cache; import sugoi.db.Cache;
import sugoi.Web; import sugoi.Web;
import sugoi.mail.Mail; import sugoi.mail.Mail;
import Common; import Common;
using Lambda; using Lambda;
using tools.DateTool; using tools.DateTool;
class Cron extends Controller class Cron extends Controller {
{ public function doDefault() {}
public function doDefault()
{
}
/** /**
* CLI only en prod * CLI only en prod
*/ */
function canRun() { function canRun() {
if (App.current.user != null && App.current.user.isAdmin()){ if (App.current.user != null && App.current.user.isAdmin()) {
return true; return true;
}else if (App.config.DEBUG) { } else if (App.config.DEBUG) {
return true; return true;
}else { } else {
if (Web.isModNeko) { if (Web.isModNeko) {
Sys.print("only CLI."); Sys.print("only CLI.");
return false; return false;
}else { } else {
return true; return true;
} }
} }
} }
public function doMinute() { public function doMinute() {
print("Cron.doMinute is called"); print("Cron.doMinute is called");
if (!canRun()) return; if (!canRun())
return;
app.event(MinutelyCron); app.event(MinutelyCron);
sendEmailsfromBuffer(); sendEmailsfromBuffer();
} }
/** /**
@@ -51,54 +46,54 @@ class Cron extends Controller
* this function can be locally tested with `neko index.n cron/hour > cron.log` * this function can be locally tested with `neko index.n cron/hour > cron.log`
*/ */
public function doHour() { public function doHour() {
app.event(HourlyCron); app.event(HourlyCron);
distribNotif(4,db.User.UserFlags.HasEmailNotif4h); //4h before distribNotif(4, db.User.UserFlags.HasEmailNotif4h); // 4h before
distribNotif(24,db.User.UserFlags.HasEmailNotif24h); //24h before distribNotif(24, db.User.UserFlags.HasEmailNotif24h); // 24h before
distribNotif(0, db.User.UserFlags.HasEmailNotifOuverture); //on command open distribNotif(0, db.User.UserFlags.HasEmailNotifOuverture); // on command open
distribValidationNotif(); distribValidationNotif();
//sendOrdersByProductWhenOrdersClose(); // sendOrdersByProductWhenOrdersClose();
} }
public function doDaily() { public function doDaily() {
if (!canRun()) return; if (!canRun())
return;
app.event(DailyCron); app.event(DailyCron);
//ERRORS MONITORING // ERRORS MONITORING
var n = Date.now(); var n = Date.now();
var yest24h = new Date(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0); var yest24h = new Date(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0);
var yest0h = DateTools.delta(yest24h, -1000 * 60 * 60 * 24); var yest0h = DateTools.delta(yest24h, -1000 * 60 * 60 * 24);
var errors = sugoi.db.Error.manager.search( $date < yest24h && $date > yest0h ); var errors = sugoi.db.Error.manager.search($date < yest24h && $date > yest0h);
if (errors.length > 0) { if (errors.length > 0) {
var report = new StringBuf(); var report = new StringBuf();
report.add("<h1>" + App.config.NAME + " : ERRORS</h1>"); report.add("<h1>" + App.config.NAME + " : ERRORS</h1>");
for (e in errors) { for (e in errors) {
report.add("<div><pre>"+e.error + " at URL " + e.url + " ( user : " + (e.user!=null?e.user.toString():"none") + ", IP : " + e.ip + ")</pre></div><hr/>"); report.add("<div><pre>" + e.error + " at URL " + e.url + " ( user : " + (e.user != null ? e.user.toString() : "none") + ", IP : " + e.ip
+ ")</pre></div><hr/>");
} }
var m = new Mail(); var m = new Mail();
m.setSender(App.config.get("default_email"),"Cagette.net"); m.setSender(App.config.get("default_email"), "Cagette.net");
m.addRecipient(App.config.get("webmaster_email")); m.addRecipient(App.config.get("webmaster_email"));
m.setSubject(App.config.NAME+" Errors"); m.setSubject(App.config.NAME + " Errors");
m.setHtmlBody( app.processTemplate("mail/message.mtt", { text:report.toString() } ) ); m.setHtmlBody(app.processTemplate("mail/message.mtt", {text: report.toString()}));
App.sendMail(m); App.sendMail(m);
} }
// DEMO CONTRATS deletion after 7 days ( see controller.Group.doCreate() )
db.Contract.manager.delete($name == "Contrat AMAP Maraîcher Exemple"
&& $startDate < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 7));
db.Contract.manager.delete($name == "Contrat Poulet Exemple"
&& $startDate < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 7));
//DEMO CONTRATS deletion after 7 days ( see controller.Group.doCreate() ) // Old Messages cleaning
db.Contract.manager.delete($name == "Contrat AMAP Maraîcher Exemple" && $startDate < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 7));
db.Contract.manager.delete($name == "Contrat Poulet Exemple" && $startDate < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 7));
//Old Messages cleaning
db.Message.manager.delete($date < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 30 * 6)); db.Message.manager.delete($date < DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 30 * 6));
//DB cleaning : I dont know how, but some people have empty string emails... // DB cleaning : I dont know how, but some people have empty string emails...
/*for ( u in db.User.manager.search($email == "", true)){ /*for ( u in db.User.manager.search($email == "", true)){
u.email = Std.random(9999) + "@cagette.net"; u.email = Std.random(9999) + "@cagette.net";
u.update(); u.update();
@@ -107,8 +102,6 @@ class Cron extends Controller
u.email2 = null; u.email2 = null;
u.update(); u.update();
}*/ }*/
} }
/** /**
@@ -117,28 +110,28 @@ class Cron extends Controller
* @param flag * @param flag
*/ */
function distribNotif(hour:Int, flag:db.User.UserFlags) { function distribNotif(hour:Int, flag:db.User.UserFlags) {
// trouve les distrib qui commencent dans le nombre d'heures demandé
//trouve les distrib qui commencent dans le nombre d'heures demandé // on recherche celles qui commencent jusqu'à une heure avant pour ne pas en rater
//on recherche celles qui commencent jusqu'à une heure avant pour ne pas en rater var from = DateTools.delta(Date.now(), 1000.0 * 60 * 60 * (hour - 1));
var from = DateTools.delta(Date.now(), 1000.0 * 60 * 60 * (hour-1));
var to = DateTools.delta(Date.now(), 1000.0 * 60 * 60 * hour); var to = DateTools.delta(Date.now(), 1000.0 * 60 * 60 * hour);
//if (App.config.DEBUG) from = DateTools.delta(from, 1000.0 * 60 * 60 * 24 * -30); // if (App.config.DEBUG) from = DateTools.delta(from, 1000.0 * 60 * 60 * 24 * -30);
// dans le cas HasEmailNotifOuverture la date à prendre est le orderStartDate // dans le cas HasEmailNotifOuverture la date à prendre est le orderStartDate
// et non pas date qui est la date de la distribution // et non pas date qui est la date de la distribution
var distribs; var distribs;
if ( db.User.UserFlags.HasEmailNotifOuverture == flag ) if (db.User.UserFlags.HasEmailNotifOuverture == flag)
distribs = db.Distribution.manager.search( $orderStartDate >= from && $orderStartDate <= to , false); distribs = db.Distribution.manager.search($orderStartDate >= from && $orderStartDate <= to, false);
else else
distribs = db.Distribution.manager.search( $date >= from && $date <= to , false); distribs = db.Distribution.manager.search($date >= from && $date <= to, false);
//Sys.print("distribNotif "+hour+" from "+from+" to "+to+"<br/>\n"); // Sys.print("distribNotif "+hour+" from "+from+" to "+to+"<br/>\n");
//on s'arrete immédiatement si aucune distibution trouvée // on s'arrete immédiatement si aucune distibution trouvée
if (distribs.length == 0) return; if (distribs.length == 0)
return;
//cherche plus tard si on a pas une "grappe" de distrib // cherche plus tard si on a pas une "grappe" de distrib
/*while (true) { /*while (true) {
var extraDistribs ; var extraDistribs ;
if ( db.User.UserFlags.HasEmailNotifOuverture != flag ) if ( db.User.UserFlags.HasEmailNotifOuverture != flag )
@@ -155,9 +148,9 @@ class Cron extends Controller
} }
}*/ }*/
//on vérifie dans le cache du jour que ces distrib n'ont pas deja été traitées lors d'un cron précédent // on vérifie dans le cache du jour que ces distrib n'ont pas deja été traitées lors d'un cron précédent
var cacheId = Date.now().toString().substr(0, 10)+Std.string(flag); var cacheId = Date.now().toString().substr(0, 10) + Std.string(flag);
var dist :Array<Int> = sugoi.db.Cache.get(cacheId); var dist:Array<Int> = sugoi.db.Cache.get(cacheId);
if (dist != null) { if (dist != null) {
for (d in Lambda.array(distribs)) { for (d in Lambda.array(distribs)) {
if (Lambda.exists(dist, function(x) return x == d.id)) { if (Lambda.exists(dist, function(x) return x == d.id)) {
@@ -165,37 +158,42 @@ class Cron extends Controller
distribs.remove(d); distribs.remove(d);
} }
} }
}else { } else {
dist = []; dist = [];
} }
//toutes les distribs trouvées ont deja été traitées // toutes les distribs trouvées ont deja été traitées
if (distribs.length == 0) return; if (distribs.length == 0)
return;
//stocke cache // stocke cache
for (d in distribs) dist.push(d.id); for (d in distribs)
dist.push(d.id);
Cache.set(cacheId, dist, 24 * 60 * 60); Cache.set(cacheId, dist, 24 * 60 * 60);
//We have now the distribs we want to notify about. // We have now the distribs we want to notify about.
var distribsByContractId = new Map<Int,db.Distribution>(); var distribsByContractId = new Map<Int, db.Distribution>();
for (d in distribs) { for (d in distribs) {
if (d == null || d.contract==null) continue; if (d == null || d.contract == null)
continue;
distribsByContractId.set(d.contract.id, d); distribsByContractId.set(d.contract.id, d);
} }
//Boucle sur les distributions pour gerer le cas de plusieurs distributions le même jour sur le même contrat // Boucle sur les distributions pour gerer le cas de plusieurs distributions le même jour sur le même contrat
var orders = []; var orders = [];
for (d in distribs) { for (d in distribs) {
if (d == null || d.contract==null) continue; if (d == null || d.contract == null)
//get orders for both type of contracts continue;
for ( x in d.contract.getOrders(d)) orders.push(x); // get orders for both type of contracts
for (x in d.contract.getOrders(d))
orders.push(x);
} }
/* /*
* Group orders by users-group to receive separate emails by groups for the same user. * Group orders by users-group to receive separate emails by groups for the same user.
* Map key is $userId-$groupId * Map key is $userId-$groupId
*/ */
var users = new Map <String,{ var users = new Map<String, {
user:db.User, user:db.User,
distrib:db.Distribution, distrib:db.Distribution,
products:Array<db.UserContract>, products:Array<db.UserContract>,
@@ -203,77 +201,92 @@ class Cron extends Controller
}>(); }>();
for (o in orders) { for (o in orders) {
var x = users.get(o.user.id + "-" + o.product.contract.amap.id);
var x = users.get(o.user.id+"-"+o.product.contract.amap.id); if (x == null)
if (x == null) x = {user:o.user,distrib:null,products:[],vendors:[]}; x = {
user: o.user,
distrib: null,
products: [],
vendors: []
};
x.distrib = distribsByContractId.get(o.product.contract.id); x.distrib = distribsByContractId.get(o.product.contract.id);
x.products.push(o); x.products.push(o);
users.set(o.user.id+"-"+o.product.contract.amap.id, x); users.set(o.user.id + "-" + o.product.contract.amap.id, x);
//trace (o.userId+"-"+o.product.contract.amap.id, x);Sys.print("<br/>\n"); // trace (o.userId+"-"+o.product.contract.amap.id, x);Sys.print("<br/>\n");
// Prévenir également le deuxième user en cas des commandes alternées // Prévenir également le deuxième user en cas des commandes alternées
if (o.user2 != null) { if (o.user2 != null) {
var x = users.get(o.user2.id+"-"+o.product.contract.amap.id); var x = users.get(o.user2.id + "-" + o.product.contract.amap.id);
if (x == null) x = {user:o.user2,distrib:null,products:[],vendors:[]}; if (x == null)
x = {
user: o.user2,
distrib: null,
products: [],
vendors: []
};
x.distrib = distribsByContractId.get(o.product.contract.id); x.distrib = distribsByContractId.get(o.product.contract.id);
x.products.push(o); x.products.push(o);
users.set(o.user2.id+"-"+o.product.contract.amap.id, x); users.set(o.user2.id + "-" + o.product.contract.amap.id, x);
//trace (o.user2.id+"-"+o.product.contract.amap.id, x);Sys.print("<br/>\n"); // trace (o.user2.id+"-"+o.product.contract.amap.id, x);Sys.print("<br/>\n");
} }
} }
//remove zero qt orders // remove zero qt orders
for( k in users.keys()){ for (k in users.keys()) {
var x = users.get(k); var x = users.get(k);
var total = 0.0; var total = 0.0;
for( o in x.products) total += o.quantity; for (o in x.products)
if(total==0.0) users.remove(k); total += o.quantity;
if (total == 0.0)
users.remove(k);
} }
// Dans le cas de l'ouverture de commande, ce sont tous les users qu'il faut intégrer // Dans le cas de l'ouverture de commande, ce sont tous les users qu'il faut intégrer
if ( db.User.UserFlags.HasEmailNotifOuverture == flag ) if (db.User.UserFlags.HasEmailNotifOuverture == flag) {
{
for (d in distribs) { for (d in distribs) {
var memberList = d.contract.amap.getMembers(); var memberList = d.contract.amap.getMembers();
for (u in memberList) { for (u in memberList) {
var x = users.get(u.id+"-"+d.contract.amap.id); var x = users.get(u.id + "-" + d.contract.amap.id);
if (x == null) x = {user:u,distrib:null,products:[],vendors:[]}; if (x == null)
x = {
user: u,
distrib: null,
products: [],
vendors: []
};
x.distrib = distribsByContractId.get(d.contract.id); x.distrib = distribsByContractId.get(d.contract.id);
x.vendors.push(d.contract.vendor); x.vendors.push(d.contract.vendor);
users.set(u.id+"-"+d.contract.amap.id, x); users.set(u.id + "-" + d.contract.amap.id, x);
//print(u.id+"-"+d.contract.amap.id, x); // print(u.id+"-"+d.contract.amap.id, x);
} }
} }
} }
for ( u in users) { for (u in users) {
if (u.user.flags.has(flag)) {
if (u.user.flags.has(flag) ) {
if (u.user.email != null) { if (u.user.email != null) {
var group = u.distrib.contract.amap; var group = u.distrib.contract.amap;
this.t = sugoi.i18n.Locale.init(u.user.lang); //switch to the user language this.t = sugoi.i18n.Locale.init(u.user.lang); // switch to the user language
var text; var text;
if ( db.User.UserFlags.HasEmailNotifOuverture == flag ) if (db.User.UserFlags.HasEmailNotifOuverture == flag) {
{ // order opening notif
//order opening notif text = t._("Opening of orders for the delivery of <b>::date::</b>", {date: view.hDate(u.distrib.date)});
text = t._("Opening of orders for the delivery of <b>::date::</b>", {date:view.hDate(u.distrib.date)});
text += "<br/>"; text += "<br/>";
text += t._("The following suppliers are involved :"); text += t._("The following suppliers are involved :");
text += "<br/><ul>"; text += "<br/><ul>";
for ( v in u.vendors) { for (v in u.vendors) {
text += "<li>" + v + "</li>"; text += "<li>" + v + "</li>";
} }
text += "</ul>"; text += "</ul>";
} else {
}else{ // Distribution notif to the users
//Distribution notif to the users
var d = u.distrib; var d = u.distrib;
text = t._("Do not forget the delivery on <b>::day::</b> from ::from:: to ::to::<br/>", {day:view.dDate(d.date),from:view.hHour(d.date),to:view.hHour(d.end)}); text = t._("Do not forget the delivery on <b>::day::</b> from ::from:: to ::to::<br/>",
{day: view.dDate(d.date), from: view.hHour(d.date), to: view.hHour(d.end)});
text += t._("Your products to collect :") + "<br/><ul>"; text += t._("Your products to collect :") + "<br/><ul>";
for ( p in u.products) { for (p in u.products) {
text += "<li>"+p.quantity+" x "+p.product.getName(); text += "<li>" + p.quantity + " x " + p.product.getName();
// Gerer le cas des contrats en alternance // Gerer le cas des contrats en alternance
if (p.user2 != null) { if (p.user2 != null) {
text += " " + t._("alternated with") + " "; text += " " + t._("alternated with") + " ";
@@ -291,36 +304,35 @@ class Cron extends Controller
text += t._("<b>Warning: you are in charge of the delivery ! Do not forget to print the attendance sheet.</b>"); text += t._("<b>Warning: you are in charge of the delivery ! Do not forget to print the attendance sheet.</b>");
} }
try{ try {
var m = new Mail(); var m = new Mail();
m.setSender(App.config.get("default_email"), "Cagette.net"); m.setSender(App.config.get("default_email"), "Cagette.net");
if(group.contact!=null) m.setReplyTo(group.contact.email, group.name); if (group.contact != null)
m.setReplyTo(group.contact.email, group.name);
m.addRecipient(u.user.email, u.user.getName()); m.addRecipient(u.user.email, u.user.getName());
if (u.user.email2 != null) m.addRecipient(u.user.email2); if (u.user.email2 != null)
m.setSubject( group.name+" : "+t._("Distribution on ::date::",{date:app.view.hDate(u.distrib.date)}) ); m.addRecipient(u.user.email2);
m.setHtmlBody( app.processTemplate("mail/message.mtt", { text:text,group:group } ) ); m.setSubject(group.name + " : " + t._("Distribution on ::date::", {date: app.view.hDate(u.distrib.date)}));
App.sendMail(m , u.distrib.contract.amap); m.setHtmlBody(app.processTemplate("mail/message.mtt", {text: text, group: group}));
}catch (e:Dynamic){ App.sendMail(m, u.distrib.contract.amap);
app.logError(e); //email could be invalid } catch (e:Dynamic) {
} app.logError(e); // email could be invalid
}
} }
} }
} }
} }
/** /**
* Check if there is a multi-distrib to validate. * Check if there is a multi-distrib to validate.
* *
* Autovalidate it after 10 days * Autovalidate it after 10 days
*/ */
function distribValidationNotif(){ function distribValidationNotif() {
var now = Date.now(); var now = Date.now();
var from = now.setHourMinute( now.getHours(), 0 ); var from = now.setHourMinute(now.getHours(), 0);
var to = now.setHourMinute( now.getHours()+1 , 0); var to = now.setHourMinute(now.getHours() + 1, 0);
var explain = t._("<p>This step is important in order to:</p>"); var explain = t._("<p>This step is important in order to:</p>");
explain += t._("<ul><li>Update orders if delivered quantities are different from ordered quantities</li>"); explain += t._("<ul><li>Update orders if delivered quantities are different from ordered quantities</li>");
@@ -329,12 +341,12 @@ class Cron extends Controller
/* /*
* warn administrator if a distribution just ended * warn administrator if a distribution just ended
*/ */
var ds = db.Distribution.manager.search( !$validated && ($end >= from) && ($end < to) , false); var ds = db.Distribution.manager.search(!$validated && ($end >= from) && ($end < to), false);
for ( d in Lambda.array(ds)){ for (d in Lambda.array(ds)) {
if ( d.contract.type != db.Contract.TYPE_VARORDER ){ if (d.contract.type != db.Contract.TYPE_VARORDER) {
ds.remove(d); ds.remove(d);
}else if ( !d.contract.amap.hasPayments() ){ } else if (!d.contract.amap.hasPayments()) {
ds.remove(d); ds.remove(d);
} }
} }
@@ -342,15 +354,16 @@ class Cron extends Controller
var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds); var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds);
var view = App.current.view; var view = App.current.view;
for ( d in ds ){ for (d in ds) {
// var subj = "["+d.contract.amap.name+"] " + t._("Validation of the ::date:: distribution",{date:view.hDate(d.date)}); // var subj = "["+d.contract.amap.name+"] " + t._("Validation of the ::date:: distribution",{date:view.hDate(d.date)});
var subj = t._("[::group::] Validation of the ::date:: distribution",{group : d.contract.amap.name , date : view.hDate(d.date)}); var subj = t._("[::group::] Validation of the ::date:: distribution", {group: d.contract.amap.name, date: view.hDate(d.date)});
var url = "http://" + App.config.HOST + "/distribution/validate/"+d.date.toString().substr(0,10)+"/"+d.place.id; var url = "http://" + App.config.HOST + "/distribution/validate/" + d.date.toString().substr(0, 10) + "/" + d.place.id;
var html = t._("<p>Your distribution just finished, don't forget to <b>validate</b> it</p>"); var html = t._("<p>Your distribution just finished, don't forget to <b>validate</b> it</p>");
html += explain; html += explain;
html += t._("<p><a href='::distriburl::'>Click here to validate the distribution</a> (You must be connected to your group Cagette)", {distriburl:url}); html += t._("<p><a href='::distriburl::'>Click here to validate the distribution</a> (You must be connected to your group Cagette)",
{distriburl: url});
App.quickMail(d.contract.amap.contact.email, subj, html); App.quickMail(d.contract.amap.contact.email, subj, html);
} }
@@ -359,66 +372,67 @@ class Cron extends Controller
* warn administrator if a distribution ended 3 days ago * warn administrator if a distribution ended 3 days ago
*/ */
var from = now.setHourMinute( now.getHours() , 0 ).deltaDays(-3); var from = now.setHourMinute(now.getHours(), 0).deltaDays(-3);
var to = now.setHourMinute( now.getHours()+1 , 0).deltaDays(-3); var to = now.setHourMinute(now.getHours() + 1, 0).deltaDays(-3);
//warn administrator if a distribution just ended // warn administrator if a distribution just ended
var ds = db.Distribution.manager.search( !$validated && ($end >= from) && ($end < to) , false); var ds = db.Distribution.manager.search(!$validated && ($end >= from) && ($end < to), false);
for ( d in Lambda.array(ds)){ for (d in Lambda.array(ds)) {
if ( d.contract.type != db.Contract.TYPE_VARORDER ){ if (d.contract.type != db.Contract.TYPE_VARORDER) {
ds.remove(d); ds.remove(d);
}else if ( !d.contract.amap.hasPayments() ){ } else if (!d.contract.amap.hasPayments()) {
ds.remove(d); ds.remove(d);
} }
} }
var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds); var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds);
for ( d in ds ){ for (d in ds) {
// var subj = d.contract.amap.name + t._(": Validation of the delivery of the ") + App.current.view.hDate(d.date); // var subj = d.contract.amap.name + t._(": Validation of the delivery of the ") + App.current.view.hDate(d.date);
var subj = t._("[::group::] Validation of the ::date:: distribution",{group : d.contract.amap.name , date : view.hDate(d.date)}); var subj = t._("[::group::] Validation of the ::date:: distribution", {group: d.contract.amap.name, date: view.hDate(d.date)});
var url = "http://" + App.config.HOST + "/distribution/validate/"+d.date.toString().substr(0,10)+"/"+d.place.id; var url = "http://" + App.config.HOST + "/distribution/validate/" + d.date.toString().substr(0, 10) + "/" + d.place.id;
var html = t._("<p>Reminder: you have a delivery to validate.</p>"); var html = t._("<p>Reminder: you have a delivery to validate.</p>");
html += explain; html += explain;
html += t._("<p><a href='::distriburl::'>Click here to validate the delivery</a> (You must be connected to your Cagette group)", {distriburl:url}); html += t._("<p><a href='::distriburl::'>Click here to validate the delivery</a> (You must be connected to your Cagette group)",
{distriburl: url});
App.quickMail(d.contract.amap.contact.email, subj, html); App.quickMail(d.contract.amap.contact.email, subj, html);
} }
/* /*
* Autovalidate unvalidated distributions after 10 days * Autovalidate unvalidated distributions after 10 days
*/ */
var from = now.setHourMinute( now.getHours() , 0 ).deltaDays( 0 - db.Distribution.DISTRIBUTION_VALIDATION_LIMIT ); var from = now.setHourMinute(now.getHours(), 0).deltaDays(0 - db.Distribution.DISTRIBUTION_VALIDATION_LIMIT);
var to = now.setHourMinute( now.getHours() + 1 , 0).deltaDays( 0 - db.Distribution.DISTRIBUTION_VALIDATION_LIMIT ); var to = now.setHourMinute(now.getHours() + 1, 0).deltaDays(0 - db.Distribution.DISTRIBUTION_VALIDATION_LIMIT);
print('AUTOVALIDATION'); print('AUTOVALIDATION');
print('Find distributions from $from to $to'); print('Find distributions from $from to $to');
var ds = db.Distribution.manager.search( !$validated && ($end >= from) && ($end < to) , true); var ds = db.Distribution.manager.search(!$validated && ($end >= from) && ($end < to), true);
for ( d in Lambda.array(ds)){ for (d in Lambda.array(ds)) {
if ( d.contract.type != db.Contract.TYPE_VARORDER ){ if (d.contract.type != db.Contract.TYPE_VARORDER) {
ds.remove(d); ds.remove(d);
}else if ( !d.contract.amap.hasPayments() ){ } else if (!d.contract.amap.hasPayments()) {
ds.remove(d); ds.remove(d);
} }
} }
for ( d in ds){ for (d in ds) {
print(d.toString()); print(d.toString());
service.PaymentService.validateDistribution(d); service.PaymentService.validateDistribution(d);
} }
//email // email
var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds); var ds = tools.ObjectListTool.deduplicateDistribsByKey(ds);
for ( d in ds ){ for (d in ds) {
// var subj = d.contract.amap.name + t._(": Validation of the distribution of the ") + App.current.view.hDate(d.date); // var subj = d.contract.amap.name + t._(": Validation of the distribution of the ") + App.current.view.hDate(d.date);
var subj = t._("[::group::] Validation of the ::date:: distribution",{group : d.contract.amap.name , date : view.hDate(d.date)}); var subj = t._("[::group::] Validation of the ::date:: distribution", {group: d.contract.amap.name, date: view.hDate(d.date)});
var html = t._("<p>As you did not validate it manually after 10 days, <br/>the delivery of the ::deliveryDate:: has been validated automatically</p>", {deliveryDate:App.current.view.hDate(d.date)}); var html = t._("<p>As you did not validate it manually after 10 days, <br/>the delivery of the ::deliveryDate:: has been validated automatically</p>",
{
deliveryDate: App.current.view.hDate(d.date)
});
App.quickMail(d.contract.amap.contact.email, subj, html); App.quickMail(d.contract.amap.contact.email, subj, html);
} }
} }
/** /**
@@ -428,28 +442,31 @@ class Cron extends Controller
* you should consider the right amount of emails to send each minute in order to avoid overlaping and getting in concurrency problems. * you should consider the right amount of emails to send each minute in order to avoid overlaping and getting in concurrency problems.
* (like "SELECT * FROM BufferedMail WHERE sdate IS NULL ORDER BY cdate DESC LIMIT 100 FOR UPDATE Lock wait timeout exceeded; try restarting transaction") * (like "SELECT * FROM BufferedMail WHERE sdate IS NULL ORDER BY cdate DESC LIMIT 100 FOR UPDATE Lock wait timeout exceeded; try restarting transaction")
*/ */
function sendEmailsfromBuffer(){ function sendEmailsfromBuffer() {
App.log("Send Emails from Buffer");
print("<h3>Send Emails from Buffer</h3>"); print("<h3>Send Emails from Buffer</h3>");
//send // send
for( e in sugoi.db.BufferedMail.manager.search($sdate==null,{limit:50,orderBy:-cdate},false) ){ for (e in sugoi.db.BufferedMail.manager.search($sdate == null, {limit: 50, orderBy: -cdate}, false)) {
e.lock(); e.lock();
if(e.isSent()) continue; if (e.isSent())
continue;
App.log('Send Email id=${e.id} - title=${e.title}');
print('#${e.id} - ${e.title}'); print('#${e.id} - ${e.title}');
e.finallySend(); e.finallySend();
Sys.sleep(0.1); Sys.sleep(0.1);
} }
//delete old emails // delete old emails
var threeMonthsAgo = DateTools.delta(Date.now(), -1000.0*60*60*24*30*3); var threeMonthsAgo = DateTools.delta(Date.now(), -1000.0 * 60 * 60 * 24 * 30 * 3);
sugoi.db.BufferedMail.manager.delete($cdate < threeMonthsAgo); sugoi.db.BufferedMail.manager.delete($cdate < threeMonthsAgo);
//emails that cannot be sent // emails that cannot be sent
for( e in sugoi.db.BufferedMail.manager.search($tries>100,{limit:50,orderBy:-cdate},true) ){ for (e in sugoi.db.BufferedMail.manager.search($tries > 100, {limit: 50, orderBy: -cdate}, true)) {
if(e.sender.email != App.config.get("default_email")){ if (e.sender.email != App.config.get("default_email")) {
var str = t._("Sorry, the email entitled <b>::title::</b> could not be sent.",{title:e.title}); var str = t._("Sorry, the email entitled <b>::title::</b> could not be sent.", {title: e.title});
App.quickMail(e.sender.email,t._("Email not sent"),str); App.quickMail(e.sender.email, t._("Email not sent"), str);
} }
e.delete(); e.delete();
} }
@@ -458,20 +475,17 @@ class Cron extends Controller
/** /**
* Email product report when orders close * Email product report when orders close
**/ **/
function sendOrdersByProductWhenOrdersClose(){ function sendOrdersByProductWhenOrdersClose() {
var range = tools.DateTool.getLastHourRange(); var range = tools.DateTool.getLastHourRange();
// Sys.println("Time is "+Date.now()+"<br/>"); // Sys.println("Time is "+Date.now()+"<br/>");
// Sys.println('Find all distributions that have closed in the last hour from ${range.from} to ${range.to} \n<br/>'); // Sys.println('Find all distributions that have closed in the last hour from ${range.from} to ${range.to} \n<br/>');
for ( d in db.Distribution.manager.search($orderEndDate >= range.from && $orderEndDate < range.to, false)){ for (d in db.Distribution.manager.search($orderEndDate >= range.from && $orderEndDate < range.to, false)) {
service.OrderService.sendOrdersByProductReport(d); service.OrderService.sendOrdersByProductReport(d);
} }
} }
function print(text) {
function print(text){ Sys.println(text + "<br/>");
Sys.println( text + "<br/>" );
} }
} }
+67 -70
View File
@@ -1,22 +1,20 @@
package controller; package controller;
import db.Message; import db.Message;
import db.UserContract; import db.UserContract;
import sugoi.form.ListData; import sugoi.form.ListData;
import sugoi.form.elements.*; import sugoi.form.elements.*;
import sugoi.form.Form; import sugoi.form.Form;
class Messages extends Controller class Messages extends Controller {
{ public function new() {
public function new()
{
super(); super();
if (!app.user.canAccessMessages()) throw Redirect("/"); if (!app.user.canAccessMessages())
throw Redirect("/");
} }
@tpl("messages/default.mtt") @tpl("messages/default.mtt")
function doDefault() { function doDefault() {
var form = new Form("msg"); var form = new Form("msg");
var senderName = ""; var senderName = "";
@@ -25,79 +23,87 @@ class Messages extends Controller
if (App.current.session.data.whichUser == 1 && app.user.email2 != null) { if (App.current.session.data.whichUser == 1 && app.user.email2 != null) {
senderMail = app.user.email2; senderMail = app.user.email2;
senderName = app.user.firstName2 + " " + app.user.lastName2; senderName = app.user.firstName2 + " " + app.user.lastName2;
} else {
}else {
senderMail = app.user.email; senderMail = app.user.email;
senderName = app.user.firstName + " " + app.user.lastName; senderName = app.user.firstName + " " + app.user.lastName;
} }
var lists = getLists(); var lists = getLists();
form.addElement( new StringInput("senderName", t._("Sender name"),senderName,true)); form.addElement(new StringInput("senderName", t._("Sender name"), senderName, true));
form.addElement( new StringInput("senderMail", t._("Sender E-Mail"),senderMail,true)); form.addElement(new StringInput("senderMail", t._("Sender E-Mail"), senderMail, true));
form.addElement( new StringSelect("list", t._("Recipients"),lists,"1", true,null,"style='width:500px;'")); form.addElement(new StringSelect("list", t._("Recipients"), lists, "1", true, null, "style='width:500px;'"));
form.addElement( new StringInput("subject", t._("Subject:"),"",false,null,"style='width:500px;'") ); form.addElement(new StringInput("subject", t._("Subject:"), "", false, null, "style='width:500px;'"));
form.addElement( new TextArea("text", t._("Message:"), "", false, null, "style='width:500px;height:350px;'") ); form.addElement(new TextArea("text", t._("Message:"), "", false, null, "style='width:500px;height:350px;'"));
if (form.checkToken()) { if (form.checkToken()) {
var listId = form.getElement("list").value; var listId = form.getElement("list").value;
var dest = getSelection(listId); var dest = getSelection(listId);
App.log('about to send emails to listId=<$listId> to destination=${dest.length}');
var mails = []; var mails = [];
for ( d in dest) { for (d in dest) {
if (d.email != null) mails.push(d.email); if (d.email != null)
if (d.email2 != null) mails.push(d.email2); mails.push(d.email);
if (d.email2 != null)
mails.push(d.email2);
} }
//send mail confirmation link // send mail confirmation link
var e = new sugoi.mail.Mail(); var e = new sugoi.mail.Mail();
e.setSubject(form.getValueOf("subject")); e.setSubject(form.getValueOf("subject"));
for ( x in mails) e.addRecipient(x); for (x in mails)
e.addRecipient(x);
e.setSender(App.config.get("default_email"),form.getValueOf("senderName")); e.setSender(App.config.get("default_email"), form.getValueOf("senderName"));
e.setReplyTo(form.getValueOf("senderMail"),form.getValueOf("senderName")); e.setReplyTo(form.getValueOf("senderMail"), form.getValueOf("senderName"));
//sender : default email ( explicitly tells that the server send an email on behalf of the user )
//e.setHeader("Sender", App.config.get("default_email")); App.log('add CC header to message: ${e.getSubject()}');
var text :String = form.getValueOf("text"); e.setHeader("CC", "pvincent@comptoirduvrac.re");
var html = app.processTemplate("mail/message.mtt", { text:text,group:app.user.amap,list:getListName(listId) });
// sender : default email ( explicitly tells that the server send an email on behalf of the user )
// e.setHeader("Sender", App.config.get("default_email"));
var text:String = form.getValueOf("text");
var html = app.processTemplate("mail/message.mtt", {text: text, group: app.user.amap, list: getListName(listId)});
e.setHtmlBody(html); e.setHtmlBody(html);
App.sendMail(e,app.user.getAmap(),listId,app.user); App.sendMail(e, app.user.getAmap(), listId, app.user);
//store message // store message
var lm = new db.Message(); var lm = new db.Message();
lm.amap = app.user.amap; lm.amap = app.user.amap;
lm.recipients = Lambda.array(Lambda.map(e.getRecipients(), function(x) return x.email)); lm.recipients = Lambda.array(Lambda.map(e.getRecipients(), function(x) return x.email));
lm.title = e.getSubject(); lm.title = e.getSubject();
lm.date = Date.now(); lm.date = Date.now();
lm.body = e.getHtmlBody(); lm.body = e.getHtmlBody();
if (listId != null) lm.recipientListId = listId; if (listId != null)
lm.recipientListId = listId;
lm.sender = app.user; lm.sender = app.user;
lm.insert(); lm.insert();
throw Ok("/messages", t._("The message has been sent")); throw Ok("/messages", t._("The message has been sent"));
} }
view.form = form; view.form = form;
if (app.user.isAmapManager()) { if (app.user.isAmapManager()) {
view.sentMessages = Message.manager.search($amap == app.user.amap && $recipientListId!=null, {orderBy:-date,limit:20}, false); view.sentMessages = Message.manager.search($amap == app.user.amap && $recipientListId != null, {orderBy: -date, limit: 20}, false);
}else { } else {
view.sentMessages = Message.manager.search($sender == app.user && $recipientListId!=null && $amap == app.user.amap , {orderBy:-date,limit:20}, false); view.sentMessages = Message.manager.search($sender == app.user && $recipientListId != null && $amap == app.user.amap, {orderBy: -date, limit: 20},
false);
} }
} }
@tpl("messages/message.mtt") @tpl("messages/message.mtt")
public function doMessage(msg:Message) { public function doMessage(msg:Message) {
if (!app.user.isAmapManager() && msg.sender.id != app.user.id)
if (!app.user.isAmapManager() && msg.sender.id != app.user.id) throw Error("/", t._("Non authorized access")); throw Error("/", t._("Non authorized access"));
view.list = getListName(msg.recipientListId); view.list = getListName(msg.recipientListId);
view.msg = msg; view.msg = msg;
//make status easier to display // make status easier to display
var s = new Array<{email:String,success:String,failure:String}>(); var s = new Array<{email:String, success:String, failure:String}>();
/*if (msg.status != null){ /*if (msg.status != null){
for ( k in msg.status.keys()) { for ( k in msg.status.keys()) {
var r = msg.getMailerResultMessage(k); var r = msg.getMailerResultMessage(k);
@@ -106,27 +112,25 @@ class Messages extends Controller
}*/ }*/
view.status = s; view.status = s;
} }
function getLists() :FormData<String>{ function getLists():FormData<String> {
var out = [ var out = [
{value:'1', label: t._("Everyone")}, {value: '1', label: t._("Everyone")},
{value:'2', label: t._("The board: persons in charge + contracts + memberships")}, {value: '2', label: t._("The board: persons in charge + contracts + memberships")},
]; ];
out.push( { value:'3', label: t._("TEST: me + spouse") } ); out.push({value: '3', label: t._("TEST: me + spouse")});
out.push( { value:'4', label: t._("Members without contract/order") } ); out.push({value: '4', label: t._("Members without contract/order")});
if(app.user.amap.hasMembership()) out.push( { value:'5', label:t._("Memberships to be renewed")} ); if (app.user.amap.hasMembership())
out.push({value: '5', label: t._("Memberships to be renewed")});
var contracts = db.Contract.getActiveContracts(app.user.amap, true);
var contracts = db.Contract.getActiveContracts(app.user.amap,true); for (c in contracts) {
for ( c in contracts) {
var label = t._("Subscribers") + " " + c.toString(); var label = t._("Subscribers") + " " + c.toString();
out.push({value:'c'+c.id,label:label}); out.push({value: 'c' + c.id, label: label});
} }
return out ; return out;
} }
/** /**
@@ -137,25 +141,24 @@ class Messages extends Controller
var l = getLists(); var l = getLists();
for (ll in l) { for (ll in l) {
if (ll.value == listId) return ll.label; if (ll.value == listId)
return ll.label;
} }
return null; return null;
} }
function getSelection(listId:String) { function getSelection(listId:String) {
if (listId.substr(0, 1) == "c") { if (listId.substr(0, 1) == "c") {
//contrats // contrats
var contract = Std.parseInt(listId.substr(1)); var contract = Std.parseInt(listId.substr(1));
var pids = db.Product.manager.search($contractId == contract, false); var pids = db.Product.manager.search($contractId == contract, false);
var pids = Lambda.map(pids, function(x) return x.id); var pids = Lambda.map(pids, function(x) return x.id);
var up = db.UserContract.manager.search($productId in pids, false); var up = db.UserContract.manager.search($productId in pids, false);
var users = []; var users = [];
for ( order in up) { for (order in up) {
if (!Lambda.has(users, order.user)) { if (!Lambda.has(users, order.user)) {
users.push(order.user); users.push(order.user);
} }
@@ -164,34 +167,34 @@ class Messages extends Controller
} }
} }
return users; return users;
} else {
}else {
var out = []; var out = [];
switch(listId) { switch (listId) {
case "1": case "1":
//tout le monde // tout le monde
out = Lambda.array(app.user.amap.getMembers()); out = Lambda.array(app.user.amap.getMembers());
case "2": case "2":
var users = []; var users = [];
users.push(app.user.amap.contact); users.push(app.user.amap.contact);
for ( c in db.Contract.manager.search($amap == app.user.amap)) { for (c in db.Contract.manager.search($amap == app.user.amap)) {
if (!Lambda.has(users, c.contact)) { if (!Lambda.has(users, c.contact)) {
users.push(c.contact); users.push(c.contact);
} }
} }
//ajouter les autres personnes ayant les droits Admin ou Gestion Adhérents ou Gestion Contrats // ajouter les autres personnes ayant les droits Admin ou Gestion Adhérents ou Gestion Contrats
for (ua in Lambda.array(db.UserAmap.manager.search($rights != null && $amap == app.user.amap, false))) { for (ua in Lambda.array(db.UserAmap.manager.search($rights != null && $amap == app.user.amap, false))) {
if (ua.hasRight(GroupAdmin) || ua.hasRight(Membership) || ua.hasRight(ContractAdmin())) { if (ua.hasRight(GroupAdmin) || ua.hasRight(Membership) || ua.hasRight(ContractAdmin())) {
if (!Lambda.has(users, ua.user)) users.push(ua.user); if (!Lambda.has(users, ua.user))
users.push(ua.user);
} }
} }
out = users; out = users;
case "3": case "3":
//moi // moi
return [app.user]; return [app.user];
case "4": case "4":
return Lambda.array(db.User.getUsers_NoContracts()); return Lambda.array(db.User.getUsers_NoContracts());
@@ -200,12 +203,6 @@ class Messages extends Controller
} }
return out; return out;
} }
} }
} }