Sunday, June 30, 2013

Activating Customer/Vendor field on Journal Transactions screen

Hi Guys,

What if our client wants to see Customer or Vendor ID on Journal Transactions screen grid?

There is an existing field, and it is populated from AR or AP modules with the ID.
But it is only available for view, we cannot edit it.
What if we need to track customer in our GL even if original transaction is from GL itself.

There are 2 ways to achieve it:

1. Add a field and make it selector from Business Accounts.

or

2. Activate the existing field so we can use for data entry.

Scenario 1. Adding a field.


It should be 30 characters long, as we will link it to the BAccount (Master table for Customer) BAccountCD field.



Last step is to choose a type of control, which is selector.



Then click Apply To Page. Lets publish the customization first to see added field to our grid.
Customization->Validate and Publish.

Now field is visible, but if I press magnifying glass message pops up:

It happens because we have not specified a Selector View in the field attributes. What I would like to do is to take existing selector from CRM module, Business Accounts screen.



Original Attributes from the Business Account field:


I will copy over PXDimensionSelector to my GL screen field.


I have to add reference to CRM module by using a prefix PX.Objects.CR in front of the DAC field:  PX.Objects.CR.BAccount.BAccountCD
There is one more hint here, we need to remove the second parameter from the selector call, finally will get this:


Apply to Page. Validate-Publish the customization. Result:






Scenario 2. Modifying Existing Customer/Vendor field.

Here we just need to change attributes for existing ReferenceID field and delete its Property.
Let's make attributes Visible and Enabled to be TRUE first.


Then we need to remove PXSegmentMaks property.


Apply to Page. Validate and Publish. Got the result:


All the best,
Sergey.

Saturday, June 29, 2013

Adding Report to AP or AR screens. Unhiding Automation Steps Links.

Hi Everyone,

While adding report to some of the screens might be an easy task, for AR or AP we have only choice of predefined hard coded reports.

So our goal for today to add report to get something like this:




Normally we do it via Automation Steps, but once you get there you will realise, we can't add any other report to the list, but only predefined existing reports.
I wanted to extend this list with newly created user report. So as usual, I added a report to a site map, it appeared in the reports section of the AP Module.

 

And because AR/AP modules are using predefined report list we will have to customize the Report method of the APDataEntryGraph
To do it, I called up Source Code Browser, found this graph, and copied Report method to my customization. Then I added new report to it:

[PXUIField(DisplayName = "Reports", MapEnableRights = PXCacheRights.Select)]
[PXButton]

protected override IEnumerable Report(PXAdapter adapter,
[PXString(8)]
[PXStringList(new string[] { "AP610500", "AP622000", "AP622500", "AP610720"}, new string[] { "AP Edit", "AP Register Detailed", "AP Payment Register", "AP Payment Voucher" })]
string reportID
)
{
APPayment doc = Document.Current;
if (doc!=null)
{
object FinPeriodID;

switch (reportID)
{
case "AP610500":
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["DocType"] = doc.DocType;
parameters["RefNbr"] = doc.RefNbr;
throw new PXReportRequiredException(parameters, reportID, "Report");
}
case "AP622000":
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["PeriodID"] = (FinPeriodID = this.Caches[typeof(APPayment)].GetValueExt<APRegister.finPeriodID>(doc)) is PXFieldState ? (string)((PXFieldState)FinPeriodID).Value : (string)FinPeriodID;
parameters["DocType"] = doc.DocType;
parameters["RefNbr"] = doc.RefNbr;
throw new PXReportRequiredException(parameters, reportID, "Report");
}
case "AP622500":
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["DocType"] = doc.DocType;
parameters["RefNbr"] = doc.RefNbr;
parameters["PeriodID"] = (FinPeriodID = this.Caches[typeof(APPayment)].GetValueExt<APRegister.finPeriodID>(doc)) is PXFieldState ? (string)((PXFieldState)FinPeriodID).Value : (string)FinPeriodID;
throw new PXReportRequiredException(parameters, reportID, "Report");
}
case "AP610720":
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["DocType"] = doc.DocType;
parameters["RefNbr"] = doc.RefNbr;
parameters["PeriodID"] = (FinPeriodID = this.Caches[typeof(APPayment)].GetValueExt<APRegister.finPeriodID>(doc)) is PXFieldState ? (string)((PXFieldState)FinPeriodID).Value : (string)FinPeriodID;
throw new PXReportRequiredException(parameters, reportID, "Report");
}

}
}
return adapter.Get();
}
 
In my case I added report AP610720.
Please note we need to add a button, its right on top of the code, also we have to place this code into our screen, in my case Checks and Payments.

Right after you added this code, option will become enabled to choose in Automation Steps newly added report.

Have a great weekend,

Sergey.

Friday, June 28, 2013

Automation Steps and Definitions Explained. Rapid Copy to Another Company.

Hi Everyone,

Well, I understand recently, thanks to your questions, that Automation Definition is a grey area.
Need to explain about what is what. And how exactly we can copy Automation Steps from one company to another.

A. Automation Steps. They are what we define as work flow. Nodes and actions.
Inside the steps we manually define, which reports or screens need to be used on each specific step of our workflow.


Please note, that Actual automation steps are UNIQUE per system and are stored directly in the database, attached to actual screens. Actual steps are not tied to anything else but to your company and screens.

B. Automation Definitions. They has nothing to do with ACTUAL steps from chapter A.
May be team used bad term. These are not definitions at all. These are just archives, where you can store certain or all steps.


You can see definition has list of screens, which you can include into it.

So most important thing to understand before we move on. Actual steps has nothing to do to Definitions. Definitions are not actually defining anything :) they are simply a storage rooms where we keep "notes" about how we CAN setup our steps.

I give you an example. I was creating Automation Steps for GL Journal Transactions screen. And I want to save my work, just in case someone else will update actual steps on GL Journal screen, I will always have a backup of what I have done.
So, I create Automation Definition, from clause B. And save my steps from the screen into it.
I give it a name - GLBACKUP. So next day I could restore my steps (override someone else steps actually) when needed.

So hope you understand that we have Actual screens, where Actual steps are sitting.
While definitions are just OUR notes about what were the steps at certain point in time.

Lets move on. There are few actions available on Definition screen.

Preload Details.
When you just created a new note, sorry, Definition. You might want to fill it up with all the available steps for all the screens from the system.
That is what this button does. It puts each and every step from all the screens into your Definition.
Like a total Backup :)

After you have done it, you may remove some unnecessary screens, if let say, you create definition for certain module only. Like AP Default should include AP screens right :)

Populate Definition.
Unlike the above total copy option, this one only copies Actual Steps for the screens that you indicated in your definition. Well it takes steps from Actual screens, then places them into your definition. Say after you removed unnecessary screens from definitions, then you can press this button to UPDATE your definition with MOST current steps from the ACTUAL system.

So, don't expect that Definition will auto update! its not actual steps, these are NOTES only. Would love my notebook write for me but... So, don't forget to press this button.

And Of course ALWAYS PRESS SAVE after you depressed either button in this screen.

Activate Definition.
This is kind of RESTORE button. It takes steps from definition and puts them ONTO ACTUAL screens. Well it takes your notes, and turns them into life.

Show Populated.
This button will open a screen, that will show you a content of the Definition. Basically its a textual form of the Definition. So you can copy/paste it anywhere you want.

======================================================================

Now the best part.
How to COPY STEPS from company X to company Y.

1. If we copy steps only for particular screens. Find the Definition, that has all the screens you would like to copy steps from. If you wish to copy ALL steps, create new definition.

2A. If you copy particular screen steps only, press POPULATE DEFINITION button. Then press SAVE.

2B. If you do a total copy. Press PRELOAD DETAILS. Then press SAVE.

3. Press SHOW POPULATED. Now copy into clipboard the content of the pop up screen.

4. Now lets change the company, so open another browser and login to another company - destination for our steps. Below steps will be done on DESTINATION company only.

5A. If you copy particular screen steps, open the similar Definition where screens you want to copy present. Then press POPULATE DEFINITION. Press SAVE.

5B. If you do total copy for all screens. Create new definition. Press PRELOAD DETAILS. Press SAVE.

6. Press SHOW POPULATED button. Select all the text there and press delete or backspace to erase it. DONT PRESS CUT :) as our clipboard will be needed. Just erase. Ok. Now press X button to close this pop up and PRESS SAVE.

Well what we have now is a skeleton of the definition without a content :)

7. Now press SHOW POPULATED again. Pop up screen should be empty this time. PASTE there all the content of the clipboard. Press X button to close the pop up and PRESS SAVE.

8. Now final part - PRESS ACTIVATE DEFINITION. It will copy the content of the definition into real screens, steps will appear.

Enjoy.

All the best,
Sergey.

Wednesday, June 19, 2013

Updating one field from another. Easy Customization.

Hi Guys,

What if we need not just add a field to a database schema, but also to update it from another field.
Based on certain event. Below is the example of customization that takes content of Description field and pushes it into newly added field.

1. Add new field to a screen. I had explained earlier how to do it. This time I add text edit field, 30 characters long.


2. Added Data Event: Field Updated to the Description field, so on the change of content it will get triggered.



3. Under description field I added a code, that takes content of the field and updates UsrDesc2 field:

protected void Batch_Description_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
{
   var row = (Batch)e.Row;
   var Description = row.Description;
      if (Description != null)
      {     
        row.UsrDesc2 = Description;
      }  
}
 
 
4. Last is to add property of the Description field to do commit, so every time we try to update it, it will push data to UsrDesc2 field as well.
 
 
Finally here is what we got:
 
 
I am sure, adding If's and Switches into the code is not a problem :)
 
All the best,
 
Sergey.

Sunday, June 2, 2013

Bundle for Sales. Recognize the Margins by Item. Non Stock Kits.

Hi Everyone,

Got a question from one of the clients: "What if we want to bundle up few items together, then position it as a single set. But internally have to recognize costs and revenue per item."

Answer: This is possible by utilizing Non-Stock Kits. They will behave as a normal Item when we sell it, but when shipping it will explode into components. Revenue will also be recognized by item.

Below are simple steps to configure and process such items on a demo system.

Create a Kit add components to it. Please take note Non Stock option should be checked.




Receive components to Warehouse.





 Set the price for the Kit



 Update it from Pending to become Effective, here we can say for which month our Promo is active.








 Create and Print a Sales Order.




Please note that in Sales order, system shows us a Bundle as a single product.

Now we generate shipment and after confirmation see the inventory part of the transaction, please note servers are serialized therefore displayed separately one by each line in GL transaction.






Now is time to Print the invoice and check the AR part. Which I made to be Deferred Revenue until customer pays us for the goods.



Now lets enter payment and recognize our revenue






In my case I use the same Sales Account for each item, but we can split it based on our company policy, and indicate at the Inventory Item master level.

All the best,
Sergey.