Notifications
Announcements
No record found.
Hey Team,I have a timesheet submission form where I need to add validation while submission. If the project stage for which the employee is filling the timesheet is not equal to "In progress" then display an error msg as "Time cannot be entered for ABCD.EFG project as it is not In progress". Now the Project stage belongs to a different form i.e All projects form and is a string field. So in this case how can I add the validation to my timesheet forma and where should I add it. please help me with this issue. Timesheet form:
Project status from Project Form:
Can't you do something like this?
if (ProjTable::find(timesheet.ProjId).Status != ProjStatus::InProcess)
As you see, you should focus on tables, not forms.
Hey Martin Dráb,
I' m sorry I had mentioned project status but it's not project status that I have to check it is project stage field. The stage field should be "In progress" and yes you are right I should deal with tables. Also this stage field on the form belongs to ProjStageTable
As far as I can say, Status field has "Project stage" label, therefore it is the field you want.
Even if you wanted a different field, the change should be very simple, now when you know how to get the project.
Hey Martin Dráb ,
I got it. Thank you so much!!!.
Great!
Now could you please mark the replies that answered your question? (Use Did this answer your question? > Yes, which is added to every reply.)
I'm a little confused as in which event handler should I call my method in to validate the above condition. According to my client I need to add a validation when timesheet is submitted to check each line for projects which do not have "Project stage" equal to "In progress".
My current code is:
[FormDataSourceEventHandler(formDataSourceStr(TSTimesheetEntry, TSTimesheetLine), FormDataSourceEventType::ValidatedWrite)] public static void TSTimesheetLine_OnValidatedWrite(FormDataSource sender, FormDataSourceEventArgs e) { TSTimesheetLine tsTimesheetLine = sender.cursor() as TSTimesheetLine; TEG_TsTimeSheetFormHandler::Timesheetvalidation(tsTimesheetLine); } public static void Timesheetvalidation(TSTimesheetLine tsTimesheetLine) { ProjTable projTable = ProjTable::find(tsTimesheetLine.ProjId); ProjStatusTypeRule projstatustyperule = ProjStatusTypeRule::find(projTable.Status, projTable.Type, ProjStatusRule::CreateJournal); if(projTable.Status != ProjStatus::InProcess && projstatustyperule.RecId) { error(strFmt("Time cannot be entered against project %1 as it is not In progress", ProjTable::find(tsTimesheetLine.ProjId).Name)); } }
please can you guide me over which form data source event handler to use according to the given requirement?
Your code runs when a timesheet line is being saved. I don't think that it's the same thing as submitting a timesheet. Think about how timesheets are submitted - ask the client if needed (I don't remember that). I guess that TsTimesheetHelper::canSubmitTimesheetToWorkflow() might be the right place for this validation.
By the way, your code doesn't prevent saving anyway. All it does is adding a message to infolog, but it doesn't set the validation as failed. It can be done in the event handler, but it's much easier when using CoC (where you simply return false from validateWrite()).
It's right what you said that my code doesn't prevent saving. So I have made a few changes to my code. Please tell me now is it the right way(i.e. will it prevent it from saving the timesheet).
public static boolean Timesheetvalidation(TSTimesheetLine tsTimesheetLine) { ProjTable projTable = ProjTable::find(tsTimesheetLine.ProjId); ProjStatusTypeRule projstatustyperule = ProjStatusTypeRule::find(projTable.Status, projTable.Type, ProjStatusRule::CreateJournal); if(projTable.Status != ProjStatus::InProcess && projstatustyperule.RecId) { return false; } return true; } [FormDataSourceEventHandler(formDataSourceStr(TSTimesheetEntry, TSTimesheetLine), FormDataSourceEventType::ValidatedWrite)] public static void TSTimesheetLine_OnValidatedWrite(FormDataSource sender, FormDataSourceEventArgs e) { TSTimesheetLine tsTimesheetLine = sender.cursor() as TSTimesheetLine; if(! TETsTimeSheetFormHandler::Timesheetvalidation(tsTimesheetLine)) { error(strFmt("Time cannot be entered against project %1 as it is not In progress", ProjTable::find(tsTimesheetLine.ProjId).Name)); } }
Your code has the same problem as before. You would have to set the return value to "e".
But let's use a better approach: Chain of Command:
public boolean validateWrite() { boolean ok = next validateWrite(); ProjTable projTable = ProjTable::find(tsTimesheetLine.ProjId); if (projTable.Status != ProjStatus::InProcess) { if (ProjStatusTypeRule::find(projTable.Status, projTable.Type, ProjStatusRule::CreateJournal)) { ok = false; } } return ok; }
That's much neater, isn't it?
I've used exist() instead of find(), because you don't need information about any fields and fetching them from database would be a waste of resources. I also run this database query only if Status has the right value (you fetched the data, but then didn't use them in this case).
Thank you so much your answer helped me alot.
Under review
Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.
As AI tools become more common, we’re introducing a Responsible AI Use…
We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…
These are the community rock stars!
Stay up to date on forum activity by subscribing.
Martin Dráb 551 Most Valuable Professional
André Arnaud de Cal... 450 Super User 2025 Season 2
BillurSamdancioglu 278 Most Valuable Professional