You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
574 lines
16 KiB
574 lines
16 KiB
package db;
|
|
import sys.db.Object;
|
|
import sys.db.Types;
|
|
import db.UserAmap;
|
|
import Common;
|
|
|
|
enum UserFlags {
|
|
HasEmailNotif4h; //send notifications by mail 4h before
|
|
HasEmailNotif24h; //send notifications by mail 24h before
|
|
HasEmailNotifOuverture; //send notifications by mail on command open
|
|
//Tuto; //enable tutorials
|
|
}
|
|
|
|
/**
|
|
* Site-wide right
|
|
*/
|
|
enum RightSite {
|
|
Admin;
|
|
}
|
|
|
|
@:index(email,unique)
|
|
class User extends Object {
|
|
|
|
public var id : SId;
|
|
public var lang : SString<2>;
|
|
@:skip public var name(get, set) : String;
|
|
public var pass : STinyText;
|
|
public var rights : SFlags<RightSite>;
|
|
|
|
public var firstName:SString<32>;
|
|
public var lastName:SString<32>;
|
|
public var email : SString<64>;
|
|
public var phone:SNull<SString<19>>;
|
|
|
|
public var firstName2:SNull<SString<32>>;
|
|
public var lastName2:SNull<SString<32>>;
|
|
public var email2 : SNull<SString<64>>;
|
|
public var phone2:SNull<SString<19>>;
|
|
|
|
public var address1:SNull<SString<64>>;
|
|
public var address2:SNull<SString<64>>;
|
|
public var zipCode:SNull<SString<32>>;
|
|
public var city:SNull<SString<25>>;
|
|
|
|
@:skip public var amap(get_amap, null) : Amap;
|
|
|
|
public var cdate : SDate; //creation
|
|
public var ldate : SNull<SDateTime>; //derniere connexion
|
|
|
|
public var flags : SFlags<UserFlags>;
|
|
|
|
@hideInForms public var tutoState : SNull<SData<{name:String,step:Int}>>; //tutorial state
|
|
|
|
public var apiKey : SNull<SString<128>>; //private API key
|
|
|
|
public function new() {
|
|
super();
|
|
|
|
//default values
|
|
cdate = Date.now();
|
|
rights = sys.db.Types.SFlags.ofInt(0);
|
|
flags = sys.db.Types.SFlags.ofInt(0);
|
|
flags.set(HasEmailNotif24h);
|
|
flags.set(HasEmailNotifOuverture);
|
|
lang = "fr";
|
|
pass = "";
|
|
|
|
}
|
|
|
|
public override function toString() {
|
|
return getName()+" ["+id+"]";
|
|
}
|
|
|
|
public function isAdmin() {
|
|
return rights.has(Admin) || id==1;
|
|
}
|
|
|
|
public static function login(user:db.User, email:String) {
|
|
|
|
user.lock();
|
|
user.ldate = Date.now();
|
|
user.update();
|
|
App.current.session.setUser(user);
|
|
if (App.current.session.data == null) App.current.session.data = {};
|
|
//Who's connected, user1 or user2 ?
|
|
App.current.session.data.whichUser = (email == user.email) ? 0 : 1;
|
|
|
|
}
|
|
|
|
/**
|
|
* is this user the manager of the current group
|
|
*/
|
|
public function isAmapManager() {
|
|
var a = getAmap();
|
|
if (a == null) return false;
|
|
var ua = getUserAmap(a);
|
|
if (ua == null) return false;
|
|
return ua.hasRight(Right.GroupAdmin);
|
|
}
|
|
|
|
function getUserAmap(amap:db.Amap):db.UserAmap {
|
|
return db.UserAmap.get(this, amap);
|
|
}
|
|
|
|
public function isFullyRegistred(){
|
|
return pass != null && pass != "";
|
|
}
|
|
|
|
public function makeMemberOf(group:db.Amap){
|
|
var ua = db.UserAmap.get(this, group);
|
|
if (ua == null) {
|
|
ua = new db.UserAmap();
|
|
ua.user = this;
|
|
ua.amap = group;
|
|
ua.insert();
|
|
}
|
|
return ua;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Est ce que ce membre a la gestion de ce contrat
|
|
* si null, est ce qu'il a la gestion d'un des contrat, n'importe lequel (utilse pour afficher 'gestion contrat' dans la nav )
|
|
* @param contract
|
|
*/
|
|
public function isContractManager(?contract:db.Contract ) {
|
|
if (isAdmin()) return true;
|
|
if (contract != null) {
|
|
return canManageContract(contract);
|
|
}else {
|
|
var ua = getUserAmap(getAmap());
|
|
if (ua == null) return false;
|
|
if (ua.rights == null) return false;
|
|
for (r in ua.rights) {
|
|
switch(r) {
|
|
case Right.ContractAdmin(cid):
|
|
return true;
|
|
default:
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function canManageAllContracts(){
|
|
if (isAdmin()) return true;
|
|
var ua = getUserAmap(getAmap());
|
|
if (ua == null) return false;
|
|
if (ua.rights == null) return false;
|
|
for (r in ua.rights) {
|
|
switch(r) {
|
|
case Right.ContractAdmin(cid):
|
|
if(cid==null) return true;
|
|
default:
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function canAccessMessages():Bool {
|
|
var ua = getUserAmap(getAmap());
|
|
if (ua == null) return false;
|
|
if (ua.hasRight(Right.Messages)) return true;
|
|
return false;
|
|
}
|
|
|
|
public function canAccessMembership():Bool {
|
|
var ua = getUserAmap(getAmap());
|
|
if (ua == null) return false;
|
|
if (ua.hasRight(Right.Membership)) return true;
|
|
return false;
|
|
}
|
|
|
|
public function canManageContract(c:db.Contract):Bool {
|
|
var ua = getUserAmap(c.amap);
|
|
if (ua == null) return false;
|
|
if (ua.hasRight(Right.ContractAdmin())) return true;
|
|
if (ua.hasRight(Right.ContractAdmin(c.id))) return true;
|
|
return false;
|
|
}
|
|
|
|
public function getContractManager(?lock=false) {
|
|
return Contract.manager.search($amap == amap && $contact == this, false);
|
|
}
|
|
|
|
public function getName() {
|
|
return get_name();
|
|
}
|
|
|
|
public function get_name() {
|
|
return lastName + " " + firstName;
|
|
}
|
|
|
|
public function getCoupleName() {
|
|
var n = lastName + " " + firstName;
|
|
if (lastName2 != null) {
|
|
n = n + " / " + lastName2 + " " + firstName2;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
public function set_name(name:String) {
|
|
var name = name.split(' ');
|
|
firstName = name[0];
|
|
lastName = name[1];
|
|
return firstName+" "+lastName;
|
|
}
|
|
|
|
/**
|
|
* Encode a user password
|
|
* @param p
|
|
*/
|
|
public function setPass(p:String) {
|
|
if (p == null){
|
|
this.pass = "";
|
|
}else{
|
|
this.pass = haxe.crypto.Md5.encode( App.config.get('key') + StringTools.trim(p));
|
|
}
|
|
return this.pass;
|
|
}
|
|
|
|
/**
|
|
* Renvoie les commandes actuelles du user
|
|
* @param _amap force une amap
|
|
* @param lock=false
|
|
*/
|
|
public function getOrders(?_amap:db.Amap,?lock = false):List<UserContract> {
|
|
var a = _amap == null ? getAmap() : _amap;
|
|
var c = a.getActiveContracts(true);
|
|
var cids = Lambda.map(c,function(m) return m.id);
|
|
var pids = Lambda.map(db.Product.manager.search($contractId in cids,false), function(x) return x.id);
|
|
var out = UserContract.manager.search(($userId == id || $userId2 == id) && $productId in pids, lock);
|
|
return out;
|
|
|
|
}
|
|
|
|
/**
|
|
* renvoie les commandes à partir d'une liste de contrats
|
|
*/
|
|
public function getOrdersFromContracts(c:Iterable<db.Contract>):List<db.UserContract> {
|
|
var cids = Lambda.map(c,function(m) return m.id);
|
|
var pids = Lambda.map(db.Product.manager.search($contractId in cids,false), function(x) return x.id);
|
|
return UserContract.manager.search(($userId == id || $userId2 == id) && $productId in pids, false);
|
|
}
|
|
|
|
/**
|
|
* renvoie les commandes de contrat variables à partir d'une distribution
|
|
*/
|
|
public function getOrdersFromDistrib(d:db.Distribution):List<db.UserContract> {
|
|
var pids = Lambda.map(db.Product.manager.search($contractId == d.contract.id, false), function(x) return x.id);
|
|
return UserContract.manager.search(($userId == id || $userId2 == id) && $distributionId==d.id && $productId in pids , false);
|
|
}
|
|
|
|
public function get_amap():Amap {
|
|
return getAmap();
|
|
}
|
|
|
|
/**
|
|
* renvoie l'amap selectionnée par le user en cours
|
|
*/
|
|
public function getAmap() {
|
|
|
|
if (App.current.user != null && id != App.current.user.id) throw "This function is valid only for the current user";
|
|
if (App.current.session == null) return null;
|
|
if (App.current.session.data == null ) return null;
|
|
var a = App.current.session.data.amapId;
|
|
if (a == null) {
|
|
return null;
|
|
}else {
|
|
return Amap.manager.get(a,false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* get groups this user belongs to
|
|
*/
|
|
public function getAmaps():List<db.Amap> {
|
|
return Lambda.map(UserAmap.manager.search($user == this, false), function(o) return o.amap);
|
|
}
|
|
|
|
public function isMemberOf(amap:Amap) {
|
|
return UserAmap.manager.select($user == this && $amapId == amap.id, false) != null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Renvoie la liste des contrats dans lequel l'adherent a des commandes
|
|
* @param lock=false
|
|
* @return
|
|
*/
|
|
public function getContracts(?lock=false):Array<Contract> {
|
|
var out = [];
|
|
var ucs = getOrders(lock);
|
|
for (uc in ucs) {
|
|
if (!Lambda.has(out, uc.product.contract)) {
|
|
out.push(uc.product.contract);
|
|
}
|
|
}
|
|
return out;
|
|
|
|
}
|
|
|
|
/**
|
|
* Merge fields of 2 users, then delete the second (u2)
|
|
* Be carefull : check before calling this function that u2 can be safely deleted !
|
|
*/
|
|
public function merge(u2:db.User) {
|
|
|
|
this.lock();
|
|
u2.lock();
|
|
|
|
var m = function(a, b) {
|
|
return a == null || a=="" ? b : a;
|
|
}
|
|
|
|
this.address1 = m(this.address1, u2.address1);
|
|
this.address2 = m(this.address2, u2.address2);
|
|
this.zipCode = m(this.zipCode, u2.zipCode);
|
|
this.city = m(this.city, u2.city);
|
|
|
|
//find how to merge the 2 names in each account
|
|
if (this.email == u2.email) {
|
|
|
|
this.firstName = m(this.firstName, u2.firstName);
|
|
this.lastName = m(this.lastName, u2.lastName);
|
|
this.phone = m(this.phone, u2.phone);
|
|
|
|
} else if (this.email == u2.email2) {
|
|
|
|
this.firstName = m(this.firstName, u2.firstName2);
|
|
this.lastName = m(this.lastName, u2.lastName2);
|
|
this.phone = m(this.phone, u2.phone2);
|
|
}
|
|
|
|
if (this.email2 == u2.email) {
|
|
|
|
this.firstName2 = m(this.firstName2, u2.firstName);
|
|
this.lastName2 = m(this.lastName2, u2.lastName);
|
|
this.phone2 = m(this.phone2, u2.phone);
|
|
|
|
} else if (this.email2 == u2.email2) {
|
|
|
|
this.firstName2 = m(this.firstName2, u2.firstName2);
|
|
this.lastName2 = m(this.lastName2, u2.lastName2);
|
|
this.phone2 = m(this.phone2, u2.phone2);
|
|
|
|
}
|
|
|
|
u2.delete();
|
|
this.update();
|
|
|
|
}
|
|
|
|
public static function getOrCreate(firstName:String, lastName:String, email:String):db.User{
|
|
var u = db.User.manager.select($email == email || $email2 == email, true);
|
|
if (u == null){
|
|
u = new db.User();
|
|
u.firstName = firstName;
|
|
u.lastName = lastName;
|
|
u.email = email;
|
|
u.insert();
|
|
}
|
|
return u;
|
|
}
|
|
|
|
/**
|
|
* Search for similar users in the DB ( same firstName+lastName or same email )
|
|
*/
|
|
public static function __getSimilar(firstName:String, lastName:String, email:String,?firstName2:String, ?lastName2:String, ?email2:String):List<db.User> {
|
|
var out = new Array();
|
|
out = Lambda.array(User.manager.search($firstName.like(firstName) && $lastName.like(lastName), false));
|
|
out = out.concat(Lambda.array(User.manager.search($email.like(email), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($firstName2.like(firstName) && $lastName2.like(lastName), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($email2.like(email), false)));
|
|
|
|
//recherche pour le deuxieme user
|
|
if (lastName2 != "" && lastName2 != null && firstName2 != "" && firstName2 != null) {
|
|
out = out.concat(Lambda.array(User.manager.search($firstName.like(firstName2) && $lastName.like(lastName2), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($firstName2.like(firstName2) && $lastName2.like(lastName2), false)));
|
|
}
|
|
if (email2 != null && email2 != "") {
|
|
out = out.concat(Lambda.array(User.manager.search($email.like(email2), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($email2.like(email2), false)));
|
|
}
|
|
|
|
//dedouble
|
|
var x = new Map<Int,db.User>();
|
|
for ( oo in out) {
|
|
x.set(oo.id, oo);
|
|
}
|
|
return Lambda.list(x);
|
|
}
|
|
|
|
/**
|
|
* Search for similar users in the DB ( same email )
|
|
*/
|
|
public static function getSameEmail(email:String, ?email2:String){
|
|
|
|
var out = new Array();
|
|
out = out.concat(Lambda.array(User.manager.search($email.like(email), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($email2.like(email), false)));
|
|
if (email2 != null && email2 != "") {
|
|
out = out.concat(Lambda.array(User.manager.search($email.like(email2), false)));
|
|
out = out.concat(Lambda.array(User.manager.search($email2.like(email2), false)));
|
|
}
|
|
return Lambda.list(out);
|
|
}
|
|
|
|
/**
|
|
* Get users with no contracts
|
|
**/
|
|
public static function getUsers_NoContracts(?index:Int,?limit:Int):List<db.User> {
|
|
var productsIds = App.current.user.getAmap().getProducts().map(function(x) return x.id);
|
|
var uc = UserContract.manager.search($productId in productsIds, false);
|
|
var uc2 = uc.map(function(x) return x.user.id); //liste des userId avec un contrat dans cette amap
|
|
|
|
// J. Le Clerc - BUGFIX#1 Ne pas oublier les contrats alternés
|
|
for (u in uc) {
|
|
if (u.user2 != null) {
|
|
uc2.add(u.user2.id);
|
|
}
|
|
}
|
|
|
|
if (uc2.length > 0){
|
|
//les gens qui sont dans cette amap et qui n'ont pas de contrat de cette amap
|
|
var ua = db.UserAmap.manager.unsafeObjects("select * from UserAmap where amapId=" + App.current.user.getAmap().id +" and userId NOT IN(" + uc2.join(",") + ")", false);
|
|
return Lambda.map(ua, function(x) return x.user);
|
|
}else{
|
|
return App.current.user.amap.getMembers();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* User with contracts
|
|
*/
|
|
public static function getUsers_Contracts(?index:Int,?limit:Int):List<db.User> {
|
|
var productsIds = App.current.user.getAmap().getProducts().map(function(x) return x.id);
|
|
if (productsIds.length == 0) return new List();
|
|
return db.User.manager.unsafeObjects("select u.* from User u, UserContract uc where uc.productId IN(" + productsIds.join(",") + ") AND (uc.userId=u.id OR uc.userId2=u.id) group by u.id ORDER BY u.lastName", false);
|
|
}
|
|
|
|
|
|
public static function getUsers_NoMembership(?index:Int,?limit:Int):List<db.User> {
|
|
var ua = new List();
|
|
if (index == null && limit == null) {
|
|
ua = db.UserAmap.manager.search($amap == App.current.user.amap, false);
|
|
}else {
|
|
ua = db.UserAmap.manager.search($amap == App.current.user.amap,{limit:[index,limit]}, false);
|
|
}
|
|
|
|
for (u in Lambda.array(ua)) {
|
|
if (u.hasValidMembership()) ua.remove(u);
|
|
}
|
|
|
|
return Lambda.map(ua, function(x) return x.user);
|
|
}
|
|
|
|
public static function getUsers_NewUsers(?index:Int, ?limit:Int):List<db.User> {
|
|
|
|
var uas = db.UserAmap.manager.search($amap == App.current.user.amap, false);
|
|
var ids = Lambda.map(uas, function(x) return x.user.id);
|
|
if (index == null && limit == null) {
|
|
return db.User.manager.search($pass == "" && ($id in ids), {orderBy:lastName} ,false);
|
|
}else {
|
|
return db.User.manager.search($pass == "" && ($id in ids), {limit:[index, limit] ,orderBy:lastName} , false);
|
|
}
|
|
|
|
}
|
|
|
|
public function sendInvitation(group:db.Amap) {
|
|
|
|
var t = sugoi.i18n.Locale.texts;
|
|
|
|
if (isFullyRegistred()) throw t._("This user cannot receive an invitation");
|
|
|
|
/*var group : db.Amap = null;
|
|
|
|
if (App.current.user == null) {
|
|
group = this.getAmaps().first();
|
|
}else {
|
|
//prend l'amap du user connecté qui a lancé l'invite.
|
|
group = App.current.user.amap;
|
|
}*/
|
|
|
|
//store token
|
|
var k = sugoi.db.Session.generateId();
|
|
sugoi.db.Cache.set("validation" + k, this.id, 60 * 60 * 24 * 30); //expire in 1 month
|
|
|
|
var e = new sugoi.mail.Mail();
|
|
if (group != null){
|
|
e.setSubject(t._("Invitation")+" "+group.name);
|
|
}else{
|
|
e.setSubject(t._("Invitation Cagette.net"));
|
|
}
|
|
|
|
e.addRecipient(this.email,this.getName());
|
|
e.setSender(App.config.get("default_email"),t._("Cagette.net"));
|
|
|
|
var html = App.current.processTemplate("mail/invitation.mtt", {
|
|
email:email,
|
|
email2:email2,
|
|
groupName:(group == null?null:group.name),
|
|
name:firstName,
|
|
k:k
|
|
} );
|
|
e.setHtmlBody(html);
|
|
|
|
App.sendMail(e);
|
|
}
|
|
|
|
/**
|
|
* cleaning before saving
|
|
*/
|
|
override public function insert() {
|
|
clean();
|
|
super.insert();
|
|
}
|
|
|
|
override public function update() {
|
|
clean();
|
|
super.update();
|
|
}
|
|
|
|
function clean() {
|
|
|
|
//emails
|
|
this.email = this.email.toLowerCase();
|
|
if (this.email2 != null) this.email2 = this.email2.toLowerCase();
|
|
|
|
//lastname
|
|
if (this.lastName != null) this.lastName = this.lastName.toUpperCase();
|
|
if (this.lastName2 != null) this.lastName2 = this.lastName2.toUpperCase();
|
|
|
|
if(pass==null) pass="";
|
|
}
|
|
|
|
public function infos():UserInfo{
|
|
return {
|
|
id:id,
|
|
name : getName(),
|
|
email : email
|
|
};
|
|
}
|
|
|
|
/**
|
|
* get form labels
|
|
*/
|
|
public static function getLabels():Map<String,String>{
|
|
var t = sugoi.i18n.Locale.texts;
|
|
return [
|
|
"firstName" => t._("First name"),
|
|
"lastName" => t._("Last name"),
|
|
"email" => t._("Email"),
|
|
"phone" => t._("Phone"),
|
|
"firstName2"=> t._("Partner first name"),
|
|
"lastName2" => t._("Partner last name"),
|
|
"email2" => t._("Partner email"),
|
|
"phone2" => t._("Partner phone"),
|
|
"lang" => t._("Language"),
|
|
"address1" => t._("Address 1"),
|
|
"address2" => t._("Address 2"),
|
|
"zipCode" => t._("Zip code"),
|
|
"city" => t._("City"),
|
|
"rights" => t._("Rights"),
|
|
"cdate" => t._("Registration date"),
|
|
"flags" => t._("Options"),
|
|
"pass" => t._("Password"),
|
|
];
|
|
}
|
|
|
|
|
|
}
|