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.
125 lines
3.7 KiB
125 lines
3.7 KiB
package react;
|
|
import react.ReactComponent;
|
|
import react.ReactMacro.jsx;
|
|
import Common;
|
|
|
|
// I need to store also the "input" because of https://stackoverflow.com/questions/29140354/how-to-handle-decimal-values-in-reacts-onchange-event-for-input
|
|
typedef VATBoxState = {ht:Float, ttc:Float, vat:Float, htInput:String, ttcInput:String,lastEdited:String};
|
|
|
|
|
|
/**
|
|
* A box to manage prices with and without VAT
|
|
* @author fbarbut
|
|
*/
|
|
class VATBox extends react.ReactComponentOfPropsAndState<{ttc:Float,currency:String,vatRates:String,vat:Float,formName:String},VATBoxState>
|
|
{
|
|
|
|
public function new(props)
|
|
{
|
|
super(props);
|
|
//trace(props);
|
|
|
|
this.state = {
|
|
ht : round(props.ttc/(1+props.vat/100)),
|
|
htInput : Std.string(round(props.ttc/(1+props.vat/100))),
|
|
ttc : round(props.ttc),
|
|
ttcInput : Std.string(round(props.ttc)),
|
|
vat:props.vat,
|
|
lastEdited:null
|
|
};
|
|
|
|
|
|
}
|
|
|
|
override public function render(){
|
|
|
|
var rates :Array<Float>= props.vatRates.split("|").map(Std.parseFloat);
|
|
|
|
var options = [for (r in rates) jsx('<option key="$r" value="$r">$r %</option>') ];
|
|
var priceInputName = props.formName+"_price";
|
|
var vatInputName = props.formName+"_vat";
|
|
|
|
return jsx('<div>
|
|
|
|
<div className="row">
|
|
<div className="col-md-4 text-center"> Hors taxe </div>
|
|
<div className="col-md-4 text-center"> Taux de TVA </div>
|
|
<div className="col-md-4 text-center"> TTC </div>
|
|
</div>
|
|
|
|
<div className="row">
|
|
<div className="col-md-4">
|
|
<div className="input-group">
|
|
<input type="text" name="htInput" value="${state.htInput}" className="form-control" onChange={onChange}/>
|
|
<div className="input-group-addon">${props.currency}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="col-md-4">
|
|
<select name="vat" className="form-control" onChange={onChange} defaultValue=${state.vat}>
|
|
${options}
|
|
</select>
|
|
</div>
|
|
|
|
<div className="col-md-4">
|
|
<div className="input-group">
|
|
<input type="text" name="ttcInput" value="${state.ttcInput}" className="form-control" onChange={onChange}/>
|
|
<div className="input-group-addon">${props.currency}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<input type="hidden" name="$priceInputName" value="${state.ttc}" />
|
|
<input type="hidden" name="$vatInputName" value="${state.vat}" />
|
|
|
|
</div>
|
|
');
|
|
}
|
|
|
|
|
|
/**
|
|
* Recompute prices
|
|
*/
|
|
function onChange(e:js.html.Event){
|
|
|
|
e.preventDefault();
|
|
var name :String = untyped e.target.name;
|
|
var input : String = Std.string(untyped e.target.value);
|
|
if (input == null || input == "") input = "0";
|
|
input = StringTools.replace(input, ",", ".");
|
|
var value : Float = Std.parseFloat(input);
|
|
if (value == null) value = 0;
|
|
|
|
var rate = 1 + (state.vat / 100);
|
|
//trace('name:$name - raw:' + untyped e.target.value+' - input:$input - value:$value ');
|
|
|
|
switch(name){
|
|
case "htInput":
|
|
|
|
this.setState(cast {ht:value , htInput:input , ttc: round(value * rate), ttcInput:round(value * rate) , lastEdited:"htInput"});
|
|
|
|
case "ttcInput":
|
|
this.setState(cast {ht: round(value / rate), htInput : round(value/rate), ttcInput:input , ttc:value , lastEdited:"ttcInput"});
|
|
|
|
case "vat":
|
|
rate = 1 + (value / 100);
|
|
if (state.lastEdited == "htInput"){
|
|
//compute ttc from ht
|
|
this.setState(cast { vat:value, ht:state.ht, htInput:state.ht, ttc:round(state.ht * rate) , ttcInput:round(state.ht * rate)} );
|
|
}else{
|
|
//compute ht from ttc
|
|
this.setState(cast { vat:value, ht: round( state.ttc/rate ), htInput: round( state.ttc/rate ), ttc:state.ttc , ttcInput:state.ttc} );
|
|
}
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
inline function round(f:Float):Float{
|
|
return Math.round(f * 100) / 100;
|
|
}
|
|
|
|
|
|
}
|