mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
CE-1068 - Progress on scheduling reports, with variable inputs
This commit is contained in:
@ -52,6 +52,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RenderSavedReportMetaDataProducer;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RunScheduledReportMetaDataProducer;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -63,6 +64,8 @@ public class SavedReportsMetaDataProvider
|
||||
|
||||
public static final String SAVED_REPORT_JOIN_SCHEDULED_REPORT = "scheduledReportJoinSavedReport";
|
||||
|
||||
public static final String SCHEDULED_REPORT_VALUES_WIDGET = "scheduledReportValuesWidget";
|
||||
public static final String RENDER_REPORT_PROCESS_VALUES_WIDGET = "renderReportProcessValuesWidget";
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -85,6 +88,7 @@ public class SavedReportsMetaDataProvider
|
||||
.filter(f -> RenderSavedReportMetaDataProducer.FIELD_NAME_STORAGE_TABLE_NAME.equals(f.getName()))
|
||||
.findFirst()
|
||||
.ifPresent(f -> f.setDefaultValue(REPORT_STORAGE_TABLE_NAME));
|
||||
instance.addWidget(defineRenderReportProcessValuesWidget());
|
||||
|
||||
instance.addWidget(defineReportSetupWidget());
|
||||
instance.addWidget(definePivotTableSetupWidget());
|
||||
@ -98,6 +102,10 @@ public class SavedReportsMetaDataProvider
|
||||
instance.addWidget(defineScheduledReportJoinSavedReportWidget(join));
|
||||
QProcessMetaData scheduledReportSyncToScheduledJobProcess = new ScheduledReportSyncToScheduledJobProcess().produce(instance);
|
||||
instance.addProcess(scheduledReportSyncToScheduledJobProcess);
|
||||
instance.addWidget(defineScheduledReportValuesWidget());
|
||||
|
||||
QProcessMetaData runScheduledReportProcess = new RunScheduledReportMetaDataProducer().produce(instance);
|
||||
instance.addProcess(runScheduledReportProcess);
|
||||
|
||||
if(instance.getPossibleValueSource(TimeZonePossibleValueSourceMetaDataProvider.NAME) == null)
|
||||
{
|
||||
@ -107,6 +115,36 @@ public class SavedReportsMetaDataProvider
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QWidgetMetaDataInterface defineScheduledReportValuesWidget()
|
||||
{
|
||||
return new QWidgetMetaData()
|
||||
.withName(SCHEDULED_REPORT_VALUES_WIDGET)
|
||||
.withType(WidgetType.DYNAMIC_FORM.getType())
|
||||
.withIsCard(true)
|
||||
.withLabel("Variable Values")
|
||||
.withCodeReference(new QCodeReference(ReportValuesDynamicFormWidgetRenderer.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QWidgetMetaDataInterface defineRenderReportProcessValuesWidget()
|
||||
{
|
||||
return new QWidgetMetaData()
|
||||
.withName(RENDER_REPORT_PROCESS_VALUES_WIDGET)
|
||||
.withType(WidgetType.DYNAMIC_FORM.getType())
|
||||
.withIsCard(false)
|
||||
.withDefaultValue("isEditable", true)
|
||||
.withCodeReference(new QCodeReference(ReportValuesDynamicFormWidgetRenderer.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -277,7 +315,8 @@ public class SavedReportsMetaDataProvider
|
||||
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "savedReportId")))
|
||||
.withSection(new QFieldSection("settings", new QIcon().withName("settings"), Tier.T2, List.of("cronExpression", "cronTimeZoneId", "isActive", "format")))
|
||||
.withSection(new QFieldSection("recipient", new QIcon().withName("email"), Tier.T2, List.of("toAddresses", "subject")))
|
||||
.withSection(new QFieldSection("variableValues", new QIcon().withName("data_object"), Tier.T2, List.of("inputValues")))
|
||||
.withSection(new QFieldSection("variableValues", new QIcon().withName("data_object"), Tier.T2).withWidgetName(SCHEDULED_REPORT_VALUES_WIDGET))
|
||||
.withSection(new QFieldSection("hidden", new QIcon().withName("visibility_off"), Tier.T2, List.of("inputValues")).withIsHidden(true))
|
||||
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")));
|
||||
|
||||
if(backendDetailEnricher != null)
|
||||
|
@ -41,7 +41,7 @@ import com.kingsrook.qqq.backend.core.model.scheduledjobs.ScheduledJob;
|
||||
import com.kingsrook.qqq.backend.core.model.scheduledjobs.ScheduledJobParameter;
|
||||
import com.kingsrook.qqq.backend.core.model.scheduledjobs.ScheduledJobType;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend.StreamedETLWithFrontendProcess;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RenderSavedReportMetaDataProducer;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.savedreports.RunScheduledReportMetaDataProducer;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.tablesync.AbstractTableSyncTransformStep;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.tablesync.TableSyncProcess;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
@ -121,7 +121,7 @@ public class ScheduledReportSyncToScheduledJobProcess extends AbstractTableSyncT
|
||||
scheduledJob.setForeignKeyValue(String.valueOf(scheduledReport.getId()));
|
||||
scheduledJob.setJobParameters(List.of(
|
||||
new ScheduledJobParameter().withKey("processName").withValue(getProcessNameScheduledJobParameter()),
|
||||
new ScheduledJobParameter().withKey("scheduledReportId").withValue(ValueUtils.getValueAsString(scheduledReport.getId()))
|
||||
new ScheduledJobParameter().withKey("recordId").withValue(ValueUtils.getValueAsString(scheduledReport.getId()))
|
||||
));
|
||||
}
|
||||
else
|
||||
@ -160,7 +160,7 @@ public class ScheduledReportSyncToScheduledJobProcess extends AbstractTableSyncT
|
||||
*******************************************************************************/
|
||||
private static String getProcessNameScheduledJobParameter()
|
||||
{
|
||||
return RenderSavedReportMetaDataProducer.NAME;
|
||||
return RunScheduledReportMetaDataProducer.NAME;
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,6 +100,7 @@ public class RenderSavedReportExecuteStep implements BackendStep
|
||||
String storageTableName = runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_STORAGE_TABLE_NAME);
|
||||
ReportFormat reportFormat = ReportFormat.fromString(runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_REPORT_FORMAT));
|
||||
String sendToEmailAddress = runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_EMAIL_ADDRESS);
|
||||
String emailSubject = runBackendStepInput.getValueString(RenderSavedReportMetaDataProducer.FIELD_NAME_EMAIL_SUBJECT);
|
||||
SavedReport savedReport = new SavedReport(runBackendStepInput.getRecords().get(0));
|
||||
String downloadFileBaseName = getDownloadFileBaseName(runBackendStepInput, savedReport);
|
||||
String storageReference = LocalDate.now() + "/" + LocalTime.now().toString().replaceAll(":", "").replaceFirst("\\..*", "") + "/" + UUID.randomUUID() + "/" + downloadFileBaseName + "." + reportFormat.getExtension();
|
||||
@ -108,7 +109,7 @@ public class RenderSavedReportExecuteStep implements BackendStep
|
||||
// if sending an email (or emails), validate the addresses before doing anything so user gets error and can fix //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
List<String> toEmailAddressList = new ArrayList<>();
|
||||
if(sendToEmailAddress != null)
|
||||
if(StringUtils.hasContent(sendToEmailAddress))
|
||||
{
|
||||
toEmailAddressList = validateEmailAddresses(sendToEmailAddress);
|
||||
}
|
||||
@ -146,6 +147,10 @@ public class RenderSavedReportExecuteStep implements BackendStep
|
||||
.withReportFormat(reportFormat)
|
||||
.withReportOutputStream(outputStream));
|
||||
|
||||
//////////////////////////
|
||||
// todo variable-values //
|
||||
//////////////////////////
|
||||
|
||||
Map<String, Serializable> values = runBackendStepInput.getValues();
|
||||
reportInput.setInputValues(values);
|
||||
|
||||
@ -192,7 +197,7 @@ public class RenderSavedReportExecuteStep implements BackendStep
|
||||
.withParty(new Party().withAddress(fromEmailAddress).withRole(EmailPartyRole.FROM))
|
||||
.withParty(new Party().withAddress(replyToEmailAddress).withRole(EmailPartyRole.REPLY_TO))
|
||||
)
|
||||
.withSubject(downloadFileBaseName)
|
||||
.withSubject(StringUtils.hasContent(emailSubject) ? emailSubject : downloadFileBaseName)
|
||||
.withContent(new Content().withContentRole(EmailContentRole.TEXT).withBody("To download your report, open this URL in your browser: " + downloadURL))
|
||||
.withContent(new Content().withContentRole(EmailContentRole.HTML).withBody("Link: <a target=\"_blank\" href=\"" + downloadURL + "\" download>" + downloadFileName + "</a>"))
|
||||
);
|
||||
|
@ -38,6 +38,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMet
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReport;
|
||||
import com.kingsrook.qqq.backend.core.model.savedreports.SavedReportsMetaDataProvider;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -53,6 +54,7 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
|
||||
public static final String FIELD_NAME_STORAGE_TABLE_NAME = "storageTableName";
|
||||
public static final String FIELD_NAME_REPORT_FORMAT = "reportFormat";
|
||||
public static final String FIELD_NAME_EMAIL_ADDRESS = "reportDestinationEmailAddress";
|
||||
public static final String FIELD_NAME_EMAIL_SUBJECT = "emailSubject";
|
||||
|
||||
|
||||
|
||||
@ -67,6 +69,7 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
|
||||
.withLabel("Render Report")
|
||||
.withTableName(SavedReport.TABLE_NAME)
|
||||
.withIcon(new QIcon().withName("print"))
|
||||
|
||||
.addStep(new QBackendStepMetaData()
|
||||
.withName("pre")
|
||||
.withInputData(new QFunctionInputMetaData()
|
||||
@ -76,18 +79,24 @@ public class RenderSavedReportMetaDataProducer implements MetaDataProducerInterf
|
||||
.withField(new QFieldMetaData(FIELD_NAME_STORAGE_TABLE_NAME, QFieldType.STRING))
|
||||
.withRecordListMetaData(new QRecordListMetaData().withTableName(SavedReport.TABLE_NAME)))
|
||||
.withCode(new QCodeReference(RenderSavedReportPreStep.class)))
|
||||
|
||||
.addStep(new QFrontendStepMetaData()
|
||||
.withName("input")
|
||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM))
|
||||
.withFormField(new QFieldMetaData(FIELD_NAME_REPORT_FORMAT, QFieldType.STRING)
|
||||
.withPossibleValueSourceName(ReportFormatPossibleValueEnum.NAME)
|
||||
.withIsRequired(true))
|
||||
.withFormField(new QFieldMetaData(FIELD_NAME_EMAIL_ADDRESS, QFieldType.STRING).withLabel("Send To Email Address")))
|
||||
.withFormField(new QFieldMetaData(FIELD_NAME_EMAIL_ADDRESS, QFieldType.STRING).withLabel("Send To Email Address"))
|
||||
.withFormField(new QFieldMetaData(FIELD_NAME_EMAIL_SUBJECT, QFieldType.STRING).withLabel("Email Subject"))
|
||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.WIDGET)
|
||||
.withValue("widgetName", SavedReportsMetaDataProvider.RENDER_REPORT_PROCESS_VALUES_WIDGET)))
|
||||
|
||||
.addStep(new QBackendStepMetaData()
|
||||
.withName("execute")
|
||||
.withInputData(new QFunctionInputMetaData().withRecordListMetaData(new QRecordListMetaData()
|
||||
.withTableName(SavedReport.TABLE_NAME)))
|
||||
.withCode(new QCodeReference(RenderSavedReportExecuteStep.class)))
|
||||
|
||||
.addStep(new QFrontendStepMetaData()
|
||||
.withName("output")
|
||||
.withComponent(new QFrontendComponentMetaData().withType(QComponentType.DOWNLOAD_FORM)));
|
||||
|
@ -63,17 +63,20 @@ public class RenderSavedReportPreStep implements BackendStep
|
||||
List<QRecord> records = runBackendStepInput.getRecords();
|
||||
if(!CollectionUtils.nullSafeHasContents(records))
|
||||
{
|
||||
throw (new QUserFacingException("No report was selected or found to be rendered."));
|
||||
throw (new QUserFacingException("No report was selected or found."));
|
||||
}
|
||||
|
||||
if(records.size() > 1)
|
||||
{
|
||||
throw (new QUserFacingException("You may only render 1 report at a time."));
|
||||
throw (new QUserFacingException("You may only run 1 report at a time."));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// put the savedReportId in values - this'll get passed into the widget, so it knows //
|
||||
// what report we're working with, and thus what inputs to prompt for //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
SavedReport savedReport = new SavedReport(records.get(0));
|
||||
|
||||
// todo - check for inputs - set up the input screen...
|
||||
runBackendStepOutput.addValue("savedReportId", savedReport.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user