The "Leave Management" application should be regarded as "Hello World!" of SharePoint !" Fish shredded meat in Sichuan cuisine, and eggs fried rice in Cantonese cuisine... Right?
How to Make simple and practical leave management is always a problem. Full code free without writingCodeIt cannot be implemented. Why should I use SharePoint if I completely write code for implementation? Simple and brisk solutions are what we are pursuing.
Problem
In general, the "Leave Management" SharePoint implementation has the following problems:
- Permission.
Either everyone can see your application form, or you can see it on your own. See the description here. A common solution is either to ignore this problem directly or to filter the data using views, but this is not the fundamental solution.
- Pre-designated approver.
The practical requirement is to dynamically specify the approver. In addition, it is often not approved by the higher-level functional manager first, but by the Project Manager of the project where the project is located. The functional manager generally agrees as long as the project manager has no opinion.
- Annual leave day constraints.
For annual leave, the number of days should be limited and reset every year. The software should automatically check the remaining days of annual leave to avoid the need to manually check the days of annual leave.
- Isolated.
It does not work with other SharePoint applications, such as projects and calendars.
Target
What should the practical "Leave Management" look like?
1. Everyone can apply for leave. As shown in:
2. automatically find the appropriate approver. In the project, the project manager is the approver (go to the project list and find the user corresponding to the "Project Manager" field); otherwise, the project manager is the functional department manager (as shown in ).
3. You cannot apply for annual leave beyond the available days of annual leave.
4. However, once you submit an application, you can only view the application by yourself, the approver, and the Administrator. The approver has the "approval" permission.
Note: SharePoint only allows each list to have 8000 list items with independent permissions. Therefore, the Information Management Policy of the list should be followed to transfer the completed application form to another place.
5. The applicant initiates the leave process.
6. the approver approves the application for leave.
7. the application cannot be modified after the application is approved.
Configure the Information Management Policy to move the items declared as records to other document libraries one month later, so that projects with independent permissions do not exceed SharePoint's limit of 8000 entries per list.
8. If you agree to the annual leave application, it will be automatically deducted from the annual leave of the current year.
9. The calendar of leave is automatically added after the application is approved.
This calendar can be combined with other calendars and displayed on the Intranet portal.
Implementation
To be honest, implementation is not simple. However, through hard work, the solution can be kept clean and brisk, and integrated with the entire architecture system.
1. Everyone can apply for leave.
You can directly disconnect permission inheritance from the "Application Form" list and set the "participate in discussion" permission level for all users.
For more information, see interrupt list or database permission inheritance.
2. automatically find the appropriate approver.
Develop custom fields and add them to the "Application Form" list.
This custom field gets the project manager of the project where the applicant is located or the superior functional manager of the applicant.
Create a Custom FieldArticleCreate a custom SharePoint 2010 field type here.
Obtain the upper-level functional manager of the current user. The userprofilemanager object is required.
Userprofilemanager UPM = New Userprofilemanager (spservicecontext. Current );
If (UPM. userexists (user. loginname ))
{
USERPROFILE u = UPM. getuserprofile (user. loginname );
USERPROFILE [] managers = U. getmanagers ();
If (Managers! = Null )
{
Foreach (USERPROFILE Manager In Managers ){
Spuser u_manager = web. siteusers [Manager [propertyconstants. accountname]. value. tostring ()];
// Other custom code.
}
}
}
3. You cannot apply for annual leave beyond the available days of annual leave.
Here, we need to use SharePoint designer to modify the "newform. aspx" file in the "ticket form" list, and use JavaScript scripts to call the client Object Model of Sharepoint to obtain the remaining annual leave and display it on the interface.
First, we need to introduce several JS libraries: jquery and jquery. spservices. Jquery has been placed in masterpage.
< SharePoint: scriptlink Name = "Sp. js" Runat = "Server" OnDemand = "True" Localizable = "False" />
< Script SRC = "Http://www.cnblogs.com/DocLib/spservices/jquery.SPServices-0.7.1a.min.js" Type = "Text/JavaScript" > </ Script >
Then, you can read the available annual leave days when selecting a false drop-down box. (Why did I use LJ as the variable name? I am also surprised .)
$ ( 'Select [Title = "fake"]' ). Change ( Function (){
VaR Lj = $ ( This ). Val ();
If (Lj = 'Annual leave' ){
Executeordelayuntilscriptloaded (get_annual_leave_days, "Sp. js" );}
Else {
$ ("Nobr: Contains ('Leave days ')" ). Children (). Each ( Function (){
$ ( This Pai.html ( "*" );
});
}
});
The get_annual_leave_days method reads the remaining annual leave days of the current user. The variable naming methods in the following functions are not uniform. This is the mark of these codes from different projects in different periods! Software development is a craft.
"_ X5269 _ x4f59 _ x5e74 _ x5047 _ x59"Is the innername of the field "remaining annual leave days.
VaR _ CTX = Null ;
VaR _ Items =Null ;
Function Get_annual_leave_days (){
_ CTX = New Sp. clientcontext. get_current ();
VaR Web = _ CTX. get_web ();
VaR Lists = web. get_lists ();
VaR List_annual_leave = lists. getbytitle ( "Annual leave summary" );
VaR Currentdate = New Date ();
VaR Year = currentdate. getfullyear ();
VaR Currentuserid = $ (). spservices. spgetcurrentuser ({
Fieldname: "ID" ,
Debug: False
});
VaR Camlquery = New Sp. camlquery ();
VaR Strcaml = "<View>" +
"<Query>" +
"<Where>" +
"<And>" +
"<EQ>" +
"<Fieldref name = '_ x4eba _ x5458 _' lookupid = 'true'/>" +
"<Value type = 'lookup '>" + Currentuserid + "</Value>" +
"</EQ>" +
"<EQ>" +
"<Fieldref name = '_ x5e74 _ x4efd _'/>" +
"<Value type = 'integer'>" + Year + "</Value>" +
"</EQ>" +
"</And>" +
"</Where>" +
"</Query>" +
"</View>" ;
Camlquery. set_viewxml (strcaml );
This . _ Items = list_annual_leave.getitems (camlquery );
_ CTX. Load (_ items );
_Ctx.exe cutequeryasync (function. createdelegate ( This , This . Onsuccess), function. createdelegate ( This , This . Onfail ));
}
Function Onsuccess (sender, argS ){
VaR Listitemenumerator = This . _ Items. getenumerator ();
While (Listitemenumerator. movenext ()){
VaR Olistitem = listitemenumerator. get_current ();
VaR Days = olistitem. get_item ( "_ X5269 _ x4f59 _ x5e74 _ x5047 _ x59" );
$ ( "Nobr: Contains ('Leave days ')" ). Children (). Each ( Function (){
$ ( This Pai.html ( "(Remaining" + Days + "Day )*" );
});
}
}
Function Onfail (sender, argS ){
Alert ('Error when obtaining annual leave days :' + Args. get_message ());
}
For more technical details, refer to the ecmascript object model series. This series is very detailed. In addition, JS scripts call the jscom of SharePoint asynchronously, and the code will be messy when the number of callbacks increases. In this article, jscex is used to enhance the Javascript client Object Model (jsom) of SharePoint 2010) provides a solution to optimize the code for your reference.
4. However, once you submit an application, you can only view the application by yourself, the approver, and the Administrator. The approver has the "approval" permission.
To implement this function, you need to process the create event of the list.
Disconnects existing inherited permissions.
Item. breakroleinheritance (False);
Then, bind the new permissions.
Protected Void Bind_role (splistitem item, spprincipal principal, sproledefinition definition)
{
Try
{
Sproleassignment assignment = New Sproleassignment (principal );
Assignment. roledefinitionbindings. Add (Definition );
Item. roleassignments. Add (assignment );
}
Catch (Exception ex)
{
Throw Ex;
}
}
Bind a role to a user.
Bind_role (item, user, Web. roledefinitions ["Participate in discussion"]);
5. The applicant initiates the leave process.
Use SharePoint designer to create a leave process.
6. the approver approves the application for leave.
You can approve the request. You can use infopath designer to open and beautify the task interface from SPD.
If you need to implement the same permission control for the job as the "Application Form", you can refer to the process for the "Application Form.
7. the application cannot be modified after the application is approved.
You need to develop code to process workflow events and declare the current project as a record.
Spworkflow WF =NewSpworkflow (Web, properties. instanceid );
Splist list = web. Lists [WF. listid];
If(List. Title ="Application Form")
{
Splistitem item = List. Items. getitembyid (WF. Itemid );
Title = item. title;
If(! Records. isrecord (item ))
{
Records. declareitemasrecord (item );
}
}
You also need to configure an Information Management Policy to automatically back up the "Application Form" that has completed the process to the archive database.
8. If you agree to the annual leave application, it will be automatically deducted from the annual leave of the current year.
Similarly, it is processed in the workflow Event code, and the number of days of annual leave is deducted. Perform subtraction. Because the applicant does not have the permission to directly modify the number of days of annual leave (this is of course), you must upgrade the permission to perform the operation. This also means that the dream of "Full sandbox solution" is to be solved on the server farm.
9. The calendar of leave is automatically added after the application is approved.
Process in the SPD workflow.
10. Check in the Code and SPD file (export the backup, or directly stsadm-O backup the website set) and write the deployment operation manual. Finished.
Some people may think, "This is not as fast as writing code !". Er, I am optimistic about the progress estimation made by myself. For more information, see [translation]. Why is it difficult to estimate the progress ?! The trip from San Francisco to Los Angeles explains why simple functions seem to work much more than originally estimated.
Added:
In step 2 of "Implementation", when creating "Information Management Policy", you must first enable the "Content Manager" (content organizer) feature of the website, then go to the management center to configure the sending link for use. For more information, see the link. This undoubtedly adds a brick to the complicated solution. However, this is still "refreshing" and does not cause any pollution to the overall architecture.
Supplement:
In step 1 of "Implementation", "however, once an application is submitted, only the person, approver, and administrator can see it .", You can also create a directory for each project or project. You can only disallow the permission of the Directory and set it to be visible only to the project owner and the approver. The number of items in the list that require independent permissions is "Number of projects" × "Number of people". If the number is less than 8000, try.
Supplement:
Here, we can correct my misunderstanding that the number of items in the list with independent permissions can be set. Application in CAProgramYou can set the number of "list unique permissions threshold". The default value is 50000, not 8000.
List unique Permissions
Threshold