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.
 
 
 
 
 
 

294 lines
9.9 KiB

package controller;
import db.Operation.OperationType;
import Common;
import service.OrderService;
using Lambda;
/**
* Transction controller
* @author fbarbut
*/
class Transaction extends controller.Controller
{
/**
* A manager inserts manually a payment
*/
@tpl('form.mtt')
public function doInsertPayment(user:db.User){
if (!app.user.isContractManager()) throw Error("/", t._("Action forbidden"));
var t = sugoi.i18n.Locale.texts;
var op = new db.Operation();
op.user = user;
op.date = Date.now();
var f = new sugoi.form.Form("payement");
f.addElement(new sugoi.form.elements.StringInput("name", t._("Label||label or name for a payment"), null, true));
f.addElement(new sugoi.form.elements.FloatInput("amount", t._("Amount"), null, true));
f.addElement(new sugoi.form.elements.DatePicker("date", t._("Date"), Date.now(), true));
var paymentTypes = service.PaymentService.getPaymentTypesForManualEntry(app.user.amap);
f.addElement(new sugoi.form.elements.StringSelect("Mtype", t._("Payment type"), paymentTypes, null, true));
//related operation
var unpaid = db.Operation.manager.search($user == user && $group == app.user.amap && $type != Payment ,{limit:20,orderBy:-date});
var data = unpaid.map(function(x) return {label:x.name, value:x.id}).array();
f.addElement(new sugoi.form.elements.IntSelect("unpaid", t._("As a payment for :"), data, null, false));
if (f.isValid()){
f.toSpod(op);
op.type = db.Operation.OperationType.Payment;
var data : db.Operation.PaymentInfos = {type:f.getValueOf("Mtype")};
op.data = data;
op.group = app.user.amap;
op.user = user;
if (f.getValueOf("unpaid") != null){
var t2 = db.Operation.manager.get(f.getValueOf("unpaid"));
op.relation = t2;
if (t2.amount + op.amount == 0) {
op.pending = false;
t2.lock();
t2.pending = false;
t2.update();
}
}
op.insert();
service.PaymentService.updateUserBalance(user, app.user.amap);
throw Ok("/member/payments/" + user.id, t._("Payment recorded") );
}
view.title = t._("Record a payment for ::user::",{user:user.getCoupleName()}) ;
view.form = f;
}
@tpl('form.mtt')
public function doEdit(op:db.Operation){
if (!app.user.canAccessMembership() || op.group.id != app.user.amap.id ) {
throw Error("/member/payments/" + op.user.id, t._("Action forbidden"));
}
if (op.getPaymentType() == "lemonway-ec") throw Error("/member/payments/"+op.user.id, t._("Editing a credit card payment is not allowed"));
op.lock();
var f = new sugoi.form.Form("payement");
f.addElement(new sugoi.form.elements.StringInput("name", t._("Label||label or name for a payment"), op.name, true));
f.addElement(new sugoi.form.elements.FloatInput("amount", t._("Amount"), op.amount, true));
f.addElement(new sugoi.form.elements.DatePicker("date", t._("Date"), op.date, true));
//f.addElement(new sugoi.form.elements.DatePicker("pending", t._("Confirmed"), !op.pending, true));
//related operation
var unpaid = db.Operation.manager.search( $user == op.user && $group == op.group && $type != Payment ,{limit:20,orderBy:-date});
var data = unpaid.map(function(x) return {label:x.name, value:x.id}).array();
if (op.relation != null) data.push({label:op.relation.name,value:op.relation.id});
f.addElement(new sugoi.form.elements.IntSelect("unpaid", t._("As a payment for :"), data, op.relation!=null ? op.relation.id : null, false));
if (f.isValid()){
f.toSpod(op);
op.pending = false;
if (f.getValueOf("unpaid") != null){
var t2 = db.Operation.manager.get(f.getValueOf("unpaid"));
op.relation = t2;
if (t2.amount + op.amount == 0) {
op.pending = false;
t2.lock();
t2.pending = false;
t2.update();
}
}
op.update();
throw Ok("/member/payments/" + op.user.id, t._("Operation updated"));
}
view.form = f;
}
/**
* Delete an operation
*/
public function doDelete(op:db.Operation){
if (!app.user.canAccessMembership() || op.group.id != app.user.amap.id ) throw Error("/member/payments/" + op.user.id, t._("Action forbidden"));
//cannot delete a bank card payment op
if (op.getPaymentType() == "lemonway-ec"){
throw Error("/member/payments/" + op.user.id, t._("Deleting a credit card payment is not allowed"));
}
//only an admin can delete an order op
if((op.type == db.Operation.OperationType.VOrder || op.type == db.Operation.OperationType.COrder) && !app.user.isAdmin()){
throw Error("/member/payments/" + op.user.id, t._("Action forbidden"));
}
if (checkToken()){
op.delete();
throw Ok("/member/payments/" + op.user.id, t._("Operation deleted"));
}
}
/**
* payement entry page
* @param distribKey
*/
@tpl("transaction/pay.mtt")
public function doPay() {
view.category = 'home';
var order : OrderInSession = app.session.data.order;
if (order == null) throw Redirect("/");
if (order.products.length == 0) throw Error("/", t._("Your cart is empty"));
view.amount = order.total;
view.paymentTypes = service.PaymentService.getAllowedPaymentTypes(app.user.amap);
view.allowMoneyPotWithNegativeBalance = app.user.amap.allowMoneyPotWithNegativeBalance;
view.futurebalance = db.UserAmap.get(app.user, app.user.amap).balance - order.total;
}
/**
* pay by check
*/
@tpl("transaction/check.mtt")
public function doCheck(){
//order in session
var tmpOrder : OrderInSession = app.session.data.order;
if (tmpOrder == null) throw Redirect("/contract");
if (tmpOrder.products.length == 0) throw Error("/", t._("Your cart is empty"));
//get a code
var d = db.Distribution.manager.get(tmpOrder.products[0].distributionId, false);
var code = payment.Check.getCode(d.date, d.place, app.user);
view.code = code;
view.amount = tmpOrder.total;
//if (checkToken()){
//record order
var orders = OrderService.confirmSessionOrder(tmpOrder);
var ops = db.Operation.onOrderConfirm(orders);
var ordersGrouped = tools.ObjectListTool.groupOrdersByKey(orders);
if (Lambda.array(ordersGrouped).length == 1){
//all orders are for the same multidistrib
var name = t._("Check for the order of ::date::", {date:view.hDate(d.date)}) + " ("+code+")";
db.Operation.makePaymentOperation(app.user,app.user.amap, payment.Check.TYPE, tmpOrder.total, name, ops[0] );
}else{
//orders are for multiple distribs : create one payment
db.Operation.makePaymentOperation(app.user,app.user.amap,payment.Check.TYPE, tmpOrder.total, t._("Check") + " ("+code+")" );
}
//throw Ok("/contract", t._("Your payment by check has been saved. It will be validated by a coordinator at the delivery."));
//}
}
/**
* pay by transfer
*/
@tpl("transaction/transfer.mtt")
public function doTransfer(){
//order in session
var tmpOrder : OrderInSession = app.session.data.order;
if (tmpOrder == null) throw Redirect("/contract");
if (tmpOrder.products.length == 0) throw Error("/", t._("Your cart is empty"));
//get a code
var d = db.Distribution.manager.get(tmpOrder.products[0].distributionId, false);
var code = payment.Check.getCode(d.date, d.place, app.user);
view.code = code;
view.amount = tmpOrder.total;
//if (checkToken()){
//record order
var orders = OrderService.confirmSessionOrder(tmpOrder);
var ops = db.Operation.onOrderConfirm(orders);
var ordersGrouped = tools.ObjectListTool.groupOrdersByKey(orders);
if (Lambda.array(ordersGrouped).length == 1){
//one multidistrib
var name = t._("Transfer for the order of ::date::", {date:view.hDate(d.date)}) + " ("+code+")";
db.Operation.makePaymentOperation(app.user,app.user.amap,payment.Transfer.TYPE, tmpOrder.total, name, ops[0] );
}else{
//many distribs
db.Operation.makePaymentOperation(app.user,app.user.amap,payment.Transfer.TYPE, tmpOrder.total, t._("Bank transfer")+" ("+code+")" );
}
//throw Ok("/contract", t._("Your payment by transfer has been saved. It will be validated by a coordinator."));
//}
}
/**
* pay by cash
*/
@tpl("transaction/cash.mtt")
public function doCash(){
//order in session
var tmpOrder : OrderInSession = app.session.data.order;
if (tmpOrder == null) throw Redirect("/contract");
if (tmpOrder.products.length == 0) throw Error("/", t._("Your cart is empty"));
view.amount = tmpOrder.total;
var d = db.Distribution.manager.get(tmpOrder.products[0].distributionId, false);
//if (checkToken()){
//record order
var orders = OrderService.confirmSessionOrder(tmpOrder);
var ops = db.Operation.onOrderConfirm(orders);
var ordersGrouped = tools.ObjectListTool.groupOrdersByKey(orders);
if (Lambda.array(ordersGrouped).length == 1){
//same multidistrib
var name = t._("Cash for the order of ::date::", {date:view.hDate(d.date)});
db.Operation.makePaymentOperation(app.user,app.user.amap,payment.Cash.TYPE, tmpOrder.total, name , ops[0] );
}else{
//various distribs
db.Operation.makePaymentOperation(app.user, app.user.amap, payment.Cash.TYPE, tmpOrder.total, t._("Cash payment"));
}
//throw Ok("/contract", t._("Your order is validated, you commited to pay in cash at the delivery."));
//}
}
/**
* Use the money pot
*/
@tpl("transaction/moneypot.mtt")
public function doMoneypot(){
//order in session
var tmpOrder : OrderInSession = app.session.data.order;
if (tmpOrder == null) throw Redirect("/contract");
if (tmpOrder.products.length == 0) throw Error("/", t._("Your cart is empty"));
var futureBalance = db.UserAmap.get(app.user, app.user.amap).balance - tmpOrder.total;
if (!app.user.amap.allowMoneyPotWithNegativeBalance && futureBalance < 0) {
throw Error("/transaction/pay", t._("You do not have sufficient funds to pay this order with your money pot."));
}
//record order
var orders = OrderService.confirmSessionOrder(tmpOrder);
var ops = db.Operation.onOrderConfirm(orders);
view.amount = tmpOrder.total;
view.balance = db.UserAmap.get(app.user, app.user.amap).balance;
}
}