package org.wsper.demo.hr.application; import org.wsper.demo.util; service application manages applications { public interface application { operation confirm create( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate,das.update}; } operation confirm update( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate,das.update}; } operation confirm process( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate,das.update}; } operation confirm offer( application ) : invalidApplication(application) { MEP = Out-In; } operation confirm acceptOffer( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate,das.update}; } operation confirm cancel( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate,das.update}; } operation confirm reject( application ) { MEP = Out-In; } query application[] get(); event newApplication(application) { MEP = Out; application.lifecycle.state is created; } event applicationCanceled(application) { MEP = Out; application.lifecycle.state is canceled; } event offerAccepted(application) { MEP = Out; application.lifecycle.state is accepted; } event offerAccepted(application.offer) { MEP = Out; } fault invalidApplication(application) { } } public interface schedule { operation meeting scheduleInterview( meeting ) : invalidMeetingRequest(meeting) { MEP = Out-In; } fault invalidMeetingNotice(meeting) { } } public interface background { operation background check( background ) : invalidBackground(background), backgroundDoesNotMatch(background) { MEP = Out-In; } fault invalidBackground(background) { } fault backgroundDoesNotMatch(background) { } } public interface employee { operation application processApplicationReview( application ) : invalidApplication(application) { MEP = In-Out; } operation confirm processReview( application ) : invalidReview(application) { MEP = In-Out; requires = {das.validate, das.update}; } operation confirm processOffer( application ) : invalidOffer(application) { MEP = In-Out; requires = {das.validate, das.update}; } operation confirm rejectCandidate( application ) : invalidApplication(application) { MEP = In-Out; requires = {das.validate, das.update}; } operation confirm hireApplicant(application) : invalidCandidate(application) { MEP = Out-In; } fault invalidReview() { } fault invalidCandidate(application) { } fault invalidOffer(application) { } fault invalidApplication(application) { } } private interface das() { operation application create(application) : invalidApplication(application) { MEP = Out-In; } operation application update(application) : invalidApplication(application) { MEP = Out-In; } operation application markDelete(application) : invalidApplication(application) { MEP = Out-In; } operation application archive(application) : invalidApplication(application) { MEP = Out-In; } query application[] get() { MEP = Out-In; } fault invalidApplication(application) { } } implementation { application app << receive(application.create,yes) { //validate & update are invoked automatically; //in case application is invalid, we return to the point //where we are waiting to receive the request retry = true; app.state = created; } reply >> confirm(app) || invalidApplication(app); on (app.lifecycle.state is created) { xor flow { repeat { app << receive(application.update) { retry = true; } reply >> confirm(app) || invalidApplication(app); } until (app.lifecycle.state != created); app << receive(application.process) { app.lifecycle.state is submitted; } reply >> confirm(app) || invalidApplication(app); app << receive(application.cancel) { app.lifecycle.state is canceled; } reply >> confirm(app) || invalidApplication(app); } } on (app.lifecycle.state is submitted) { xor flow { app << receive(application.process) { app.lifecycle.state is reviewed; } reply >> confirm(app) ; app << receive(application.cancel) { app.lifecycle.state is canceled; } reply >> confirm(app) || invalidApplication(app); } } on(app.lifecycle.state is reviewed) { or flow { app << receive(application.reject) { app.lifecycle.state is rejected; } reply >> confirm(app) ; app << receive(application.process) { try { app || backgroundDoesNotMatch(app) << invoke(background.check) >> app; foreach( interviewer in app.reviewer) { app << invoke(scheduler.scheduleInterview) >> app; } confirm(app) << invoke( das.update ) >> app; app.lifecycle.state is interviewScheduled; } catch( backgroundDoesNotMatch(app)) { app.lifecycle.state is rejected; } } reply confirm(app) ; app << receive(application.cancel) { app.lifecycle.state is canceled; } reply >> confirm(app) || invalidApplication(app); } } on(app.lifecycle.state is interviewScheduled) { or flow { forany( interviewer in app.reviewer) { app << receive(employee.processReview(app)) { } reply >> confirm(app) | invalidApplication(app); } app << receive(application.cancel) { app.lifecycle.state is canceled; } reply >> confirm(app) || invalidApplication(app); app << receive(employee.rejectCandidate) { app.lifecycle.state is rejected; } reply >> confirm(app) || invalidApplication(app); app << receive(employee.processOffer) { app << invoke(application.offer) >> app; app.lifecycle.state is offered; } reply >> confirm(app) || invalidApplication(app); } } on(app.lifecycle.state is offered) { xor flow { app << receive(application.acceptOffer) { app.lifecycle.state is accepted; } reply >> confirm(app) || invalidApplication(app); app << receive(application.cancel) { app.lifecycle.state is refused; } reply >> confirm(app) || invalidApplication(app); } } on(app.lifecycle.state is accepted) { confirm(app) << invoke(employee.hireApplicant) >> app.candidate; app.lifecycle.state is hired; } on(app.lifecycle.state in {canceled,rejected,refused}) { terminate(); } } } component _application composes application, schedule { public interface application; public interface employee connector(application.scheduleInterview,schedule.scheduleMeeting); } entity application { element application { string positionPostingId; string positionTitle; enum positionClassification { "Direct Hire", "Referal"}; enum positionSchedule {"Full Time", "Part Time", "Contract"}; element shift { string id; enum name { "Morning","Afternoon","Day","Night"}; time startTime; time endTime; bool exempt; } element supplier { string id; string name; enum role { "Recruiter", "Website"} ; element contact { element telephone, fax : org.un.ccts.phoneNumber; } } //The candidate element is open content open element candidate { string personName; string preferredPositionId; element employmentHistory[] { element employerOrg { string employerOrgName; element employerContactInfo { element locationSummary : location; string organizationName; } } string positionType; string title; string description; date startDate; date endDate; } element educationHistory[] { enum schoolType { "University", "Community College", "Technical University", "High School"} element school { string name; element locationSummary : location; } string degree; boolean graduated; string major; string minor; string description; date startDate; date endDate; } } element reviewer[] { string reviewerId; element interview[] { string location; datetime dateAndTime; } string reviewerName; string review; int score; bool pass; } element offer { float annualSalary; float bonus; float stockGrant; bool retirementPlan; bool pensionPlan; bool medical; element relocationAssistance { bool provided; float amount; } int daysOff; int sickDays; } } machine lifecycle { protected start state created; protected state submitted; protected state reviewed; protected fault state canceled; protected fault state rejected; local state interviewScheduled; protected state offered; protected state accepted; protected fault state refused; protected end state hired; transition(created,submitted); transition(created,canceled); transition(submitted,canceled); transition(submitted,reviewed); transition(reviewed,rejected); transition(reviewed,interviewScheduled); transition(interviewScheduled,rejected); transition(interviewScheduled,offered); transition(offered,refused); transition(offered,hired); } } entity meeting { open element meeting { } }