File: D:/HostingSpaces/blijegasten/blijegasten.be/resources/js/kms/attributes/currency.js
/**
* Controls the Currency attribute.
* See currency.blade.php
*/
class Currency {
constructor(currencyWrapper) {
if(currencyWrapper === undefined || currencyWrapper.tagName !== "DIV") {
console.error('Currency:constructor Missing the expected div element that represents the Currency wrapper.'); return;
}
this._wrapper = currencyWrapper;
if(!'incVat' in this._wrapper.dataset || typeof this._wrapper.dataset.incVat !== "string") {
console.error('Currency:constructor the currency wrapper must have a dataset property called incVat that must have a boolean value.'); return;
}
this._priceEnterdIncludingVat = this._wrapper.dataset.incVat === '1';
this._realInput = this._wrapper.querySelector('input[type="hidden"]'); //NOTE: The real input MUST ALWAYS hold the price excluding vat.
if(!this._realInput) {
console.error('Currency:constructor Missing the expected hidden input in the currency wrapper.'); return;
}
this._previewInput = this._wrapper.querySelector('input.js_preview_input');
this._regionContainer = this._wrapper.querySelector('.region');
this._userInput = this._wrapper.querySelector('input.user_input');
if(!this._userInput) {
console.error('Currency:constructor Missing the expected ex vat input in the currency wrapper.'); return;
}
this._userInput = this._wrapper.querySelector('input.user_input');
this._inputChanged = this._inputChanged.bind(this);
this._vatCalculationResponseReceived = this._vatCalculationResponseReceived.bind(this);
this._initialize();
this.controlEventListeners();
}
/**
* @param {boolean} enable
*/
controlEventListeners(enable = true)
{
this._userInput.removeEventListener('change', this._inputChanged);
if(enable) {
this._userInput.addEventListener('change', this._inputChanged);
}
}
/**
* Triggered when the user input was changed.
*
* @param event
* @private
*/
_inputChanged(event)
{
let self = this;
let requestData = new VatCalculationRequest();
requestData.isIncludingVat = this._priceEnterdIncludingVat;
requestData.price = Math.round(this._userInput.value * 100);
Ajax.post('/kms/calculateVatAmount', requestData, this._vatCalculationResponseReceived);
}
_initialize()
{
let requestData = new VatCalculationRequest();
requestData.isIncludingVat = false; //The real input always contains the price ex vat.
requestData.price = (this._realInput.value === '') ? 0 : this._realInput.value;
Ajax.post('/kms/calculateVatAmount', requestData, this._vatCalculationResponseReceived);
}
/**
* @param {{}} xhr
* @private
*/
_vatCalculationResponseReceived(xhr)
{
let isVatCalculationResponse = VatCalculationResponse.is(xhr.response, true);
if(isVatCalculationResponse) {
let vatCalculationResponse = VatCalculationResponse.fromJsonString(xhr.response);
this._previewInput.value = (this._priceEnterdIncludingVat) ? vatCalculationResponse.priceExVatForNumberInput : vatCalculationResponse.priceIncVatForNumberInput;
// this._userInput.value = (this._priceEnterdIncludingVat) ? vatCalculationResponse.priceIncVatForNumberInput : vatCalculationResponse.priceExVatForNumberInput;
this._regionContainer.innerText = vatCalculationResponse.vatPercentage+'% - '+vatCalculationResponse.regionDisplayName;
this._realInput.value = vatCalculationResponse.priceExVat;
}
else {
console.error('Currency:_inputChanged The response was not a valid vatCalculationResponse: '+xhr.response);
}
}
}
/**
* Represents a request from the frontend to the backend for calculating a certain price vat
*/
class VatCalculationRequest {
constructor()
{
this._price = 0;
this._isIncludingVat = false;
this.toJSON = this._toJSON.bind(this);
}
/**
* @return {{price: number, isIncludingVat: boolean}}
* @private
*/
_toJSON()
{
return {
'price': this._price,
'isIncludingVat': this._isIncludingVat,
}
}
/**
* @param {string} json
* @return {CheckoutInformationResponse|null}
*/
static fromJsonString(json) {
if(!this.is(json)) {
return null;
}
let jsonObject = JSON.parse(json);
let instance = new this;
instance._price = jsonObject.price;
instance._isIncludingVat = jsonObject.isIncludingVat;
return instance;
}
/**
* Checks that the given json string represents a CheckoutInformationResponse
*
* @param {string} json
* @param {boolean} logErrors
* @return {boolean}
*/
static is(json, logErrors = true)
{
let jsonObject = null;
try {
jsonObject = JSON.parse(json);
if(!jsonObject) {
if(logErrors) console.error('VatCalculationRequest: The given json does not represent a valid VatCalculationRequest since the json string was not a valid json');
return false;
}
} catch (e) {
if(logErrors) console.error('VatCalculationRequest: The given json does not represent a valid VatCalculationRequest since the json string was not a valid json');
return false;
}
if(!jsonObject.hasOwnProperty('price') || typeof jsonObject.price !== 'number') {
if(logErrors) console.error('VatCalculationResponse: The object must have a price property that is a number. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('isIncludingVat') || typeof jsonObject.isIncludingVat !== "boolean") {
if(logErrors) console.error('VatCalculationResponse: The object must have a isIncludingVat property that is a boolean. Object: ', jsonObject);
return false;
}
return true;
}
get price() {
return this._price;
}
set price(value) {
this._price = value;
}
get isIncludingVat() {
return this._isIncludingVat;
}
set isIncludingVat(value) {
this._isIncludingVat = value;
}
}
/**
* Represents a response from the backend as response on a VatCalculationRequest that was sent to the backend
*/
class VatCalculationResponse {
constructor() {
this._priceExVat = 0;
this._priceExVatFormatted = '';
this._priceExVatForNumberInput = 0;
this._priceIncVat = 0;
this._priceIncVatFormatted = '';
this._priceIncVatForNumberInput = 0;
this._vatAmount = 0;
this._vatPercentage = 0;
this._vatAmountFormatted = '';
this._vatAmountForNumberInput = 0;
this._regionDisplayName = '';
}
/**
* @param {string} json
* @return {CheckoutInformationResponse|null}
*/
static fromJsonString(json) {
if(!this.is(json)) {
return null;
}
let jsonObject = JSON.parse(json);
let instance = new this;
instance._priceExVat = jsonObject.priceExVat;
instance._priceExVatFormatted = jsonObject.priceExVatFormatted;
instance._priceExVatForNumberInput = jsonObject.priceExVatForNumberInput;
instance._priceIncVat = jsonObject.priceIncVat;
instance._priceIncVatFormatted = jsonObject.priceIncVatFormatted;
instance._priceIncVatForNumberInput = jsonObject.priceIncVatForNumberInput;
instance._vatAmount = jsonObject.vatAmount;
instance._vatPercentage = jsonObject.vatPercentage;
instance._vatAmountFormatted = jsonObject.vatAmountFormatted;
instance._vatAmountForNumberInput = jsonObject.vatAmountForNumberInput;
instance._regionDisplayName = jsonObject.regionDisplayName;
return instance;
}
/**
* Checks that the given json string represents a CheckoutInformationResponse
*
* @param {string} json
* @param {boolean} logErrors
* @return {boolean}
*/
static is(json, logErrors = true)
{
let jsonObject = null;
try {
jsonObject = JSON.parse(json);
if(!jsonObject) {
if(logErrors) console.error('VatCalculationResponse: The given json does not represent a valid VatCalculationResponse since the json string was not a valid json');
return false;
}
} catch (e) {
if(logErrors) console.error('VatCalculationResponse: The given json does not represent a valid VatCalculationResponse since the json string was not a valid json');
return false;
}
if(!jsonObject.hasOwnProperty('priceExVat') || typeof jsonObject.priceExVat !== 'number') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceExVat property that is a number. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('priceExVatFormatted') || typeof jsonObject.priceExVatFormatted !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceExVatFormatted property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('priceExVatForNumberInput') || typeof jsonObject.priceExVatForNumberInput !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceExVatForNumberInput property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('priceIncVat') || typeof jsonObject.priceIncVat !== 'number') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceIncVat property that is a number. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('priceIncVatFormatted') || typeof jsonObject.priceIncVatFormatted !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceIncVatFormatted property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('priceIncVatForNumberInput') || typeof jsonObject.priceIncVatForNumberInput !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a priceIncVatForNumberInput property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('vatAmount') || typeof jsonObject.vatAmount !== 'number') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a vatAmount property that is a number. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('vatAmountFormatted') || typeof jsonObject.vatAmountFormatted !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a vatAmountFormatted property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('vatAmountForNumberInput') || typeof jsonObject.vatAmountForNumberInput !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a vatAmountForNumberInput property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('regionDisplayName') || typeof jsonObject.regionDisplayName !== 'string') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a regionDisplayName property that is a string. Object: ', jsonObject);
return false;
}
if(!jsonObject.hasOwnProperty('vatPercentage') || typeof jsonObject.vatPercentage !== 'number') {
if(logErrors) console.error('VatCalculationResponse: The response object must have a vatPercentage property that is a number. Object: ', jsonObject);
return false;
}
return true;
}
get priceExVat() {
return this._priceExVat;
}
set priceExVat(value) {
this._priceExVat = value;
}
get priceExVatFormatted() {
return this._priceExVatFormatted;
}
set priceExVatFormatted(value) {
this._priceExVatFormatted = value;
}
get priceExVatForNumberInput() {
return this._priceExVatForNumberInput;
}
set priceExVatForNumberInput(value) {
this._priceExVatForNumberInput = value;
}
get priceIncVat() {
return this._priceIncVat;
}
set priceIncVat(value) {
this._priceIncVat = value;
}
get priceIncVatFormatted() {
return this._priceIncVatFormatted;
}
set priceIncVatFormatted(value) {
this._priceIncVatFormatted = value;
}
get priceIncVatForNumberInput() {
return this._priceIncVatForNumberInput;
}
set priceIncVatForNumberInput(value) {
this._priceIncVatForNumberInput = value;
}
get vatAmount() {
return this._vatAmount;
}
set vatAmount(value) {
this._vatAmount = value;
}
get vatAmountFormatted() {
return this._vatAmountFormatted;
}
set vatAmountFormatted(value) {
this._vatAmountFormatted = value;
}
get vatAmountForNumberInput() {
return this._vatAmountForNumberInput;
}
set vatAmountForNumberInput(value) {
this._vatAmountForNumberInput = value;
}
get regionDisplayName() {
return this._regionDisplayName;
}
set regionDisplayName(value) {
this._regionDisplayName = value;
}
get vatPercentage() {
return this._vatPercentage;
}
set vatPercentage(value) {
this._vatPercentage = value;
}
}