Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement #431 (#437) #1

Merged
merged 1 commit into from
May 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/main/java/alfio/config/DataSourceConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import alfio.config.support.PlatformProvider;
import alfio.manager.Jobs.*;
import alfio.manager.UploadedResourceManager;
import alfio.manager.system.ConfigurationManager;
import alfio.util.TemplateManager;
import ch.digitalfondue.npjt.QueryFactory;
import ch.digitalfondue.npjt.mapper.ZonedDateTimeMapper;
Expand Down Expand Up @@ -164,8 +165,8 @@ public MessageSource messageSource() {
}

@Bean
public TemplateManager getTemplateManager(UploadedResourceManager uploadedResourceManager) {
return new TemplateManager(getTemplateLoader(), messageSource(), uploadedResourceManager);
public TemplateManager getTemplateManager(UploadedResourceManager uploadedResourceManager, ConfigurationManager configurationManager) {
return new TemplateManager(getTemplateLoader(), messageSource(), uploadedResourceManager, configurationManager);
}

@Bean
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/alfio/config/MvcConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import alfio.model.Event;
import alfio.model.system.Configuration.ConfigurationPathKey;
import alfio.util.MustacheCustomTagInterceptor;
import alfio.util.TemplateManager;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand Down Expand Up @@ -203,6 +204,8 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response,
modelMap.putIfAbsent("paypalTestUsername", configurationManager.getStringConfigValue(alfio.model.system.Configuration.getSystemConfiguration(PAYPAL_DEMO_MODE_USERNAME), "<missing>"));
modelMap.putIfAbsent("paypalTestPassword", configurationManager.getStringConfigValue(alfio.model.system.Configuration.getSystemConfiguration(PAYPAL_DEMO_MODE_PASSWORD), "<missing>"));
}

modelMap.putIfAbsent(TemplateManager.VAT_TRANSLATION_TEMPLATE_KEY, TemplateManager.getVATString(event, messageSource, RequestContextUtils.getLocaleResolver(request).resolveLocale(request), configurationManager));
});
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void getGoogleAnalyticsScript(HttpSession session, HttpServletResponse re
Map<String, Object> model = new HashMap<>();
model.put("clientId", trackingId);
model.put("account", id.get());
script = templateManager.renderTemplate(TemplateResource.GOOGLE_ANALYTICS, model, Locale.ENGLISH);
script = templateManager.renderTemplate(ev, TemplateResource.GOOGLE_ANALYTICS, model, Locale.ENGLISH);
} else {
script = id.map(x -> String.format(GOOGLE_ANALYTICS_SCRIPT, x)).orElse(EMPTY);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ public Map<String, Object> assignTicketToPerson(@PathVariable("eventName") Strin

Optional<ValidationResult> validationResult = assignmentResult.map(Triple::getLeft);
if(validationResult.isPresent() && validationResult.get().isSuccess()) {
result.put("partial", templateManager.renderServletContextResource("/WEB-INF/templates/event/assign-ticket-result.ms", model.asMap(), request, TemplateManager.TemplateOutput.HTML));
result.put("partial", templateManager.renderServletContextResource("/WEB-INF/templates/event/assign-ticket-result.ms",
assignmentResult.get().getMiddle(),//<- ugly, but will be removed
model.asMap(), request, TemplateManager.TemplateOutput.HTML));
}
result.put("validationResult", validationResult.orElse(ValidationResult.failed(new ValidationResult.ErrorDescriptor("fullName", "error.fullname"))));
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public Map<String, Object> subscribe(WaitingQueueSubscriptionForm subscription,
ValidationResult validationResult = Validator.validateWaitingQueueSubscription(subscription, bindingResult, event);
if(validationResult.isSuccess()) {
model.addAttribute("error", !waitingQueueManager.subscribe(event, subscription.toCustomerName(event), subscription.getEmail(), subscription.getSelectedCategory(), subscription.getUserLanguage()));
result.put("partial", templateManager.renderServletContextResource("/WEB-INF/templates/event/waiting-queue-subscription-result.ms", model.asMap(), request, HTML));
result.put("partial", templateManager.renderServletContextResource("/WEB-INF/templates/event/waiting-queue-subscription-result.ms", event, model.asMap(), request, HTML));
}
result.put("validationResult", validationResult);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public void previewTemplate(@PathVariable("name") TemplateResource name, @PathVa
Organization organization = organizationRepository.getById(organizationId);
Optional<TemplateResource.ImageData> image = TemplateProcessor.extractImageModel(event, fileUploadManager);
Map<String, Object> model = name.prepareSampleModel(organization, event, image);
String renderedTemplate = templateManager.renderString(template.getFileAsString(), model, loc, name.getTemplateOutput());
String renderedTemplate = templateManager.renderString(event, template.getFileAsString(), model, loc, name.getTemplateOutput());
if("text/plain".equals(name.getRenderedContentType())) {
response.addHeader("Content-Disposition", "attachment; filename="+name.name()+".txt");
response.setContentType("text/plain");
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/alfio/manager/WaitingQueueManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private void notifySubscription(Event event, CustomerName name, String email, Lo
new Object[] {subscriptionType, event.getDisplayName()}, Locale.ENGLISH);
notificationManager.sendSimpleEmail(event, organization.getEmail(), messageSource.getMessage("email-waiting-queue.subscribed.admin.subject",
new Object[]{event.getDisplayName()}, Locale.ENGLISH),
() -> templateManager.renderString(adminTemplate, model, Locale.ENGLISH, TemplateManager.TemplateOutput.TEXT));
() -> templateManager.renderString(event, adminTemplate, model, Locale.ENGLISH, TemplateManager.TemplateOutput.TEXT));
}

}
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/alfio/manager/support/CustomMessageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public void sendMessages(String eventName, Optional<Integer> categoryId, List<Me
Ticket ticket = triple.getLeft();
MessageModification m = Optional.ofNullable(byLanguage.get(ticket.getUserLanguage())).orElseGet(() -> byLanguage.get(byLanguage.keySet().stream().findFirst().orElseThrow(IllegalStateException::new))).get(0);
Model model = triple.getRight();
String subject = renderResource(m.getSubject(), model, m.getLocale(), templateManager);
String text = renderResource(m.getText(), model, m.getLocale(), templateManager);
String subject = renderResource(m.getSubject(), event, model, m.getLocale(), templateManager);
String text = renderResource(m.getText(), event, model, m.getLocale(), templateManager);
List<Mailer.Attachment> attachments = new ArrayList<>();
if(m.isAttachTicket()) {
ticketReservationManager.findById(ticket.getTicketsReservationId()).ifPresent(reservation -> {
Expand All @@ -137,7 +137,8 @@ private List<MessageModification> preview(Event event, List<MessageModification>
model.addAttribute("ticketURL", "https://this-is-the-ticket-url");
model.addAttribute("reservationID", "RESID");
return input.stream()
.map(m -> MessageModification.preview(m, renderResource(m.getSubject(), model, m.getLocale(), templateManager), renderResource(m.getText(), model, m.getLocale(), templateManager), m.isAttachTicket()))
.map(m -> MessageModification.preview(m, renderResource(m.getSubject(), event, model, m.getLocale(), templateManager),
renderResource(m.getText(), event, model, m.getLocale(), templateManager), m.isAttachTicket()))
.collect(Collectors.toList());
}

Expand All @@ -150,7 +151,7 @@ public static Mailer.Attachment generateTicketAttachment(Ticket ticket, TicketRe
return new Mailer.Attachment("ticket-" + ticket.getUuid() + ".pdf", null, "application/pdf", model, Mailer.AttachmentIdentifier.TICKET_PDF);
}

private static String renderResource(String template, Model model, Locale locale, TemplateManager templateManager) {
return templateManager.renderString(template, model.asMap(), locale, TemplateManager.TemplateOutput.TEXT);
private static String renderResource(String template, Event event, Model model, Locale locale, TemplateManager templateManager) {
return templateManager.renderString(event, template, model.asMap(), locale, TemplateManager.TemplateOutput.TEXT);
}
}
12 changes: 9 additions & 3 deletions src/main/java/alfio/model/system/ConfigurationKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,14 @@ public enum ConfigurationKeys {
ALFIO_PI_INTEGRATION_ENABLED("Enable Alf.io-PI integration", false, SettingCategory.ALFIO_PI, ComponentType.BOOLEAN, false, EnumSet.of(SYSTEM), false),
OFFLINE_CHECKIN_ENABLED("Offline Check-in enabled", false, SettingCategory.ALFIO_PI, ComponentType.BOOLEAN, false, EnumSet.of(EVENT), false),
LABEL_PRINTING_ENABLED("Label Printing enabled", false, SettingCategory.ALFIO_PI, ComponentType.BOOLEAN, false, EnumSet.of(EVENT), false),
LABEL_LAYOUT("Label layout", false, SettingCategory.ALFIO_PI, ComponentType.TEXTAREA, false, EnumSet.of(EVENT), false);

LABEL_LAYOUT("Label layout", false, SettingCategory.ALFIO_PI, ComponentType.TEXTAREA, false, EnumSet.of(EVENT), false),

//
TRANSLATION_OVERRIDE_VAT_EN("Override the default tax term EN: VAT", false, SettingCategory.TRANSLATIONS, ComponentType.TEXT, false, EnumSet.of(SYSTEM, ORGANIZATION, EVENT), false),
TRANSLATION_OVERRIDE_VAT_DE("Override the default tax term DE: Mehrwertsteuer", false, SettingCategory.TRANSLATIONS, ComponentType.TEXT, false, EnumSet.of(SYSTEM, ORGANIZATION, EVENT), false),
TRANSLATION_OVERRIDE_VAT_FR("Override the default tax term FR: TVA", false, SettingCategory.TRANSLATIONS, ComponentType.TEXT, false, EnumSet.of(SYSTEM, ORGANIZATION, EVENT), false),
TRANSLATION_OVERRIDE_VAT_IT("Override the default tax term IT: IVA", false, SettingCategory.TRANSLATIONS, ComponentType.TEXT, false, EnumSet.of(SYSTEM, ORGANIZATION, EVENT), false),
TRANSLATION_OVERRIDE_VAT_NL("Override the default tax term NL: BTW", false, SettingCategory.TRANSLATIONS, ComponentType.TEXT, false, EnumSet.of(SYSTEM, ORGANIZATION, EVENT), false);

@Getter
public enum SettingCategory {
Expand All @@ -166,7 +171,8 @@ public enum SettingCategory {
INVOICE_EU("Invoice settings for EU"),
MAIL("E-Mail settings"),
ALFIO_PI("Offline check-in and badge printing"),
MAP("Maps settings");
MAP("Maps settings"),
TRANSLATIONS("Translations");

private final String description;
SettingCategory(String description) {
Expand Down
57 changes: 42 additions & 15 deletions src/main/java/alfio/util/TemplateManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

import alfio.config.WebSecurityConfig;
import alfio.manager.UploadedResourceManager;
import alfio.manager.system.ConfigurationManager;
import alfio.model.Event;
import alfio.model.system.Configuration;
import alfio.model.system.ConfigurationKeys;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Compiler;
import com.samskivert.mustache.Mustache.Formatter;
Expand Down Expand Up @@ -54,60 +57,84 @@ public class TemplateManager {

private final MessageSource messageSource;

public static final String VAT_TRANSLATION_TEMPLATE_KEY = "vatTranslation";

public enum TemplateOutput {
TEXT, HTML
}

private final Map<TemplateOutput, Compiler> compilers;

private final UploadedResourceManager uploadedResourceManager;
private final ConfigurationManager configurationManager;

private static final Formatter DATE_FORMATTER = (o) -> (o instanceof ZonedDateTime) ? DateTimeFormatter.ISO_ZONED_DATE_TIME.format((ZonedDateTime) o) : String.valueOf(o);

@Autowired
public TemplateManager(JMustacheTemplateLoader templateLoader,
MessageSource messageSource,
UploadedResourceManager uploadedResourceManager) {
UploadedResourceManager uploadedResourceManager,
ConfigurationManager configurationManager) {
this.messageSource = messageSource;
this.uploadedResourceManager = uploadedResourceManager;
Formatter dateFormatter = (o) -> {
return (o instanceof ZonedDateTime) ? DateTimeFormatter.ISO_ZONED_DATE_TIME
.format((ZonedDateTime) o) : String.valueOf(o);
};
this.configurationManager = configurationManager;

this.compilers = new EnumMap<>(TemplateOutput.class);
this.compilers.put(TemplateOutput.TEXT, Mustache.compiler()
.escapeHTML(false)
.standardsMode(false)
.defaultValue("")
.nullValue("")
.withFormatter(dateFormatter)
.withFormatter(DATE_FORMATTER)
.withLoader(templateLoader));
this.compilers.put(TemplateOutput.HTML, Mustache.compiler()
.escapeHTML(true)
.standardsMode(false)
.defaultValue("")
.nullValue("")
.withFormatter(dateFormatter)
.withFormatter(DATE_FORMATTER)
.withLoader(templateLoader));
}

public String renderTemplate(TemplateResource templateResource, Map<String, Object> model, Locale locale) {
return render(new ClassPathResource(templateResource.classPath()), model, locale, templateResource.getTemplateOutput());
public String renderTemplate(Optional<Event> event, TemplateResource templateResource, Map<String, Object> model, Locale locale) {
return render(new ClassPathResource(templateResource.classPath()), modelEnricher(model, event, locale), locale, templateResource.getTemplateOutput());
}

public String renderTemplate(Event event, TemplateResource templateResource, Map<String, Object> model, Locale locale) {
Map<String, Object> updatedModel = modelEnricher(model, Optional.ofNullable(event), locale);
return uploadedResourceManager.findCascading(event.getOrganizationId(), event.getId(), templateResource.getSavedName(locale))
.map(resource -> render(new ByteArrayResource(resource), model, locale, templateResource.getTemplateOutput()))
.orElseGet(() -> renderTemplate(templateResource, model, locale));
.map(resource -> render(new ByteArrayResource(resource), updatedModel, locale, templateResource.getTemplateOutput()))
.orElseGet(() -> renderTemplate(Optional.ofNullable(event), templateResource, updatedModel, locale));
}

public String renderString(String template, Map<String, Object> model, Locale locale, TemplateOutput templateOutput) {
return render(new ByteArrayResource(template.getBytes(StandardCharsets.UTF_8)), model, locale, templateOutput);
public String renderString(Event event, String template, Map<String, Object> model, Locale locale, TemplateOutput templateOutput) {
return render(new ByteArrayResource(template.getBytes(StandardCharsets.UTF_8)), modelEnricher(model, Optional.ofNullable(event), locale), locale, templateOutput);
}

//TODO: to be removed when only the rest api will be exposed
public String renderServletContextResource(String servletContextResource, Map<String, Object> model, HttpServletRequest request, TemplateOutput templateOutput) {
public String renderServletContextResource(String servletContextResource, Event event, Map<String, Object> model, HttpServletRequest request, TemplateOutput templateOutput) {
model.put("request", request);
model.put(WebSecurityConfig.CSRF_PARAM_NAME, request.getAttribute(CsrfToken.class.getName()));
return render(new ServletContextResource(request.getServletContext(), servletContextResource), model, RequestContextUtils.getLocale(request), templateOutput);
Locale locale = RequestContextUtils.getLocale(request);
return render(new ServletContextResource(request.getServletContext(), servletContextResource), modelEnricher(model, Optional.ofNullable(event), locale), locale, templateOutput);
}

private Map<String, Object> modelEnricher(Map<String, Object> model, Optional<Event> event, Locale locale) {
Map<String, Object> toEnrich = new HashMap<>(model);
event.ifPresent(ev -> {
toEnrich.put(VAT_TRANSLATION_TEMPLATE_KEY, getVATString(ev, messageSource, locale, configurationManager));
});
return toEnrich;
}


public static String getVATString(Event event, MessageSource messageSource, Locale loc, ConfigurationManager configurationManager) {
String locale = messageSource.getMessage("locale", null, loc);
String translatedVat = messageSource.getMessage("common.vat", null, loc);
ConfigurationKeys vatKey = ConfigurationKeys.valueOf("TRANSLATION_OVERRIDE_VAT_"+locale.toUpperCase(Locale.ENGLISH));
Configuration.ConfigurationPathKey vatPathKey = Optional.ofNullable(event).map(e -> alfio.model.system.Configuration.from(e.getOrganizationId(), e.getId(), vatKey))
.orElseGet(() -> alfio.model.system.Configuration.getSystemConfiguration(vatKey));
return configurationManager.getStringConfigValue(vatPathKey, translatedVat);
}

private String render(AbstractResource resource, Map<String, Object> model, Locale locale, TemplateOutput templateOutput) {
Expand Down
Loading