package controller; import db.UserContract; import sugoi.form.Form; import sugoi.form.elements.HourDropDowns; using tools.DateTool; import Common; class Distribution extends Controller { /** * Attendance sheet by user-product (single distrib) */ @tpl('distribution/list.mtt') function doList(d:db.Distribution) { view.distrib = d; view.place = d.place; view.contract = d.contract; view.orders = service.OrderService.prepare(d.getOrders()); } /** * Attendance sheet by product-user (single distrib) */ @tpl('distribution/listByProductUser.mtt') function doListByProductUser(d:db.Distribution) { view.distrib = d; view.place = d.place; view.contract = d.contract; // view.orders = UserContract.prepare(d.getOrders()); //make a 2 dimensons table : data[userId][productId] //WARNING : BUGS WILL APPEAR if there is many Order line for the same product var data = new Map>(); var products = []; var uo = d.getOrders(); for(o in uo){ products.push(o.product); } for ( o in service.OrderService.prepare(uo)) { var user = data[o.userId]; if (user == null) user = new Map(); user[o.productId] = o; data[o.userId] = user; } //products var products = tools.ObjectListTool.deduplicate(products); products.sort(function(b, a) { return (a.name < b.name)?1:-1; }); view.products = products; //users var users = Lambda.array(d.getUsers()); // var usersMap = tools.ObjectListTool.toIdMap(users); users.sort(function(b, a) { return (a.lastName < b.lastName)?1:-1; }); view.users = users; // view.usersMap = usersMap; view.orders = data; //total to pay by user view.totalByUser = function(uid:Int){ var total = 0.0; for( o in data[uid]) total+= o.total; return total; } //total qty of product view.totalByProduct = function(pid:Int){ var total = 0.0; for( uid in data.keys()){ var x = data[uid][pid]; if(x!=null) total+= x.quantity; } return total; } } function getUser(uid:Int):db.User { return db.User.manager.get(uid, false); } function getBasket(userId, placeId, date){ var user = getUser(userId); var place = db.Place.manager.get(placeId, false); return db.Basket.getOrCreate(user, place, date); } /** * Attendance sheet to print ( mutidistrib ) */ @tpl('distribution/listByDate.mtt') function doListByDate(date:Date,place:db.Place, ?type:String, ?fontSize:String) { if (!app.user.isContractManager()) throw Error('/', t._("Forbidden action")); view.place = place; if (type == null) { //display form var f = new sugoi.form.Form("listBydate", null, sugoi.form.Form.FormMethod.GET); f.addElement(new sugoi.form.elements.RadioGroup("type", "Affichage", [ { value:"one", label:t._("One person per page") }, { value:"contract", label:t._("One person per page sorted by contract") }, { value:"all", label:t._("All") }, { value:"allshort", label:t._("All but without prices and totals") }, ],"all")); f.addElement(new sugoi.form.elements.RadioGroup("fontSize", "Taille de police", [ { value:"S" , label:"S" }, { value:"M" , label:"M" }, { value:"L" , label:"L" }, { value:"XL", label:"XL" }, ], "S", "S", false)); view.form = f; app.setTemplate("form.mtt"); if (f.checkToken()) { var suburl = f.getValueOf("type")+"/"+f.getValueOf("fontSize"); var url = '/distribution/listByDate/' + date.toString().substr(0, 10)+"/"+place.id+"/"+suburl; throw Redirect( url ); } return; }else { view.date = date; view.fontRatio = switch(fontSize){ case "M" : 125; //100x1.25 case "L" : 156; //125x1.25 case "XL": 195; //156x1.25 default : 100; }; switch(type) { case "one": app.setTemplate("distribution/listByDateOnePage.mtt"); case "allshort" : app.setTemplate("distribution/listByDateShort.mtt"); case "contract" : app.setTemplate("distribution/listByDateOnePageContract.mtt"); } var d1 = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); var d2 = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59); var contracts = app.user.amap.getActiveContracts(true); //var cids = Lambda.map(contracts, function(c) return c.id); var cconst = []; var cvar = []; for ( c in contracts) { if (c.type == db.Contract.TYPE_CONSTORDERS) cconst.push(c.id); if (c.type == db.Contract.TYPE_VARORDER) cvar.push(c.id); } //commandes variables var distribs = db.Distribution.manager.search(($contractId in cvar) && $date >= d1 && $date <= d2 && $place==place, false); var orders = db.UserContract.manager.search($distributionId in Lambda.map(distribs, function(d) return d.id) , { orderBy:userId } ); //commandes fixes var distribs = db.Distribution.manager.search(($contractId in cconst) && $date >= d1 && $date <= d2 && $place==place, false); var orders = Lambda.array(orders); for ( d in distribs) { var orders2 = db.UserContract.manager.search($productId in Lambda.map(d.contract.getProducts(), function(d) return d.id) , { orderBy:userId } ); orders = orders.concat(Lambda.array(orders2)); } var orders3 = service.OrderService.prepare(Lambda.list(orders)); view.orders = orders3; if (type == "csv") { var data = new Array(); for (o in orders3) { var basket = getBasket(o.userId,view.place.id,view.date); data.push( { "NUM": basket.num, "ADHERENT":o.userName, "PRODUIT":o.productName, "QTÉ":o.quantity, // "price":view.formatNum(o.productPrice), // "fees":view.formatNum(o.fees), // "total":view.formatNum(o.total), // "paid":o.paid }); } sugoi.tools.Csv.printCsvDataFromObjects(data, ["NUM","ADHERENT", "PRODUIT", "QTÉ"],"Export-commandes-"+date.toString().substr(0,10)+"-Cagette"); //sugoi.tools.Csv.printCsvDataFromObjects(data, ["NUM","ADHERENT", "PRODUIT", "QTÉ","price","fees","total","paid"],"Export-commandes-"+date.toString().substr(0,10)+"-Cagette"); //sugoi.tools.Csv.printCsvDataFromObjects(data, ["NUM","ADHERENT", "PRODUIT", "price", "quantity","fees","total", "paid"],"Export-commandes-"+date.toString().substr(0,10)+"-Cagette"); return; } } } function doDelete(d:db.Distribution) { if (!app.user.isContractManager(d.contract)) throw Error('/', t._("Forbidden action")); var contractId = d.contract.id; try { service.DistributionService.delete(d); } catch(e:tink.core.Error){ throw Error("/contractAdmin/distributions/" + contractId, e.message); } throw Ok("/contractAdmin/distributions/" + contractId, t._("the delivery has been deleted")); } /** * Edit a distribution */ @tpl('form.mtt') function doEdit(d:db.Distribution) { if (!app.user.isContractManager(d.contract)) throw Error('/', t._('Forbidden action') ); var contract = d.contract; var form = sugoi.form.Form.fromSpod(d); form.removeElement(form.getElement("contractId")); form.removeElement(form.getElement("end")); form.removeElement(form.getElement("distributionCycleId")); var x = new sugoi.form.elements.HourDropDowns("end", t._("End time") ,d.end,true); form.addElement(x, 3); if (d.contract.type == db.Contract.TYPE_VARORDER ) { form.addElement(new sugoi.form.elements.DatePicker("orderStartDate", t._("Orders opening date"), d.orderStartDate)); form.addElement(new sugoi.form.elements.DatePicker("orderEndDate", t._("Orders closing date"), d.orderEndDate)); } if (form.isValid()) { var orderStartDate = null; var orderEndDate = null; try{ if (d.contract.type == db.Contract.TYPE_VARORDER ) { orderStartDate = form.getValueOf("orderStartDate"); orderEndDate = form.getValueOf("orderEndDate"); } d = service.DistributionService.edit(d, form.getValueOf("date"), form.getValueOf("end"), form.getValueOf("placeId"), form.getValueOf("distributor1Id"), form.getValueOf("distributor2Id"), form.getValueOf("distributor3Id"), form.getValueOf("distributor4Id"), orderStartDate, orderEndDate); } catch(e:tink.core.Error){ throw Error('/contractAdmin/distributions/' + contract.id,e.message); } if (d.date == null) { var msg = t._("The distribution has been proposed to the supplier, please wait for its validation"); throw Ok('/contractAdmin/distributions/'+contract.id, msg ); } else { throw Ok('/contractAdmin/distributions/'+contract.id, t._("The distribution has been recorded") ); } } else { app.event(PreEditDistrib(d)); } view.form = form; view.title = t._("Edit a distribution"); } @tpl('form.mtt') function doEditCycle(d:db.DistributionCycle) { if (!app.user.isContractManager(d.contract)) throw Error('/', 'Action interdite'); var form = sugoi.form.Form.fromSpod(d); form.removeElement(form.getElement("contractId")); if (form.isValid()) { form.toSpod(d); //update model d.update(); throw Ok('/contractAdmin/distributions/'+d.contract.id, t._("The delivery is now up to date")); } view.form = form; view.title = t._("Modify a delivery"); } @tpl("form.mtt") public function doInsert(contract:db.Contract) { if (!app.user.isContractManager(contract)) throw Error('/', t._('Forbidden action') ); var d = new db.Distribution(); d.place = contract.amap.getMainPlace(); var form = sugoi.form.Form.fromSpod(d); form.removeElement(form.getElement("contractId")); form.removeElement(form.getElement("distributionCycleId")); form.removeElement(form.getElement("end")); var x = new sugoi.form.elements.HourDropDowns("end", t._("End time") ); form.addElement(x, 3); //default values form.getElement("date").value = DateTool.now().deltaDays(30).setHourMinute(19, 0); form.getElement("end").value = DateTool.now().deltaDays(30).setHourMinute(20, 0); if (contract.type == db.Contract.TYPE_VARORDER ) { form.addElement(new sugoi.form.elements.DatePicker("orderStartDate", t._("Orders opening date"),DateTool.now().deltaDays(10).setHourMinute(8, 0))); form.addElement(new sugoi.form.elements.DatePicker("orderEndDate", t._("Orders closing date"),DateTool.now().deltaDays(20).setHourMinute(23, 59))); } if (form.isValid()) { var createdDistrib = null; var orderStartDate = null; var orderEndDate = null; try { if (contract.type == db.Contract.TYPE_VARORDER ) { orderStartDate = form.getValueOf("orderStartDate"); orderEndDate = form.getValueOf("orderEndDate"); } createdDistrib = service.DistributionService.create( contract, form.getValueOf("date"), form.getValueOf("end"), form.getValueOf("placeId"), form.getValueOf("distributor1Id"), form.getValueOf("distributor2Id"), form.getValueOf("distributor3Id"), form.getValueOf("distributor4Id"), orderStartDate, orderEndDate); } catch(e:tink.core.Error){ throw Error('/contractAdmin/distributions/' + contract.id,e.message); } if (createdDistrib.date == null) { var html = t._("Your request for a delivery has been sent to ::supplierName::.
Be patient, you will receive an e-mail indicating if the request has been validated or refused.", {supplierName:contract.vendor.name}); var btn = "OK"; App.current.view.extraNotifBlock = App.current.processTemplate("block/modal.mtt",{html:html,title:t._("Distribution request sent"),btn:btn} ); } else { throw Ok('/contractAdmin/distributions/'+ createdDistrib.contract.id , t._("The distribution has been recorded") ); } }else{ //event app.event(PreNewDistrib(contract)); } view.form = form; view.title = t._("Create a distribution"); } /** * create a distribution cycle for a contract */ @tpl("form.mtt") public function doInsertCycle(contract:db.Contract) { if (!app.user.isContractManager(contract)) throw Error('/', t._("Forbidden action")); var dc = new db.DistributionCycle(); dc.place = contract.amap.getMainPlace(); var form = sugoi.form.Form.fromSpod(dc); form.removeElementByName("contractId"); form.getElement("startDate").value = DateTool.now(); form.getElement("endDate").value = DateTool.now().deltaDays(30); //start hour form.removeElementByName("startHour"); var x = new HourDropDowns("startHour", t._("Start time"), DateTool.now().setHourMinute( 19, 0) , true); form.addElement(x, 5); //end hour form.removeElement(form.getElement("endHour")); var x = new HourDropDowns("endHour", t._("End time"), DateTool.now().setHourMinute(20, 0), true); form.addElement(x, 6); if (contract.type == db.Contract.TYPE_VARORDER){ form.getElement("daysBeforeOrderStart").value = 10; form.getElement("daysBeforeOrderStart").required = true; form.removeElementByName("openingHour"); var x = new HourDropDowns("openingHour", t._("Opening time"), DateTool.now().setHourMinute(8, 0) , true); form.addElement(x, 8); form.getElement("daysBeforeOrderEnd").value = 2; form.getElement("daysBeforeOrderEnd").required = true; form.removeElementByName("closingHour"); var x = new HourDropDowns("closingHour", t._("Closing time"), DateTool.now().setHourMinute(23, 0) , true); form.addElement(x, 10); }else{ form.removeElementByName("daysBeforeOrderStart"); form.removeElementByName("daysBeforeOrderEnd"); form.removeElementByName("openingHour"); form.removeElementByName("closingHour"); } if (form.isValid()) { var createdDistribCycle = null; var daysBeforeOrderStart = null; var daysBeforeOrderEnd = null; var openingHour = null; var closingHour = null; try{ if (contract.type == db.Contract.TYPE_VARORDER) { daysBeforeOrderStart = form.getValueOf("daysBeforeOrderStart"); daysBeforeOrderEnd = form.getValueOf("daysBeforeOrderEnd"); openingHour = form.getValueOf("openingHour"); closingHour = form.getValueOf("closingHour"); } createdDistribCycle = service.DistributionService.createCycle( contract, form.getElement("cycleType").getValue(), form.getValueOf("startDate"), form.getValueOf("endDate"), form.getValueOf("startHour"), form.getValueOf("endHour"), daysBeforeOrderStart, daysBeforeOrderEnd, openingHour, closingHour, form.getValueOf("placeId")); } catch(e:tink.core.Error){ throw Error('/contractAdmin/distributions/' + contract.id,e.message); } if (createdDistribCycle != null) { throw Ok('/contractAdmin/distributions/'+ contract.id, t._("The delivery has been saved")); } } else{ dc.contract = contract; app.event(PreNewDistribCycle(dc)); } view.form = form; view.title = t._("Schedule a recurrent delivery"); } /** * Delete a distribution cycle */ public function doDeleteCycle(cycle:db.DistributionCycle){ if (!app.user.isContractManager(cycle.contract)) throw Error('/', t._("Forbidden action")); var contractId = cycle.contract.id; var messages = service.DistributionService.deleteCycleDistribs(cycle); if (messages.length > 0){ App.current.session.addMessage( messages.join("
"),true); } throw Ok("/contractAdmin/distributions/" + contractId, t._("Recurrent deliveries deleted")); } /** * Doodle-like participation planning */ @tpl("distribution/planning.mtt") public function doPlanning(contract:db.Contract) { view.contract = contract; var doodle = new Map}>(); var distribs = contract.getDistribs(true, 150); for ( d in distribs ) { for (u in [d.distributor1, d.distributor2, d.distributor3, d.distributor4]) { if (u != null) { var udoodle = doodle.get(u.id); if (udoodle == null) udoodle = { user:u, planning:new Map() }; udoodle.planning.set(d.id, true); doodle.set(u.id, udoodle); } } } view.distribs = distribs; view.doodle = doodle; } /** * Ajax service for doPlanning() */ public function doRegister(args: { register:Bool, distrib:db.Distribution } ) { if (args != null) { var d = args.distrib; d.lock(); if (args.register) { if (d.distributor1 == null) d.distributor1 = app.user; else if (d.distributor2 == null) d.distributor2 = app.user; else if (d.distributor3 == null) d.distributor3 = app.user; else if (d.distributor4 == null) d.distributor4 = app.user; }else { if (d.distributor1 == app.user) d.distributor1 = null; else if (d.distributor2 == app.user) d.distributor2 = null; else if (d.distributor3 == app.user) d.distributor3 = null; else if (d.distributor4 == app.user) d.distributor4 = null; } d.update(); } } /** * Validate a multi-distrib * @param date * @param place */ @tpl('distribution/validate.mtt') public function doValidate(date:Date, place:db.Place){ if (!app.user.isAmapManager()) throw t._("Forbidden access"); var md = MultiDistrib.get(date, place, db.Contract.TYPE_VARORDER); view.confirmed = md.checkConfirmed(); view.users = md.getUsers(); view.date = date; view.place = place; } /** * Admin can autovalidate a multidistrib */ @admin public function doAutovalidate(date:Date,place:db.Place){ var md = MultiDistrib.get(date,place,db.Contract.TYPE_VARORDER); for ( d in md.distributions){ if(d.validated) continue; service.PaymentService.validateDistribution(d); } throw Ok("/contractAdmin",t._("This distribution have been validated")); } @admin public function doUnvalidate(date:Date,place:db.Place){ var md = MultiDistrib.get(date,place,db.Contract.TYPE_VARORDER); for ( d in md.distributions){ if(!d.validated) continue; service.PaymentService.unvalidateDistribution(d); } throw Ok("/contractAdmin",t._("This distribution have been Unvalidated")); } }