744 lines
22 KiB
JavaScript
744 lines
22 KiB
JavaScript
/**
|
|
* This file contains the JavaScript code for the Twingle Shop integration.
|
|
*/
|
|
|
|
/**
|
|
* This function initializes the Twingle Shop integration.
|
|
*/
|
|
function twingleShopInit() {
|
|
cj('#twingle-shop-spinner').hide();
|
|
|
|
// Run once on page load
|
|
load_financial_types();
|
|
twingle_shop_active_changed();
|
|
twingle_map_products_changed();
|
|
twingle_fetch_products();
|
|
|
|
// Add event listeners
|
|
cj('#enable_shop_integration:checkbox').change(twingle_shop_active_changed);
|
|
cj('#shop_map_products:checkbox').change(twingle_map_products_changed);
|
|
cj('#btn_fetch_products').click(function (event) {
|
|
event.preventDefault(); // Prevent the default form submission behavior
|
|
twingle_fetch_products();
|
|
});
|
|
}
|
|
|
|
// Define financial types as global variable
|
|
let financialTypes = {};
|
|
|
|
/**
|
|
* Load financial types from CiviCRM
|
|
*/
|
|
function load_financial_types() {
|
|
CRM.api3('FinancialType', 'get', {
|
|
'sequential': 1,
|
|
'options': { 'limit': 0 },
|
|
}).then(function (result) {
|
|
financialTypes = result.values.reduce((obj, item) => {
|
|
obj[item.id] = item.name;
|
|
return obj;
|
|
}, {});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetches the Twingle products for the given project identifiers.
|
|
*/
|
|
function twingle_fetch_products() {
|
|
let active = cj('#shop_map_products:checkbox:checked').length;
|
|
if (active) {
|
|
cj('#twingle-shop-spinner').show();
|
|
CRM.api3('TwingleShop', 'fetch', {
|
|
'project_identifiers': cj('#selectors :input').val(),
|
|
}).then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#btn_fetch_products').crmError(result.error_message, ts('Could not fetch products', []));
|
|
cj('#twingle-shop-spinner').hide();
|
|
return;
|
|
}
|
|
buildShopTables(result);
|
|
cj('#twingle-shop-spinner').hide();
|
|
}, function () {
|
|
cj('#btn_fetch_products').crmError(ts('Could not fetch products. Please check your Twingle API key.', []));
|
|
cj('#twingle-shop-spinner').hide();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the form fields based on whether shop integration is currently active
|
|
*/
|
|
function twingle_shop_active_changed() {
|
|
let active = cj('#enable_shop_integration:checkbox:checked').length;
|
|
if (active) {
|
|
cj('.twingle-shop-element').show();
|
|
} else {
|
|
cj('.twingle-shop-element').hide();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display fetch button and product mapping when the corresponding option is active
|
|
*/
|
|
function twingle_map_products_changed() {
|
|
let active = cj('#shop_map_products:checkbox:checked').length;
|
|
if (active) {
|
|
cj('.twingle-product-mapping').show();
|
|
} else {
|
|
cj('.twingle-product-mapping').hide();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function builds the shop tables.
|
|
* @param shopData
|
|
*/
|
|
function buildShopTables(shopData) {
|
|
|
|
let productTables = [];
|
|
|
|
// Create table for each project (shop)
|
|
for (const key in shopData.values) {
|
|
productTables.push(new ProductsTable(shopData.values[key]));
|
|
}
|
|
|
|
// Add table container to DOM
|
|
const tableContainer = document.getElementById('tableContainer');
|
|
|
|
// Add tables to table container
|
|
for (const productTable of productTables) {
|
|
tableContainer.appendChild(productTable.table);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the value of the default financial type for the shops defined in this profile.
|
|
* @returns {string|string}
|
|
*/
|
|
function getShopDefaultFinancialType() {
|
|
const default_selection = document.getElementById('s2id_shop_financial_type');
|
|
const selected = default_selection.getElementsByClassName('select2-chosen')[0];
|
|
return selected ? selected.textContent : '';
|
|
}
|
|
|
|
/**
|
|
* Get the value of the default financial type.
|
|
* @returns {string}
|
|
*/
|
|
function getShopDefaultFinancialTypeValue() {
|
|
const shopDefaultFinancialType = getShopDefaultFinancialType();
|
|
return Object.keys(financialTypes).find(key => financialTypes[key] === shopDefaultFinancialType);
|
|
}
|
|
|
|
/**
|
|
* This class represents a Twingle Product.
|
|
*/
|
|
class Product {
|
|
|
|
/**
|
|
* Creates a new Product object.
|
|
* @param productData
|
|
* @param parentTable
|
|
*/
|
|
constructor(productData, parentTable) {
|
|
this.parentTable = parentTable;
|
|
this.setProps(productData);
|
|
}
|
|
|
|
/**
|
|
* Sets the properties of this product.
|
|
* @param productData
|
|
* @private
|
|
*/
|
|
setProps(productData) {
|
|
this.id = productData.id;
|
|
this.name = productData.name;
|
|
this.isActive = productData.is_active;
|
|
this.price = productData.price;
|
|
this.sort = productData.sort;
|
|
this.description = productData.description;
|
|
this.projectId = productData.project_id;
|
|
this.externalId = productData.external_id;
|
|
this.isOutdated = productData.is_outdated;
|
|
this.isOrphaned = productData.is_orphaned;
|
|
// this.updatedAt = productData.updated_at;
|
|
this.createdAt = productData.created_at;
|
|
this.twUpdatedAt = productData.tw_updated_at;
|
|
this.financialTypeId = productData.financial_type_id;
|
|
this.priceFieldId = productData.price_field_id;
|
|
}
|
|
|
|
/**
|
|
* Dumps the product data.
|
|
* @returns {{id, name, is_active, price, sort, description, project_id, external_id, financial_type_id, tw_updated_at, twingle_shop_id: *}}
|
|
*/
|
|
dumpData() {
|
|
return {
|
|
'id': this.id,
|
|
'name': this.name,
|
|
'is_active': this.isActive,
|
|
'price': this.price,
|
|
'sort': this.sort,
|
|
'description': this.description,
|
|
'project_id': this.projectId,
|
|
'external_id': this.externalId,
|
|
'financial_type_id': this.financialTypeId,
|
|
'price_field_id': this.priceFieldId,
|
|
'tw_updated_at': this.twUpdatedAt,
|
|
'twingle_shop_id': this.parentTable.id,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a button for creating, updating or deleting the price field for
|
|
* this product.
|
|
* @param action
|
|
* @param handler
|
|
* @returns {HTMLButtonElement}
|
|
* @private
|
|
*/
|
|
createProductButton(action, handler) {
|
|
// Create button
|
|
const button = document.createElement('button');
|
|
button.id = action + '_twingle_product_tw_' + this.externalId;
|
|
button.classList.add('twingle-shop-cell-button');
|
|
|
|
// Add button text
|
|
let text = action === 'create' ? ts('Create', []) : action === 'update' ? ts('Update', []) : ts('Delete', []);
|
|
button.textContent = ' ' + ts(text, []);
|
|
|
|
// Add button handler
|
|
if (handler) {
|
|
button.onclick = handler;
|
|
} else {
|
|
button.disabled = true;
|
|
}
|
|
|
|
// Deactivate 'create' button if product hast no financial type
|
|
if (action === 'create' && this.financialTypeId === null) {
|
|
button.disabled = true;
|
|
}
|
|
|
|
// Deactivate 'update' button if product is not outdated
|
|
if (action === 'update' && !this.isOutdated) {
|
|
button.disabled = true;
|
|
}
|
|
|
|
// Add icon
|
|
const icon = document.createElement('i');
|
|
const iconClass = action === 'create' ? 'fa-plus-circle' : action === 'update' ? 'fa-refresh' : 'fa-trash';
|
|
icon.classList.add('crm-i', iconClass);
|
|
button.insertBefore(icon, button.firstChild);
|
|
|
|
return button;
|
|
}
|
|
|
|
/**
|
|
* Creates a handler for creating a price field for this product.
|
|
* @returns {(function(*): void)|*}
|
|
* @private
|
|
*/
|
|
createPriceFieldHandler() {
|
|
const self = this;
|
|
return function (event) {
|
|
event.preventDefault();
|
|
const action = event.target.innerText.includes('Update') ? 'updated' : 'created';
|
|
CRM.api3('TwingleProduct', 'create', self.dumpData())
|
|
.then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#create_twingle_product_tw_' + self.id).crmError(result.error_message, ts('Could not create Price Field for this product', []));
|
|
} else {
|
|
self.update(result.values);
|
|
CRM.alert(ts(`The Price Field was ${action} successfully.`, []), ts(`Price Field ${action}`, []), 'success', {'expires': 5000});
|
|
}
|
|
}, function (error) {
|
|
cj('#create_twingle_product_tw_' + self.id).crmError(error.message, ts('Could not create Price Field for this product', []));
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a handler for creating a price field for this product.
|
|
* @returns {(function(*): void)|*}
|
|
* @private
|
|
*/
|
|
deletePriceFieldHandler() {
|
|
let self = this;
|
|
return function (event) {
|
|
event.preventDefault();
|
|
const options = {
|
|
'title': ts('Delete Price Field', []),
|
|
'message': ts('Are you sure you want to delete the price field associated with this product?', []),
|
|
};
|
|
CRM.confirm(options)
|
|
.on('crmConfirm:yes', function () {
|
|
CRM.api3('TwingleProduct', 'delete', { 'id': self.id })
|
|
.then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#create_twingle_product_tw_' + self.id).crmError(result.error_message, ts('Could not delete Price Field', []));
|
|
} else {
|
|
self.update();
|
|
}
|
|
CRM.alert(ts('The Price Field was deleted successfully.', []), ts('Price Field deleted', []), 'success', {'expires': 5000});
|
|
}, function (error) {
|
|
cj('#create_twingle_product_tw_' + self.id).crmError(error.message, ts('Could not delete Price Field', []));
|
|
});
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a new row with the product name and buttons for creating, updating
|
|
* or deleting the price field for this product.
|
|
* @returns {*}
|
|
*/
|
|
createRow() {
|
|
let row;
|
|
|
|
// Clear row
|
|
if (this.row) {
|
|
for (let i = this.row.cells.length - 1; i >= 0; i--) {
|
|
// Delete everything from row
|
|
this.row.deleteCell(i);
|
|
}
|
|
row = this.row;
|
|
} else {
|
|
// Create new row element
|
|
row = document.createElement('tr');
|
|
|
|
// Add id to row
|
|
row.id = 'twingle_product_tw_' + this.externalId;
|
|
}
|
|
|
|
// Add cell with product name
|
|
const nameCell = document.createElement('td');
|
|
if (this.isOrphaned) {
|
|
nameCell.classList.add('strikethrough');
|
|
}
|
|
nameCell.textContent = this.name;
|
|
row.appendChild(nameCell);
|
|
|
|
// Add cell for buttons
|
|
let buttonCell = row.insertCell(1);
|
|
|
|
// Add product buttons which allow to create, update or delete the price
|
|
// field for this product
|
|
if (this.parentTable.id) {
|
|
let buttons = this.createProductButtons();
|
|
for (const button of buttons) {
|
|
buttonCell.appendChild(button);
|
|
}
|
|
}
|
|
|
|
// Add financial type dropdown for each product if price set exists
|
|
if (this.parentTable.id) {
|
|
let dropdown = this.createFinancialTypeDropdown();
|
|
const cell = document.createElement('td');
|
|
cell.classList.add('twingle-shop-financial-type-select');
|
|
cell.appendChild(dropdown);
|
|
row.insertCell(2).appendChild(cell);
|
|
}
|
|
// else add default financial type
|
|
else {
|
|
const cell = document.createElement('td');
|
|
cell.classList.add('twingle-shop-financial-type-default');
|
|
cell.innerHTML = '<i>' + getShopDefaultFinancialType() + '</i>';
|
|
row.insertCell(1).appendChild(cell);
|
|
}
|
|
|
|
this.row = row;
|
|
return this.row;
|
|
}
|
|
|
|
/**
|
|
* Determining which actions are available for this product and creating a
|
|
* button for each of them.
|
|
* @returns {Array} Array of buttons
|
|
*/
|
|
createProductButtons() {
|
|
let actionsAndHandlers = [];
|
|
let buttons = [];
|
|
|
|
// Determine actions; if product has price field id, it can be updated or
|
|
// deleted, otherwise it can be created
|
|
if (this.priceFieldId) {
|
|
if (!this.isOrphaned) {
|
|
actionsAndHandlers.push(['update', this.createPriceFieldHandler()]);
|
|
}
|
|
actionsAndHandlers.push(['delete', this.deletePriceFieldHandler()]);
|
|
} else if (!this.isOrphaned) {
|
|
actionsAndHandlers.push(['create', this.createPriceFieldHandler()]);
|
|
}
|
|
|
|
// Create button for each action
|
|
for (const [action, handler] of actionsAndHandlers) {
|
|
buttons.push(this.createProductButton(action, handler));
|
|
}
|
|
|
|
return buttons;
|
|
}
|
|
|
|
/**
|
|
* Creates a dropdown for selecting the financial type for this product.
|
|
* @returns {HTMLSelectElement}
|
|
* @private
|
|
*/
|
|
createFinancialTypeDropdown() {
|
|
// Create new dropdown element
|
|
const dropdown = document.createElement('select');
|
|
dropdown.id = 'twingle_product_tw_' + this.externalId + '_financial_type';
|
|
|
|
// Add empty option if no price field exists
|
|
if (!this.priceFieldId) {
|
|
let option = document.createElement('option');
|
|
option.value = '';
|
|
option.innerHTML = '<' + ts('select financial type', []) + '>';
|
|
option.selected = true;
|
|
option.disabled = true;
|
|
dropdown.appendChild(option);
|
|
}
|
|
|
|
// Add options for each financial type available in CiviCRM
|
|
for (const key in financialTypes) {
|
|
let option = document.createElement('option');
|
|
option.value = key;
|
|
option.text = financialTypes[key]; // financialTypes is defined in twingle_shop.tpl as smarty variable
|
|
if (this.financialTypeId !== null && this.financialTypeId.toString() === key) {
|
|
option.selected = true;
|
|
}
|
|
dropdown.appendChild(option);
|
|
}
|
|
|
|
// Add handlers
|
|
let self = this;
|
|
dropdown.onchange = function () {
|
|
|
|
// Enable 'create' or 'update' button if financial type is selected
|
|
const button = document.getElementById('twingle_product_tw_' + self.externalId).getElementsByClassName('twingle-shop-cell-button')[0];
|
|
if (button.textContent.includes('Create') || button.textContent.includes('Update')) {
|
|
button.disabled = dropdown.value === '0';
|
|
}
|
|
|
|
// Update financial type
|
|
self.financialTypeId = dropdown.value;
|
|
};
|
|
|
|
return dropdown;
|
|
}
|
|
|
|
/**
|
|
* Updates the product properties and rebuilds the row.
|
|
* @param productData
|
|
*/
|
|
update(productData = null) {
|
|
if (productData) {
|
|
this.setProps(productData);
|
|
} else {
|
|
this.reset();
|
|
}
|
|
this.createRow();
|
|
}
|
|
|
|
/**
|
|
* Resets the product properties.
|
|
*/
|
|
reset() {
|
|
this.financialTypeId = null;
|
|
this.priceFieldId = null;
|
|
this.isOutdated = null;
|
|
this.isOutdated = null;
|
|
// this.updatedAt = null;
|
|
this.createdAt = null;
|
|
this.id = null;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* This class represents a Twingle Shop.
|
|
*/
|
|
class ProductsTable {
|
|
|
|
/**
|
|
* Creates a new ProductsTable object.
|
|
* @param projectData
|
|
*/
|
|
constructor(projectData) {
|
|
this.setProps(projectData);
|
|
}
|
|
|
|
/**
|
|
* Sets the properties of this project.
|
|
* @param projectData
|
|
* @private
|
|
*/
|
|
setProps(projectData) {
|
|
this.id = projectData.id;
|
|
this.name = projectData.name;
|
|
this.numericalProjectId = projectData.numerical_project_id;
|
|
this.projectIdentifier = projectData.project_identifier;
|
|
this.products = projectData.products.map(productData => new Product(productData, this));
|
|
this.priceSetId = projectData.price_set_id;
|
|
this.table = this.buildTable();
|
|
}
|
|
|
|
/**
|
|
* Dumps the projects data.
|
|
* @returns {{price_set_id, financial_type_id, numerical_project_id, name, id, project_identifier, products: *}}
|
|
*/
|
|
dumpData() {
|
|
return {
|
|
'id': this.id,
|
|
'name': this.name,
|
|
'numerical_project_id': this.numericalProjectId,
|
|
'project_identifier': this.projectIdentifier,
|
|
'price_set_id': this.priceSetId,
|
|
'products': this.products.map(product => product.dumpData()),
|
|
'financial_type_id': getShopDefaultFinancialTypeValue()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Builds the table for this project (shop).
|
|
* @returns {HTMLTableElement}
|
|
* @private
|
|
*/
|
|
buildTable() {
|
|
let table;
|
|
|
|
// Clear table body
|
|
if (this.table) {
|
|
this.clearTableHeader();
|
|
this.clearTableBody();
|
|
this.updateTableButtons();
|
|
table = this.table;
|
|
} else {
|
|
// Create new table element
|
|
table = document.createElement('table');
|
|
table.classList.add('twingle-shop-table');
|
|
table.id = this.projectIdentifier;
|
|
|
|
// Add caption
|
|
const caption = table.createCaption();
|
|
caption.textContent = this.name + ' (' + this.projectIdentifier + ')';
|
|
caption.classList.add('twingle-shop-table-caption');
|
|
|
|
// Add table body
|
|
const tbody = document.createElement('tbody');
|
|
table.appendChild(tbody);
|
|
|
|
// Add table buttons
|
|
this.addTableButtons(table);
|
|
}
|
|
|
|
// Add header row
|
|
const thead = table.createTHead();
|
|
const headerRow = thead.insertRow();
|
|
const headers = [ts('Product', []), ts('Financial Type', [])];
|
|
|
|
// Add price field column if price set exists
|
|
if (this.priceSetId) {
|
|
headers.splice(1, 0, ts('Price Field', []));
|
|
}
|
|
|
|
for (const headerText of headers) {
|
|
const headerCell = document.createElement('th');
|
|
headerCell.textContent = headerText;
|
|
headerRow.appendChild(headerCell);
|
|
}
|
|
|
|
// Add products to table
|
|
this.addProductsToTable(table);
|
|
|
|
return table;
|
|
}
|
|
|
|
/**
|
|
* Adds buttons for creating, updating or deleting the price set for the
|
|
* given project (shop).
|
|
* @private
|
|
*/
|
|
addTableButtons(table) {
|
|
table.appendChild(this.createTableButton('update', this.updatePriceSetHandler()));
|
|
if (this.priceSetId === null) {
|
|
table.appendChild(this.createTableButton('create', this.createPriceSetHandler()));
|
|
} else {
|
|
table.appendChild(this.createTableButton('delete', this.deletePriceSetHandler()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a button for creating, updating or deleting the price set for the
|
|
* given project (shop).
|
|
* @param action
|
|
* @param handler
|
|
* @returns {HTMLButtonElement}
|
|
* @private
|
|
*/
|
|
createTableButton(action, handler) {
|
|
// Create button
|
|
const button = document.createElement('button');
|
|
button.id = 'btn_' + action + '_twingle_shop_' + this.projectIdentifier;
|
|
button.classList.add('crm-button', 'twingle-shop-table-button');
|
|
|
|
// Add button text
|
|
const text = action === 'create' ? ts('Create Price Set', []) : action === 'update' ? ts('Update Price Set', []) : ts('Delete Price Set', []);
|
|
button.textContent = ' ' + ts(text, []);
|
|
|
|
// Add button handler
|
|
button.onclick = handler;
|
|
|
|
// Add icon
|
|
const icon = document.createElement('i');
|
|
const iconClass = action === 'create' ? 'fa-plus-circle' : action === 'update' ? 'fa-refresh' : 'fa-trash';
|
|
icon.classList.add('crm-i', iconClass);
|
|
button.insertBefore(icon, button.firstChild);
|
|
|
|
return button;
|
|
}
|
|
|
|
/**
|
|
* Adds products to table body.
|
|
* @param table
|
|
* @private
|
|
*/
|
|
addProductsToTable(table) {
|
|
// Get table body
|
|
const tbody = table.getElementsByTagName('tbody')[0];
|
|
|
|
// Add products to table body
|
|
for (const product of this.products) {
|
|
// Add row for product
|
|
const row = product.createRow();
|
|
// Add row to table
|
|
tbody.appendChild(row);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the table buttons.
|
|
*/
|
|
updateTableButtons() {
|
|
const table_buttons = this.table.getElementsByClassName('twingle-shop-table-button');
|
|
// Remove all price set buttons from table
|
|
while (table_buttons.length > 0) {
|
|
table_buttons[0].remove();
|
|
}
|
|
this.addTableButtons(this.table);
|
|
}
|
|
|
|
/**
|
|
* Clears the table header.
|
|
* @private
|
|
*/
|
|
clearTableHeader() {
|
|
const thead = this.table.getElementsByTagName('thead')[0];
|
|
while (thead.firstChild) {
|
|
thead.removeChild(thead.firstChild);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clears the table body.
|
|
*/
|
|
clearTableBody() {
|
|
const tbody = this.table.getElementsByTagName('tbody')[0];
|
|
while (tbody.firstChild) {
|
|
tbody.removeChild(tbody.firstChild);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a handler for creating the price set for the given project (shop).
|
|
* @returns {(function(*): void)|*}
|
|
*/
|
|
createPriceSetHandler() {
|
|
let self = this;
|
|
return function (event) {
|
|
event.preventDefault();
|
|
CRM.api3('TwingleShop', 'create', self.dumpData())
|
|
.then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not create Twingle Shop', []));
|
|
} else {
|
|
self.update();
|
|
CRM.alert(ts('The Price Set was created successfully.', []), ts('Price Field created', []), 'success', {'expires': 5000});
|
|
}
|
|
}, function (error) {
|
|
cj('#btn_create_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not create TwingleShop', []));
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a handler for deleting the price set for the given project (shop).
|
|
* @returns {(function(*): void)|*}
|
|
*/
|
|
deletePriceSetHandler() {
|
|
let self = this;
|
|
return function (event) {
|
|
event.preventDefault();
|
|
const options = {
|
|
'title': ts('Delete Price Set', []),
|
|
'message': ts('Are you sure you want to delete the price set associated with this Twingle Shop?', []),
|
|
};
|
|
CRM.confirm(options)
|
|
.on('crmConfirm:yes', function () {
|
|
CRM.api3('TwingleShop', 'delete', {
|
|
'project_identifier': self.projectIdentifier,
|
|
}).then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not delete Twingle Shop', []));
|
|
} else {
|
|
self.update();
|
|
CRM.alert(ts('The Price Set was deleted successfully.', []), ts('Price Set deleted', []), 'success', {'expires': 5000});
|
|
}
|
|
}, function (error) {
|
|
cj('#btn_delete_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not delete Twingle Shop', []));
|
|
});
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a handler for updating the price set for the given project (shop).
|
|
* @returns {(function(*): void)|*}
|
|
*/
|
|
updatePriceSetHandler() {
|
|
let self = this;
|
|
return function (event) {
|
|
cj('#twingle-shop-spinner').show();
|
|
if (event) {
|
|
event.preventDefault();
|
|
}
|
|
CRM.api3('TwingleShop', 'fetch', {
|
|
'project_identifiers': self.projectIdentifier,
|
|
}).then(function (result) {
|
|
if (result.is_error === 1) {
|
|
cj('#btn_create_price_set_' + self.projectIdentifier).crmError(result.error_message, ts('Could not delete Twingle Shop', []));
|
|
cj('#twingle-shop-spinner').hide();
|
|
} else {
|
|
self.update(result.values[self.projectIdentifier]);
|
|
cj('#twingle-shop-spinner').hide();
|
|
}
|
|
}, function (error) {
|
|
cj('#btn_update_price_set_' + self.projectIdentifier).crmError(error.message, ts('Could not update Twingle Shop', []));
|
|
cj('#twingle-shop-spinner').hide();
|
|
});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Updates the project properties and rebuilds the table.
|
|
* @param projectData
|
|
*/
|
|
update(projectData) {
|
|
if (!projectData) {
|
|
const updatePriceSet = this.updatePriceSetHandler();
|
|
updatePriceSet();
|
|
} else {
|
|
this.setProps(projectData);
|
|
this.buildTable();
|
|
}
|
|
}
|
|
}
|