Custom batch to import bank group with progress bar. #SADA =>A_BankGroupImport
class A_BankGroupImport extends RunBaseBatch
{
CommaTextIO importFile;
Counter progressCounter;
Counter icounter;
boolean processOK;
DialogRunbase dialog;
DialogField dialogFilename;
Filename filename;
#define.CurrentVersion(1)
#localmacro.CurrentList
filename
#endmacro
#isoCountryRegionCodes
#file
#macrolib.AviFiles
}
/// <summary>
/// Returns false.
/// </summary>
/// <returns>
/// Always returns false.
/// </returns>
/// <remarks>
/// This method must be in this class because it is called from the <c>dialogRunbase</c> class.
/// </remarks>
public boolean canGoBatch()
{
return false;
}
/// <summary>
/// Determines whether the class is shown in the list of the <c>Journal</c> types.
/// </summary>
/// <returns>
/// true if the class is shown in the list of <c>Journal</c> types; otherwise, false.
/// </returns>
/// <remarks>
/// A class that can be used in a batch journal is a class where the same parameters can be used
/// repeatedly. The dialog can be shown and the parameters can be changed but parameters of some
/// classes might build on data that is only valid for a short time. Not all classes can be run two
/// times with the same parameters. If the <c>canGoBatch</c> method returns false, this method will not
/// have any effect.
/// </remarks>
protected boolean canGoBatchJournal()
{
return true;
}
/// <summary>
/// Returns a class that contains the methods that are described by the <c>RunBaseDialogable</c>
/// interface.
/// </summary>
/// <returns>
/// A class that contains the methods that are described by the <c>RunBaseDialogable</c> interface.
/// </returns>
/// <remarks>
/// A dialog can be either built by using the <c>Dialog</c> class or by using a class that is created
/// in the Application Object Tree (AOT).
/// </remarks>
public Object dialog()
{
dialog = new DialogRunbase("@RNS260", this);
dialogFilename = dialog.addFieldValue(extendedTypeStr(FilenameOpen), filename, "@SYS16423");
dialog.allowUpdateOnSelectCtrl(true);
this.dialogSelectCtrl();
return dialog;
}
/// <summary>
/// When using the <c>dialog</c> class for dialog, this method is called whenever a control is selected.
/// </summary>
/// <remarks>
/// To enable this callback, the <c>allowUpdateOnSelectCtrl</c> method must have been set to true.
/// </remarks>
public void dialogSelectCtrl()
{
super();
}
public Filename fileName(Filename _filename = filename)
{
;
filename = _filename;
return filename;
}
public boolean getFromDialog()
{
filename = dialogFilename.value();
return super();
}
protected void openFile(str _fileOpen = #io_read)
{
;
importFile = new CommaTextIO(filename, _fileOpen, 1252);
if (! importFile)
{
throw error(strFmt("@SYS18678", filename));
}
}
public container pack()
{
return [#CurrentVersion,#CurrentList];
}
/// <summary>
/// Update the progress.
/// </summary>
/// <param name="_incCount">
/// Indicates if the count of imported records should be updated.
/// </param>
protected void progressUpdate(boolean _incCount = 1)
{
this.progressUpdateInt(_incCount ? 1 : 0);
}
/// <summary>
/// Update the progress.
/// </summary>
/// <param name="_incCount">
/// The number of records imported.
/// </param>
protected void progressUpdateInt(int _incCount = 1)
{
progressCounter += _incCount;
progress.setCount(progressCounter);
progress.setText(strFmt("@SYS52615",progressCounter));
}
protected void readFile()
{
BankGroup bankGroup;
LogisticsPostalAddress postalAddress;
LogisticsAddressZipCode zipCode;
container readCon;
int totalRecords = 0; //Counter for total records
int counter = 0; //Counter for number of records processed
str 5 abi, cab;
LogisticsAddressCity city;
LogisticsAddressZipCodeId zipCodeId;
LogisticsAddressStreet street;
LogisticsAddressCountyId county;
Description50 branchName;
Name bankName;
#characters
setprefix("@RNS260");
info("@SYS4128" + ' ' + filename);
this.openFile();
importFile.inRecordDelimiter(#delimiterEnter);
importFile.inFieldDelimiter(#semicolon);
readcon = importFile.read();
while ((importFile.status() == IO_Status::Ok))
{
this.progressUpdateInt();
readcon = importFile.read();
totalRecords++;
abi = conpeek(readcon, 1);
cab = conpeek(readcon, 2);
bankName = conpeek(readcon, 3);
branchName = conpeek(readcon, 4);
street = conpeek(readcon, 5);
city = conpeek(readcon, 6);
zipCodeId = conpeek(readcon, 7);
county = conpeek(readcon, 8);
if (strLen(strFmt("%1%2",abi,cab)) != 10)
continue;
if (BankGroup::exist(strFmt("%1%2",abi,cab)))
{
bankGroup = BankGroup::find(strFmt("%1%2",abi,cab),true);
if (!bankGroup.validateDelete())
continue;
bankGroup.delete();
}
bankGroup.clear();
bankGroup.initValue();
bankGroup.BankGroupId = strFmt("%1%2",abi,cab);
bankGroup.RegistrationNum = bankGroup.BankGroupId;
bankGroup.Name = bankName;
bankGroup.BranchName = branchName;
bankGroup.CompanyPaymId = abi;
bankGroup.CurrencyCode = CompanyInfo::standardCurrency();
bankGroup.Location = LogisticsLocation::create(bankName).RecId;
postalAddress.initValue();
postalAddress.City = city;
postalAddress.Street = street;
postalAddress.CountryRegionId = CompanyInfo::find().postalAddress().CountryRegionId;
postalAddress.County = county;
postalAddress.ZipCode = zipCodeId;
postalAddress.Location = bankGroup.Location;
zipCode = LogisticsAddressZipCode::findBestMatch(postalAddress, false);
if (zipCode)
{
postalAddress.State = zipCode.State;
postalAddress.County = zipCode.County;
postalAddress.CountryRegionId = zipCode.CountryRegionId;
}
else
{
// No exact match - try to fill in empty fields based on not exact matches.
zipCode = LogisticsAddressZipCode::findBestMatch(postalAddress);
if (!postalAddress.City && zipCode)
{
postalAddress.City = zipCode.City;
}
if (!postalAddress.State && zipCode)
{
postalAddress.State = zipCode.State;
}
if (!postalAddress.County && zipCode)
{
postalAddress.County = zipCode.County;
}
if (!postalAddress.CountryRegionId && zipCode)
{
postalAddress.CountryRegionId = zipCode.CountryRegionId;
}
}
postalAddress.Address = LogisticsPostalAddress::formatAddress(postalAddress.Street, postalAddress.zipCode, postalAddress.city, postalAddress.countryRegionId, postalAddress.state, postalAddress.county);
if (!postalAddress.validateWrite())
continue;
postalAddress.insert();
if (!bankGroup.validateWrite())
continue;
bankGroup.insert();
counter++;
}
info(strfmt("@SYS105159",totalRecords,totalRecords - counter));
processOK = true;
}
public void run()
{
#OCCRetryCount
if (! this.validate())
throw error("");
try
{
startLengthyOperation();
if (! progress)
{
progress = RunbaseProgress::construct(1, null);
}
progress.setCaption("@RNS260");
progress.setTotal(icounter);
progress.setAnimation(#AviFilemove);
progress.updateInterval(1);
ttsbegin;
progressCounter = 0;
this.readFile();
if (processOK)
{
ttscommit;
}
else
{
ttsabort;
}
}
catch (Exception::Deadlock)
{
retry;
}
catch (Exception::UpdateConflict)
{
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::UpdateConflict;
}
}
endLengthyOperation();
}
/// <summary>
/// Determines whether the batch task is run on the server or on a client.
/// </summary>
/// <returns>
/// Always returns false.
/// </returns>
/// <remarks>
/// Your classes that extend this class must override the <c>runsImpersonated</c> method and return
/// <c>false</c>, if you want those tasks to run on a client.
/// </remarks>
public boolean runsImpersonated()
{
return true;
}
public boolean unpack(container _packedClass)
{
Integer version = conPeek(_packedClass,1);
switch (version)
{
case #CurrentVersion:
[version,#CurrentList] = _packedClass;
break;
default :
return false;
}
return true;
}
public boolean validate(Object _calledFrom = null)
{
boolean ret = true;
;
if (! filename)
{
ret = checkFailed("@SYS18624");
}
if (! WinAPI::fileExists(filename))
{
ret = checkFailed(strFmt("@SYS26666", filename));
}
return ret;
}
/// <summary>
/// Creates an instance of the <c>AddressZipCodeImport</c> class.
/// </summary>
/// <param name="_addressZipCodeImportCountryRegion">
/// The member of the <c>LogisticsAddrZipCodeImportCountryRegion</c> class.
/// </param>
/// <returns>
/// A new instance of an <c>AddressZipCodeImport</c> class.
/// </returns>
/// <exception cref="M:Exception::Error">
/// The call of the class is incorrect.
/// </exception>
public static A_BankGroupImport construct()
{
A_BankGroupImport bankGroupImport;
bankGroupImport = new A_BankGroupImport();
return bankGroupImport;
}
client server public static ClassDescription description()
{
return ("@RNS260");
}
public static void main(Args args)
{
A_BankGroupImport bankGroupImport;
;
bankGroupImport = A_BankGroupImport::construct();
if (bankGroupImport.prompt())
{
bankGroupImport.run();
}
}