const VOUCHER_FOLDER_ID = „10hDojPe6IC-i04J8tXudO8SJcox8K8oP“; const INVOICE_FOLDER_ID = „1bxGdyWPvEsUvefsH9xSi9Xwoz8xSVa45“; const ANSWERS_SPREADSHEET_ID = „1JiFHTW8s4I0IslvDAnRwYHeNLBN8bwcbdSGCA2TxEnk“; const ANSWERS_SHEET_GID = 2060634537; const LOYALTY_CARDS_SHEET_GID = 665561420; const POUKAZY_TRICKA_SHEET_GID = 1531842547; const TOTAL_COLUMN_COUNT = 22; const TEMPLATE_TYPE = {Doc: „doc“, Slide: „slide“}; /** * Helper function to get a sheet by its GID from a spreadsheet * @param {string} spreadsheetId – The ID of the spreadsheet * @param {string} gid – The GID of the sheet * @returns {Sheet} – The sheet object */ function getSheetByGid(spreadsheetId, gid) { const spreadsheet = SpreadsheetApp.openById(spreadsheetId); const sheet = spreadsheet.getSheets().find(sheet => sheet.getSheetId() === Number(gid)); return sheet || null; } /** * Attempts to load discount information from a discount code. * Returns discount info if successful, null if the code is invalid or not found. * This function does NOT store anything – it only retrieves the discount percentage. * * @param {string} discountCode – The discount code (e.g., „RP10“ or loyalty card ID) * @returns {Object|null} – { discountPercent, discountType, codeId } or null if invalid */ function getDiscountInfo(discountCode) { if (!discountCode || discountCode.trim() === „“) { return null; } const code = discountCode.trim(); try { // Handle RP10 special discount code if (code === „RP10“) { return { discountPercent: 10, discountType: „slevový kód“, codeId: „RP10“ }; } // Try to find the code in loyalty cards sheet const loyaltyCardsSheet = getSheetByGid(ANSWERS_SPREADSHEET_ID, LOYALTY_CARDS_SHEET_GID.toString()); if (!loyaltyCardsSheet) { return null; } const targetData = loyaltyCardsSheet.getDataRange().getValues(); const headers = targetData[0]; // Find the column index for „Kolikrát už byli v Nestu“ const targetHeader = ‚Kolikrát už byli v Nestu‘; const targetColumnIndex = headers.indexOf(targetHeader); if (targetColumnIndex === -1) { return null; } // Search for the Loyalty Card ID in column A let rowIndexLoyaltyCard = -1; for (let i = 1; i < targetData.length; i++) { if (targetData[i][0] === code) { rowIndexLoyaltyCard = i; break; } } if (rowIndexLoyaltyCard === -1) { return null; // Code not found } // Get the specific row data const rowData = targetData[rowIndexLoyaltyCard]; // Count total number of visits across all game columns (B to target column) const startColumn = 2; // Column B (1-based indexing) const endColumn = targetColumnIndex; let count = 0; const datePattern = /\d{1,2}\.\d{1,2}\.\d{4}/g; for (let col = startColumn - 1; col < endColumn; col++) { const cellValue = rowData[col]; if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { const cellString = cellValue.toString(); const matches = cellString.match(datePattern); if (matches && matches.length > 1) { count += matches.length; } else { count += 1; } } } // Calculate discount based on visit count let discountPercent = 0; if (count === 1) { discountPercent = 25; } else if (count === 2) { discountPercent = 40; } else if (count === 3) { discountPercent = 80; } else if (count > 3) { return null; // Card is no longer valid } else { // count === 0, first visit – no discount yet from loyalty card return null; } return { discountPercent: discountPercent, discountType: „věrnostní kartička“, codeId: code }; } catch (error) { // If anything goes wrong, return null – invoice will be generated without discount return null; } } /** * Parses encoded data (phone, AlzaBox location, discount code) from a special request field. * Returns an object with extracted values and the remaining user notes. * @param {string} rawInput – The raw input string potentially containing encoded data * @returns {Object} – { phone, alzaboxLocation, discountCode, userNotes } */ function parseEncodedFormData(rawInput) { let remaining = rawInput || „“; let phone = „“; let alzaboxLocation = „“; let discountCode = „“; // Extract phone number const phoneMatch = remaining.match(/P40N3NUMB3RST4RT3544:(.*?)P40N3NUMB3R3ND3544/); if (phoneMatch) { phone = phoneMatch[1]; remaining = remaining.replace(phoneMatch[0], „“); } // Extract AlzaBox location const alzaboxMatch = remaining.match(/4LZ4B0XL0C4T10NST4RT3544:(.*?)4LZ4B0XL0C4T10N3ND3544/); if (alzaboxMatch) { alzaboxLocation = alzaboxMatch[1]; remaining = remaining.replace(alzaboxMatch[0], „“); } // Extract discount code const discountMatch = remaining.match(/D1SC0UNTC0D3ST4RT3544:(.*?)D1SC0UNTC0D33ND3544/); if (discountMatch) { discountCode = discountMatch[1]; remaining = remaining.replace(discountMatch[0], „“); } return { phone: phone, alzaboxLocation: alzaboxLocation, discountCode: discountCode, userNotes: remaining.trim() }; } function getPrice(variantaVariable,verzeVariable){ var calculatedPrice = parseInt(variantaVariable.match(/\d{3,}/)[0],10); const voucherDeliveryPrice = verzeVariable.match(/\d{3,}/); if (voucherDeliveryPrice) { calculatedPrice += parseInt(voucherDeliveryPrice,10); } return calculatedPrice; } function createPdfFromTemplate({folderId, templateId, fileName, values, templateType}) { const folder = DriveApp.getFolderById(folderId); const templateFileCopy = DriveApp.getFileById(templateId).makeCopy(fileName, DriveApp.getFolderById(folderId));; let templateDocument, body; // we need to open document via DocumentApp/SlidesApp to be able to edit it (DriveApp seems to be not enough) if (templateType === TEMPLATE_TYPE.Doc) { templateDocument = DocumentApp.openById(templateFileCopy.getId()); body = templateDocument.getBody(); } else if (templateType === TEMPLATE_TYPE.Slide) { templateDocument = SlidesApp.openById(templateFileCopy.getId()); body = templateDocument.getSlides()[0]; } for (let [name, value] of Object.entries(values)) { if (value && typeof value === „object“) { // image (QR code) const rangeElement = body.findText(name); const element = rangeElement.getElement(); const childIndex = element.getParent().getChildIndex(element); element.asText().setText(„“); var qrCodeImage = element.getParent().asParagraph().insertInlineImage(0, value); qrCodeImage.setHeight(300) // set the same height and width, as QR code is a square qrCodeImage.setWidth(300) // set the same height and width, as QR code is a square } else { const placeholder = `{${name}}`; if (templateType === TEMPLATE_TYPE.Doc) { body.replaceText(placeholder, value); } else if (templateType === TEMPLATE_TYPE.Slide) { body.replaceAllText(placeholder, value); } } } // flush the changes templateDocument.saveAndClose(); // reopen the file again, because there apparently isn’t way to flush changes without closing it templateDocument = DriveApp.getFileById(templateFileCopy.getId()) const templateDocumentPdf = templateDocument.getAs(MimeType.PDF); templateDocumentPdf.setName(`${fileName}.pdf`); const pdfFile = folder.createFile(templateDocumentPdf); // remove the redundant template copy templateFileCopy.setTrashed(true); return pdfFile; } function createPdfFromDocTemplate(args){ return createPdfFromTemplate({…args, templateType: TEMPLATE_TYPE.Doc}); } function createPdfFromSlideTemplate(args){ return createPdfFromTemplate({…args, templateType: TEMPLATE_TYPE.Slide}); } function createVoucher({code, voucherLanguage, variableNumber, …rest},templateIdSet) { var voucherFileName = „“; if (code === „“) { if (voucherLanguage === „CZ“) { voucherFileName = `Voucher_bez_kodu_k_fakture_p0${variableNumber}`; } else { voucherFileName = `Voucher_without_code_for_Invoice_p0${variableNumber}`; } } else { voucherFileName = `A5_voucher_${code}`; } return createPdfFromSlideTemplate({ folderId: VOUCHER_FOLDER_ID, templateId: templateIdSet, fileName: voucherFileName, values: {code, …rest} }); } function createInvoice({code, …rest},invoiceTemplateIdSet,fakturaCZorENSet) { return createPdfFromDocTemplate({ folderId: INVOICE_FOLDER_ID, templateId: invoiceTemplateIdSet, fileName: `${fakturaCZorENSet}_${code}`, values: {code, …rest} }); } // returns Date object in given „days“ in the future function getInDaysDate(inDays){ const date = new Date(); date.setDate(date.getDate() + inDays); return date; } function getQrCode({dateDue},variableNumberVariable,variableCostVariable) { const amount = variableCostVariable; const dateDueQRFormatted = Utilities.formatDate(dateDue, „Europe/Prague“, „yyyy-MM-dd“); const variableSymbol = variableNumberVariable; const msg = „Dárkový poukaz – Nest Escape“; try { const url = encodeURI(`http://api.paylibo.com/paylibo/generator/czech/image?accountNumber=1333806031&bankCode=3030&amount=${amount}.00&currency=CZK&vs=${variableSymbol}&date=${dateDueQRFormatted}&message=${msg}`); const chart = UrlFetchApp.fetch(url).getBlob().getAs(‚image/png‘); return chart; } catch (error) { try { // Send e-mail with info on the QR generation failure to us const recipient = „nestescape@gmail.com“ const sendersName = „Nest Escape“; const subject = „Selhalo generování QR kódu pomocí api.paylibo.com“; body = „Selhalo generování QR kódu pomocí api.paylibo.com“; GmailApp.sendEmail(recipient, subject, body, { name: sendersName, htmlBody: „
Selhalo generování QR kódu pomocí api.paylibo.com – nastala následující chyba: “ + error + „
„}); // Fetch general QR code instead from our server const chart = UrlFetchApp.fetch(‚https://www.nestescape.cz/wp-content/uploads/2024/01/qr_platba.png‘).getBlob().getAs(‚image/png‘); return chart; } catch (error_general) { // Send e-mail with info on the general QR generation failure to us const recipient = „nestescape@gmail.com“ const sendersName = „Nest Escape“; const subject = „Selhalo stažení obecného QR kódu z našeho serveru“; body = „Selhalo stažení obecného QR kódu z našeho serveru“; GmailApp.sendEmail(recipient, subject, body, { name: sendersName, htmlBody: „
Selhalo stažení obecného QR kódu z https://www.nestescape.cz/wp-content/uploads/2024/01/qr_platba.png – nastala následující chyba: “ + error_general + „
„}); return „Omlouváme se, ale generování QR kódu selhalo kvůli výpadku služeb stránky QR Platba (qr-platba.cz)“; } } } function onFormSubmit(e) { //nastavení sheetu, ve kterém má script fungovat const spreadsheet = SpreadsheetApp.openById(ANSWERS_SPREADSHEET_ID); const responseSheet = spreadsheet.getSheets().find(sheet => sheet.getSheetId() === ANSWERS_SHEET_GID); //výpočet a zapsání nového variabilního čísla responseSheet.getRange(1,TOTAL_COLUMN_COUNT).setValue(responseSheet.getRange(1,TOTAL_COLUMN_COUNT).getValue() + 1); const variableNumber = responseSheet.getRange(1,TOTAL_COLUMN_COUNT).getValue(); //výpočet dalšího náhodného čísla na konci poukazu a jeho zapsání var RandomNumber = responseSheet.getRange(2, TOTAL_COLUMN_COUNT).getValue() + Math.round(Math.random() * 15) + 5; if (RandomNumber > 999) { RandomNumber = RandomNumber – 900; } responseSheet.getRange(2,TOTAL_COLUMN_COUNT).setValue(RandomNumber); //Vyčtení veškerých hodnot, které zadal + řádku, na který byly zapsány v Sheetu const namedValues = e.namedValues; const variantaVoucheru = namedValues[„Herní varianta“][0]; const verzeVoucheru = namedValues[„Verze poukazu“][0]; const marketingConsent = namedValues[„Chci být v obraze:“][0]; var proKoho = namedValues[‚Pro koho (max. 35 znaků, skloňování ve 4. pádu: např. „pro Janču, Dominika, Soňu a Jindru“)‘][0]; const jmenoPrijmeni = namedValues[„Vaše jméno a příjmení“][0]; const ulice = namedValues[„Ulice a číslo popisné“][0]; const mesto = namedValues[„Město“][0]; const psc = namedValues[„PSČ“][0]; const wishText = namedValues[„Text přání (max. 250 znaků)“][0]; const recipient = namedValues[„Váš e-mail“][0]; const rawSpeslPozadavek = namedValues[„Ještě se chci Nestu na něco zeptat nebo o něco speciálního požádat 🙂“][0]; const lastRowIndex = e.range.getRow(); // Parse encoded data from the special request field const parsedData = parseEncodedFormData(rawSpeslPozadavek); const alzaboxPhone = parsedData.phone; const alzaboxLocation = parsedData.alzaboxLocation; const discountCode = parsedData.discountCode; const speslPozadavek = parsedData.userNotes; // Výpočet a zapsání ceny poukazu var priceCalc = getPrice(variantaVoucheru, verzeVoucheru); // Try to apply discount if discount code was provided var discountInfo = null; var discountNote = „“; // Note to add as second line of variant on invoice var originalPrice = priceCalc; // Keep original price for reference if (discountCode) { discountInfo = getDiscountInfo(discountCode); if (discountInfo) { // Calculate discounted price (rounded to whole number) priceCalc = Math.round(originalPrice * (1 – discountInfo.discountPercent / 100)); } } // Store price in sheet (with discount note if applicable) if (discountInfo) { responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-5)).setValue(priceCalc + “ Kč – “ + discountInfo.discountType + “ “ + discountInfo.codeId); } else { responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-5)).setValue(priceCalc + “ Kč“); } // Check whether this is Czech or English voucher and define values that are different for CZ and EN var voucherLanguage = „“; var priceString = „“; var voucherCodeStart = „“; var INVOICE_TEMPLATE_ID = „“; var prefixes = []; var fakturaCZorEN = „“; var dateFormat = „“; if (variantaVoucheru.includes(„Kč“)) { voucherLanguage = „CZ“; priceString = priceCalc + “ Kč“; voucherCodeStart = „N“; INVOICE_TEMPLATE_ID = „1__gpvoorr-8yL8RUJdx4Z-HMDj-QUWhB5qty8tBpwnc“; prefixes = [„pro „, „pro:“]; fakturaCZorEN = „faktura“; dateFormat = „d. M. yyyy“; } else if (variantaVoucheru.includes(„CZK“)) { voucherLanguage = „EN“; priceString = priceCalc + “ CZK“; voucherCodeStart = „EN“; INVOICE_TEMPLATE_ID = „1CyR9_oQCnf_9_YU1_iKEq4SS0neQwPt0mUB7a1nihOk“; prefixes = [„for „, „for:“]; fakturaCZorEN = „Invoice“; dateFormat = „d MMMMMMMMMMMMMMM yyyy“; } else { throw new Error(`ERROR: The script will now be terminated because the voucher name „${variantaVoucheru}“ does not include „Kč“ nor „CZK“ – please fix!`); } // Create language-appropriate discount note for invoice if (discountInfo) { if (voucherLanguage === „CZ“) { discountNote = `(sleva ${discountInfo.discountPercent}% – ${discountInfo.discountType} ${discountInfo.codeId})`; } else if (voucherLanguage === „EN“) { const discountTypeEN = discountInfo.discountType === „věrnostní kartička“ ? „loyalty card“ : „discount code“; discountNote = `(${discountInfo.discountPercent}% discount – ${discountTypeEN} ${discountInfo.codeId})`; } } // Handle case where discount code was provided but not detected – treat as special request var effectiveSpeslPozadavek = speslPozadavek; if (discountCode && !discountInfo) { const failedDiscountNote = voucherLanguage === „CZ“ ? `[AUTOMATICKY PŘIDÁNO: Zákazník zadal slevový kód „${discountCode}“, ale nepodařilo se ho automaticky rozpoznat. Prosím zkontrolujte manuálně do 24 hodin.]` : `[AUTOMATICALLY ADDED: Customer entered discount code „${discountCode}“, but it could not be automatically recognized. Please check manually within 24 hours.]`; if (effectiveSpeslPozadavek) { effectiveSpeslPozadavek = effectiveSpeslPozadavek + „\n\n“ + failedDiscountNote; } else { effectiveSpeslPozadavek = failedDiscountNote; } } // Create discount success note for emails when discount was applied var discountSuccessNoteCZ = „“; var discountSuccessNoteEN = „“; if (discountInfo) { discountSuccessNoteCZ = `

Na Vaši objednávku byla úspěšně uplatněna sleva ${discountInfo.discountPercent}% (${discountInfo.discountType} ${discountInfo.codeId}).`; const discountTypeEN = discountInfo.discountType === „věrnostní kartička“ ? „loyalty card“ : „discount code“; discountSuccessNoteEN = `

A ${discountInfo.discountPercent}% discount (${discountTypeEN} ${discountInfo.codeId}) has been successfully applied to your order.`; } //zapsání konce čísla poukazu a kódu poukazu do Evidence poukazů responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-6)).setValue(variableNumber); const uniqueId = voucherCodeStart + Utilities.formatDate(new Date(), „Europe/Prague“, „yyMMdd“) + RandomNumber; responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-8)).setValue(uniqueId); responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-7)).setValue(RandomNumber); if (marketingConsent === „“){ responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-9)).setValue(“ „); } //stanoveni ID voucheru var voucherID = „“; var voucherIDInvalid = „“; var voucherValue = „“; //hodnota obecného dárkového poukazu if (variantaVoucheru.startsWith(„ZKÁZA ČERNOBYLU pro 2 – 5 hráčů“)) { if (proKoho === „“) { voucherID = „1ILqCUO54UQBPsZL1M2kdwdDDpnw3Cc85dKIs72Kf3KU“; voucherIDInvalid = „1ZjpfuafepRXBNXBY89Ak0Bf9HiBRiEze-h8Wjmy1Pfs“;} else { voucherID = „1USiUWnq28Oh0bi2cBPvkmH2g14ejmJ64VrgK3vkVTi4“; voucherIDInvalid = „1xdn5EtO7rVQgMmyC9CtEEOwPdFOTiJQ1iF9xpo6QjJY“;} } else if (variantaVoucheru.startsWith(„KONEC SVĚT(L)A pro 2 – 5 hráčů“)) { if (proKoho === „“) { voucherID = „1S5byaC-DjpGRYLNYSaVVHYjZfsgZhZh5wWvVkxy9-IQ“; voucherIDInvalid = „1J7f5oJsFtboCR_A1Xr1zfxmGAMgLkpChRvqVabg_G7s“;} else { voucherID = „1RKWYQKiwe2BG2nOH8CRwBB6Wf_iIG0VXaYuqTdIJWs8“; voucherIDInvalid = „1pzLtWjwdSUHXoV_fL2_TjVCNL290VQEmZRbAUf9z2VA“;} } else if (variantaVoucheru.startsWith(„TAJEMSTVÍ PAŘÍŽE pro 2 – 6 hráčů“)) { if (proKoho === „“) { voucherID = „1ih9FZLTdMWYEb9_LC9yiyVvhayx3-K7DTg42vFDCikE“; voucherIDInvalid = „1zlyPMffWWLhjQAtP5qi2-oxGhUbFVmMeeLWnx_1SP9k“;} else { voucherID = „1xYrudZvIKMp2UKGeOBI3WWq1AUgFWfzuC0V2XiAH3MQ“; voucherIDInvalid = „1Fb6f4Sh2faDCkyhIgiDMegrr_gAIZgRZSMWFNB8mEYo“;} } else if (variantaVoucheru.startsWith(„ZTRACENÉ MĚSTO pro 2 – 5 hráčů“)) { if (proKoho === „“) { voucherID = „1uxeXNxNHkgb9Uqzc4sE6oaAUsu8EU-HY39r23iw5__M“; voucherIDInvalid = „14mG8GNiGya0hPrJCvacj8E7XE9FTYbtVT5163IyDg8U“;} else { voucherID = „1iJn8WX__0TnkTZVPOJ9mUPfq7LE6sMUof9zKMzyi2XQ“; voucherIDInvalid = „1ddLV6Y-ne-LWFOBEImbS5yvOz4nm2t8rxUa_VP4rWRQ“;} } else if (variantaVoucheru.startsWith(„Obecný poukaz v hodnotě“)) { voucherValue = variantaVoucheru.substring(24,28); if (proKoho === „“) { voucherID = „1O8mDLT5wEq8kt_KdDC63jVIYpcqYTshxPf_QcyA62go“; voucherIDInvalid = „1MGCIa17ewUo2zBgPJUkyFpji9VIhoBrUHcxccQgCCLA“;} else { voucherID = „1kaX1t0upkfUHXPot09Mg-x-OIXZKKyawo6Ehsdhsi74“; voucherIDInvalid = „1Qpv-QnbfAocU74-CEPT_1dqBa9VIuzDs0nu6YZbdEy8“;} } else if (variantaVoucheru.startsWith(„ILUMINÁTI“)) { if (proKoho === „“) { voucherID = „1ln3LQINd39F3PXMkc8zJPd3jIbq4FciPTLOHWYrIzuo“; voucherIDInvalid = „1w19hHb4_l8lmbBFwR8paVxrhyiPPMe0lTBGtU2NkMo0“;} else { voucherID = „1F6ttxbfvEVucgXEMYwX-vkB3fqNgE5izlG01_l24lD8“; voucherIDInvalid = „14dcULbKBK2NS73_WgtXSDQDNcPnDkQdBLvuxH-DOidk“;} } else if (variantaVoucheru.startsWith(„CHERNOBYL´S DOOM for 2 – 5 players“)) { if (proKoho === „“) { voucherID = „1KufnL4utsD_lAd4MBIUA1brr32ksdnHRdXEl4mmq5sM“; voucherIDInvalid = „1wgzkqEYJtmmU-3S2tAsS8xSvhvBkI8eysWLuKQMZsUQ“;} else { voucherID = „1KtWY9obLOIV-eHDYq7XV_-0TwKRzBCOVzKCLbVxgrFg“; voucherIDInvalid = „1wtrDuQk3ZwCkO8vyNhoJTdh4vPCmUssWPuJ2HwArB0E“;} } else if (variantaVoucheru.startsWith(„THE END OF DAY(S) for 2 – 5 players“)) { if (proKoho === „“) { voucherID = „1l-KSAYYVfHS4gTzLuI2owwO-uSz29-DdbFK7r2Aq_5k“; voucherIDInvalid = „1sWHmesc7-_AQquD6etA2SbILvTQXT5jDQuWGemt3SGw“;} else { voucherID = „1WvKtOCcrbPmrjl9Jc–CKr0MtEq_D8cONh9mwzIMVMU“; voucherIDInvalid = „1coEty6wm81-ATNtSEnbZwRxiJFEVTu-U0NCDfvUOWuo“;} } else if (variantaVoucheru.startsWith(„THE SECRETS OF PARIS for 2 – 6 players“)) { if (proKoho === „“) { voucherID = „12xXL6RwRJGeaTaROM-KbFVmY_oMLlfLJNXhAxIg9fqQ“; voucherIDInvalid = „1k5B9hq4LIt2fDyHzt5tqWuJrcC4Kopdhkgp2Qr-VYEc“;} else { voucherID = „1ZhTi6xgA99N8NfmJfl3PH8wMcLmGXkSrM8G68FUFCzI“; voucherIDInvalid = „19z8z0N1CDtXhM8RMoUkH9ENdSYiyoHBZNVyGV1WfShQ“;} } else if (variantaVoucheru.startsWith(„THE LOST CITY for 2 – 5 players“)) { if (proKoho === „“) { voucherID = „1JL7g0bO86ucPAt4IyHBwpZpR2sZBxUd-UTGpTCgGgmo“; voucherIDInvalid = „1qPmaSJSTdeetIZQpqj9S1_teZSRQRjiaZYM6-kD_X3w“;} else{ voucherID = „1Y66_jdiNi40x5x02iIMwZDnNfmceyldoJRLtYbWYfp8“; voucherIDInvalid = „1ZyzvAjA-FXAymw8a_33wOUBfqs7W6kaNazeM240sMi0“;} } else if (variantaVoucheru.startsWith(„Universal gift voucher worth“)) { voucherValue = variantaVoucheru.substring(29,33); if (proKoho === „“){ voucherID = „1bCqfOgPpRIcKsb0b7vysiNNsCDjz8OnVv0_7uFZCS-4“; voucherIDInvalid = „1vxew5ziwKP8jRlxLl3mVqqQ7O4azuWluhvBuEMDQ_VY“;} else{ voucherID = „1EdsprUz9V3x4VW1UrFcma7xGuQQTGZyzmOxpOExKld4“; voucherIDInvalid = „1MwvRZsLmS-RbSwED21PkUYE59WvuZXw70ZQ9F2fydf4“;} } const lowerProKoho = proKoho.toLowerCase(); if (prefixes.some(prefix => lowerProKoho.startsWith(prefix))) { proKoho = proKoho.substring(4); // Odmazání duplikovaného PRO/FOR – to už je napevno v grafice poukazu } proKoho = proKoho.charAt(0).toUpperCase() + proKoho.slice(1); // První písmeno přání vždy velké const voucherValidTill = Utilities.formatDate(getInDaysDate(190), „Europe/Prague“, dateFormat); const voucher = createVoucher({ code: „“, nameFor: proKoho, wish: wishText, validTill: voucherValidTill, voucherValue, voucherLanguage, variableNumber, }, voucherIDInvalid); const voucherValidTillCzechFormat = Utilities.formatDate(getInDaysDate(190), „Europe/Prague“, „d. M. yyyy“); responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-4)).setValue(voucherValidTillCzechFormat); const dateDue = getInDaysDate(7); const dateDueFormatted = Utilities.formatDate(dateDue, „Europe/Prague“, dateFormat); const dateDueQR = getInDaysDate(0); // Prepare type text for invoice – add discount note right after type if applicable var invoiceType = verzeVoucheru; if (discountNote) { invoiceType = verzeVoucheru + „\n“ + discountNote; } const invoice = createInvoice({ code: „p0“ + variableNumber, name: jmenoPrijmeni, type: invoiceType, street: ulice, city: mesto, zipcode: psc, variant: variantaVoucheru, variableNumber: variableNumber, dateIssued: Utilities.formatDate(new Date(), „Europe/Prague“, dateFormat), dateDueFormed: dateDueFormatted, qrcode: getQrCode({dateDue: dateDueQR},variableNumber,priceCalc), price: priceString }, INVOICE_TEMPLATE_ID,fakturaCZorEN); var subject = „“; //předmět e-mailu var body = „Děkujeme za objednávku!“; const sendersName = „Nest Escape“; if (effectiveSpeslPozadavek === „“) { if (verzeVoucheru.startsWith(„Elektronický dárkový poukaz“)) { subject = „Nest Escape – elektronický dárkový poukaz“; body = „Děkujeme za objednávku!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Dobrý den,

děkujeme za objednávku!

Přiložili jsme dárkový poukaz bez kódu a fakturu s informacemi k platbě.${discountSuccessNoteCZ} Poukaz s kódem obdržíte po proplacení přiložené faktury – v případě okamžitého bankovního převodu během následujících 20 minut, v případě standardního převodu během následujícího pracovního dne.

Pokud byste voucher náhodou potřebovali nějak doladit, určitě neváhejte se nám ozvat a my se na to nejpozději do 24 hodin podíváme 😊

www.nestescape.cz+420 730 521 639
         (10:00 – 22:00 každý den)


Hybešova 271/29 602 00 Brno
IČO: 23198966
`}) } else if (verzeVoucheru.startsWith(„Electronic gift voucher“)) { subject = „Nest Escape – electronic gift voucher“; body = „Thank you for your order!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Hello,

thank you for your order!

We have attached a gift voucher without its code and invoice with payment information.${discountSuccessNoteEN} You will receive the voucher with the code after payment of the attached invoice – in case of immediate bank transfer within following 20 minutes, in case of standard transfer within the next working day.

In case you would like to tweak your voucher in any way, don’t hesitate to contact us and we will have a look at it within 24 hours 😊

www.nestescape.cz+420 730 521 639
         (10AM – 10PM every day)


Hybešova 271/29 602 00 Brno
IČO (CIN): 23198966
`}) } else if (verzeVoucheru.startsWith(„Fyzický dárkový poukaz“) || verzeVoucheru.startsWith(„Zalaminovaný poukaz“)) { // Declare text based of VoucherType var physVoucherType = „“; var physVoucherTypeCapital = „“; var physVoucherTypeDeclined = „“; if (verzeVoucheru.startsWith(„Fyzický dárkový poukaz“)) { physVoucherType = „fyzický“; physVoucherTypeCapital = „Fyzický“; physVoucherTypeDeclined = „fyzického“; } else if (verzeVoucheru.startsWith(„Zalaminovaný poukaz“)) { physVoucherType = „zalaminovaný“; physVoucherTypeCapital = „Zalaminovaný“; physVoucherTypeDeclined = „zalaminovaného“; } subject = `Nest Escape – ${physVoucherType} dárkový poukaz`; body = „Děkujeme za objednávku!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Dobrý den,

děkujeme za objednávku!

Přiložili jsme návrh dárkového poukazu bez kódu – prosíme, zkontrolujte ho a dejte nám vědět, pokud budete chtít něco doladit. Přiložili jsme také fakturu – náhled poukazu s kódem obdržíte po jejím proplacení – v případě okamžitého bankovního převodu během následujících 20 minut, v případě standardního převodu během následujícího pracovního dne.${discountSuccessNoteCZ}

${physVoucherTypeCapital} poukaz následně doručíme do Vámi zvoleného AlzaBoxu do týdne od přijetí platby. Potřebujete-li ho dříve, dejte nám prosím vědět a my se to pokusíme urychlit 😊

Zkontrolujte prosím také správnost lokace AlzaBoxu pro doručení poukazu: ${alzaboxLocation}
A také správnost telefonního čísla, na které Vám dorazí kód pro otevření AlzaBoxu: ${alzaboxPhone}

www.nestescape.cz+420 730 521 639
         (10:00 – 22:00 každý den)


Hybešova 271/29 602 00 Brno
IČO: 23198966
` }); } else if (verzeVoucheru.startsWith(„Paper gift voucher“) || verzeVoucheru.startsWith(„Laminated voucher“)) { // Declare text based of VoucherType var physVoucherType = „“; var physVoucherTypeCzech = „“; var physVoucherTypeCzechDeclined = „“; if (verzeVoucheru.startsWith(„Paper gift voucher“)) { physVoucherType = „paper“; physVoucherTypeCapital = „Paper“; physVoucherTypeCzech = „fyzického“; physVoucherTypeCzechDeclined = „fyzický“; } else if (verzeVoucheru.startsWith(„Laminated voucher“)) { physVoucherType = „laminated“; physVoucherTypeCzech = „zalaminovaného“; physVoucherTypeCzechDeclined = „zalaminovaný“; } subject = „Nest Escape – “ + physVoucherType + “ gift voucher“; body = „Thank you for your order!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Hello,

thank you for your order!

We have attached a draft gift voucher without its code – please check it and let us know if you want to tweak anything. We have also attached an invoice – you will receive preview of the voucher with its code after it has been paid – in case of immediate bank transfer within following 20 minutes, in case of standard transfer within the next working day.${discountSuccessNoteEN}

The ${physVoucherType} voucher will normally be delivered to your chosen AlzaBox within a week after payment is received. If you need it sooner, please let us know and we will try to expedite it 😊

Please also double-check the voucher delivery AlzaBox location: ${alzaboxLocation}
And also your phone number, to which the AlzaBox opening code will be sent: ${alzaboxPhone}

www.nestescape.cz+420 730 521 639
         (10AM – 10PM every day)


Hybešova 271/29 602 00 Brno
IČO (CIN): 23198966
` }); }; } else { const voucherTypeFirstWord = verzeVoucheru.trim().split(/\s+/)[0]; var alzaboxLocationCheck = „“; var phoneNumberCheckRequest = „“; if (voucherLanguage === „CZ“) { if (alzaboxLocation) { alzaboxLocationCheck = `Prosím pro jistotu zkontrolujte správnost lokace zvoleného AlzaBoxu: ${alzaboxLocation}

`; } if (alzaboxPhone) { phoneNumberCheckRequest = `Prosím také ještě pro jistotu zkontrolujte správnost svého telefonního čísla pro doručení kódu k otevření AlzaBoxu: ${alzaboxPhone}

`; } subject = `Nest Escape – ${voucherTypeFirstWord.toLowerCase()} dárkový poukaz se speciálním požadavkem`; body = „Děkujeme za objednávku!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Dobrý den,

děkujeme za objednávku!

Přiložili jsme automaticky vygenerovaný dárkový poukaz bez kódu a fakturu s informacemi k platbě.${discountSuccessNoteCZ} Poukaz s kódem obdržíte po proplacení přiložené faktury – v případě okamžitého bankovního převodu během následujících 20 minut, v případě standardního převodu během následujícího pracovního dne.

Evidujeme také Váš speciální požadavek, kterému se budeme do 24 hodin věnovat a dáme Vám vědět, co pro Vás můžeme udělat 😊

Váš speciální požadavek:
${effectiveSpeslPozadavek}

${alzaboxLocationCheck} ${phoneNumberCheckRequest}
www.nestescape.cz+420 730 521 639
         (10:00 – 22:00 každý den)


Hybešova 271/29 602 00 Brno
IČO: 23198966
` }); } else if (voucherLanguage === „EN“) { if (alzaboxLocation) { alzaboxLocationCheck = `Please double-check the location of the selected AlzaBox: ${alzaboxLocation}

`; } if (alzaboxPhone) { phoneNumberCheckRequest = `By the way, please double-check your phone number to ensure it is correct for receiving the code to open your AlzaBox: ${alzaboxPhone}

`; } subject = `Nest Escape – ${voucherTypeFirstWord.toLowerCase()} gift voucher with special request`; body = „Thank you for your order!“; GmailApp.sendEmail(recipient, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `
Hello,

thank you for your order!

We have attached an automatically generated gift voucher without its code and invoice with payment information.${discountSuccessNoteEN} You will receive the voucher with the code after payment of the attached invoice – in case of immediate bank transfer within following 20 minutes, in case of standard transfer within the next working day.

We have also registered your special request, which we will address within 24 hours and let you know what we can do for you 😊

Your special request:
${effectiveSpeslPozadavek}

${alzaboxLocationCheck} ${phoneNumberCheckRequest}
www.nestescape.cz+420 730 521 639
         (10AM – 10PM every day)


Hybešova 271/29 602 00 Brno
IČO (CIN): 23198966
` }); } subject = „Fuck, někdo si od nás objednal poukaz s nějakým speciálním požadavkem“; body = „Měli bychom se na to mrknout co nejdřív!!“; GmailApp.sendEmail(„nestescape@gmail.com“, subject, body, { attachments: [voucher, invoice], name: sendersName, htmlBody: `Typ poukazu: ${verzeVoucheru}
Spešl požadavek: ${effectiveSpeslPozadavek}
Mail na zákazníka: ${recipient}
Jméno a příjmení zákazníka: ${jmenoPrijmeni}
Lokace AlzaBoxu: ${alzaboxLocation}
Telefonní číslo na zákazníka: ${alzaboxPhone}
Zadaný slevový kód: ${discountCode || „(žádný)“}
Rozpoznaná sleva: ${discountInfo ? discountInfo.discountPercent + „% – “ + discountInfo.discountType + “ “ + discountInfo.codeId : „(žádná)“}
` }); } const columns = [-1, -2, -3, -4, -5, -6, -8].map(offset => TOTAL_COLUMN_COUNT + offset); const range = responseSheet.getRange(lastRowIndex, Math.min(…columns), 1, columns.length); range.setHorizontalAlignment(„center“).setVerticalAlignment(„middle“); if (verzeVoucheru.startsWith(„Fyzický dárkový poukaz“) || verzeVoucheru.startsWith(„Paper gift voucher“)) { responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-15)).setBackground(„red“)} else if (verzeVoucheru.startsWith(„Zalaminovaný poukaz“) || verzeVoucheru.startsWith(„Laminated voucher“)) { responseSheet.getRange(lastRowIndex,(TOTAL_COLUMN_COUNT-15)).setBackground(„fuchsia“)}; // Now, create the voucher with code for delivery once the customer pays createVoucher({ code: uniqueId, nameFor: proKoho, wish: wishText, validTill: voucherValidTill, voucherValue, voucherLanguage, variableNumber, }, voucherID); }
Přejít nahoru