BrightSide Workbench Full Report + Source Code
EditServiceControl.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2020 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.contacts.service;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26 import org.turro.string.Strings;
27 import org.turro.url.UrlCompose;
28 import org.apache.commons.mail.EmailException;
29 import org.turro.action.IAgreements;
30 import org.turro.action.MailSenders;
31 import org.turro.action.Plugins;
32 import org.turro.auth.Authentication;
33 import org.turro.collections.KeyValueMap;
34 import org.turro.contacts.BusinessCombobox;
35 import org.turro.contacts.ContactService;
36 import org.turro.contacts.ContactServiceRole;
37 import org.turro.contacts.CoworkerCombobox;
38 import org.turro.contacts.db.ContactsPU;
39 import org.turro.elephant.TemplateControl;
40 import org.turro.elephant.calendar.Periodicity;
41 import org.turro.elephant.context.Application;
42 import org.turro.elephant.context.ElephantContext;
43 import org.turro.elephant.context.IConstructor;
44 import org.turro.elephant.util.Messages;
45 import org.turro.entities.Entities;
46 import org.turro.file.util.FileAttach;
47 import org.turro.i18n.I_;
48 import org.turro.jpa.Dao;
49 import org.turro.marker.MarkerHelper;
50 import org.turro.plugin.contacts.IContact;
51 import org.turro.upload.Medias;
52 import org.turro.zkoss.input.ExpressionInput;
53 import org.turro.zkoss.input.PeriodicityListbox;
54 import org.turro.zkoss.text.WikiEditor;
55 import org.zkoss.image.AImage;
56 import org.zkoss.util.media.Media;
57 import org.zkoss.zk.ui.event.UploadEvent;
58 import org.zkoss.zk.ui.select.annotation.Listen;
59 import org.zkoss.zk.ui.select.annotation.Wire;
60 import org.zkoss.zk.ui.util.Clients;
61 import org.zkoss.zul.Button;
62 import org.zkoss.zul.Datebox;
63 import org.zkoss.zul.Image;
64 import org.zkoss.zul.Textbox;
65 
70 public class EditServiceControl extends TemplateControl {
71 
72  private ContactService service;
73  private String contextPath;
74 
75  @Wire("#title") private Textbox title;
76  @Wire("#business") private BusinessCombobox business;
77  @Wire("#responsible") private CoworkerCombobox responsible;
78  @Wire("#role") private ServiceRoleListbox role;
79  @Wire("#type") private ServiceTypeCombobox type;
80  @Wire("#thematic") private ServiceThematicCombobox thematic;
81  @Wire("#relurl") private Textbox relatedUrl;
82  @Wire("#start") private Datebox start;
83  @Wire("#end") private Datebox end;
84  @Wire("#price") private ExpressionInput price;
85  @Wire("#tax") private ExpressionInput tax;
86  @Wire("#periodicity") private PeriodicityListbox periodicity;
87  @Wire("#image") private Image image;
88  @Wire("#text") private WikiEditor text;
89  @Wire("#publish") private Button publish;
90  @Wire("#delete") private Button delete;
91 
92  @Listen("onChange=#title")
93  public void onTitle() {
94  service.setTitle(title.getValue());
95  }
96 
97  @Listen("onSelect=#business")
98  public void onBusiness() {
99  service.setIContact(business.getObjectValue());
100  responsible.setContact(business.getObjectValue());
101  responsible.setObjectValue(null);
102  }
103 
104  @Listen("onSelect=#responsible")
105  public void onResponsible() {
106  service.setIResponsible(responsible.getObjectValue());
107  }
108 
109  @Listen("onSelect=#role")
110  public void onRole() {
111  service.setRole(role.getObjectValue());
112  }
113 
114  @Listen("onChange=#type")
115  public void onType() {
116  service.setType(type.getObjectValue());
117  }
118 
119  @Listen("onChange=#thematic")
120  public void onThematic() {
121  service.setThematic(thematic.getObjectValue());
122  }
123 
124  @Listen("onChange=#relurl")
125  public void onRelatedUrl() {
126  String relUrl = relatedUrl.getValue();
127  if(!Strings.isBlank(relUrl)) {
128  if(relUrl.contains("@")) {
129  service.setRelatedURL(UrlCompose.fillMailGaps(relUrl));
130  } else {
131  service.setRelatedURL(UrlCompose.fillWebGaps(relUrl));
132  }
133  } else {
134  service.setRelatedURL(null);
135  }
136  relatedUrl.setValue(service.getRelatedURL());
137  }
138 
139  @Listen("onChange=#start")
140  public void onStart() {
141  service.setStartDate(start.getValue());
142  }
143 
144  @Listen("onChange=#end")
145  public void onEnd() {
146  service.setEndDate(end.getValue());
147  }
148 
149  @Listen("onChange=#price")
150  public void onPrice() {
151  service.setPrice(price.getDoubleValue());
152  price.setValue(service.getPrice());
153  }
154 
155  @Listen("onChange=#tax")
156  public void onTax() {
157  service.setTax(tax.getDoubleValue());
158  tax.setValue(service.getTax());
159  }
160 
161  @Listen("onSelect=#periodicity")
162  public void onPeriodicity() {
163  service.setPeriodicity(periodicity.getObjectValue());
164  }
165 
166  @Listen("onUpload=#upload")
167  public void onUpload(UploadEvent event) {
168  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(service));
169  File newFile = new File(ElephantContext.getRealPath(fileAttach.getPublishable() + "/profile/face.png"));
170  if(!newFile.getParentFile().exists()) {
171  newFile.getParentFile().mkdirs();
172  }
173  Media media = event.getMedia();
174  if(media != null) {
175  Medias.toFile(media, newFile, Medias.smart(900, 450));
176  }
177  if(newFile.exists()) {
178  try {
179  image.setContent(new AImage(newFile.getAbsolutePath()));
180  } catch (IOException ex) {
181  Logger.getLogger(EditServiceControl.class.getName()).log(Level.SEVERE, null, ex);
182  }
183  } else {
184  image.setSrc(null);
185  }
186  }
187 
188  @Listen("onChange=#text")
189  public void onText() {
190  service.setWiki(text.getValue());
191  service.setText(text.getHtml());
192  }
193 
194  @Listen("onClick=#sendTest")
195  public void onSendTest() {
196  if(!service.isEmpty()) {
197  HashMap args = new HashMap();
198  args.put("service", service);
199  args.put("wrapper", new ContactServiceWrapper(service));
200  args.put("notifier", this);
201  if(!Strings.isBlank(service.getId())) {
202  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(service));
203  args.put("face", fileAttach.getPublicFile("/profile/face.png", false));
204  args.put("link", Entities.getController(service).getEntityUrl());
205  }
206  try {
209  .addByEntity(service, null)
210  .setRoot("/services")
211  .putAll(args)
212  .sendTemplate("service-test", composeSubject(service));
213  Clients.showNotification(I_.get("Test sent"));
214  } catch (EmailException ex) {
215  Logger.getLogger(EditServiceControl.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
216  }
217  } else {
218  Clients.showNotification(I_.get("Fill required fields"));
219  }
220  }
221 
222  @Listen("onClick=#save")
223  public void onSave() {
224  if(!service.isEmpty()) {
225  // check @ and replace with &#64;
226  ContactServiceWrapper wrapper = new ContactServiceWrapper(service);
227  service = wrapper.save();
228  Application.getApplication().sendRedirect(contextPath + "?" +
229  MarkerHelper.setObfuscatedRightNowPars("item=" + service.getId()));
230  } else {
231  Clients.showNotification(I_.get("Fill required fields"));
232  }
233  }
234 
235  @Listen("onClick=#cancel")
236  public void onCancel() {
237  if(!Strings.isBlank(service.getId())) {
238  Application.getApplication().sendRedirect(contextPath + "?" +
239  MarkerHelper.setObfuscatedRightNowPars("item=" + service.getId()));
240  } else {
241  Application.getApplication().sendRedirect(contextPath);
242  }
243  }
244 
245  @Listen("onClick=#publish")
246  public void onPublish() {
247  if(!service.isEmpty()) {
248  onSave();
249  HashMap args = new HashMap();
250  args.put("service", service);
251  args.put("wrapper", new ContactServiceWrapper(service));
252  args.put("notifier", this);
253  if(!Strings.isBlank(service.getId())) {
254  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(service));
255  args.put("face", fileAttach.getPublicFile("/profile/face.png", false));
256  args.put("link", Entities.getController(service).getEntityUrl());
257  }
258  try {
261  .addByEntity(service, null)
262  .setRoot("/services")
263  .putAll(args)
264  .sendTemplate("service-marketplace", composeSubject(service));
265  } catch (EmailException ex) {
266  Logger.getLogger(EditServiceControl.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
267  }
268  Application.getApplication().sendRedirect(contextPath + "?" +
269  MarkerHelper.setObfuscatedRightNowPars("item=" + service.getId()));
271  }
272  }
273 
274  @Listen("onClick=#delete")
275  public void onDelete() {
276  if(!Strings.isBlank(service.getId())) {
277  Messages.confirmDeletion().add(service.getTitle()).show(() -> {
278  ContactServiceWrapper wrapper = new ContactServiceWrapper(service);
279  wrapper.delete();
280  Application.getApplication().sendRedirect(contextPath);
281  });
282  }
283  }
284 
285  @Listen("onClick=#delimg")
286  public void onDeleteImage() {
287  if(!Strings.isBlank(service.getId())) {
288  Messages.confirmDeletion().add(I_.get("Image")).show(() -> {
289  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(service));
290  File newFile = new File(ElephantContext.getRealPath(fileAttach.getPublishable() + "/profile/face.png"));
291  if(newFile.exists()) {
292  newFile.delete();
293  image.setSrc(null);
294  }
295  });
296  }
297  }
298 
299  public String getContextPath() {
300  return contextPath;
301  }
302 
303  public void setContextPath(String contextPath) {
304  this.contextPath = contextPath;
305  }
306 
307  public void setResponse(ContactService service) {
308  this.service = service;
309  }
310 
312  checkService();
313  return service;
314  }
315 
316  public String getImgUploadMsg() {
317  return I_.format("Image will be converted to %dx%d", 900, 450);
318  }
319 
320  @Override
321  protected void doFinally() {
322  super.doFinally();
323  IAgreements agreements = Plugins.loadImplementation(IAgreements.class, "agreements");
324  agreements.setContact(Authentication.getIContact());
325  if(!agreements.canAct("marketplace-new")) {
326  Application.getApplication().sendRedirect(agreements.getPendingActURL("marketplace-new"));
327  } else {
328  checkService();
329  initComponents();
330  }
331  }
332 
333  /* Send test */
334 
335  public String createRef(IConstructor constructor, ContactService service, IContact contact) throws Exception {
336  return createRef(constructor, service.getTimesSent() >=1 ?
337  Entities.getController(service).getEntityUrl() :
338  Entities.getController(service).getMemberUrl());
339  }
340 
341  public String createRef(IConstructor constructor, String redir) throws Exception {
342  return "{liveref:" + redir + "}";
343  }
344 
345  private void checkService() {
346  KeyValueMap kvm = MarkerHelper.getObfuscatedParameters();
347  if(service == null) {
348  if(kvm != null && !kvm.isEmpty() && kvm.containsKey("item")) {
349  String serviceId = kvm.get("item");
350  if(!Strings.isBlank(serviceId)) {
351  service = getDao().find(ContactService.class, serviceId);
352  }
353  } else {
354  service = new ContactService();
355  service.setRole(ContactServiceRole.SERVICE_SUPPLY);
356  service.setPeriodicity(Periodicity.PUNCTUAL);
357  }
358  }
359  if(service == null) {
360  Application.getApplication().sendRedirect(contextPath);
361  }
362  }
363 
364  private void initComponents() {
365  business.setAllowSelf(ServiceContext.getAllowSingle());
366  responsible.setAllowSelf(ServiceContext.getAllowSingle());
367  business.setContact(Authentication.getIContact());
368  responsible.setContact(null);
369  if(!Strings.isBlank(service.getId())) {
370  title.setValue(service.getTitle());
371  business.setObjectValue(service.getIContact());
372  responsible.setObjectValue(service.getIResponsible());
373  role.setObjectValue(service.getRole());
374  type.setObjectValue(service.getType());
375  thematic.setObjectValue(service.getThematic());
376  relatedUrl.setValue(service.getRelatedURL());
377  start.setValue(service.getStartDate());
378  end.setValue(service.getEndDate());
379  price.setValue(service.getPrice());
380  tax.setValue(service.getTax());
381  periodicity.setObjectValue(service.getPeriodicity());
382  image.setSrc(service.getImage());
383  text.setValue(service.getWiki());
384  text.setFileFolder("/_internal/files/service/" + service.getId());
385  text.setImageFolder("/_internal/files/service/" + service.getId());
386  } else {
387  text.setFileFolder("/_internal/files/service/empty");
388  text.setImageFolder("/_internal/files/service/empty");
389  text.setReadOnlyRepository(true);
390  }
391  boolean all = Application.getApplication().isInRole("contact:all");
392  publish.setDisabled(service.getTimesSent() >= 1 && !all);
393  delete.setDisabled(Strings.isBlank(service.getId()) || !(all ||
394  service.isInBusiness(business.getContact())));
395  }
396 
397  private String composeSubject(ContactService service) {
398  return "[" + I_.byKey(service.getRole().toString()) + "]" +
399  " " + I_.byKey(service.getType()) +
400  ": " + service.getTitle();
401  }
402 
403  /* Dao */
404 
405  private Dao _dao;
406 
407  private Dao getDao() {
408  if(_dao == null) {
409  _dao = new ContactsPU();
410  }
411  return _dao;
412  }
413 
414 }
static IMailSender getPool()
static< T > T loadImplementation(Class< T > jclass)
Definition: Plugins.java:57
void setAllowSelf(boolean allowSelf)
void setRelatedURL(String relatedURL)
void setIContact(IContact contact)
void setPeriodicity(Periodicity periodicity)
void setIResponsible(IContact responsible)
boolean isInBusiness(IContact worker)
void setRole(ContactServiceRole role)
void setAllowSelf(boolean allowSelf)
static String getObjectPath(Object object)
Definition: ContactsPU.java:68
String createRef(IConstructor constructor, String redir)
String createRef(IConstructor constructor, ContactService service, IContact contact)
abstract void sendRedirect(String uri)
static Messages confirmDeletion()
Definition: Messages.java:87
Messages add(String word)
Definition: Messages.java:50
static IElephantEntity getController(String path)
Definition: Entities.java:78
String getPublicFile(String file)
Definition: FileAttach.java:59
static String format(String msg, Object... arguments)
Definition: I_.java:49
static String get(String msg)
Definition: I_.java:41
static KeyValueMap getObfuscatedParameters()
static String setObfuscatedRightNowPars(String parameters)
static void toFile(Media media, File file)
Definition: Medias.java:66
static Consumer< File > smart(double width, double height)
Definition: Medias.java:114
void setImageFolder(String folder)
void setValue(String value)
Definition: WikiEditor.java:98
void setFileFolder(String folder)
void setReadOnlyRepository(boolean readOnlyRepository)
void setContact(IContact contact)
String getPendingActURL(String action)
boolean canAct(String action)