• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 682
  • Last Modified:

Microsoft CRM 4.0 - Fiscal Period Close

I have created a custom entity called Fiscal Periods that contains a closed period date for each Business Unit.  I am trying to prevent an invoice from posting if the closed period date has passed (e.g. end of previous month)

I have tried several approaches but I am hitting a dead end.  What I want is a script that would run in the Invoice entity that checks the closed period date in the Fiscal Periods entity for the Bus Unit of the invoice and pops up an alert telling the user that the period has been closed.

Any help would be great.  Let me know if you need more details.

Thanks
0
apollo7
Asked:
apollo7
  • 26
  • 13
1 Solution
 
Chinmay PatelEnterprise ArchitectCommented:
Hi appolo7,

A Script? really? I thought we were going with Plugins? I still recommend you to use a Plugin.

However, we can check your script as well. Kindly provide your script, if any.

If not then I would need little idea about your fiscal entity or maybe customization.xml for your fiscal entity[if possible.].

Regards,
Chinmay.
0
 
apollo7Author Commented:
Chinmay,

I agree the right idea is a plug-in but I just dont have enough time to develop (not as quick with c# as you are).  I can provide the customization.xml for Fiscal Periods as well as the script I am fumbling around with (not sure how helpful it will be, just testing things)

I will post the customizations.xml shortly

Thanks
0
 
apollo7Author Commented:
Here is the customizations.xml for the Fiscal Periods entity I created.  I will also post the little bit of script I have created but need to clean it up first - kind of a mess

What I am trying to do is:
1. Populate Fiscal Periods with a Business Unit and a month end date
2. When I post an invoice, check Fiscal Periods for the BU of the invoice and stop the user from posting if the posting date is less than the month end date in Fiscal Periods
3. I have tried scripts, workflows but I am just floundering around - need some direction

Thanks
 customizations.xml
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
apollo7Author Commented:
I am trying to work on this myself but am making no progress.  I just have no idea of where to start (using javascript, xml and client side events) to check the invoice post date against the Fiscal Periods business unit and fiscal period close date.

I have mapped Fiscal Periods to fields in the Invoice and the Business Unit entity.  I am going into settings and opening a business unit to assign a fiscal period close date.  I can then map the fiscal period business unit to an invoice but from there I am not seeing how to connect the invoice to the correct fiscal business unit and related close date.

Is this something that can be done with xml in an onload or onsave event?

Thanks
0
 
Chinmay PatelEnterprise ArchitectCommented:
Hi apollo7,

I think the relationships need to be re-worked. Each BU will have multiple Fiscal periods so how it will be determined which period to check against?
How about directly having an N:1 relationship with Invoices and Fiscal Periods? So whatever date is defined on that Fiscal we will stop them from saving the record, if current date is past that date.

Regards,
Chinmay.
0
 
apollo7Author Commented:
Chinmay,

Reworking the relationships is fine - right now I am not tied to any approach.  A N:1 with Invoices and Fiscal Periods makes sense to me to compare Fiscal Close Date and the current date.

Also, got your text (thx) - look forward to seeing the script you are working on.

Thanks for your help.
0
 
apollo7Author Commented:
Chinmay - I have reworked how I update the Month End date - instead of trying to assign at the Invoice level, I add it (manually at this point) to Account for the BU of the invoice I want to create.  In our system, the BU moves from the Account to the order, then invoice, then custom entities we have created (like payments and refunds)

I found that trying to add the BU and month end date directly to the Invoice did not work.  What I really need now is a way to add the BU and related Month End date (from the Fiscal Periods entity) to the Account either onload, onchange, onsave or any other way you think will work.

Any information on how the script would need to work (for example, xml or javascript onload) would be very helpful.  

Any work you have done on a script would be great :)

Thanks and let me know if you need any other customizations.xml or information.
0
 
Chinmay PatelEnterprise ArchitectCommented:
Hi apollo7,

Let's talk today and close this. I have few things for you this time, that might remove me from the scripts part. you will never need me to make scripts for you.

1. Download : http://www.avanadeblog.com/files/avanadecrmservice.zip
2. Check : http://www.avanadeblog.com/xrm/2010/05/a-microsoft-dynamics-crm-javascript-sdk-in-celebration-of-an-amazing-year-.html

remember the name of the CrmService is changed now. It is : new Avanade_CrmService(ORG_UNIQUE_NAME, crmURL);

using the retrieve you can easily retrieve fiscal data. Let me know if you need help.

Regards,
Chinmay.
0
 
apollo7Author Commented:
Thanks - will check these out and get back to you.

0
 
apollo7Author Commented:
Chinmay

Downloaded this and unzipped the files. Also reviewed the web page.

Does the .js file need to be placed on the CRM server or can I run it using my IFD connection?

Thanks
0
 
Chinmay PatelEnterprise ArchitectCommented:
It has to be on CRM Server under ISV folder. And OnLoad of CRM form you will dynamically inject the JS file by using the following code

    function LoadScript(source, scriptName) {
        scriptName = document.createElement('script');
        scriptName.language = 'JavaScript';
        scriptName.src = source;
        document.getElementsByTagName('head')[0].appendChild(scriptName);
        return scriptName;
    }

 var crmService = LoadScript("/ISV/" + ORG_UNIQUE_NAME + "/crmService.js", "crmService");

 crmService.readystatechange = function()
{
if (this.readyState == 'complete' || this.readyState == 'loaded') {
           //Call to CrmService functions   
   }
}

Open in new window


0
 
apollo7Author Commented:
Chinmay,

Placed the CrmService.js under the ISV folder on the CRM server.  I also placed the code you provided above to the onload event of my Account form.

I assume this will allow me to retrieve the date field from Fiscal Periods to my Account date field.

Is there a link or information you can provide to let me know what I need to add below the code above to populate new_monthenddate on my Account form?

Thanks
0
 
Chinmay PatelEnterprise ArchitectCommented:
Hi apollo7,

Alright. Do you have Fiscal period on your Account form? if yes then you will have the id of the fiscal period now you can use the CrmService.Retrieve method. Check the link I sent earlier for example.


   var columns = ["crmxpress_date"];
            var result = crmService.Retrieve("crmxpress_fiscal", crmForm.all.crmxpress_fiscalid.DataValue[0].id, columns);

            alert(result.attributes["crmxpress_date"].value);

Open in new window


You will then use the result to do necessary calculations.

Regards,
Chinmay.
0
 
apollo7Author Commented:
Thanks Chinmay, I am starting to get the picture.

I will bang away on this and let you know what I come up with.
0
 
apollo7Author Commented:
Chinmay,

I added the code you supplied and have a couple questions:

@chinmay: "Do you have Fiscal period on your Account form?"

I have a mapping from my Fiscal Periods to my Account.  The field that is mapped is the Business Unit.  On Fiscal Periods it is called 'new_fiscalperiodsaccountid' and on Account it is called 'new_fiscalperiodbusunitid'.  The new_fiscalperiodbusunitid is on the Account form.

My question is: does new_fiscalperiodbusunitid represent the id of the fiscal period that you refer to above (that I can use for the CrmService.Retrieve method)?

I have included the onload script that I currently have.  The last line is the alert (which I presume will display the Period Closed Date retrieved from the Fiscal Period entity).

I have tried several variations on the second code example you sent and have not been successful.  I have included a question below regarding what goes in each placeholder.

var columns = ["crmxpress_date"];  
var result = crmService.Retrieve("crmxpress_fiscal", crmForm.all.crmxpress_fiscalid.DataValue[0].id, columns);  
alert(result.attributes["crmxpress_date"].value);

crmexpress_date = ?  (monthend date on Account or monthend date on Fiscal Periods)
crmxpress_fiscal = ?
crmxpress_fiscalid = ? (id from Account or id from Fiscal Periods)

Please check over the onLoad code below and let me know why I am not getting an alert when I open an account. (Note: this is one version of the fields I used to replace "crmxpress" fields you used in your example. I have tried both fields from Account and from Fiscal Periods).

Thanks

function LoadScript(source, scriptName) {  
        scriptName = document.createElement('script');  
        scriptName.language = 'JavaScript';  
        scriptName.src = source;  
        document.getElementsByTagName('head')[0].appendChild(scriptName);  
        return scriptName;  
    }  
  
var crmService = LoadScript("/ISV/" + ORG_UNIQUE_NAME + "/crmService.js", "crmService");  
  
 crmService.readystatechange = function()  
{  

if (this.readyState == 'complete' || this.readyState == 'loaded') {  
           //Call to CrmService functions    

var columns = ["new_fiscalperioddate"];  
            var result = crmService.Retrieve("new_fiscalperioddate", crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);  
  
            alert(result.attributes["new_fiscalperioddate"].value);
   }  
}

Open in new window

0
 
Chinmay PatelEnterprise ArchitectCommented:
Yes. Ofcoures you will replace crmxpress with your org prefix[new in this case]. Could you put a debugger; statement and try to debug?

crmService.readystatechange = function()  {
debugger;

And if you are not comfortable with JavaScript debugging then I suggest you put an alert and see if that alert is being fired

crmService.readystatechange = function()  {
alert();

Regards,
Chinmay.
0
 
apollo7Author Commented:
Thanks - putting in the alert now.  I will let you know what the result is.
0
 
apollo7Author Commented:
I put in the alert (with and without text) in the onload.  I placed it at the top of the script and after the script.

I get an error (Microsoft error, not CRM error) - the kind of error where it asks if I want to send the error to Microsoft and I click "Don't Send"

The alert does not popup - the error occurs when I close the form.

I am pasting in the following:

crmService.readystatechange = function()  {
alert();

0
 
Chinmay PatelEnterprise ArchitectCommented:
Hmmm... could you tell me where you have placed your CrmService.JS file and also that alert should be part of the entire script, I removed everything else to keep it short.
0
 
apollo7Author Commented:
Chinmay,

I have included the script as it exists (with the alert) below.  In this example, the alert is at the bottom - I also tried the alert at the top of the script and in the middle right after "//Call to CrmService functions"

The path on the CRM server where I placed the CrmService.JS file is:
C:\Program Files\Microsoft Dynamics CRM\CRMWeb\ISV\

Thanks for your help and for hanging in with me on this.

function LoadScript(source, scriptName) {    
        scriptName = document.createElement('script');    
        scriptName.language = 'JavaScript';    
        scriptName.src = source;    
        document.getElementsByTagName('head')[0].appendChild(scriptName);    
        return scriptName;    
    }    
    
var crmService = LoadScript("/ISV/" + ORG_UNIQUE_NAME + "/crmService.js", "crmService");    
    
 crmService.readystatechange = function()    
{    
  
if (this.readyState == 'complete' || this.readyState == 'loaded') {    
           //Call to CrmService functions      
  
var columns = ["new_fiscalperioddate"];    
            var result = crmService.Retrieve("new_fiscalperioddate", crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);    
    
            alert(result.attributes["new_fiscalperioddate"].value);  
   }    
} 

crmService.readystatechange = function()  { 
alert();

Open in new window

0
 
Chinmay PatelEnterprise ArchitectCommented:
Try this :
function LoadScript(source, scriptName) {

    scriptName = document.createElement('script');
    scriptName.language = 'JavaScript';
    scriptName.src = source;
    document.getElementsByTagName('head')[0].appendChild(scriptName);
    return scriptName;
}
var crmService = LoadScript("/ISV/crmService.js", "crmService");
crmService.readystatechange = function() {
    if (this.readyState == 'complete' || this.readyState == 'loaded') {               //Call to CrmService functions
        var columns = ["new_fiscalperioddate"];
        var result = crmService.Retrieve("new_fiscalperioddate", crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);
        alert(result.attributes["new_fiscalperioddate"].value);
    }
} 

Open in new window

0
 
apollo7Author Commented:
I loaded the script above in the onLoad event.  

After publishing the customizations, I can open Account and not get any errors.

I do not get an alert for alert(result.attributes["new_fiscalperioddate"].value);  so I assume I have some fields not defined properly?  (in the section of the code I included below)

I think I may have not entered the fields from Fiscal Periods or Account correctly.

Thanks
{               
//Call to CrmService functions  
        var columns = ["new_fiscalperioddate"];  
        var result = crmService.Retrieve("new_fiscalperioddate", crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);  
        alert(result.attributes["new_fiscalperioddate"].value);  
    }

Open in new window

0
 
Chinmay PatelEnterprise ArchitectCommented:
You should get an error if this line is being executed.
var result = crmService.Retrieve("new_fiscalperioddate", crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);
It should be this
var result = crmService.Retrieve(<<EntityName>>, crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);

Seems your CrmServices is not being called at all.

Between line 10 and 11, put this
alert('Check Loading');

Open in new window



Between line 11 and 12, put this
alert('Called');

Open in new window


Let me know how it goes.

Regards,
Chinmay.
0
 
apollo7Author Commented:
I made the change to the script you indicated and also put in the alerts.  I have included the revised script below.  

When I open an Account I do not get any errors or alerts.


function LoadScript(source, scriptName) {  
  
    scriptName = document.createElement('script');  
    scriptName.language = 'JavaScript';  
    scriptName.src = source;  
    document.getElementsByTagName('head')[0].appendChild(scriptName);  
    return scriptName;  
}  
var crmService = LoadScript("/ISV/crmService.js", "crmService");  
crmService.readystatechange = function() {  

alert('Check Loading'); 

    if (this.readyState == 'complete' || this.readyState == 'loaded') 
    {               //Call to CrmService functions  

 alert('Called'); 

        var columns = ["new_fiscalperioddate"];  
        var result = crmService.Retrieve(new_fiscalperiods, crmForm.all.new_fiscalperiodbusunitid.DataValue[0].id, columns);
        alert(result.attributes["new_fiscalperioddate"].value);  
    }  
}

Open in new window

0
 
apollo7Author Commented:
Chinmay,

Noticed something today while searching the web and found something that might be relevant to the problem I am having:

http://www.avanadeblog.com/xrm/2010/07/updated-crmservicejs.html

1. There is an updated version (I previously downloaded the old version, have obtained the newer version)

2. In the the blog link above, there are comments regarding problems when using it with IFD.  Our users all use IFD and I have been testing using IFD.  

I have now tried opening the Account from the CRM server but I still do not get the alert popups.

I will try opening the Account from the CRM server once I have added the updated CrmService.JS
0
 
Chinmay PatelEnterprise ArchitectCommented:
Oh!!! I think I did send you the updated one in the very first post, the direct link. Anyways, do let me know if it does not work for you. and Last time we worked it was on OnPremise so was in that impression. Sorry.
0
 
apollo7Author Commented:
Chinmay,

Thanks - downloaded the latest version (not sure why I downloaded the older one??) but still no luck.  

Also I am now testing from the server to avoid the IFD issue but would need to address this if it starts working - it appears the fix would be a change to the authentication method.

0
 
apollo7Author Commented:
Chinmay

I added the code to the onload and changed the CrmAuthenticationToken AuthenticationType from "0" (AD) to "2" SPLA (for IFD) in the CrmService.js file.

Still not getting any alerts, is there anything else I should try to get the CrmService.js working or is there another way to approach this?

Thanks
0
 
apollo7Author Commented:
Chinmay,

Can you give me my other options in terms of getting the Fiscal Close date to compare to the Invoice Post Date and alert the user that they are trying to post to a past period?

I need to have something that can be tested by Friday and I am making no progress on my own.

Can you propose any xml / javascript that could retrieve Fiscal Close date by Fiscal Period business unit using the Invoice onload?  Is there another way to accomplish this (that I can handle) that could be tested by Friday?

Thanks for your help and advice.
0
 
Chinmay PatelEnterprise ArchitectCommented:
Hi apollo7,

Things were crazy on my end, let's do a skype session and fix it.

Regards,
Chinmay.
0
 
apollo7Author Commented:
Chinmay,

Thought you were tied up with something.

When do you want to do the Skype session?

Thanks
0
 
Chinmay PatelEnterprise ArchitectCommented:
hmmm Now?
0
 
apollo7Author Commented:
Works for me - what do I need to do for the Skype session?
0
 
apollo7Author Commented:
Thanks for the information.  I was not aware of this rule. I will refrain from outside of EE activity in the future.

Skype was used for a phone call, so there is not a transcript to post.

0
 
apollo7Author Commented:
I've requested that this question be closed as follows:

Accepted answer: 0 points for apollo7's comment http:/Q_26989752.html#35746951

for the following reason:

Thanks, got this to work.
0
 
apollo7Author Commented:
I did not intend to click my own comment.  Chinmay's comments suggesting using crmservice.js provided the solution I needed.

I do not want this closed with 0 points. I want it attributed to Chinmay with a grade of A and 500 points.

Thanks
0
 
apollo7Author Commented:
Thanks, got this to work.
0
 
apollo7Author Commented:
I was not aware that a full description of the solution was required to award points.  If you look at the 30 plus entries and the work that the expert put into this, I would think that this explains what the solution was.  

But so that this expert is awarded his points, I will describe exactly how his comments led me to a solution.

He first recommended a plugin (which I did not feel comfortable using).  So we worked to get a way that I could call CRM webservices using javascript and xml.  After trying a number of things, he pointed me to CrmService.js which allows you to call webservices using javascript from an onload event.  At first I had trouble getting this to work, but then found syntax errors in addition to the change needed to the authentication type.  This allowed me to call webservices from onload and complete my change.  I highly recommend CrmService.js as a easy way to call webservices and it will make my job much easier in the future.

Let me know if you need additional information regarding the solution.

Thank you.
0
 
Chinmay PatelEnterprise ArchitectCommented:
Super Thanks apollo7. :). BTW I think by recommending CrmService.js, I've essentially removed myself from the equation... you will never need me to write the JS from now on. :)
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 26
  • 13
Tackle projects and never again get stuck behind a technical roadblock.
Join Now