Friday, 26 May 2017

Filtering Inventory Items by new Field

Hi There,

Have you seen a situation when you want to filter list in the selector by the custom field?
Most probably yes, as that is quite common requirement form many different users.

Here I want to show you how to do that easily based on example with custom field in Inventory Item.

Custom Field
First of all lets add a custom field to inventory item. nothing complicated, just a custom text box.

Showing Field in Selector
By default that field will not be shown in selector, but we can easily add it there by modifying PXUIField Attibute: Visibility = PXUIVisibility.SelectorVisible.

public class InventoryItemExt : PXCacheExtension<PX.Objects.IN.InventoryItem>
{
       #region UsrModuleNumber
       [PXDBString(64)]
       [PXUIField(DisplayName = "Module Number", Visibility=PXUIVisibility.SelectorVisible)]
       public virtual string UsrModuleNumber { get; set; }
       public abstract class usrModuleNumber : IBqlField { }
       #endregion

}

PXUIVisibility.SelectorVisible will make that field visible in all selectors for InventoryItem. But here is important exception - if we have defined columns in selector manually, than this field will not affect anything. But fortunately Selector for aggregate attribute [Inventory()] does not have specified list of selector fields, so Acumatica platform will dynamically generate list of fields from DAC fields where Visibility option is marked as Selector Visible.

Note: after applying that parameter you most probably need to restart whole site, as list of columns is cached in memory for all individual selectors.

Now we can see that field.

Filtering by Custom Field
Now to filter by this field we just need to add in in the list of Fast Filter Fields of selector control.
Find PXSelector -> GridProperties -> FastFilterFields
Fields added here will be automatically added for searching conditions during select to DB.

Final Testing
Now we finally ready to test it. And it works perfectly.


Have a nice customization!

Monday, 22 May 2017

Sending Notification Template from Custom Code

Hi There,

Today want to share with you how to send emails from Acumatica custom code based on Notification Templates.
User scenario is very simple - lets assume we want to send an email from Acumatica that informs about contract, quote expiration or something else. But in the same time we want to keep activity linked to our document for the future reference.
Basically, if we do that manually we need to create new Email activity, fill all details there, attach to entity and send it than,

The obvious way to automate it is usage of Notification Templates.
Notification templates are special type of emails, that can be combined dynamically with data from Acumatica. On screenshot above you can see grayed out text, that represents a name of the data view and field in Acumatica.
((Document.OrderNbr)) - Document here is data view name, OrderNbr is field name in the main DAC of the data view. Hopefully you do not need to know the name if view, as you can easily select these fields from special dialog:
Note: Because of names of the views and fields each notification template is linked with Acumatica screen. so be careful when you using notification from code - only specially designed templates (which are linked with exact screen) can work with entity you going to send.

As soon as we have notification template we can link it with any possible setup screen to use from the code.

Good, now we can actually use it from code. To send notification we are going to use TemplateNotificationGenerator class that actually will do all the dirty work for us. And we just need to provide entity and notification template to it

public static void AddEmailActivity(SOOrder order, Int32 notificationTemplateID)
{
       SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();

       SOBillingContact contact = PXSelect<SOBillingContact,
Where<SOBillingContact.contactID,
Equal<Required<SOBillingContact.contactID>>>>
.Select(graph, order.BillContactID);
Notification notification = PXSelect<Notification, Where<Notification.notificationID,
Equal<Required<Notification.notificationID>>>>
.Select(graph, notificationTemplateID);

       bool sent = false;
       string sError = "Failed to send E-mail.";
       try
       {
              TemplateNotificationGenerator sender = TemplateNotificationGenerator
.Create(order, notification.NotificationID.Value);
              sender.MailAccountId = (notification.NFrom.HasValue)
? notification.NFrom.Value
: PX.Data.EP.MailAccountManager.DefaultMailAccountID;
              sender.RefNoteID = order.NoteID;
              sender.Owner = order.OwnerID;
              sender.To = contact.Email;

              sent |= sender.Send().Any();
       }
       catch (Exception ex)
       {
              sent = false;
              sError = ex.Message;
       }
       if (!sent)
       {
              throw new PXException(sError);
       }

}

Please note that generated Email Activity is linked to exact entity (in my case it is sales order) by Note ID reference. Note ID here is a unique identifier of any record in DB, you can read more about it here.

As the result code above, you will see email activity attached to your order.

Profit!
Also note that email is create, but might not be sent automatically. It depends on how your email processing is configured.

Have a nice notifications ;)

Friday, 19 May 2017

End User Training Approach

Hi There,

Some time ago I had a new great experience for me - doing training for ERP end users.
In was interesting and different form all my previous training experience because of following things:
  • Training was half online half on site. That means that half of the team was in the room and half of the team was online, so I had to find a balance between online and offline communication.
  • End users are focused on process and not on configurations or understanding.
  • End users expect system to be fully ready.
  • We need to keep and ensure focus of onsite and remote users
  • We need to understand knowledge of attendees after training
That was interesting and challenging together. But after that training I have done some important conclusions and ideas that i want to share with you:

Friday, 12 May 2017

Calling Base Actions by example of Generating Time Cards

Hi All,

Just a short article where I can share with you customization that can generate time cards from uploaded time activities.
Customization doing following:
  • Selects the first and the last unreported (where no time-cards assigned) activity from currently selected employee.
  • Goes week by week between first and last activities
  • Create a new time card for every week using TimeCardMaint graph
  • Code also automatically submit time card for approval
  • In case there is unreported activity for already submitted or released time card, code can automatically generate time card correction and submit it again.

Wednesday, 10 May 2017

Get PDF file from Report using Code

Hi Everyone,

In this article I want to show you the way how you can dynamically generate PDF file from any report of Acumatica and attach if to an entity.
I will do that on example of printing AR Invoice Form out of AR Invoice with custom button

In general that task can be split in 4 steps:
  • Defining reports parameters
  • Creation and processing report
  • Get report as PDF file
  • Attach report to entity
Parameters
All reports have different parameter so before writing a code, check what parameters are required in that report. All parameter should be provided as dictionary - name/value.

Report
To work with reports you need a reference to PX.Reports.dll, so make sure you have added it before compiling code below. To work with reports you can use PX.Reports.Controls.Report class there.

PDF
Acumatica generated PDF in unattended mode mostly for sending reports by email, so here we are going to reuse some of the mailing features:
PX.Reports.Mail.Message.GenerateReport(reportNode, ReportProcessor.FilterPdf) - will create a PDF file based on generated report.

Attaching File
In general last step is optional and if you just want send report though email or save it somewhere you can skip it and do whatever you need, but in my case I just want to attach report to entity to not loose it and see result.

By the way you also can send this file for downloading right from memory (without saving to DB) by usage of PXRedirectToFileException with InMemory parameter and saving file to session by FileID

FileInfo file = new FileInfo(Guid.NewGuid(), "report.pdf"null, data);
PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[file.UID.ToString()] = file;
throw new PXRedirectToFileException(file.UID, 0, truetrue);

As a result you have report:

Full code snippet you can find here:

Monday, 8 May 2017

Trial Balance Detailed Generic Inquiry

Hi All,

During my last project I have faces a situation that Acumatica does not give us ability to see Trial Balance detailed by subaccount with denominated currency balance.
That information might be needed because of integration with 3rd party system.

They only things available:
  • Account Summary Inquiry screen - it gives us account balances withing base and denominated currency, but it does not give us information about subaccounts.
  • Trial Balance Detailed report - it gives us detailed information about subaccounts, but there is not balance in denominated currency.
But we have a solution under the cut.

Thursday, 16 March 2017

Launch Multiple Reports with one Exception

Hi All

Today I want to share with you an example how you can launch multiple unrelated reports with one single PXReportRequiredException.

PXReportRequiredException has a helper method - CombineReport(..), where you can pass multiple ReportRequiredExceptions and Acumatica will process them together.

Acumatica will extract each separate report from extension and can open it with following rules:

  • Print all report as a single PDF file - ex.SeparateWindows = false;
  • Open each separate report in a new tab - ex.SeparateWindows = true;

There same rule as with other Pop-ups we can open it with new tab, window or the same window as well - ex.Mode = PXBaseRedirectException.WindowMode.New;

Also note that you should pass report parameters to all reports separately.



Full Code Snippet:

Have a nice development!

Tuesday, 14 March 2017

Copy notes from AP/AR Invoice to GL Batch

Hi All,

Just want to share with you short example of how you can copy Notes and Files from AP/AR invoices directly to General Ledger Batch.

For archive it we are doing following steps:
  1. Define extension for (AP/AR)ReleaseProcess graph. Exactly this graph is responsible for releasing operation.
  2. On the Initialize method we are trying to subscribe on InstanceCreated event for JournalEntry graph, where we can catch exact graph instance used for saving batch. 
    1. InstanceCreated even is very useful for customization purposes. Here you can subscribe events and pass parameters between different graphs.
  3. Subscribe to ARRegister_BatchNbr_FieldUpdated to catch moment when batch is saved and linked to our invoice.
  4. Using graph and batch number we can find exact batch.
  5. Using PXNoteAttribute.CopyNoteAndFiles we can copy notes and files from one object to another.
Full Code Snippet:

Have a nice development!

Monday, 27 February 2017

Hide Action from Datasource

Hi All,

When you new create action in the PXGraphExtensions, it is automatically getting visible in in the data-source actions bar, even if you have not customized ASPX.
public class JournalEntry_Extension:PXGraphExtension<JournalEntry>
{
    public PXAction<PX.Objects.GL.BatchNewAction;  
    [PXButton(CommitChanges true)]
    [PXUIField(DisplayName "New Action")]
    protected void newAction()
    {
    }
}
It looks like here:

But if you want to hide that button, it is very easy to do it with Customization Browser. Just drag and drop button to the data-source in page editor:

Than just set the Name to your action name and Visible to false.

That is all. Now Action is not visible anymore.

Have a nice development!

Thursday, 23 February 2017

Customization and Source Control

Hi All,

I'm sure you know that Acumatica customization project is just a big XML file that has some links on external files. You can easily export ZIP archive with all linked files and store it on the file system. Unfortunately is not really good for tracking changes.

But do you know that Acumatica has very easy-to-use integration with source control where you can export project as set of text files? Let me show you how to use it:

As I said customization project is big zip file, but it can be split by items, that you can see using File -Edit Project Items menu:

All of these items we can export to some folder as a separate files, so it will be much easier to store them and track changes.
To export them click on Source Control -> Save To Folder