Browse Source

App.log

master
pvincent 3 years ago
parent
commit
0426a175aa
  1. 2
      .gitignore
  2. 8
      src/App.hx
  3. 128
      src/controller/Cron.hx
  4. 63
      src/controller/Messages.hx

2
.gitignore

@ -30,8 +30,8 @@ www/file/*
www/js/app.js
www/js/libs.js
www/css/.sass-cache
www/css/*.css
!www/css/bootstrap.min.css
config-dev.xml

8
src/App.hx

@ -77,11 +77,11 @@ class App extends sugoi.BaseApp {
}
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('[${infos.fileName}:${infos.lineNumber} ${infos.className}#${infos.methodName}] ' + Std.string(t));
}
}
public function event(e:Event) {
if (e == null)
@ -263,10 +263,14 @@ class App extends sugoi.BaseApp {
var params = group == null ? null : {remoteId: group.id};
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) {
App.log('quickMail subject=$subject');
var e = new sugoi.mail.Mail();
e.setSubject(subject);
e.setRecipient(to);

128
src/controller/Cron.hx

@ -1,18 +1,15 @@
package controller;
import sugoi.db.Cache;
import sugoi.Web;
import sugoi.mail.Mail;
import Common;
using Lambda;
using tools.DateTool;
class Cron extends Controller
{
public function doDefault()
{
}
class Cron extends Controller {
public function doDefault() {}
/**
* CLI only en prod
@ -23,7 +20,6 @@ class Cron extends Controller
} else if (App.config.DEBUG) {
return true;
} else {
if (Web.isModNeko) {
Sys.print("only CLI.");
return false;
@ -34,15 +30,14 @@ class Cron extends Controller
}
public function doMinute() {
print("Cron.doMinute is called");
if (!canRun()) return;
if (!canRun())
return;
app.event(MinutelyCron);
sendEmailsfromBuffer();
}
/**
@ -51,7 +46,6 @@ class Cron extends Controller
* this function can be locally tested with `neko index.n cron/hour > cron.log`
*/
public function doHour() {
app.event(HourlyCron);
distribNotif(4, db.User.UserFlags.HasEmailNotif4h); // 4h before
@ -62,9 +56,9 @@ class Cron extends Controller
// sendOrdersByProductWhenOrdersClose();
}
public function doDaily() {
if (!canRun()) return;
if (!canRun())
return;
app.event(DailyCron);
@ -78,7 +72,8 @@ class Cron extends Controller
var report = new StringBuf();
report.add("<h1>" + App.config.NAME + " : ERRORS</h1>");
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();
@ -89,11 +84,11 @@ class Cron extends Controller
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));
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));
@ -107,8 +102,6 @@ class Cron extends Controller
u.email2 = null;
u.update();
}*/
}
/**
@ -117,7 +110,6 @@ class Cron extends Controller
* @param flag
*/
function distribNotif(hour:Int, flag:db.User.UserFlags) {
// 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
var from = DateTools.delta(Date.now(), 1000.0 * 60 * 60 * (hour - 1));
@ -136,7 +128,8 @@ class Cron extends Controller
// Sys.print("distribNotif "+hour+" from "+from+" to "+to+"<br/>\n");
// 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
/*while (true) {
@ -170,25 +163,30 @@ class Cron extends Controller
}
// toutes les distribs trouvées ont deja été traitées
if (distribs.length == 0) return;
if (distribs.length == 0)
return;
// 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);
// We have now the distribs we want to notify about.
var distribsByContractId = new Map<Int, db.Distribution>();
for (d in distribs) {
if (d == null || d.contract==null) continue;
if (d == null || d.contract == null)
continue;
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
var orders = [];
for (d in distribs) {
if (d == null || d.contract==null) continue;
if (d == null || d.contract == null)
continue;
// get orders for both type of contracts
for ( x in d.contract.getOrders(d)) orders.push(x);
for (x in d.contract.getOrders(d))
orders.push(x);
}
/*
@ -203,9 +201,14 @@ class Cron extends Controller
}>();
for (o in orders) {
var x = users.get(o.user.id + "-" + o.product.contract.amap.id);
if (x == null) x = {user:o.user,distrib:null,products:[],vendors:[]};
if (x == null)
x = {
user: o.user,
distrib: null,
products: [],
vendors: []
};
x.distrib = distribsByContractId.get(o.product.contract.id);
x.products.push(o);
users.set(o.user.id + "-" + o.product.contract.amap.id, x);
@ -214,7 +217,13 @@ class Cron extends Controller
// Prévenir également le deuxième user en cas des commandes alternées
if (o.user2 != null) {
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.products.push(o);
users.set(o.user2.id + "-" + o.product.contract.amap.id, x);
@ -226,18 +235,25 @@ class Cron extends Controller
for (k in users.keys()) {
var x = users.get(k);
var total = 0.0;
for( o in x.products) total += o.quantity;
if(total==0.0) users.remove(k);
for (o in x.products)
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
if ( db.User.UserFlags.HasEmailNotifOuverture == flag )
{
if (db.User.UserFlags.HasEmailNotifOuverture == flag) {
for (d in distribs) {
var memberList = d.contract.amap.getMembers();
for (u in memberList) {
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.vendors.push(d.contract.vendor);
users.set(u.id + "-" + d.contract.amap.id, x);
@ -247,16 +263,13 @@ class Cron extends Controller
}
for (u in users) {
if (u.user.flags.has(flag)) {
if (u.user.email != null) {
var group = u.distrib.contract.amap;
this.t = sugoi.i18n.Locale.init(u.user.lang); // switch to the user language
var text;
if ( db.User.UserFlags.HasEmailNotifOuverture == flag )
{
if (db.User.UserFlags.HasEmailNotifOuverture == flag) {
// order opening notif
text = t._("Opening of orders for the delivery of <b>::date::</b>", {date: view.hDate(u.distrib.date)});
text += "<br/>";
@ -266,11 +279,11 @@ class Cron extends Controller
text += "<li>" + v + "</li>";
}
text += "</ul>";
} else {
// Distribution notif to the users
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>";
for (p in u.products) {
text += "<li>" + p.quantity + " x " + p.product.getName();
@ -294,29 +307,28 @@ class Cron extends Controller
try {
var m = new Mail();
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());
if (u.user.email2 != null) m.addRecipient(u.user.email2);
if (u.user.email2 != null)
m.addRecipient(u.user.email2);
m.setSubject(group.name + " : " + t._("Distribution on ::date::", {date: app.view.hDate(u.distrib.date)}));
m.setHtmlBody(app.processTemplate("mail/message.mtt", {text: text, group: group}));
App.sendMail(m, u.distrib.contract.amap);
} catch (e:Dynamic) {
app.logError(e); // email could be invalid
}
}
}
}
}
/**
* Check if there is a multi-distrib to validate.
*
* Autovalidate it after 10 days
*/
function distribValidationNotif() {
var now = Date.now();
var from = now.setHourMinute(now.getHours(), 0);
@ -350,7 +362,8 @@ class Cron extends Controller
var html = t._("<p>Your distribution just finished, don't forget to <b>validate</b> it</p>");
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);
}
@ -383,12 +396,12 @@ class Cron extends Controller
var html = t._("<p>Reminder: you have a delivery to validate.</p>");
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);
}
/*
* Autovalidate unvalidated distributions after 10 days
*/
@ -408,17 +421,18 @@ class Cron extends Controller
print(d.toString());
service.PaymentService.validateDistribution(d);
}
// email
var ds = tools.ObjectListTool.deduplicateDistribsByKey(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 = 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);
}
}
/**
@ -429,13 +443,16 @@ class Cron extends Controller
* (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() {
App.log("Send Emails from Buffer");
print("<h3>Send Emails from Buffer</h3>");
// send
for (e in sugoi.db.BufferedMail.manager.search($sdate == null, {limit: 50, orderBy: -cdate}, false)) {
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}');
e.finallySend();
Sys.sleep(0.1);
@ -459,7 +476,6 @@ class Cron extends Controller
* Email product report when orders close
**/
function sendOrdersByProductWhenOrdersClose() {
var range = tools.DateTool.getLastHourRange();
// 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/>');
@ -467,10 +483,8 @@ class Cron extends Controller
for (d in db.Distribution.manager.search($orderEndDate >= range.from && $orderEndDate < range.to, false)) {
service.OrderService.sendOrdersByProductReport(d);
}
}
function print(text) {
Sys.println(text + "<br/>");
}

63
src/controller/Messages.hx

@ -1,22 +1,20 @@
package controller;
import db.Message;
import db.UserContract;
import sugoi.form.ListData;
import sugoi.form.elements.*;
import sugoi.form.Form;
class Messages extends Controller
{
public function new()
{
class Messages extends Controller {
public function new() {
super();
if (!app.user.canAccessMessages()) throw Redirect("/");
if (!app.user.canAccessMessages())
throw Redirect("/");
}
@tpl("messages/default.mtt")
function doDefault() {
var form = new Form("msg");
var senderName = "";
@ -25,7 +23,6 @@ class Messages extends Controller
if (App.current.session.data.whichUser == 1 && app.user.email2 != null) {
senderMail = app.user.email2;
senderName = app.user.firstName2 + " " + app.user.lastName2;
} else {
senderMail = app.user.email;
senderName = app.user.firstName + " " + app.user.lastName;
@ -39,22 +36,31 @@ class Messages extends Controller
form.addElement(new TextArea("text", t._("Message:"), "", false, null, "style='width:500px;height:350px;'"));
if (form.checkToken()) {
var listId = form.getElement("list").value;
var dest = getSelection(listId);
App.log('about to send emails to listId=<$listId> to destination=${dest.length}');
var mails = [];
for (d in dest) {
if (d.email != null) mails.push(d.email);
if (d.email2 != null) mails.push(d.email2);
if (d.email != null)
mails.push(d.email);
if (d.email2 != null)
mails.push(d.email2);
}
// send mail confirmation link
var e = new sugoi.mail.Mail();
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.setReplyTo(form.getValueOf("senderMail"), form.getValueOf("senderName"));
App.log('add CC header to message: ${e.getSubject()}');
e.setHeader("CC", "pvincent@comptoirduvrac.re");
// 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");
@ -70,11 +76,11 @@ class Messages extends Controller
lm.title = e.getSubject();
lm.date = Date.now();
lm.body = e.getHtmlBody();
if (listId != null) lm.recipientListId = listId;
if (listId != null)
lm.recipientListId = listId;
lm.sender = app.user;
lm.insert();
throw Ok("/messages", t._("The message has been sent"));
}
@ -83,15 +89,15 @@ class Messages extends Controller
if (app.user.isAmapManager()) {
view.sentMessages = Message.manager.search($amap == app.user.amap && $recipientListId != null, {orderBy: -date, limit: 20}, false);
} 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")
public function doMessage(msg:Message) {
if (!app.user.isAmapManager() && msg.sender.id != app.user.id) throw Error("/", t._("Non authorized access"));
if (!app.user.isAmapManager() && msg.sender.id != app.user.id)
throw Error("/", t._("Non authorized access"));
view.list = getListName(msg.recipientListId);
view.msg = msg;
@ -106,7 +112,6 @@ class Messages extends Controller
}*/
view.status = s;
}
function getLists():FormData<String> {
@ -117,8 +122,8 @@ class Messages extends Controller
out.push({value: '3', label: t._("TEST: me + spouse")});
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);
for (c in contracts) {
@ -126,7 +131,6 @@ class Messages extends Controller
out.push({value: 'c' + c.id, label: label});
}
return out;
}
/**
@ -137,11 +141,11 @@ class Messages extends Controller
var l = getLists();
for (ll in l) {
if (ll.value == listId) return ll.label;
if (ll.value == listId)
return ll.label;
}
return null;
}
function getSelection(listId:String) {
@ -153,7 +157,6 @@ class Messages extends Controller
var pids = Lambda.map(pids, function(x) return x.id);
var up = db.UserContract.manager.search($productId in pids, false);
var users = [];
for (order in up) {
if (!Lambda.has(users, order.user)) {
@ -164,7 +167,6 @@ class Messages extends Controller
}
}
return users;
} else {
var out = [];
switch (listId) {
@ -184,7 +186,8 @@ class Messages extends Controller
// 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))) {
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);
}
}
@ -200,12 +203,6 @@ class Messages extends Controller
}
return out;
}
}
}
Loading…
Cancel
Save