app.controller('WizardCtrl', function($scope, $http, $routeParams, Hotel, Flight, Activity, $filter, $location, $timeout, notify) {
// original camp data
$scope.originalCampData = {};
$scope.verbergenTonen = [];
$scope.hotelOption = {};
$scope.customerFilter = '';
$scope.customerAccounts = [];
$scope.approveQuotation = function() {
var req = {
url: '/quotation/approve/' + $routeParams.hash,
method: 'GET',
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
//succes message
swal('Gelukt!', 'De offerte is geaccepteerd en klaar om te verzenden.', 'success');
$location.url('/page/offertes');
} else {
swal('Mislukt!', response.data.message, 'error');
}
});
}
$scope.readyForCheck = function() {
// Check if calculatedMargin and marginpp are exists
if ($scope.calculatedMargin && $scope.calculatedMargin.marginpp !== undefined) {
let marginpp = $scope.calculatedMargin.marginpp * 100;
var req = {
url: '/quotation/readyForCheck/' + $routeParams.hash + '/' + marginpp,
method: 'GET',
};
$http(req).then(function(response) {
if (response.status && response.data.status) {
// Succesbericht
if (marginpp < 15) {
swal('Gelukt!', 'De offerte is klaar gezet voor controle.', 'success');
} else {
swal('Gelukt!', 'De offerte is geaccepteerd en klaar om te verzenden.', 'success');
}
$location.url('/page/offertes');
}
}).catch(function(error) {
console.error('Fout bij het aanvragen van de status update:', error);
});
} else {
// Als marginpp niet beschikbaar is, toon een waarschuwing
console.error('Fout: marginpp is niet beschikbaar. Bereken de marge eerst.');
$scope.notification('Waarschuwing!', 'De marge is niet berekend, probeer opnieuw.', 'warning');
}
};
$scope.declineQuotation = function() {
swal({
title: 'Let op!',
text: 'U wilt offerte ' + $scope.quotationNumber + ' weigeren.\nGeef hieronder een reden op:',
type: 'warning',
content: 'input',
buttons: {
cancel: 'Terug',
confirm: {
text: 'OK',
closeModal: false,
},
},
}).then(name => {
if (!name) {
throw null;
}
// If the user confirms
if (name.length >= 0) {
var req = {
url: '/quotation/internalDecline/' + $routeParams.hash,
method: 'POST',
data: {'decline_reason': name},
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
//succes message
swal('Gelukt!', 'De offerte is geweigerd.', 'success');
$location.url('/page/offertes');
}
});
} else {
// No valid camp name
swal({
title: 'Let op!',
text: 'Voer een geldige reden in.', type: 'warning'
});
}
})
}
// quotation layout information
$scope.layout = {};
$scope.informationHeaders = [];
$scope.getInformationHeaders = function() {
var req = {
url: '/quotation_information_header/getAll',
method: 'GET',
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
$scope.informationHeaders = response.data.data;
}
});
}
$scope.getInformationHeaders();
$scope.notification = function(title, message, type, duration) {
if (type == undefined) {
type == 'success';
}
if (duration == undefined) {
duration = 5000;
}
notify({
message: message,
messageTemplate: '
' + title + '' + message + '
',
classes: ["alert-" + type],
duration: duration,
position: "right",
})
}
$scope.getLayoutImages = function() {
var images = (Array.isArray($scope.hotelOption['images']) ? $scope.hotelOption['images'] : []);
if ($scope.campData['activities'] !== undefined && Array.isArray($scope.campData['activities'])) {
$scope.campData['activities'].forEach(function(activity) {
if (activity['images'] !== undefined && Array.isArray(activity['images']) && activity['images'].length) {
images = images.concat(activity['images']);
}
if (activity['football_match'] !== undefined && activity['football_match']['images'] && Array.isArray(activity['football_match']['images']) && activity['football_match']['images'].length) {
images = images.concat(activity['football_match']['images']);
}
});
}
return images;
}
$scope.setLayoutImages = function(field, number) {
if (field['value']['images'] == undefined) {
field['value']['images'] = new Array();
}
var images = $scope.getLayoutImages();
for (let i = 0; i < images.length; i++) {
//set i + 1 to start with 1 and not with 0
if (!field['value']['images'][i+1] || !images.includes(field['value']['images'][i+1])) {
field['value']['images'][i+1] = images[i];
}
}
}
// END - quotation layout information
$scope.getStandardTexts = function() {
var req = {
url: '/standard_text/get',
method: 'GET',
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
$scope.standardTexts = response.data.data;
}
});
}
$scope.getStandardTexts();
$scope.filterStandardTexts = function(header) {
if ($scope.standardTexts && header){
let standardTextLines = $scope.standardTexts.filter(function(text) {
return text.tag == header.tag
});
return standardTextLines;
}
}
$scope.newInformationLine = {};
$scope.addNewInformationLine = function(header, value) {
if (value['info'] === undefined || Array.isArray(value['info'])) {
value['info'] = {};
}
if (value['info'][header] === undefined) {
value['info'][header] = [];
}
value['info'][header].push($scope.newInformationLine[header]);
$scope.newInformationLine[header] = '';
}
$scope.changeTitle = function (type, key) {
if ($scope.verbergenTonen[type][key] && $scope.verbergenTonen[type][key] == 'Tonen') {
$scope.verbergenTonen[type][key] = 'Verbergen';
} else {
$scope.verbergenTonen[type][key] = 'Tonen';
}
}
// hotel room information
$scope.rooms = [];
$scope.roomTypes = [];
$scope.amountOfAttendees = 0;
$scope.changeNumberOfAttendees = function(field) {
$scope.amountOfAttendees = parseInt(field.value);
}
$scope.changeNumberOfRooms = function(field) {
$scope.rooms = [];
if ($scope.roomTypes !== undefined && Array.isArray($scope.roomTypes)) {
$scope.roomTypes.forEach(function(room) {
if (room['amount'] !== undefined && angular.isNumber(room['amount'])) {
for (var i = 0; i < room['amount']; i++) {
$scope.rooms.push(angular.copy(room));
}
}
});
}
}
// reload hotel option rooms from standardisation
$scope.reloadHotelOptionRooms = function() {
if ($scope.originalCampData['hotels'] !== undefined && Array.isArray($scope.originalCampData['hotels'])
&& $scope.hotelOption['id'] !== undefined && $scope.hotelOption['id']) {
$scope.originalCampData['hotels'].forEach(function(hotel) {
if (hotel['id'] !== undefined && $scope.hotelOption['id'] == hotel['id'] && hotel['rooms'] !== undefined && typeof hotel['rooms'] === 'string') {
try {
$scope.hotelOption['rooms'] = JSON.parse(hotel['rooms']);
$scope.getHotelRoomTypes();
} catch (e) {
// JSON failed, do nothing
}
}
});
} else {
if ($scope.hotelOption['id'] !== undefined && $scope.hotels !== undefined && Array.isArray($scope.hotels)) {
$scope.hotels.forEach(function(hotel) {
if (hotel['id'] !== undefined && $scope.hotelOption['id'] == hotel['id'] && hotel['rooms'] !== undefined){
$scope.hotelOption['rooms'] = hotel['rooms'];
}
});
}
}
}
$scope.onChangeRoomOptions = function() {
$scope.getHotelRoomTypes();
}
// generates hotel room types array, call when hotel room options change
$scope.getHotelRoomTypes = function() {
// initialize array
$scope.roomTypes = [];
// add default room to array
$scope.roomTypes.push({
name: $scope.hotelOption['room_name'],
amount_of_singles: parseInt($scope.hotelOption['room_amount_of_singles']),
amount_of_doubles: parseInt($scope.hotelOption['room_amount_of_doubles']),
});
// add surcharge rooms to array
if ($scope.hotelOption['rooms'] !== undefined && Array.isArray($scope.hotelOption['rooms'])) {
$scope.hotelOption['rooms'].forEach(function(room) {
$scope.roomTypes.push(room);
});
}
// reset input on number of rooms
$scope.changeNumberOfRooms();
}
$scope.getAmountOfBeds = function(rooms) {
if ($scope.roomTypes === undefined || !Array.isArray($scope.roomTypes)) {
return 0;
}
return $scope.roomTypes.reduce(function(total, room) {
var amountOfBeds = 0;
if (room['amount_of_singles'] !== undefined && angular.isNumber(parseInt(room['amount_of_singles']))) {
amountOfBeds += parseInt(room['amount_of_singles']);
}
if (room['amount_of_doubles'] !== undefined && angular.isNumber(parseInt(room['amount_of_doubles']))) {
amountOfBeds += parseInt(room['amount_of_doubles'] * 2);
}
total += amountOfBeds * (room['amount'] !== undefined && angular.isNumber(room['amount']) ? room['amount'] : 0);
return total;
}, 0);
}
$scope.setMatchPanel = function(activity){
return Activity.setMatchPanel(activity, $scope);
}
/* Flow:
* 1 getNumOfPages
* 2 preparePage
* 3 getPageData
*/
// Initialize variables
$scope.currentPage = 0;
$scope.numOfPages = 0;
$scope.quotationNumber = null;
$scope.quotationHash = 0;
$scope.wizard = {
'id': 0,
};
$scope.pageType = 'wizard'
$scope.selectWizard = function(btn, row) {
$scope.wizard = row;
$scope.getNumOfPages();
}
// Get the fields and values for wizard 1 and the current page
$scope.getNumOfPages = function() {
// Get the fields
var req = {
method: 'GET',
url: '/wizard_page/getNumOfPages/' + $scope.wizard.id,
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
$scope.numOfPages = response.data.data.numOfPages;
if ($scope.numOfPages) {
// Load the data
$scope.currentPage = 1;
$scope.getPageData();
} else {
// Warning
$scope.notification('Foutmelding', 'Geen pagina data gevonden', 'danger');
}
} else {
// Error
$scope.notification('Foutmelding', response.data.message, 'danger');
}
});
}
$scope.getCountryById = function(countryId) {
angular.forEach($scope.countries, function(country) {
if (country.id == countryId) {
countryName = country.name;
}
})
return countryName;
}
// Prepare the page
$scope.preparePage = function(pageNum) {
if (pageNum <= $scope.numOfPages) {
if ((pageNum == 3) && $scope.pageData.campCountry) {
var countryName = $scope.getCountryById($scope.pageData.campCountry)
// Get the location
if (countryName == 'Nederland' || countryName == 'België' || countryName == 'Duitsland') {
// Switch to wizard 'Binnenland'
$scope.getPageData(3, 2);
} else if ($scope.pageData.campCountry != undefined) {
$scope.getPageData(3);
}
}
} else {
// Load the data for the last page
$scope.pageData.titles[5] = {name: 'Offerte Gegenereerd'};
}
}
function getMailTemplate () {
var req = {
method: 'GET',
url: '/wizard/getQuotationTemplate',
}
$http(req).then(function(response) {
if (response.data && response.data.status) {
$scope.emailTemplate = response.data.data;
if (typeof $scope.emailTemplate.variables == 'string') {
try {
$scope.emailTemplate.variables = JSON.parse($scope.emailTemplate.variables)
} catch (e) {
$scope.emailTemplate.variables = [];
}
}
//make variables for button
$scope.makeElements();
}
});
}
getMailTemplate();
function getInformalMail () {
var req = {
method: 'GET',
url: '/email_template/getByEmailName/QUOTATION_INFORMAL',
}
$http(req).then(function(response) {
if (response.data && response.data.status) {
$scope.informalMail = response.data.data;
$scope.originalInformalMail = response.data.data;
$scope.updatePreviewMail();
}
});
}
getInformalMail();
// Get the fields and values for wizard 1
$scope.getPageData = function(pageNum = 0, wizardId = 1) {
$scope.loadingPage = true;
if ($routeParams.hash || ($scope.currentPage <= $scope.numOfPages)) {
if ($scope.pageData == undefined) {
$scope.pageData = {};
}
// Get the page titles
var req = {
method: 'GET',
url: '/wizard_page/getByWizard/' + (pageNum ? 2 : 1),
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
if (pageNum) {
// Get one title
$scope.pageData.titles[pageNum-1] = response.data.data[0];
} else {
// Get all page titles
$scope.pageData.titles = response.data.data;
}
}
})
// Get the fields
var req = null
if ((pageNum == 0) && $routeParams.hash) {
// If this is an existing quotation
req = {
method: 'GET',
url: '/quotation/getForWizard/' + $routeParams.hash,
}
} else
// If the quotation is being created
if ((!$routeParams.hash || $scope.quotationStatus == 'Concept')) {
req = {
method: 'POST',
url: '/wizard/getData',
data: {
wizard_id: wizardId,
page_num: pageNum,
},
}
}
if (req) {
$http(req).then(function(response) {
if (response.status && response.data.status) {
$scope.setPageFields(pageNum, response.data.data.fields);
// Deleted/Old version?
$scope.deletedAt = response.data.data.deleted_at;
$scope.declineReason = response.data.data.decline_reason;
$scope.internalDeclineReason = response.data.data.internal_decline_reason;
// Get the status
if ((pageNum == 0) && $routeParams.hash) {
$scope.quotationStatus = response.data.data.status;
} else {
$scope.quotationStatus = 'Concept';
}
// Get the field options
$scope.getPageFieldOptions(pageNum);
if ((pageNum == 0) && $routeParams.hash) {
// Set the wizard id
$scope.wizard.id = 1;
// Set the quotation number
$scope.quotationNumber = response.data.data.quotation_number;
$scope.quotationReadOnly = $scope.quotationStatus != 'Concept';
}
//build index
$scope.fieldIndex = [];
angular.forEach($scope.pageData.fields, function(field, key) {
//update index
$scope.fieldIndex[field.subtype] = key;
page = parseInt(field.page_num);
if (page > $scope.numOfPages) {
$scope.numOfPages = page;
}
});
//check campId
$scope.checkCampId();
//set budget
$scope.budget = $scope.getfVar('budget');
if ($location.search().p !== undefined && angular.isNumber(parseInt($location.search().p))) {
$scope.setValues(parseInt($location.search().p));
}
} else {
$scope.pageData = {};
// Set the quotation number and status
$scope.quotationNumber = response.data.data.quotation_number;
$scope.quotationStatus = response.data.data.status;
// Error
$scope.notification('Foutmelding', response.data.message, 'danger');
}
});
}
} else {
// Load the data for the last page
$scope.pageData = {
fields: [],
titles: {5: {name: 'Offerte Gegenereerd'}},
};
}
$scope.loadingPage = false;
}
$scope.setfVar = function(fieldSubType, fieldValue){
if($scope.fieldIndex[fieldSubType] !== undefined){
$scope.pageData.fields[$scope.fieldIndex[fieldSubType]].value = fieldValue;
}
}
$scope.validateFlightDate = function(departure ,dateTime) {
if (departure) {
fromDate = $scope.pageData.fields.filter(field => field.subtype == 'from')
if (fromDate[0] && fromDate[0].value){
fromDate = fromDate[0].value;
if (dateTime.getTime() < fromDate.getTime()) {
$scope.notification('Let op!', 'De opgegeven heenvlucht is eerder dan de begin datum van het trainingskamp.', 'warning');
}
}
} else {
tillDate = $scope.pageData.fields.filter(field => field.subtype == 'till')
if (tillDate[0] && tillDate[0].value){
tillDate = tillDate[0].value;
dateTimeCopy = angular.copy(dateTime);
dateTimeCopy.setHours(0,0,0,0);
//remove time from return flight for good comparison
if (dateTimeCopy.getTime() > tillDate.getTime()) {
$scope.notification('Let op!', 'De terugvlucht is later dan de eind datum van het trainingskamp.', 'warning');
}
}
}
}
$scope.getfVar = function(fieldSubType){
if($scope.fieldIndex[fieldSubType] !== undefined){
return $scope.pageData.fields[$scope.fieldIndex[fieldSubType]].value;
}
}
$scope.getField = function(fieldSubType){
if($scope.fieldIndex != undefined && $scope.fieldIndex[fieldSubType] !== undefined){
return $scope.pageData.fields[$scope.fieldIndex[fieldSubType]];
}else{
return {};
}
}
$scope.setPageFields = function(pageNum, newFields) {
if ($scope.pageData == undefined) {
$scope.pageData = {};
}
// Set the fields
fields = [];
if (pageNum > 0) {
// Remove the current page fields
angular.forEach($scope.pageData.fields, function(field, key) {
if (field.page_num != pageNum) {
fields[key] = field;
}
});
// Add the new page fields, with the id as key
angular.forEach($scope.formatGetData(angular.copy(newFields)), function(field, key) {
// set existing field back to fields, add only new fields
if ($scope.pageData.fields[field.id] !== undefined) {
fields[field.id] = $scope.pageData.fields[field.id];
} else {
fields[field.id] = field;
}
switch (field.subtype) {
case 'flights':
if ($scope.originalCampData == undefined) {
$scope.originalCampData = {};
}
if ($scope.originalCampData.flights == undefined) {
$scope.originalCampData.flights = [];
}
Flight.set($scope, $scope.originalCampData.flights);
// Add/show these options by default
Flight.resetAddMany($scope, $scope.campData, $scope.originalCampData.flights);
break;
}
});
} else {
fieldsObj = $scope.formatGetData(angular.copy(newFields));
angular.forEach(fieldsObj, function(field, key) {
// Set a default value per field
switch (field.subtype) {
case 'customer':
if (field.value) {
$scope.retrieveCustomerAccounts(field.value);
$scope.updatePreviewMail();
}
break;
case 'adminbv':
if (field.value == undefined || field.value == null) {
field.value = '1';
}
break;
case 'camp':
if (field.value) {
// Get the hotel options for this camp
$scope.campHotelsLoaded = true;
$scope.onChange(field, true);
}
break;
case 'exclusive':
if (field.value == undefined || field.value == null) {
field.value = ($scope.defaultTexts['OFFERTE-EXCLUSIEF'] !== undefined ? $scope.defaultTexts['OFFERTE-EXCLUSIEF']['description'] : '');
}
break;
case 'from':
if (field.value) {
$scope.onChange(field);
}
break;
case 'till':
if (field.value) {
$scope.onChange(field);
}
break;
case 'hotels':
if ($scope.campData == undefined) {
$scope.campData = {};
}
if (field.value) {
$scope.hotelOption = field.value[0];
} else {
$scope.hotelOption = {};
}
// If needed, set the default hotel options
if (!$scope.hotels) {
Hotel.init($scope, $http);
field.options = $scope.hotels;
}
break;
case 'rooms':
if (field.value) {
// set room types
$scope.roomTypes = field.value;
// initiate via change function
$scope.changeNumberOfRooms(field);
}
break;
case 'flights':
if ($scope.campData == undefined) {
$scope.campData = {};
}
angular.forEach(field.value, function(flight) {
Flight.add($scope, $scope.campData, flight);
});
// If needed, set the default flight options
if (!$scope.flights) {
Flight.init($scope, $http);
field.options = $scope.flights;
}
// Set the right carrier data
if ($scope.campData.flights !== undefined && angular.isArray($scope.campData.flights)) {
angular.forEach($scope.campData.flights, function(flightOption) {
$scope.changeCarrier(flightOption);
});
}
break;
case 'activities':
if ($scope.campData == undefined) {
$scope.campData = {};
}
angular.forEach(field.value, function(activity) {
Activity.add($scope, $scope.campData, activity);
})
// If needed, set the default activit options
if (!$scope.activities) {
Activity.init($scope, $http);
field.options = $scope.activities;
}
break;
case 'pax':
$scope.onChange(field);
break;
case 'guests':
$scope.onChange(field);
break;
case 'marginpp':
if (field.value == undefined || field.value == null) {
field.value = 20;
}
field.readOnly = false;
case 'deposit':
if (field.readOnly == undefined || field.readOnly == null) {
field.readOnly = true;
}
if (field.value == undefined || field.value == null) {
field.value = 0.00;
}
break;
case 'tourist_tax':
$scope.onChange(field);
break;
case 'manualdeposit':
field.readOnly = $scope.user.rights['wizard'] === undefined || $scope.user.rights['wizard']['changedeposit'] === undefined || !$scope.user.rights['wizard']['changedeposit'];
if (field.value == undefined || field.value == null) {
field.value = false;
}
break;
case 'mail_template':
if (field.value == undefined || field.value == null || field.value.length <= 0) {
// get default mail template and set it in field.value
field.value = $scope.emailTemplate.default;
}
break;
case 'formal_mail':
if (field.value == undefined || field.value == null || field.value == false) {
if (!$routeParams.hash){
field.value = true;
}
}
break;
case 'additional_text_template':
$scope.updatePreviewMail(field);
break;
}
fields[field.id] = field;
});
// Set the default hotel service
if ($scope.hotelOption == undefined) {
$scope.hotelOption = {};
}
if ($scope.hotelOption.service_level == undefined) {
$scope.hotelOption.service_level = 'Logies';
}
// Set the default flights
if ($scope.campData == undefined) {
$scope.campData = {};
}
}
$scope.pageData.fields = fields;
$scope.updatePreviewMail();
}
$scope.getLayoutImageLabel = function(key) {
return 'Afbeelding ' + (parseInt(key) + 1);
}
$scope.getHotel = function(hotelId) {
if (hotelId == 'Nieuw' || !hotelId) {
hotelOption = null
} else {
// Get the hotel option
var hotelId = parseInt(hotelId)
angular.forEach($scope.hotels, function(option) {
if (hotelId == option.id) {
hotelOption = angular.copy(option)
}
})
if (typeof hotelOption === 'undefined') {
hotelOption = null;
}
}
return hotelOption;
}
$scope.flightModalFieldsChanged = false;
$scope.updateQuotation = function() {
if ($scope.flightModalFieldsChanged) {
$scope.currentPage = 2;
$scope.flightModalFieldsChanged = false;
// Error
$scope.notification('Waarschuwing', 'De kamp data is gewijzigd, controleer de offerte.', 'warning');
} else {
$scope.postQuotation(true);
}
$('#flight-modal').modal('hide');
}
// If a quotation should be loaded, load it
$scope.selectWizard(null, {id: 1});
$scope.onChangeModalField = function(field) {
$scope.flightModalFieldsChanged = true;
}
$scope.calculatetotalPrice = function() {
$scope.totalPricePP = 0.0;
$scope.totalPricePPSales = 0.0;
if (!$scope.amountOfAttendees) {
$scope.amountOfAttendees = 0
}
if ($scope.hotelOption && $scope.hotelOption.price_per_person_per_night) {
if (!$scope.numOfNights) {
$scope.numOfNights = 0
}
// Add the hotel price
$scope.totalPricePP += ($scope.hotelOption.price_per_person_per_night && $scope.numOfNights ? $scope.hotelOption.price_per_person_per_night * $scope.numOfNights: 0);
$scope.totalPricePPSales += ($scope.hotelOption.price_per_person_per_night_sales && $scope.numOfNights ? $scope.hotelOption.price_per_person_per_night_sales * $scope.numOfNights: 0);
}
// Add room surcharges
angular.forEach($scope.roomTypes, function(roomType) {
$scope.totalPricePP += ($scope.calcRoomTypePrice(roomType) / $scope.amountOfAttendees) * $scope.numOfNights;
$scope.totalPricePPSales += ($scope.calcRoomTypePrice(roomType, true) / $scope.amountOfAttendees) * $scope.numOfNights;
});
// Add the laundry surcharge
if ($scope.hotelOption && $scope.hotelOption.price_laundry_service) {
$scope.totalPricePP += ($scope.hotelOption.price_laundry_service * $scope.calcTrainingsPlusMatches());
$scope.totalPricePPSales += ($scope.hotelOption.price_laundry_service * $scope.calcTrainingsPlusMatches()) * 1.2;
}
// Add the activity prices
angular.forEach($scope.campData.activities, function(option) {
if (option.pay_per_camp) {
$scope.totalPricePP += option.price && $scope.amountOfAttendees ? option.price / $scope.amountOfAttendees : 0;
$scope.totalPricePPSales += option.price_sales && $scope.amountOfAttendees ? (option.price_sales / $scope.amountOfAttendees) : (option.price_sales ? option.price_sales : (option.price && $scope.amountOfAttendees ? (option.price / $scope.amountOfAttendees) * 1.2 : 0));
} else {
$scope.totalPricePP += option.price ? option.price : 0;
$scope.totalPricePPSales += option.price_sales ? option.price_sales : (option.price ? option.price * 1.2 : 0);
}
});
// Add the flight prices and flight baggage prices
$scope.baggagePricePP = 0.0;
angular.forEach($scope.campData.flights, function(option) {
$scope.totalPricePP += option.price && parseFloat(option.price) ? parseFloat(option.price) * option.passengers / $scope.amountOfAttendees : 0;
$scope.totalPricePPSales += option.price && parseFloat(option.price) ? parseFloat(option.price) * option.passengers / $scope.amountOfAttendees * 1.2 : 0;
$scope.baggagePricePP += option.luggage_price && parseFloat(option.luggage_price) ? parseFloat(option.luggage_price) * option.passengers / $scope.amountOfAttendees : 0;
$scope.totalPricePP += option.luggage_price && parseFloat(option.luggage_price) ? parseFloat(option.luggage_price) * option.passengers / $scope.amountOfAttendees : 0;
$scope.totalPricePPSales += option.luggage_price && parseFloat(option.luggage_price) ? parseFloat(option.luggage_price) * option.passengers / $scope.amountOfAttendees * 1.2 : 0;
});
// calculate margin based on new price
if($scope.totalPricePP != $scope.oldTotalPricePP){
$scope.oldTotalPricePP = $scope.totalPricePP;
if($scope.getField('pricepp') && !isNaN($scope.getField('pricepp').value)){
$scope.changePrice($scope.getField('pricepp'));
}
}
$scope.changePrice($scope.getField('pricepp'));
//calculate
let brutoMargin = ($scope.getField('pricepp') * $scope.amountOfAttendees) - ($scope.totalPricePP * $scope.amountOfAttendees);
let rbrCosts = 21/121 * brutoMargin;
$scope.setfVar('brutomargin', parseFloat(brutoMargin.toFixed(2)));
$scope.setfVar('rbrcosts', parseFloat(rbrCosts.toFixed(2)));
}
$scope.hasPrice = function(item) {
return item.price !== undefined && item.price !== null && item.price != 0;
}
$scope.getFieldOrder = function(item) {
return parseInt(item.order);
}
$scope.setValues = function(nextPage) {
$scope.currentPage = nextPage;
switch (nextPage) {
case 4:
$scope.calculatetotalPrice();
break;
}
if ($routeParams.hash !== undefined && $routeParams.hash) {
$location.url('/page/offerte/' + $routeParams.hash + '?p=' + nextPage);
}
}
// Get the options for each select box
$scope.getPageFieldOptions = function(pageNum) {
angular.forEach($scope.pageData.fields, function(field) {
if ((pageNum == 0) || (field.page_num == pageNum)) {
// If this is a select box, get the options
if (['select','customer','camp'].includes(field.type) && field.controller) {
$scope.getFieldOptions(field);
}
}
});
}
$scope.getType = function(value) {
return typeof value
}
// Get the options for the field
$scope.getFieldOptions = function(field) {
if (field.function && field.function.length) {
get_function = field.function;
} else {
get_function = 'get';
}
// Get the fields
var req = {
method: 'GET',
url: '/' + field.controller + '/' + get_function,
}
$http(req).then(function(response) {
// Success? Set the options
if (response.status && response.data.status) {
field.options = response.data.data;
if (!$routeParams.hash) {
$scope.onChange(field);
}
} else {
// Error
}
});
}
// Get the flight carriers
$scope.getCarriers = function() {
// Get the fields
var req = {
method: 'GET',
url: '/carrier/getAll',
}
$http(req).then(function(response) {
// Success? Set the options
if (response.status && response.data.status) {
$scope.carriers = response.data.data;
} else {
// Error
$scope.notification('Foutmelding', "De vliegmaatschappijen konden niet opgehaald worden." + response.data.message, 'danger');
}
});
}
$scope.getCarriers();
// Get the airports
$scope.getAirports = function() {
// Get the fields
var req = {
method: 'GET',
url: '/airport/getForSelect',
}
$http(req).then(function(response) {
// Success? Set the options
if (response.status && response.data.status) {
$scope.airports = response.data.data;
} else {
// Error
$scope.notification('Foutmelding', "De vliegmaatschappijen konden niet opgehaald worden." + response.data.message, 'danger');
}
});
}
$scope.getAirports();
// A field value is changed
$scope.onChange = function(field, option = null) {
// If the value is JSON formatted, decode it
if (isJSON(field.value)) {
field.value = JSON.parse(field.value);
}
// Convert a number to a string
if (['select','customer','customer_account','camp'].includes(field.type) && parseInt(field.value)) {
field.value = field.value.toString()
}
if (field.on_change_function && field.on_change_function.length) {
if (typeof $scope[field.on_change_function] === 'function') {
// Call the function
$scope[field.on_change_function](field, option);
}
}
//informal/ formal text
if (field.subtype == 'formal_mail') {
$scope.onMailChange(field);
}
}
$scope.onMailChange = function(changedField) {
angular.forEach(angular.copy($scope.pageData.fields), function(field, key){
if (field != undefined && field.subtype != undefined) {
switch (field.subtype){
case 'formal_mail':
if (changedField.subtype == 'informal_mail' && changedField.value == true) {
$scope.pageData.fields[key].value = false;
} else if (changedField.subtype == 'informal_mail') {
$scope.pageData.fields[key].value = true
}
break;
case 'informal_mail':
if (changedField.subtype == 'formal_mail' && changedField.value == true) {
$scope.pageData.fields[key].value = false;
}
break;
}
}
});
}
// A field is blurred (focus is turned off)
$scope.onBlur = function(field, option = null) {
// If the value is JSON formatted, decode it
if (isJSON(field.value)) {
field.value = JSON.parse(field.value);
}
// Convert a number to a string
if (['select','customer','customer_account','camp'].includes(field.type) && parseInt(field.value)) {
field.value = field.value.toString()
}
if (field.on_blur_function && field.on_blur_function.length) {
if (typeof $scope[field.on_blur_function] === 'function') {
// Call the function
$scope[field.on_blur_function](field, option);
}
}
}
$scope.updatePreviewMail = function(field, option) {
if ($scope.originalInformalMail && $scope.pageData && $scope.pageData.fields) {
$scope.informalMail = JSON.parse(JSON.stringify($scope.originalInformalMail));
angular.forEach($scope.pageData.fields, function(field, key) {
if (field.value) {
switch (field.subtype) {
case 'additional_text_template':
$scope.informalMail.html = $scope.informalMail.html.replace('##text##', field.value);
break;
case 'contact':
$scope.informalMail.html = $scope.informalMail.html.replace('##customerName##', field.value);
break;
}
}
});
}
}
// A field is initiated
$scope.onInit = function(field, option = null) {
// If the value is JSON formatted, decode it
if (isJSON(field.value)) {
field.value = JSON.parse(field.value);
}
// Convert a number to a string
if (['select','customer','customer_account','camp'].includes(field.type) && parseInt(field.value)) {
field.value = field.value.toString()
}
if (field.on_init_function && field.on_init_function.length) {
if (typeof $scope[field.on_init_function] === 'function') {
// Call the function
$scope[field.on_init_function](field, option);
}
}
}
$scope.setDefaultCampChoise = function (field, option) {
//set default value
if (field.value == undefined) {
field.value = 'yes';
}
}
$scope.setDefaultHotelChoise = function (field, option) {
//set default value
if (field.value == undefined) {
field.value = 'yes';
}
}
$scope.setDefaultFlightChoise = function (field, option) {
//set default value
if (field.value == undefined) {
field.value = 'yes';
}
}
$scope.changePrice = function (field) {
// Update the field values
if (field && field.value && $scope.totalPricePP) {
// Calculate margin pp
let isRbr = $scope.getfVar('rbr');
let pp = ($scope.totalPricePP * $scope.amountOfAttendees);
let ap = field.value * $scope.amountOfAttendees;
let bm = ap - pp;
let rbrCosts = 0;
if (isRbr) {
rbrCosts = bm * (21 / 121);
} else {
rbrCosts = 0;
}
let m = bm - rbrCosts;
let mp = (m / ap) * 100;
// Add results to $scope so they can be used in other places
$scope.calculatedMargin = {
brutomargin: parseFloat(bm.toFixed(2)),
rbrcosts: parseFloat(rbrCosts.toFixed(2)),
marginppabs: parseFloat(m.toFixed(2)),
marginpp: parseFloat(mp.toFixed(2))
};
// Update the scope with the calculated margin
$scope.setfVar('brutomargin', parseFloat(bm.toFixed(2)));
$scope.setfVar('rbrcosts', parseFloat(rbrCosts.toFixed(2)));
$scope.setfVar('marginppabs', parseFloat(m.toFixed(2)));
$scope.setfVar('marginpp', parseFloat(mp.toFixed(2)));
if (mp < 20) {
$scope.notification('Waarschuwing!', 'De nieuwe marge p.p. ligt onder de 20%', 'warning');
}
// Calculate total price of whole arrangement
if (field && field.value && $scope.amountOfAttendees) {
field.comment = "Totale prijs voor arrangement: € " + parseFloat(ap).toFixed(2);
$scope.calculateDeposit();
}
}
if (field && field.value < $scope.totalPricePP) {
$scope.notification('Waarschuwing!', 'Deze prijs is lager dan de berekende totaalprijs per persoon.', 'warning');
}
}
$scope.changeMargin = function (field) {
// Update the field values
if(field && !isNaN(field.value)){
let isRbr = $scope.getfVar('rbr');
let mp = field.value / 100;
let pp = ($scope.totalPricePP * $scope.amountOfAttendees);
let m = 0;
let bm = 0;
if (isRbr) {
m = (mp * pp) / (1-(1.21*mp));
bm = m * 1.21;
} else {
m = (mp * pp) / (1-(mp));
bm = m;
}
let ap = (pp + bm);
let appp = ap / $scope.amountOfAttendees;
let rbrCosts = bm - m;
// Add results to $scope so they can be used in other places
$scope.calculatedMargin = {
brutomargin: parseFloat(bm.toFixed(2)),
rbrcosts: parseFloat(rbrCosts.toFixed(2)),
marginppabs: parseFloat(m.toFixed(2)),
marginpp: parseFloat(mp.toFixed(2))
};
$scope.setfVar('brutomargin', parseFloat(bm.toFixed(2)));
$scope.setfVar('rbrcosts', parseFloat(rbrCosts.toFixed(2)));
$scope.setfVar('pricepp', parseFloat(appp.toFixed(2)));
$scope.setfVar('marginppabs', parseFloat(m.toFixed(2)));
if (parseFloat(field.value) < 20) {
$scope.notification('Waarschuwing!', 'De nieuwe marge p.p. ligt onder de 20%', 'warning');
}
}
}
$scope.changeMarginAbs = function (field) {
// Update the field values
if(field && !isNaN(field.value)){
let isRbr = $scope.getfVar('rbr');
let m = field.value;
let purchasePrice = ($scope.totalPricePP * $scope.amountOfAttendees);
let bm = 0;
if (isRbr) {
bm = m * 1.21;
} else {
bm = m;
}
let ap = (purchasePrice + bm);
let appp = ap / $scope.amountOfAttendees;
let mp = (m / ap) * 100;
let rbrCosts = bm - m;
// Add results to $scope so they can be used in other places
$scope.calculatedMargin = {
brutomargin: parseFloat(bm.toFixed(2)),
rbrcosts: parseFloat(rbrCosts.toFixed(2)),
pricepp: parseFloat(appp.toFixed(2)),
marginpp: parseFloat(mp.toFixed(2))
};
$scope.setfVar('brutomargin', parseFloat(bm.toFixed(2)));
$scope.setfVar('rbrcosts', parseFloat(rbrCosts.toFixed(2)));
$scope.setfVar('pricepp', parseFloat(appp.toFixed(2)));
$scope.setfVar('marginpp', parseFloat(mp.toFixed(2)));
if (parseFloat(mp) < 20) {
$scope.notification('Waarschuwing!', 'De nieuwe marge p.p. ligt onder de 20%', 'warning');
}
}
}
// calculate deposit amount if manual deposit is not checked
$scope.calculateDeposit = function() {
var priceppField = $scope.getField('pricepp');
if (priceppField !== undefined && priceppField !== null && priceppField.value) {
var totalPrice = parseFloat(priceppField.value) * $scope.amountOfAttendees;
// calculate and set deposit amount if the manual deposit is not checked
var manualDepositField = $scope.getField('manualdeposit');
if (manualDepositField === undefined || manualDepositField === null || manualDepositField.value == false) {
var depositAmount = totalPrice * 0.3;
//get from date field
var fromDate = $scope.getField('from');
if (fromDate.value != undefined) {
var diffTime = Math.abs(new Date() - fromDate.value );
var diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays >= 60 && diffDays <= 90) {
depositAmount = totalPrice * 0.7; // 70% invoice
} else if (diffDays < 60) {
depositAmount = totalPrice; // 100% inovice
} else {
depositAmount = totalPrice * 0.3; // %30 invoice
}
}
depositAmount = depositAmount.toFixed(2);
$scope.setfVar('deposit', parseFloat(depositAmount));
}
}
}
$scope.changeManualDeposit = function (field) {
// set deposit field read only based on manual input
var depositField = $scope.getField('deposit');
if (depositField !== undefined && depositField !== null) {
depositField.readOnly = field.value ? false : true;
// if read only, recalculate total price
if (depositField.readOnly) {
$scope.calculateDeposit();
}
}
}
$scope.changeActivityMatch = function (activity) {
Activity.setMatch($scope, activity);
}
// The customer is changed
$scope.changeCustomer = function(changedField) {
if (changedField) {
var selectedOption = null;
if (changedField.value && !isNaN(changedField.value)) {
selectedOption = changedField.options.filter(option => option.id === changedField.value)
}
selectedOption = selectedOption ? selectedOption[0] : {};
// Update the field values
angular.forEach($scope.pageData.fields, function(field, key) {
switch (field.subtype) {
// Customer name
case 'customername':
$scope.pageData.fields[key].value = selectedOption.name;
if (selectedOption.name && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// Club name
case 'club':
$scope.pageData.fields[key].value = selectedOption.club_name;
if (selectedOption.club_name && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// Salutation
case 'salutation':
$scope.pageData.fields[key].value = selectedOption.contactperson_salutation;
if (selectedOption.contactperson_salutation && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// Contact person
case 'contact':
$scope.pageData.fields[key].value = selectedOption.contactperson_name;
if (selectedOption.contactperson_name && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// Address
case 'address':
$scope.pageData.fields[key].value = selectedOption.address;
if (selectedOption.address && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// postalcode
case 'zipcode':
$scope.pageData.fields[key].value = selectedOption.postalcode;
if (selectedOption.postalcode && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// place
case 'place':
$scope.pageData.fields[key].value = selectedOption.place;
if (selectedOption.place && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// country
case 'country':
if (selectedOption.country) {
var selectedCountry = $filter('filter')($scope.countries, {'code': selectedOption.country });
$scope.pageData.fields[key].value = selectedCountry[0] && selectedCountry[0].id ? selectedCountry[0].id : {};
if (selectedOption.country && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
} else {
$scope.pageData.fields[key].readOnly = false;
}
} else {
$scope.pageData.fields[key].value = null;
$scope.pageData.fields[key].readOnly = false;
}
break;
// VAT code
case 'vatcode':
$scope.pageData.fields[key].value = selectedOption.vat_code;
if (selectedOption.vat_code && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// email
case 'email':
$scope.pageData.fields[key].value = selectedOption.email;
if (selectedOption.email && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// coc_code
case 'coccode':
$scope.pageData.fields[key].value = parseInt(selectedOption.coc_code);
if (selectedOption.coc_code && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
// phone_number
case 'phone':
$scope.pageData.fields[key].value = selectedOption.phone_number;
if (selectedOption.phone_number && !selectedOption.new) {
$scope.pageData.fields[key].readOnly = true;
}else{
$scope.pageData.fields[key].readOnly = false;
}
break;
//empty cc, bcc
case 'cc':
$scope.pageData.fields[key].value = '';
break;
case 'bcc':
$scope.pageData.fields[key].value = '';
break;
}
});
// retrieve customer accounts
$scope.retrieveCustomerAccounts(selectedOption.id);
}else{
//if new customer all fields !readOnly
angular.forEach($scope.pageData.fields, function(field, key) {
$scope.pageData.fields[key].readOnly = false;
});
}
}
$scope.retrieveCustomerAccounts = function(customerId) {
$scope.customerAccounts = [];
var req = {
method: 'GET',
url: '/customer/getAccounts/' + customerId + '/1',
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status && response.data.data[0]) {
$scope.customerAccounts = response.data.data;
} else {
$scope.customerAccounts = [];
}
}, function(error) {
$scope.customerAccounts = [];
});
}
$scope.initLocationPicker = function() {
$scope.selectedHotelOption = $scope.hotelOption;
$scope.createMap($scope.hotelOption);
$scope.showGoogleMap = true;
}
$scope.changeHotel = function(option) {
if (option) {
// If the value is JSON formatted, decode it
if (isJSON(option)) {
option = JSON.parse(option);
}
$scope.hotelOption = $scope.getHotel(option);
if (option == 'Nieuw') {
$scope.selectedAccommodation = 'Nieuw';
}
if ($scope.hotelOption) {
Hotel.formatData($scope.hotelOption);
// Set the default service
$scope.hotelOption.service_level = ($scope.hotelOption.service_level && $scope.hotelOption.service_level.length) ? $scope.hotelOption.service_level : 'Logies'
/*
// Get the camp hotel images
$scope.$broadcast('getImages', {
model: 'training_camp_hotels',
id: $scope.hotelOption.id,
item: $scope.hotelOption,
});
*/
// Show the location on the map
$scope.createMap($scope.hotelOption);
$scope.showGoogleMap = true;
let informationLines = {};
if ($scope.hotelOption['information_lines']) {
try {
informationLines = JSON.parse($scope.hotelOption['information_lines']);
} catch(e) {
informationLines = {};
}
}
angular.forEach($scope.pageData.fields, function(field, key) {
if (field.subtype == 'layout') {
if (informationLines.info_header || informationLines.info) {
if ($scope.pageData.fields[key].value == undefined){
$scope.pageData.fields[key].value = {};
}
//set info headers
if ($scope.pageData.fields[key].value['info_header'] == undefined){
$scope.pageData.fields[key].value['info_header'] = {};
}
$scope.pageData.fields[key].value['info_header']['FACILITIES'] = informationLines['info_header']['FACILITIES'];
$scope.pageData.fields[key].value['info_header']['MEALS'] = informationLines['info_header']['MEALS'];
//set info
if ($scope.pageData.fields[key].value['info'] == undefined){
$scope.pageData.fields[key].value['info'] = {};
}
$scope.pageData.fields[key].value['info']['FACILITIES'] = informationLines['info']['FACILITIES'];
$scope.pageData.fields[key].value['info']['MEALS'] = informationLines['info']['MEALS'];
}
}
});
}
} else {
// New hotel
$scope.hotelOption = {};
$scope.hotelOption.service_level = 'Logies';
}
// generate hotel types
$scope.getHotelRoomTypes();
}
function daysBetween(startDate, endDate) {
if ((typeof startDate !== 'object')
||(typeof endDate !== 'object')) {
return null;
}
// The number of milliseconds in all UTC days (no DST)
const ONE_DAY = 1000 * 60 * 60 * 24;
// Convert both dates to milliseconds
var start_ms = startDate.getTime();
var end_ms = endDate.getTime();
if (start_ms <= end_ms) {
// Calculate the difference in milliseconds
var difference_ms = Math.abs(start_ms - end_ms);
// Convert back to days and return
return Math.round(difference_ms/ONE_DAY);
} else {
// startDate > endDate
return -1;
}
}
// Change the (hotel) booking period - from date
$scope.changeFromDate = function(field) {
if (field) {
$scope.fromDate = field.value;
$scope.calculateDeposit();
if ($scope.tillDate) {
// Calculate the number of nights
var nights = daysBetween($scope.fromDate, $scope.tillDate);
// Check #nights
if (nights == -1) {
$scope.notification('Let op!', 'De startdatum valt na de einddatum', 'warning');
} else if (nights >= 0) {
$scope.numOfNights = nights
}
$scope.filterFlights();
}
}
}
// Change the (hotel) booking period - to date
$scope.changeToDate = function(field) {
if (field) {
$scope.tillDate = field.value;
if ($scope.fromDate) {
// Calculate the number of nights
var nights = daysBetween($scope.fromDate, $scope.tillDate);
// Check #nights
if (nights == -1) {
$scope.notification('Let op!', 'De startdatum valt na de einddatum', 'warning');
} else if (nights >= 0) {
$scope.numOfNights = nights
}
$scope.filterFlights();
}
}
}
$scope.flightsFound = true;
// change the flights based on dates
$scope.filterFlights = function() {
if ($scope.fromDate && $scope.tillDate && $scope.campId) {
var req = {
method: 'POST',
url: '/training_camp/getWithDates/' + $scope.pageData.fields[$scope.fieldIndex['camp']]['value'],
data: {
'from': $scope.convertDateObjToJS($scope.fromDate, true, 'datetime'),
'till': $scope.convertDateObjToJS($scope.tillDate, true, 'datetime'),
}
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status && response.data.data[0]) {
$scope.flightsFound = true;
Flight.set($scope, response.data.data[0].flights);
} else {
$scope.flightsFound = false;
}
});
}
}
$scope.reloadCamp = function() {
if ($scope.campId) {
$scope.changeCamp($scope.pageData.fields[$scope.fieldIndex['camp']], false);
}
}
$scope.checkCampId = function() {
if ($scope.fieldIndex !== undefined && $scope.fieldIndex['camp'] !== undefined && ($scope.pageData.fields[$scope.fieldIndex['camp']].value) !== null && !isNaN($scope.pageData.fields[$scope.fieldIndex['camp']].value)) {
$scope.campId = true;
} else {
$scope.campId = false;
}
}
$scope.changeCamp = function(field, setOnlyOptions = false) {
$scope.checkCampId();
if (field && field.value) {
if (setOnlyOptions) {
// Get the camp ID
if (campId = parseInt(field.value)) {
// Get the training camp details
var req = {
method: 'GET',
url: '/training_camp/getWith/' + campId,
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status && response.data.data[0]) {
$scope.updateCampFields(response.data.data[0], setOnlyOptions);
} else {
// Error
$scope.notification('Foutmelding', 'De trainingskamp velden konden niet worden bijgewerkt', 'danger');
}
});
} else {
$scope.updateCampFields(null, setOnlyOptions)
}
} else {
// Give a swal
swal({
title: 'Let op!',
text: 'Als u dit trainingskamp selecteert, worden de huidige velden overschreven met de gegevens van dit trainingskamp.',
icon: 'warning',
buttons: {
cancel: 'Annuleren',
OK: {
text: 'OK',
value: true,
closeModal: false,
},
},
}).then(
function(inputValue){
if (inputValue === true && inputValue !== null) {
//ok button clicked
if (!inputValue) throw null;
// Get the camp ID
if (campId = parseInt(field.value)) {
// Get the training camp details
var req = {
method: 'GET',
url: '/training_camp/getWith/' + campId,
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status) {
$scope.updateCampFields(response.data.data[0], setOnlyOptions);
swal.stopLoading();
swal.close();
} else {
// Error
$scope.notification('Foutmelding', 'De trainingskamp velden konden niet worden bijgewerkt', 'danger');
}
});
} else {
$scope.updateCampFields(null, setOnlyOptions);
swal.stopLoading();
swal.close();
}
} else {
//cancel button clicked
$scope.pageData.fields[field.id].value = null;
}
}).catch(err => {
if (err) {
$scope.notification('Foutmelding', 'Er is een onbekende fout opgetreden!', 'danger');
console.error(err)
} else {
swal.stopLoading();
swal.close();
}
})
}
}
}
function isJSON(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
// VAT changed
$scope.changeVat = function(field) {
if (field.value) {
// Check the BTW validity
var req = {
method: 'POST',
url: '/quotation/checkVatCode/' + field.value,
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status) {
$scope.hash = response.data.data.hash;
// Success
fields[field.id].valid = true;
} else {
// Error
fields[field.id].valid = false;
$scope.notification('Foutmelding', 'Het opgegeven BTW-nummer is ongeldig', 'danger');
}
})
}
}
// On changing the activity
$scope.changeActivity = function(activity) {
// Change the activity date/time
Activity.formatData(activity, false, $scope);
}
$scope.changeCountry = function(field) {
$scope.pageData.campCountry = field.value;
$scope.preparePage(3);
//find country
if (field.value != undefined) {
let country = field.options.find(country => country.id == field.value);
if (country != undefined && country.is_rbr == 1) {
$scope.pageData.fields.forEach((pageDataField) => {
if (pageDataField.id == 59) {
pageDataField.value = true;
}
if (pageDataField.id == 77 || pageDataField.id == 78) {
pageDataField.readOnly = true;
}
});
}
}
}
$scope.changeHandBaggage = function(field) {
$scope.handBaggage = field.value;
}
$scope.changeBaggage = function(field) {
$scope.baggage = field.value;
}
$scope.changeBudget = function(field) {
$scope.budget = field.value;
}
$scope.changeSportBaggage = function(field) {
$scope.sportBaggage = field.value;
}
$scope.changeSelfTransport = function(field) {
$scope.selfTransport = field.value;
}
$scope.changeTouristTax = function(field) {
$scope.tourist_tax = field.value;
}
$scope.getAirports = function() {
var req = {
method: 'GET',
url: '/airport/getAll',
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status && response.data.data) {
$scope.airports = response.data.data;
} else {
$scope.notification('Foutmelding', 'Geen beschikbare vluchten gevonden', 'danger');
}
});
}
$scope.getAirports();
$scope.getAirportByIata = function(iata) {
if ($scope.airports && Array.isArray($scope.airports)) {
let selectedAirport = {};
angular.forEach(angular.copy($scope.airports), function(airport) {
if (airport.iata == iata) {
selectedAirport = airport;
}
}, selectedAirport);
return selectedAirport.name + ' (' + selectedAirport.iata + ')';
}
}
$scope.getSelectOptions = function(field) {
if (field) {
switch (field.subtype) {
case 'hotels':
field.options = $scope.hotels
break;
case 'flights':
field.options = $scope.flights
break;
case 'country':
field.options = $scope.countries
break;
}
return field.options;
}
return [];
}
$scope.getFilteredCustomers = function(field, filter) {
var customers = $scope.getSelectOptions(field);
//check if customers are defined
if (customers !== undefined && customers !== null) {
//filter customers with filter
customers = customers.filter(function (customer) {
return customer.name.toLowerCase().includes(filter.toLowerCase());
}, filter);
//if only 1 result fill and call onchange
if (customers.length == 1 && field.value != customers[0]['id']) {
field.value = customers[0]['id'];
$scope.onChange(field);
}
}
return customers;
}
$scope.getFilteredCustomerAccounts = function(field) {
return $scope.customerAccounts;
}
$scope.selectOptionName = function(option, field = null) {
var optionName = '';
optionName = option.name;
return optionName;
}
$scope.toggleTKorAllHotels = function() {
if ($scope.campHotels !== undefined) {
if ($scope.hotels == $scope.allHotels) {
$scope.hotels = $scope.campHotels;
} else {
$scope.hotels = $scope.allHotels;
}
}
}
$scope.updateCampFields = function(data, setOnlyOptions = null) {
//$scope.originalCampData = angular.copy(data);
// Update the field values
angular.forEach($scope.pageData.fields, function(field, key) {
switch (field.subtype) {
// Camp name
case 'campname':
if (!setOnlyOptions) {
$scope.pageData.fields[key].value = data ? data.name : null;
}
break;
// Training camp place/location
case 'camplocation':
if (!setOnlyOptions) {
$scope.pageData.fields[key].value = data ? data.location : null;
}
break;
// Training camp country
case 'campcountry':
if (!setOnlyOptions) {
if (data) {
country = data.country.id;
$scope.pageData.fields[key].value = country;
$scope.pageData.campCountry = data.country;
$scope.changeCountry(field);
} else {
$scope.pageData.campCountry = null
}
}
break;
case 'description':
if (data && !setOnlyOptions) {
$scope.pageData.fields[key].value = data.description;
break;
}
// Training camp transfers
case 'transfers':
if (!setOnlyOptions) {
if (data) {
$scope.pageData.fields[key].value = data.transfers;
}
}
break;
// Tourist tax options
case 'tourist_tax':
if (!setOnlyOptions) {
if (data) {
if (data.has_tourist_tax == "0") {
$scope.pageData.fields[key].value = false;
} else {
$scope.pageData.fields[key].value = true;
}
}
}
break;
// Flight options
case 'flights':
$scope.filterFlights();
break;
// if (data && !setOnlyOptions) {
// Flight.set($scope, data.flights);
// // Add/show these options by default
// Flight.resetAddMany($scope, $scope.campData, data.flights);
// } else {
// Flight.init($scope, $http);
// }
// break;
// Activity options
case 'activities':
if (data && !setOnlyOptions) {
//remove options not standardised in standard camp
//Activity.set($scope, data.activities);
data.activities = $filter('orderBy')(angular.copy(data.activities), 'day');
// Add/show these options by default
Activity.resetAddMany($scope, $scope.campData, data.activities);
} else {
Activity.init($scope, $http);
}
break;
// The camp exclusion
case 'exclusive':
if (data && !setOnlyOptions) {
$scope.pageData.fields[key].value = data && data.exclusive ? data.exclusive : null;
break;
}
break;
// The selected hotel
case 'hotels':
// Set the hotel options
if (data) {
// Set the hotel options
// Hotel.set($scope, data.hotels);
if (!setOnlyOptions) {
// If there is only 1 hotel option, select it by default
if (data.hotels.length == 1) {
// format hotel option for number data
Hotel.formatData(data.hotels[0]);
$scope.pageData.fields[key].value = data.hotels[0];
if(data.hotels[0]['price_surcharge_single_sales']){
data.hotels[0]['price_surcharge_single_sales'] = parseFloat(data.hotels[0]['price_surcharge_single_sales']);
}
if(data.hotels[0]['price_laundry_service']){
data.hotels[0]['price_laundry_service'] = parseFloat(data.hotels[0]['price_laundry_service']);
}
if(data.hotels[0]['phone_number']){
data.hotels[0]['phone_number'] = data.hotels[0]['phone_number'];
}
if(data.hotels[0]['email']){
data.hotels[0]['email'] = data.hotels[0]['email'];
}
if (data.hotels[0]['rooms'] !== undefined && Array.isArray(data.hotels[0]['rooms'])) {
// correct format
} else if (data.hotels[0]['rooms'] !== undefined) {
try {
data.hotels[0]['rooms'] = JSON.parse(data.hotels[0]['rooms']);
} catch (e) {
data.hotels[0]['rooms'] = [];
}
}
// set hotel option
$scope.hotelOption = data.hotels[0];
$scope.selectedAccommodation = data.hotels[0].id;
// create map
$scope.createMap($scope.hotelOption);
$scope.showGoogleMap = true;
// generate hotel room types for chambers
$scope.getHotelRoomTypes();
} else {
// set default value
$scope.hotelOption = {
service_level: 'Logies'
}
$scope.selectedAccommodation = null;
}
}
//set Available Hotels
$scope.campHotels = data.hotels;
$scope.hotels = data.hotels;
} else {
Hotel.init($scope, $http)
$scope.selectedAccommodation = null
}
break;
case 'layout':
if (data && !setOnlyOptions) {
let informationLines = {
info: {},
info_header: {},
};
if (data.hotels && Array.isArray(data.hotels) && data.hotels.length == 1 && data.hotels[0] && data.hotels[0]['information_lines']) {
try {
let hotelInformationLines = JSON.parse(data.hotels[0]['information_lines']);
informationLines = Object.assign(informationLines, hotelInformationLines);
} catch(e) {
informationLines = {
info: {},
info_header: {},
};
}
}
if (data['information_lines']) {
try {
let generalInformationLines = JSON.parse(data['information_lines']);
if (generalInformationLines['info'] !== undefined && generalInformationLines['info'] && typeof generalInformationLines['info'] === 'object') {
if (informationLines['info'] !== undefined && informationLines['info'] && typeof informationLines['info'] === 'object') {
informationLines['info'] = Object.assign(informationLines['info'], generalInformationLines['info']);
} else {
informationLines['info'] = generalInformationLines['info'];
}
}
if (generalInformationLines['info_header'] !== undefined && generalInformationLines['info_header'] && typeof generalInformationLines['info_header'] === 'object') {
if (informationLines['info_header'] !== undefined && informationLines['info_header'] && typeof informationLines['info_header'] === 'object') {
informationLines['info_header'] = Object.assign(informationLines['info_header'], generalInformationLines['info_header']);
} else {
informationLines['info_header'] = generalInformationLines['info_header'];
}
}
} catch(e) {
informationLines = {
info: {},
info_header: {},
};
}
}
if ($scope.pageData.fields[key].value !== undefined && informationLines){
$scope.pageData.fields[key].value = Object.assign($scope.pageData.fields[key].value, informationLines);
} else if ($scope.pageData.fields[key].value === undefined) {
$scope.pageData.fields[key].value = informationLines;
}
}
break;
}
});
}
// Save the current page and go to the next page
$scope.nextPage = function() {
$scope.setValues($scope.currentPage + 1);
}
// Save the current page and go to the next page
$scope.previousPage = function() {
$scope.setValues($scope.currentPage - 1);
}
// Go top page [pageNum]
$scope.goToPage = function(pageNum) {
// Set the current values
$scope.setValues(pageNum);
}
// Send an e-mail to the customer
$scope.sendMail = function() {
// Send an email
var req = {
method: 'POST',
url: '/quotation/email/' + $scope.quotationHash,
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status) {
// Success
$scope.notification('Succes','De nieuwe offerte is successvol verzonden!', 'success');
} else {
// Error
$scope.notification('Foutmelding', 'Deze offerte kan niet verzonden worden.
' + response.data.message, 'danger');
}
});
}
// Format the retrieved data
$scope.formatGetData = function(fields) {
angular.forEach(fields, function(field, key) {
// Format the date and time format
if (['date','time'].includes(field.type)) {
fields[key].value = $scope.convertDateObjToJS(field.value, false, field.type);
}
// Convert boolean values
fields[key].ask_validation = field.ask_validation == '1';
if (field.type == 'checkbox') {
fields[key].value = field.value == '1';
}
});
return fields;
}
$scope.convertDateObjToJS = function(objDate, reverse, type) {
if (!objDate) {
return objDate;
}
if (!reverse) {
if (typeof objDate === 'object') {
return objDate;
}
tempTime = objDate.split(/[- :T.]/)
switch(type){
case 'date':
tempNewTime = new Date(tempTime[0], tempTime[1]-1, tempTime[2], 0, 0, 0);
break;
case 'time':
if(!tempTime[2]){
tempTime[2] = 0;
}
tempNewTime = new Date(0 ,0, 0, tempTime[0], tempTime[1], 0);
break;
case 'datetime':
tempNewTime = new Date(tempTime[0], tempTime[1]-1, tempTime[2], tempTime[3], tempTime[4], tempTime[5] ? tempTime[5] : 0);
break;
}
return tempNewTime;
}else{
if (typeof objDate === 'string') {
return objDate;
}
switch(type){
case 'date':
if(typeof objDate.getFullYear !== 'function'){
return null;
}
return ([objDate.getFullYear(), objDate.getMonth()+1, objDate.getDate()].join('-'));
break;
case 'time':
if(typeof objDate.getHours !== 'function'){
return null;
}
return ([('00' + objDate.getHours()).slice(-2), ('00' + objDate.getMinutes()).slice(-2)].join(':'));
break;
case 'datetime':
if(typeof objDate.getFullYear !== 'function'){
return null;
}
return ([objDate.getFullYear(), objDate.getMonth()+1, objDate.getDate()].join('-')+' '+[('00' + objDate.getHours()).slice(-2), ('00' + objDate.getMinutes()).slice(-2)].join(':'));
break;
default:
return objDate;
break;
}
}
}
// Create a new quotation using the data in the database
$scope.createQuotation = function() {
// Is an existing quotation revised? Warn the user
if ($routeParams.hash) {
swal({
title: 'Let op!',
text: 'Er wordt een bijgewerkte, nieuwe versie van deze offerte aangemaakt.',
icon: 'warning',
buttons: {
cancel: 'Annuleren',
OK: true,
},
}).then(ok => {
if (!ok) throw null;
$scope.postQuotation();
}).catch(err => {
if (err) {
swal('Foutmelding', 'De aanvraag is mislukt!', 'error');
console.error(err)
} else {
swal.stopLoading();
swal.close();
}
});
} else {
$scope.postQuotation();
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
$scope.postQuotation = function(saveOk = false) {
//check
if (!saveOk) {
if ($scope.fromDate && $scope.tillDate && $scope.campData.flights) {
let showModal = false;
let fromDateInFlight = false;
let tillDateInFlight = false;
//loop flights to see if they are on the camp dates
if ($scope.campData.flights.length) {
angular.forEach(angular.copy($scope.campData.flights), function(flight) {
if (!(moment(flight.departure_date).format('YYYY-MM-DD') >= moment($scope.fromDate).format('YYYY-MM-DD') && moment(flight.arrival_date).format('YYYY-MM-DD') <= moment($scope.tillDate).format('YYYY-MM-DD'))) {
showModal = true;
}
if (moment(flight.departure_date).format('YYYY-MM-DD') == moment($scope.fromDate).format('YYYY-MM-DD')) {
fromDateInFlight = true;
}
if (moment(flight.arrival_date).format('YYYY-MM-DD') == moment($scope.tillDate).format('YYYY-MM-DD')) {
tillDateInFlight = true;
}
});
if (!fromDateInFlight || !tillDateInFlight) {
showModal = true;
}
} else {
saveOk = true;
}
if (showModal) {
$('#flight-modal').modal('show');
return;
} else {
saveOk = true;
}
} else {
saveOk = true;
}
}
// Copy the fields object
var fields = Object.assign({}, $scope.pageData.fields);
// angular copy to evade warnings when transforming date objects
fields = angular.copy(fields);
angular.forEach(fields, function(field, key) {
// Format the dates
if (['date','time'].includes(field.type)) {
fields[key].value = $scope.convertDateObjToJS(field.value, true, field.type);
}
if ((field.ask_validation == false) && field.controller) {
// Delete the field options
delete field.options;
}
if (field.subtype == 'customer'){
if ($scope.customerId !== undefined) {
fields[key].value = $scope.customerId;
}
}
switch (field.type) {
// Set the hotel options
case 'hotels':
if ($scope.hotelOption) {
fields[key].value = [$scope.hotelOption];
newHotelId = field.show_on_field_id;
}
break;
// Set the activities
case 'activities':
fields[key].value = angular.copy($scope.campData.activities);
// Format the data
angular.forEach(fields[key].value, function(activity) {
Activity.formatData(activity, true, $scope);
});
break;
// Set the flights
case 'flights':
var campDataFlights = [];
if ($scope.campData.flights) {
campDataFlights = angular.copy($scope.campData.flights);
angular.forEach(campDataFlights, function(flight, index) {
if (flight['arrival_date']){
campDataFlights[index]['arrival_date'] = moment(flight['arrival_date']).format('YYYY-MM-DD HH:mm:ss');
}
if (flight['departure_date']){
campDataFlights[index]['departure_date'] = moment(flight['departure_date']).format('YYYY-MM-DD HH:mm:ss');
}
});
}
fields[key].value = campDataFlights;
break;
// Set the rooms
case 'chambers':
fields[key].value = $scope.roomTypes;
break;
}
});
if(saveOk) {
// Create the quotation, send the data
var req = {
method: 'POST',
url: '/quotation/createQuotation',
data: {
'quotation_number': $scope.quotationNumber,
'fields': fields,
}
}
$http(req).then(async function(response) {
// Success?
if (response.status && response.data.status) {
$scope.quotationHash = response.data.data.hash;
if (response.data.message) {
$scope.quotationReadOnly = true;
// Warning
$scope.notification('Warning', response.data.message, "warning");
await sleep(2000);
}
// Rewrite the url
if ($location.search().p !== undefined && angular.isNumber(parseInt($location.search().p))) {
window.location.replace('page/offerte/' + $scope.quotationHash + '?p=' + $location.search().p);
} else {
window.location.replace('page/offerte/' + $scope.quotationHash);
}
// Success
$scope.notification('Success', ($routeParams.hash ? 'De offerte is bijgewerkt' : 'De nieuwe offerte is successvol aangemaakt!'), "success");
} else {
// Error
$scope.notification('Foutmelding', 'De offerte kon helaas niet aangemaakt worden.
' + response.data.message, "danger");
}
}, function(error) {
// Error
$scope.notification('Foutmelding', 'De offerte kon helaas niet aangemaakt worden.', "danger");
});
}
}
$scope.formatFlightDate = function(date, dateFormat) {
return moment(date).format(dateFormat);
}
// Get the countries
$scope.getCountries = function() {
var req = {
method: 'GET',
url: '/country/getNames',
}
$http(req).then(function(response) {
// Success? Set the options
if (response.status && response.data.status) {
$scope.countries = response.data.data;
} else {
// Error
$scope.notification('Foutmelding', response.data.message, "danger");
}
});
}
$scope.getCountries();
$scope.campData = {};
Activity.init($scope, $http);
// Add a flight
$scope.addFlight = function(newItem) {
if (newItem) {
//check allotment
let req = {
method: 'POST',
url: '/quotation/getavailableallotments',
data: newItem,
}
$http(req).then(function(response) {
if (response.status && response.data.status) {
newItem.available_allotments = response.data.data.available_allotments;
}
//check for carrier id and set in carrier object
if (newItem.carrier_id) {
newItem['carrier'] = new Object();
newItem['carrier']['id'] = newItem.carrier_id;
//execute changeCarrier function to set defaults
$scope.changeCarrier(newItem);
}
var itemNum = Flight.add($scope, $scope.campData, newItem)
$timeout(function() { $('#flight' + itemNum).collapse() }, 0);
});
} else {
var itemNum = Flight.add($scope, $scope.campData, newItem)
$timeout(function() { $('#flight' + itemNum).collapse() }, 0);
}
}
// Delete a flight
$scope.deleteFlight = function(key) {
swal({
title: 'Waarschuwing!',
text: 'Weet u zeker dat u deze vlucht wilt verwijderen?',
icon: 'warning',
buttons: {
cancel: 'Annuleren',
OK: true,
},
}).then(ok => {
if (!ok) throw null;
if ($scope.quotationStatus == 'Concept') {
Flight.delete(key, $scope.campData);
$scope.$apply();
}
}).catch(err => {
if (err) {
$scope.notification('Foutmelding', 'Het verwijderen is mislukt!', 'danger');
console.error(err)
} else {
swal.stopLoading();
swal.close();
}
})
}
// Add an activity
$scope.addActivity = function(newItem) {
//var itemNum =
Activity.add($scope, $scope.campData, newItem);
//$timeout(function() { $('#activity' + itemNum).collapse() }, 0);
}
// Delete an activity
$scope.deleteActivity = function(key, activityOption) {
//find activity for the right activity to delete
let selectedActivity = $scope.campData.activities.findIndex(activity => activity == activityOption);
swal({
title: 'Waarschuwing!',
text: 'Weet u zeker dat u deze activiteit wilt verwijderen?',
icon: 'warning',
buttons: {
cancel: 'Annuleren',
OK: true,
},
}).then(ok => {
if (!ok) throw null;
if ($scope.quotationStatus == 'Concept') {
Activity.delete(selectedActivity, $scope.campData);
$scope.$apply();
}
}).catch(err => {
if (err) {
$scope.notification('Foutmelding', 'Het verwijderen is mislukt!', "danger");
console.error(err)
} else {
swal.stopLoading();
swal.close();
}
})
}
// Add an hotel
$scope.addHotel = function(newItem) {
Hotel.add($scope, $scope.campData, newItem)
}
// Delete an hotel
$scope.deleteHotel = function(key) {
swal({
title: 'Waarschuwing!',
text: 'Weet u zeker dat u dit hotel wilt verwijderen?',
icon: 'warning',
buttons: {
cancel: 'Annuleren',
OK: true,
},
}).then(ok => {
if (!ok) throw null;
if ($scope.quotationStatus == 'Concept') {
Hotel.delete(key, $scope.campData);
}
}).catch(err => {
if (err) {
$scope.notification('Foutmelding', 'Het verwijderen is mislukt!', "danger");
console.error(err)
} else {
swal.stopLoading();
swal.close();
}
})
}
/**
* Function to initiate Google Maps
*/
$scope.createMap = function(hotelOption) {
if (!hotelOption) {
console.warn('Er is geen hotel geselecteerd.');
}
// Get lat and long from the hotel
if (hotelOption
&& hotelOption.latitude != undefined
&& !isNaN(parseFloat(hotelOption.latitude))
&& hotelOption.longitude != undefined
&& !isNaN(parseFloat(hotelOption.longitude))) {
zoomLevel = parseInt(hotelOption.zoom_level);
// Set lat en long from hotel
var LatLng = {lat: parseFloat(hotelOption.latitude), lng: parseFloat(hotelOption.longitude)};
setMarker = true;
} else {
//if undefined set Amsterdam lat en long
var LatLng = {lat: 52.3545653, lng: 4.7585435};
setMarker = false;
}
// Get the zoom level
if ((typeof zoomLevel === 'undefined') || !zoomLevel || isNaN(zoomLevel)) {
zoomLevel = 4;
}
// Init map
mapId = 'hotelMap'
if (mapElement = document.getElementById(mapId)) {
var map = new google.maps.Map(mapElement, {
zoom: zoomLevel,
center: LatLng,
disableDefaultUI: $scope.quotationReadOnly,
});
if (setMarker) {
$scope.marker = new google.maps.Marker({
position: LatLng,
map: map,
title: "Hotel"
});
} else {
$scope.marker = null
}
if (!$scope.quotationReadOnly) {
// Create the search box and link it to the UI element.
var card = document.getElementById('pac-card');
var input = document.getElementById('pac-input');
var infowindowContent = document.getElementById('infowindow-content');
map.controls[google.maps.ControlPosition.LEFT_TOP].push(card);
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
infowindow.setContent(infowindowContent);
autocomplete.addListener('place_changed',function() {
document.getElementById("location-error").style.display = 'none';
infowindow.close();
var place = autocomplete.getPlace();
if (!place.geometry) {
document.getElementById("location-error").style.display = 'inline-block';
document.getElementById("location-error").innerHTML = "Cannot Locate '" + input.value + "' on map";
return;
}
map.fitBounds(place.geometry.viewport);
if ($scope.marker != null) {
$scope.marker.setPosition(place.geometry.location);
$scope.marker.setVisible(true);
} else {
$scope.marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title: "Hotel"
});
}
});
google.maps.event.addListener(map, 'click', function( event ){
var LatLng = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
// (Re)place the marker
if ($scope.marker) {
// Replace the current marker
$scope.marker.setPosition(LatLng);
} else {
$scope.marker = new google.maps.Marker({
position: LatLng,
map: map,
title: "Hotel"
});
}
hotelOption.latitude = event.latLng.lat();
hotelOption.longitude = event.latLng.lng();
hotelOption.zoom_level = map.getZoom();
});
}
} else {
console.error('Google map element ' + mapId + ' is not found.')
}
}
/**
* Functions for the image modal
*/
$scope.showImageModal = function (item, key) {
$scope.$broadcast('showImageModal', {
model: null,
cardSubjectId: key,
item: item,
});
}
$scope.showCampHotelImageUploader = function(item, key) {
$scope.showImageModal(item, key);
}
$scope.showCampActivityImageUploader = function(item, key) {
$scope.showImageModal(item, key);
}
$scope.showCampMatchImageUploader = function(item, key) {
$scope.showImageModal(item, key);
}
/**
* Functions to add a new item dynamically in a popup form
*/
$scope.setNewItemFields = function(fields) {
$scope.newItemFields = fields;
}
$scope.addNewItem = function(item) {
// Create the item, send the data
var req = {
method: 'POST',
url: '/' + item.controller + '/insert',
data: item.data,
}
$http(req).then(function(response) {
// Success?
if (response.status && response.data.status) {
// Success
$scope.notification('Success', 'Het nieuwe item is successvol aangemaakt!', 'success');
} else {
// Error
$scope.notification('Foutmelding', response.data.message,"danger");
}
});
}
$scope.closeView = function() {
window.location.replace('page/offertes')
}
/*--------[Hotel Calc]------------*/
$scope.calcHotelSingles = function(rooms){
singles = 0;
angular.forEach(rooms, function(room){
if((room.doubles == 0 || !room.doubles) && room.singles && room.singles == 1){
singles = singles +1;
}
});
return singles;
}
$scope.calcRoomTypePrice = function(roomType, sales = false) {
// set different key when sales
var priceKey = 'price_surcharge';
if (sales) {
priceKey = 'price_surcharge_sales';
}
// check required data
if (roomType['amount'] !== undefined && roomType['amount'] > 0 && roomType[priceKey] !== undefined && roomType[priceKey] != 0) {
if (roomType['price_surcharge_per'] !== undefined && roomType['price_surcharge_per'] === 'PERSON') {
return roomType['amount'] * (parseInt(roomType['amount_of_singles']) + (parseInt(roomType['amount_of_doubles']) * 2)) * roomType[priceKey];
} else if (roomType['price_surcharge_per'] !== undefined && roomType['price_surcharge_per'] === 'ROOM') {
return roomType['amount'] * roomType[priceKey];
}
}
return 0.0;
}
// callback for manual washes
$scope.changeManualWashes = function(field) {
$scope.calcTrainingsPlusMatches();
}
/*--------[Laundry Calc]------------*/
$scope.calcTrainingsPlusMatches = function() {
// check if manual entry for laundry amount
var manualLaundryAmount = false;
angular.forEach($scope.pageData.fields, function (field) {
if (field.subtype == 'manualwashes' && $scope.pageData.fields[field.id] !== undefined && $scope.pageData.fields[field.id].value !== undefined) {
manualLaundryAmount = $scope.pageData.fields[field.id].value;
}
});
var laundryAmt = 0;
if (manualLaundryAmount) {
// find laundry amount and set field to readOnly
angular.forEach($scope.pageData.fields, function (field) {
if (field.subtype == 'washes' && $scope.pageData.fields[field.id] !== undefined && $scope.pageData.fields[field.id].value !== undefined) {
laundryAmt = parseInt($scope.pageData.fields[field.id].value);
$scope.pageData.fields[field.id].readOnly = false;
}
});
} else {
// calculate laundry amount based on matches and trainings
if($scope.campData.activities){
angular.forEach($scope.campData.activities, function(activity){
/* Matches and Trainings */
if(activity.activity_type){
activity_type = JSON.parse(activity.activity_type)
if(activity_type.id){
if(activity_type.id == 1 || activity_type.id == 5) {
laundryAmt = laundryAmt + 1;
}
}
}
});
}
// write calculated laundry amount back to field
angular.forEach($scope.pageData.fields, function (field) {
if (field.subtype == 'washes') {
$scope.pageData.fields[field.id].value = laundryAmt;
$scope.pageData.fields[field.id].readOnly = true;
}
});
}
return laundryAmt;
}
//email template functions
$scope.makeElements = function() {
$scope.htmlElements = '';
//replace names elements
angular.forEach($scope.emailTemplate.variables, function(variable, key){
$scope.htmlElements += '';
});
$scope.htmlElements += '';
if ($('#email_html')) {
var documentContents = $('#email_html').summernote('code');
$('#email_html').summernote('reset');
if (angular.isString(documentContents)) {
$('#email_html').summernote('code', documentContents);
}
}
}
$scope.insertElement = function (context) {
var ui = $.summernote.ui;
var list = $('#elements-list').val();
var button = ui.buttonGroup([
ui.button({
className: 'dropdown-toggle',
contents: 'Voeg een variabele in',
tooltip: "Elements",
container: false,
data: {
toggle: 'dropdown'
},
click: function() {
// Cursor position must be saved because is lost when dropdown is opened.
context.invoke('editor.saveRange');
}
}),
ui.dropdown({
className: 'drop-default summernote-list',
contents: $scope.htmlElements,
callback: function($dropdown) {
$dropdown.find('ul').click(function() {
context.invoke('editor.restoreRange');
context.invoke('editor.focus');
context.invoke('editor.insertText', $(this)[0].innerText);
});
}
})
]);
return button.render();
}
//summernote config
$scope.summernoteoptions = {
toolbar: [
['edit',['undo','redo']],
['headline', ['style']],
['style', ['bold', 'italic', 'underline', 'clear']],
['fontface', ['fontname']],
['textsize', ['fontsize']],
['fontclr', ['color']],
['alignment', ['ul', 'ol', 'paragraph', 'lineheight']],
['height', ['height']],
['table', ['table']],
['insert', ['link','hr','picture']],
['view', ['fullscreen', 'codeview']],
['extraColom', ['element']],
],
buttons: {
element: $scope.insertElement
}
};
});
app.directive('stringToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(value) {
return '' + value;
});
ngModel.$formatters.push(function(value) {
return parseFloat(value);
});
}
};
});