Episode 464: Out-of-pocket Expenses Reimbursement Claim (Starter Template)

Monday, January 4, 2016

I'm going to consider "Starter Template" of the 2016 edition.

This time, it is going to be the 3rd of the series, "Out-of-pocket Expenses Claim" in simplicity.


This Workflow will be Started by sending an email with attachment of receipt image taken with Smart phone. (Email Start)

Despite Reimbursement claim for Out-of-pocket Expense is carried out collectively at the end of months in most companies, in this example, it must be done at each time payment occurs. It is a focused to ease the management of the correspondence between the receipt image. After all, it is a business flow to let an employee to make E-mail application at the moment of getting a receipt, such as taxi fare or dining bill. It should be noted, it must be sent from a company email address (Login ID] of the workflow).

(That is not difficult for employees of a company that has introduced a Cloud-based email system like Google Apps.)

By the way, although it might needless to say again, this Workflow is a Business Process in anticipation of "Regulation change (around January 2017) that allowing to discard the original receipt replacing with the receipt image taken with smartphone".

Even though it seems "Premature" to include this into "Starter Template pack" of 2016 edition, yet it is significant to be ahead of the next generation toward the coming era of "Taking picture of Receipt with Smart phone". We should actively operate this Workflow in commissioning, and prepare by organizing various issues on its operation in advance. (Be aware that you are required to store the "original receipts" until the end of 2016. In addition, it is different from the regulation which has been enforced in October 2015, in the point of "Image of Scanned receipt".)

[Out-of-pocket Expenses Claim]

Assuming the actual operation on and after January 2017 a little more concrete, "Signature" on the receipt will be required before taking the picture.

That is, pictures should be taken with "the name of claimer" and "month of claiming" written on the original receipt, in the means of preventing "multiple claiming". It might take time to get used to do so. However, in my fantasy of "business scene of several years after", I think it will have become a very ordinary act.


By the way, this Business Process is configured to automatically set
  • the strings of "Email subject" to the "Title"(Summary),
  • the entire "Email body" to "Remarks".
Also,
  • if there is a numeric in "the first line of the email body", it will set to "Amount of money",
  • if there is a Date (20160101) in the second line of the email body", it will set to "Date of paid",
  • if there is a string of Expense item in the third line of the email body", it will set to "Item"
each of them will be done automatically.
It is assumed that detailed data will be entered at the first Step [1. Claim (appending, altering)], whereas, it is also possible to complete only by email.


For example, claiming for "Expense for which receipt attachment is not required" such as Travel and transportation expenses, you only need to send an email of
> Subject: Karasuma-Oike ⇔ Osaka
> 1540
<Expense item classification in this template>
Train-Bus Taxi Shinkansen-airplane Accommodation Advertising Consumables Taxes and dues Entertainment Conference cost Communications Membership fee Newspaper and book


P.S. 1:
E-mail address to actually send is different for each workflow platform. Please register in the address book by referring to the detailed setting of running [Process Model]. (E.g.: bill.m123.karasuma-oike-000@questetra-bpms.appspotmail.com) In addition, it would be also good to associate with an alias that is more easy to remember, by setting your own email server. (E.g.: bi@example.com)

P.S. 2:
To utilize "Email Start", you need to set "Enable" to your Workflow platform. (Disabled in the default) Please login as a User with System administrative authorization, and go to [System Setting] > [Process Model External Connectivity] > [Message Start Event (email)], then check on the [Enable message start event (email)]. (See for the details HERE: http://www.questetra.com/tour/m3/m318/)


[Out-of-pocket Expenses Claim:"1. Claim (appending, altering) screen]

▼ Setting sample for Script Step "Auto-processing of Claiming by Email" (Server-side Javascript)
//// ▽Claimer identification▽
//// == Retrieving ==
var quserEmail = data.get("16"); // [Mail-From]

//// == Calculating ==
var quser = quserDao.findByEmail(quserEmail);
if ( quser != null ){
  var qgrouplist = qgroupDao.findByQuserAndPosition(quser, false );
  // returns List<QgroupView>
  // my group list as Staff-Member

//// == Updating ==
  if ( qgrouplist.size() != 0 ){
    retVal.put("1", qgrouplist.get(0) ); // ->[Organization of the Claimer]
  } else {
    retVal.put("1", qgroupDao.findById(1) ); // ->[Organization of the Claimer]
  }
  retVal.put("2", quser ); // ->[Claimer]
} 


//// ▽Analysis on Email▽
//// == Retrieving ==
var mailBody = data.get("7") + ""; // [Payment Remarks]

//// == Calculating ==
var array = mailBody.split("\n");
var money = "";
var moneyInt = NaN;
if( array.length >= 1 ){
  money = array[0]; // [Amount paid ]
  moneyInt = parseInt( money.split(',').join('').trim(), 10 ); 
}
var paydate = "";
if( array.length >= 2 ){
  paydate = array[1]; // [Date of payment]eg: 20160101
}
var accountCategory = "";
if( array.length >= 3 ){
  accountCategory = array[2]; // [Expense classification]eg: Conference cost
}


//// == Updating ==
retVal.put("3", data.get("17") ); // [Mail-Datetime]-> [Date Time of Claiming]
if ( ! isNaN(moneyInt) ){
  retVal.put("4", java.math.BigDecimal(moneyInt) );
}
if ( paydate.match( /^[0-9]{8}/ ) ){
  retVal.put("5", java.sql.Date.valueOf(
    paydate.substr(0, 4) + "-" +
    paydate.substr(4, 2) + "-" +
    paydate.substr(6, 2) ) );
}

var accountCategorySelect = new java.util.ArrayList();
if ( accountCategory.search("Train") > -1 ){
  accountCategorySelect.add("Train-Bus");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Bus") > -1 ){
  accountCategorySelect.add("Train-Bus");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Shinkansen") > -1 ){
  accountCategorySelect.add("Shinkansen-Airplane");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Airplane") > -1 ){
  accountCategorySelect.add("Shinkansen-Airplane");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Accommodation") > -1 ){
  accountCategorySelect.add("Accommodation");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Advertising") > -1 ){
  accountCategorySelect.add("Advertising");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Consumables") > -1 ){
  accountCategorySelect.add("Consumables");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Tax") > -1 ){
  accountCategorySelect.add("Taxes and dues");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Gift") > -1 ){
  accountCategorySelect.add("Entertainment");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Entertainment") > -1 ){
  accountCategorySelect.add("Entertainment");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Conference") > -1 ){
  accountCategorySelect.add("Conference");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Membership") > -1 ){
  accountCategorySelect.add("Membership fee");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Newspaper") > -1 ){
  accountCategorySelect.add("Newspaper and Book");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Book") > -1 ){
  accountCategorySelect.add("Newspaper and Book");
  retVal.put("6", accountCategorySelect );
} else if ( accountCategory.search("Magazine") > -1 ){
  accountCategorySelect.add("Newspaper and Book");
  retVal.put("6", accountCategorySelect );
} 

▼ Setting sample for Script Step "Recording before correction (Auto-processing) (Server-side Javascript)
//// == Retrieving == 
var quser = data.get("2"); // [Claimer] 
var selects = data.get("6");  // [Expense classification] 
var selected = selects.get(0).getDisplay() + ""; // Selected value of [Expense classification] 
var money = data.get("4") + "";  // [Amount paid] 
var moneyInt = parseInt( money.split(',').join('').trim(), 10 );  

//// == Updating == 
retVal.put("9", quser.getEmail() ); // [Claimer] -> [Email address of Claimer] 
retVal.put("10", data.get("5") ); // [Date of payment] -> [Accounting month] 
retVal.put("11", selected ); // [Accounts Title] 
retVal.put("12", java.math.BigDecimal(moneyInt) ); // [Settlement amount] 


[Data Items list]


[Free Download]
<Similar Models>
<<Related Article>>

[Japanese Entry (ε’Œζ–‡θ¨˜δΊ‹)]