|
|
package; import Common; using tools.ObjectListTool; using Lambda; using tools.ObjectListTool;
/** * MultiDistrib represents many db.Distribution which happen on the same day + same place. * * @author fbarbut */ class MultiDistrib { public var distributions : Array<db.Distribution>; public var contracts : Array<db.Contract>; //public var actions : Array<Link>; public var extraHtml : String; public var type : Null<Int>; //contract type, both contract types cannot be mixed in a same multidistrib.
public function new(){ distributions = []; contracts = []; extraHtml = ""; //actions = []; } public static function get(date:Date, place:db.Place,contractType:Int){ var m = new MultiDistrib(); var start = tools.DateTool.setHourMinute(date, 0, 0); var end = tools.DateTool.setHourMinute(date, 23, 59); var contracts = place.amap.getContracts().array();
//filter by type if(contractType==db.Contract.TYPE_VARORDER){ for(c in contracts.copy() ){ if(c.type!=db.Contract.TYPE_VARORDER) contracts.remove(c); } }else if(contractType==db.Contract.TYPE_CONSTORDERS){ for(c in contracts.copy() ){ if(c.type!=db.Contract.TYPE_CONSTORDERS) contracts.remove(c); } } var cids = contracts.getIds(); m.distributions = db.Distribution.manager.search(($contractId in cids) && ($date >= start) && ($date <= end) && $place==place, { orderBy:date }, false).array(); m.type = contractType; return m; }
/** Get multidistribs from a time range + place + type **/ public static function getFromTimeRange(group:db.Amap,from:Date,to:Date,?contractType:Int):Array<MultiDistrib>{ var multidistribs = []; var start = tools.DateTool.setHourMinute(from, 0, 0); var end = tools.DateTool.setHourMinute(to, 23, 59); var cids = group.getContracts().getIds(); var distributions = db.Distribution.manager.search(($contractId in cids) && ($date >= start) && ($date <= end) , { orderBy:date }, false).array();
//sort by day-place-type var multidistribs = new Map<String,MultiDistrib>(); for ( d in distributions){
//filter by contractType if(contractType!=null){ if(d.contract.type!=contractType) continue; }
var key = d.getKey() + "-" + d.contract.type; if(multidistribs[key]==null){ var m = new MultiDistrib(); m.distributions.push(d); m.type = d.contract.type; multidistribs[key] = m; }else{ multidistribs[key].distributions.push(d); } } var multidistribs = Lambda.array(multidistribs);
//trigger event for(md in multidistribs) App.current.event(MultiDistribEvent(md)); //sort by date desc multidistribs.sort(function(x,y){ return Math.round( x.getDate().getTime()/1000 ) - Math.round(y.getDate().getTime()/1000 ); });
return multidistribs; }
/** * TODO : refacto this to use getFromTimeRange(); */ /*public static function getNextMultiDeliveries(group:db.Amap){ var out = new Map < String, { place:db.Place, //common delivery place startDate:Date, //global delivery start endDate:Date, //global delivery stop orderStartDate:Date, //global orders opening date orderEndDate:Date, //global orders closing date active:Bool, products:Array<ProductInfo>, //available products ( if no order ) myOrders:Array<{distrib:db.Distribution,orders:Array<UserOrder>}> //my orders }>(); var n = Date.now(); var now = new Date(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0); var contracts = db.Contract.getActiveContracts(group); var cids = Lambda.map(contracts, function(p) return p.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); //available deliveries var inSixMonth = DateTools.delta(now, 1000.0 * 60 * 60 * 24 * 30 * 6); var distribs = db.Distribution.manager.search(($contractId in cids) && $date >= now && $date <= inSixMonth , { orderBy:date }, false); for (d in distribs) { //we had the distribution key ( place+date ) and the contract type in order to separate constant and varying contracts var key = d.getKey() + "|" + d.contract.type; var o = out.get(key); if (o == null) o = {place:d.place, startDate:d.date, active:null, endDate:d.end, products:[], myOrders:[], orderStartDate:null,orderEndDate:null}; //user orders var orders = []; if(App.current.user!=null) orders = d.contract.getUserOrders(App.current.user,d); if (orders.length > 0){ o.myOrders.push({distrib:d,orders:service.OrderService.prepare(orders)}); }else{ //no "order block" if no shop mode if (!group.hasShopMode() ) { continue; }
//if its a constant order contract, skip this delivery if (d.contract.type == db.Contract.TYPE_CONSTORDERS){ continue; } //products preview if no orders for ( p in d.contract.getProductsPreview(9)){ o.products.push( p.infos(null,false) ); } } if (d.contract.type == db.Contract.TYPE_VARORDER){ //old distribs may have an empty orderStartDate if (d.orderStartDate == null) { continue; } //if order opening is more far than 1 month, skip it // if (d.orderStartDate.getTime() > inOneMonth.getTime() ){ // continue; // } //display closest opening date if (o.orderStartDate == null){ o.orderStartDate = d.orderStartDate; }else if (o.orderStartDate.getTime() > d.orderStartDate.getTime()){ o.orderStartDate = d.orderStartDate; } //display most far closing date if (o.orderEndDate == null){ o.orderEndDate = d.orderEndDate; }else if (o.orderEndDate.getTime() < d.orderEndDate.getTime()){ o.orderEndDate = d.orderEndDate; } out.set(key, o); }else{ //in constant orders, add block only if there is an order if(o.myOrders.length>0) out.set(key, o); } } //shuffle and limit product lists for ( o in out){ o.products = thx.Arrays.shuffle(o.products); o.products = o.products.slice(0, 9); } //decide if active or not var now = Date.now(); for( o in out){ if (o.orderStartDate == null) continue; //constant orders if (now.getTime() >= o.orderStartDate.getTime() && now.getTime() <= o.orderEndDate.getTime() ){ //order currently open o.active = true; }else { o.active = false; } } return Lambda.array(out); }*/
public function getPlace(){ if(distributions.length==0) throw "This multidistrib is empty"; return distributions[0].place; }
public function getDate(){ if(distributions.length==0) throw "This multidistrib is empty"; return distributions[0].date; }
public function getEndDate(){ if(distributions.length==0) throw "This multidistrib is empty"; return distributions[0].end; }
public function getProductsExcerpt():Array<ProductInfo>{ var key = "productsExcerpt-"+getKey(); var cache:Array<Int> = sugoi.db.Cache.get(key); if(cache!=null){ var out = []; //try{ for( pid in cache.array()){ var p = db.Product.manager.get(pid,false); if(p!=null) out.push(p.infos()); } //}catch(e:Dynamic){ // sugoi.db.Cache.destroy(key); // } return out; }
var products = []; for( d in distributions){ for ( p in d.contract.getProductsPreview(9)){ products.push( p.infos(null,false) ); } } products = thx.Arrays.shuffle(products); products = products.slice(0, 9); sugoi.db.Cache.set(key, products.map(function(p)return p.id).array(), 3600 ); return products;
}
public function userHasOrders(user:db.User):Bool{ if(user==null) return false; for ( d in distributions){ if(d.getUserOrders(user).length>0) return true; } return false; } /** orders currently open ? **/ public function isActive(){
if (getOrdersStartDate() == null) return false; //constant orders var now = Date.now(); if (now.getTime() >= getOrdersStartDate().getTime() && now.getTime() <= getOrdersEndDate().getTime() ){ return true; }else { return false; } }
public function getOrdersStartDate(){ var date = null;
for( d in distributions ){ if(d.orderStartDate==null) continue; //display closest opening date if (date == null){ date = d.orderStartDate; }else if (date.getTime() > d.orderStartDate.getTime()){ date = d.orderStartDate; } } return date; }
/*public function hasOnlyConstantOrders(){ for(d in distributions){ if( d.contract.type==db.Contract.TYPE_VARORDER ) { return false; } } return true; }*/
public function getOrdersEndDate(){ var date = null;
for( d in distributions ){ if(d.orderEndDate==null) continue; //display most far closing date if (date == null){ date = d.orderEndDate; }else if (date.getTime() < d.orderEndDate.getTime()){ date = d.orderEndDate; } } return date; }
/** * Get all orders involved in this multidistrib */ public function getOrders(){ var out = []; for ( d in distributions){ out = out.concat(d.getOrders().array()); } return out; }
/** * Get orders for a user in this multidistrib * @param user */ public function getUserOrders(user:db.User){ var out = []; for ( d in distributions){ var pids = Lambda.map( d.contract.getProducts(false), function(x) return x.id); var userOrders = db.UserContract.manager.search( $userId == user.id && $distributionId==d.id && $productId in pids , false); for( o in userOrders ){ out.push(o); } } return out; } public function getUsers(){ var users = []; for ( o in getOrders()) users.push(o.user); return users.deduplicate(); } public function isConfirmed():Bool{ //cannot be in future if(getDate().getTime()>Date.now().getTime()) return false;
return Lambda.count( distributions, function(d) return d.validated) == distributions.length; } public function checkConfirmed():Bool{ var orders = getOrders(); var c = Lambda.count( orders, function(d) return d.paid) == orders.length; if (c){ for ( d in distributions){ if (!d.validated){ d.lock(); d.validated = true; d.update(); } } } return c; }
//get key by date-place-type public function getKey(){ return distributions[0].getKey() + "-" + distributions[0].contract.type; }
}
|