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.
search in acumatica


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.
send emails from Acumatica custom code
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 acumatica
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:
Notification Templates acumatica
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.
Notification Templates acumatica

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.
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:

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.
generate PDF file acumatica
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:
report PDF file acumatica

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.