For this project the end result was for there to be 2 error reports sent to an error file at as well as a listing of account summary information printed out. While i can get a majority of the account information printed out such as Balance before transaction and transaction to the account or if there were insufficient funds for the transaction, that's all that will print out as it should be. I'm receiving no errors or exceptions so i'm in all honesty not too sure where the issue at hand may be. I was hoping a second pair of eyes on my code could possibly point out where my issue may be, below is my code of the Account.java, CheckingAccount.java CreditCard.java and lastly D4.java which contains the main method.
Account.java
public class Account {
protected String accountNo, institution, name;
protected double balance;
public Account (String accountNo, String name, String institution, double balance) {
this.name = name;
this.accountNo = accountNo;
this.balance = balance;
this.institution = institution;
}
public String getAccount() {
return accountNo;
}
public boolean debitAccount(double amt) {
return false;
}
public boolean creditAccount(double amt) {
return false;
}
}
CheckingAccount.java
public class CheckingAccount extends Account {
public CheckingAccount(String acctNo, String name, String inst, double balance) {
super(acctNo, name, inst, balance);
this.name = name;
this.accountNo = acctNo;
this.balance = balance;
this.institution = institution;
}
public double getBalance()
{
return balance;
}
public boolean debitAccount(double amt) {
balance += amt;
return false;
}
public boolean creditAccount(double amt) {
balance -= amt;
return false;
}
}
CreditCard.java
public class CreditCard extends Account {
private double creditLimit;
private double availableCredit;
public CreditCard(String acctNo, String name, String inst, double limit, double balance) {
super(acctNo, name, inst, 0);
this.creditLimit = creditLimit;
this.availableCredit = availableCredit;
this.balance = balance;
}
public boolean debitAccount(double amt) {
balance -= amt;
return false;
}
public double getCreditLimit(){
return creditLimit;
}
public double getBalance()
{
return balance;
}
public boolean creditAccount(double amt) {
balance += amt;
return false;
}
}
D4.java
import java.io.*;
import java.util.*;
public class D4 {
public static void main(String[] args) throws FileNotFoundException
{
Boolean valid;
String transactionFile = args[0];
String theaccount, transaction;
File transactions = new File(transactionFile);
Scanner infile = new Scanner(transactions);
File errorFile = new File(args[1]);
PrintWriter error = new PrintWriter(errorFile);
Vector<Account> account = new Vector<Account>();
while(infile.hasNext())
{
transaction = infile.nextLine();
valid = performTrans(account, transaction, error, errorFile);
}
}
private static Account findAccount(Vector<Account> a, String acctNo) {
for(int index = 0; index < a.size(); index ++)
{
if (a.elementAt(index).getAccount().equals(acctNo))
{
return a.elementAt(index);
}
}
return null;
}
private static boolean Checkingacct(Account a)
{
if(a instanceof CheckingAccount)
{
return true;
}
else
{
return false;
}
}
private static boolean Creditcrd(Account a)
{
if(a instanceof CreditCard)
{
return true;
}
else
{
return false;
}
}
private static String errorLog(Vector<Account> a, String transaction)
{
String[] trans = transaction.split(":");
String error;
if(findAccount(a, trans[1])==null)
{
error = ("Invalid account: " + transaction);
System.out.println(error);
return error;
}
else
{
Account acc = findAccount(a, trans[1]);
if( trans[0] == "debit")
{
error = ("Transaction denied: " + transaction);
System.out.println(error);
return error;
}
else
{
return null;
}
}
}
private static boolean performTrans(Vector<Account> account, String transaction, PrintWriter log, File errorFile)
{
String[] pieces = transaction.split(":");
String trans = pieces[0];
System.out.println(pieces);
if(trans.equals("create"))
{
if( pieces[1].equals("checking"))
{
CheckingAccount checking = new CheckingAccount(pieces[2], pieces[3], pieces[4], Double.parseDouble(pieces[5]));
account.add(checking);
return true;
}
else if (pieces[1].equals("credit"))
{
CreditCard creditCard = new CreditCard(pieces[2], pieces[3], pieces[4], 0, Double.parseDouble(pieces[5]));
account.add(creditCard);
return true;
}
else
{
System.out.println("not sure what to put here");
return false;
}
}
else if(trans.equals("debit"))
{
if(findAccount(account, pieces[1]) == null)
{
return false;
}
else
{
Account a = findAccount(account, pieces[1]);
double amount = Double.parseDouble(pieces[2]);
if(Checkingacct(a) == true)
{
CheckingAccount checking = (CheckingAccount) a;
System.out.println("Balance before transaction: " + checking.getBalance());
checking.creditAccount(amount);
System.out.println("Transaction to account: " + amount);
System.out.println("Balance after transaction: " + checking.getBalance() + "\n");
return true;
}
else if(Creditcrd(a) == true)
{
CreditCard creditCard = (CreditCard) a;
System.out.println("Balance before transaction: " + creditCard.getBalance());
System.out.println("Transaction to account: " + amount);
if(amount + creditCard.getBalance() > creditCard.getCreditLimit())
{
System.out.println("Insufficient funds for transaction");
return false;
}
else
{
creditCard.creditAccount(amount);
return true;
}
}
}
}
else if(trans.equals("credit"))
{
if(findAccount(account, pieces[1]) == null)
{
System.out.println("Print Error Message");
return false;
}
else
{
Account a = findAccount(account, pieces[1]);
double amount = Double.parseDouble(pieces[2]);
if(Creditcrd(a) == true)
{
CheckingAccount checking = (CheckingAccount) a;
System.out.println("Balance before transaction: " + checking.getBalance());
checking.debitAccount(amount);
System.out.println("Transaction to account: " + amount);
System.out.println("Balance after transaction: " + checking.getBalance() + "\n");
return true;
}
else if(Creditcrd(a) == true)
{
CreditCard creditCard = (CreditCard) a;
System.out.println(creditCard.getBalance());
return true;
}
}
}
else if(trans.equals("report"))
{
return true;
}
return false;
}
}
The text file im attempting to read from is called D4.txt and the information inside of it is
create:checking:10-3784665:Chase:Joe Holder:2000
create:credit:1234567898765432:First Card:Bob Badger:4000
create:checking:11-3478645:Dime:Melissa Martin:1000
report
debit:10-3784665:523.67
debit:1234567898765432:3500
credit:10-3784665:50
credit:11-3478645:30
debit:10-839723:200
debit:1234567898765432:600
report
The two errors im supposed to be able to print out and see in the errorFile.txt or whatever you choose to call it is and is where the main problem is as this information for some reason is not being processed and printed onto the outputfle.
Invalid account: debit:10839723:200
Transaction denied: debit:1234567898765432:600
The information printed to the console is supposed to look like
Account Summary:
Checking account #103784665
Bank: Chase
Name on account: Joe Holder
Balance: 1526.33
Credit Account #1234567898765432
Bank: First Card
Issued to: Bob Badger
Credit Limit: 4000
Balance: 3500.00
Available credit: 500.00
Checking account #113478645
Bank: Dime
Name on account: Melissa Martin
Balance: 1030.00
End account summary.
But this is also a part of the issue as currently when i run the code whats being printed out to the console is
run D4 d4.txt errorFile.txt
[Ljava.lang.String;#1d540a51
[Ljava.lang.String;#b31c562
[Ljava.lang.String;#3db12bab
[Ljava.lang.String;#4ff0c6b8
[Ljava.lang.String;#4d40d320
Balance before transaction: 2000.0
Transaction to account: 523.67
Balance after transaction: 1476.33
[Ljava.lang.String;#2c9cc42e
Balance before transaction: 4000.0
Transaction to account: 3500.0
Insufficient funds for transaction
[Ljava.lang.String;#2bb07c61
[Ljava.lang.String;#483b594b
[Ljava.lang.String;#31470572
[Ljava.lang.String;#20aedee
Balance before transaction: 4000.0
Transaction to account: 600.0
Insufficient funds for transaction
[Ljava.lang.String;#2ea4aa4d
I know this is a lot of information to sort through and i just want to thank anyone and everyone in advance for your help and hope its something simple that im just overlooking!
Related
I am getting an Error in the IDE:
UnimplementedFeatureError: Copying of type struct ChatGroups.Message memory[] memory to storage not yet supported.
And I really don't know what to do with everything that I made ( It's commented in French )
There is the full code, and I really tried to find how can I implement what do I want with a different approach if someone could help for that and if I can preserv this code.
Thanks a lot for the people that are going to help !
pragma solidity ^0.6.12;
contract ChatGroups {
struct Group {
string name;
address[] members;
Message[] messages;
}
struct Message {
uint id;
string text;
address author;
bool deleted;
}
Group[] groups;
address[] users;
event GroupCreated(uint groupId, string groupName);
event MessagePublished(uint groupId, uint messageId, string messageText, address messageAuthor);
event MessageDeleted(uint groupId, uint messageId);
event UserAddedToGroup(uint groupId, address user);
event UserRemovedFromGroup(uint groupId, address user);
function createGroup(string memory groupName) public {
require(isUser(msg.sender), "Unauthorized user");
groups.push(Group({
name: groupName,
members: new address[](1),
messages: new Message[](0)
}));
groups[groups.length - 1].members[0] = msg.sender;
emit GroupCreated(groups.length, groupName);
}
function publishMessage(uint groupId, string memory messageText) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isMember(group, msg.sender), "Unauthorized user");
group.messages.push(Message({
id: group.messages.length + 1,
text: messageText,
author: msg.sender,
deleted: false
}));
emit MessagePublished(groupId, group.messages[group.messages.length - 1].id, messageText, msg.sender);
}
function deleteMessage(uint groupId, uint messageId) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isMember(group, msg.sender) && group.messages[messageId - 1].author == msg.sender, "Unauthorized user");
group.messages[messageId - 1].deleted = true;
emit MessageDeleted(groupId, messageId);
}
function removeUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(isMember(group, user), "Unauthorized user");
uint index = getMemberIndex(group, user);
group.members[index] = group.members[group.members.length - 1];
group.members.length--;
emit UserRemovedFromGroup(groupId, user);
}
function addUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(!isMember(group, user), "User already member of group");
group.members.push(user);
emit UserAddedToGroup(groupId, user);
}
function isUser(address user) private view returns (bool) {
for (uint i = 0; i < users.length; i++) {
if (users[i] == user) {
return true;
}
}
return false;
}
function isMember(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function isAdmin(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function getMemberIndex(Group storage group, address user) private view returns (uint) {
for (uint i = 0; i < group.members.length; i++) {
if (group.members[i] == user) {
return i;
}
}
return group.members.length;
}
}
While compiling it, I'm getting this error, and I really have no solutions in my mind...
In your smart contract, there are some issues related to your logic in different operation. Thought, the main issue that you shared in this thread refers to a struct inside another struct (in this case, I say about Message[] struct).
The error say that you cannot pass a struct array initializing at runtime because this object is memorized inside storage space.
In details, you have to change the implementation for valorized attribute related to group struct (method: createGroup(string memory groupName)). The change to make is:
Group storage group = groups.push();
group.name = groupName;
group.members = new address[](1);
group.members[0] = msg.sender;
In this way, you create before a space into storage memory array, and then you fill it with the variable (if them has been valorized). At this point, you have to change the method called publishMessage() changing this line:
Group storage group = groups[groupId - 1];
with:
Group storage group = groups[groupId];
This same improvement you have to do in: deleteMessage() and addUser().
In following lines, I put your smart contract with my changes:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
contract ChatGroups {
struct Group {
string name;
address[] members;
Message[] messages;
}
struct Message {
uint id;
string text;
address author;
bool deleted;
}
Group[] groups;
address[] users;
event GroupCreated(uint groupId, string groupName);
event MessagePublished(uint groupId, uint messageId, string messageText, address messageAuthor);
event MessageDeleted(uint groupId, uint messageId);
event UserAddedToGroup(uint groupId, address user);
event UserRemovedFromGroup(uint groupId, address user);
function createGroup(string memory groupName) public {
require(isUser(msg.sender), "Unauthorized user");
// NOTE: I changed at this point your original implementation
Group storage group = groups.push();
group.name = groupName;
group.members = new address[](1);
group.members[0] = msg.sender;
emit GroupCreated(groups.length, groupName);
}
function publishMessage(uint groupId, string memory messageText) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isMember(group, msg.sender), "Unauthorized user");
group.messages.push(Message({
id: group.messages.length + 1,
text: messageText,
author: msg.sender,
deleted: false
}));
emit MessagePublished(groupId, group.messages[group.messages.length - 1].id, messageText, msg.sender);
}
function deleteMessage(uint groupId, uint messageId) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isMember(group, msg.sender) && group.messages[messageId - 1].author == msg.sender, "Unauthorized user");
group.messages[messageId - 1].deleted = true;
emit MessageDeleted(groupId, messageId);
}
function removeUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId - 1];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(isMember(group, user), "Unauthorized user");
uint index = getMemberIndex(group, user);
group.members[index] = group.members[group.members.length - 1];
// NOTE: The attribute length() is only read-only, you cannot modify or handle the length of array using in this way!
group.members.length;
emit UserRemovedFromGroup(groupId, user);
}
function addUser(uint groupId, address user) public {
require(isUser(msg.sender), "Unauthorized user");
Group storage group = groups[groupId];
require(isAdmin(group, msg.sender), "Unauthorized user");
require(!isMember(group, user), "User already member of group");
group.members.push(user);
emit UserAddedToGroup(groupId, user);
}
function isUser(address user) private view returns (bool) {
for (uint i = 0; i < users.length; i++) {
if (users[i] == user) {
return true;
}
}
return false;
}
function isMember(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function isAdmin(Group memory group, address user) public view returns (bool) {
if (group.members[0] == user) {
return true;
}
for (uint i = 1; i < group.members.length; i++) {
if (group.members[i] == user) {
return true;
}
}
return false;
}
function getMemberIndex(Group storage group, address user) private view returns (uint) {
for (uint i = 0; i < group.members.length; i++) {
if (group.members[i] == user) {
return i;
}
}
return group.members.length;
}
}
P.S.: I think that you have to integrate users before call the various method inside users array. Although, the smart contract logic give you this error: "Unauthorized user". I think you should think better about this aspect
I am trying to undo the automatic total amount round in A/R RESERVEI NVOICE b1 on an add on extension.
The error throws after:
txtDocTotalAfterDiscountFreightCharge.Active = true;
txtDocTotalAfterDiscountFreightCharge.String = total.ToString();
with this error: Only if I undo the round on A/R RESERVEI NVOICE.
A/R invoice - document total, field cannot be updated (odbc -1029)
for A/R INVOICE it is working well.
[BasicSapForm(Consts.FORM_RESERVE_INVOICE)]
[BasicSapForm(Consts.FORM_INVOICE)]
class OinvListener : SapDocumentsForm
{
public OinvListener(string uniqueId, object extraInfo)
: base(uniqueId, extraInfo)
{
}
public override void Init()
{
}
[BasicSapEvent(SAPbouiCOM.BoEventTypes.et_FORM_DATA_UPDATE, "", true)]
[BasicSapEvent(SAPbouiCOM.BoEventTypes.et_FORM_DATA_ADD, "", true)]
private bool BeforeFormAdd(SAPbouiCOM.BusinessObjectInfo pVal)
{
if (MO_ModuleManager.Common.B1Starter.userModules.ContainsKey(ModuleInfo.Code))
{
if (MO_ModuleManager.Common.B1Starter.userModules.ContainsKey(ModuleInfo.SubCode2))
{
di.BusinessPartners diBp = SapUtils.GetDiObjectByFormTypeAndKey (Consts.FORM_BP, txtCardCode.String) as di.BusinessPartners;
if (diBp.UserFields.Fields.Item("U_RoundAum").Value.ToString() == "N")
{
double total = TypeUtils.ExtractDouble
(txtDocTotalAfterDiscountFreightCharge.String);
ui.EditText txtDisc = mForm.Items.Item("42").Specific as ui.EditText;
if (false == string.IsNullOrEmpty(txtDisc.String))
total += TypeUtils.ExtractDouble(txtDisc.String);
try
{
txtDocTotalAfterDiscountFreightCharge.Active = true;
txtDocTotalAfterDiscountFreightCharge.String = total.ToString();
}
catch { }
}
}
}
return true;
}
}
When I select a Cash Account in the "Founds Transfers" (CA301000), GL Balance and Avaliable Balance Entries are updated.
Where these amounts come from? I mean, I need to query these field via GI but I cannot figure out the Table's name.
Any Clues?
GL Balance and Available Balance fields are part of the CATransfer DAC.
You won't find them in the CATransfer database table because they are calculated at runtime in CATransfer DAC as unbound fields using the FieldSelecting events of GLBalanceAttribute and CashBalanceAttribute.
You can find out the DAC and Data Field of a UI element by holding Ctl+Alt and clicking on that field.
For reference, here are the GLBalance attributes inCATransfer Dac:
#region InGLBalance
public abstract class inGLBalance : PX.Data.IBqlField
{
}
protected Decimal? _InGLBalance;
[PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
[PXCury(typeof(CATransfer.inCuryID))]
[PXUIField(DisplayName = "GL Balance", Enabled = false)]
[GLBalance(typeof(CATransfer.inAccountID), null, typeof(CATransfer.inDate))]
public virtual Decimal? InGLBalance
{
get
{
return this._InGLBalance;
}
set
{
this._InGLBalance = value;
}
}
#endregion
#region OutGLBalance
public abstract class outGLBalance : PX.Data.IBqlField
{
}
protected Decimal? _OutGLBalance;
[PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
[PXCury(typeof(CATransfer.outCuryID))]
[PXUIField(DisplayName = "GL Balance", Enabled = false)]
[GLBalance(typeof(CATransfer.outAccountID), null, typeof(CATransfer.outDate))]
public virtual Decimal? OutGLBalance
{
get
{
return this._OutGLBalance;
}
set
{
this._OutGLBalance = value;
}
}
#endregion
Here is the GLBalanceAttribute class FieldSelecting event where the value is calculated:
public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
GLSetup gLSetup = PXSelect<GLSetup>.Select(sender.Graph);
decimal? result = 0m;
object CashAccountID = sender.GetValue(e.Row, _CashAccount);
object FinPeriodID = null;
if (string.IsNullOrEmpty(_FinPeriodID))
{
object FinDate = sender.GetValue(e.Row, _FinDate);
FinPeriod finPeriod = PXSelect<FinPeriod, Where<FinPeriod.startDate, LessEqual<Required<FinPeriod.startDate>>,
And<FinPeriod.endDate, Greater<Required<FinPeriod.endDate>>>>>.Select(sender.Graph, FinDate, FinDate);
if (finPeriod != null)
{
FinPeriodID = finPeriod.FinPeriodID;
}
}
else
{
FinPeriodID = sender.GetValue(e.Row, _FinPeriodID);
}
if (CashAccountID != null && FinPeriodID != null)
{
// clear glhistory cache for ReleasePayments longrun
sender.Graph.Caches<GLHistory>().ClearQueryCache();
sender.Graph.Caches<GLHistory>().Clear();
GLHistory gLHistory = PXSelectJoin<GLHistory,
InnerJoin<GLHistoryByPeriod,
On<GLHistoryByPeriod.accountID, Equal<GLHistory.accountID>,
And<GLHistoryByPeriod.branchID, Equal<GLHistory.branchID>,
And<GLHistoryByPeriod.ledgerID, Equal<GLHistory.ledgerID>,
And<GLHistoryByPeriod.subID, Equal<GLHistory.subID>,
And<GLHistoryByPeriod.lastActivityPeriod, Equal<GLHistory.finPeriodID>>>>>>,
InnerJoin<Branch,
On<Branch.branchID, Equal<GLHistory.branchID>,
And<Branch.ledgerID, Equal<GLHistory.ledgerID>>>,
InnerJoin<CashAccount,
On<GLHistoryByPeriod.branchID, Equal<CashAccount.branchID>,
And<GLHistoryByPeriod.accountID, Equal<CashAccount.accountID>,
And<GLHistoryByPeriod.subID, Equal<CashAccount.subID>>>>,
InnerJoin<Account,
On<GLHistoryByPeriod.accountID, Equal<Account.accountID>,
And<Match<Account, Current<AccessInfo.userName>>>>,
InnerJoin<Sub,
On<GLHistoryByPeriod.subID, Equal<Sub.subID>, And<Match<Sub, Current<AccessInfo.userName>>>>>>>>>,
Where<CashAccount.cashAccountID, Equal<Required<CashAccount.cashAccountID>>,
And<GLHistoryByPeriod.finPeriodID, Equal<Required<GLHistoryByPeriod.finPeriodID>>>
>>.Select(sender.Graph, CashAccountID, FinPeriodID);
if (gLHistory != null)
{
result = gLHistory.CuryFinYtdBalance;
}
}
e.ReturnValue = result;
e.Cancel = true;
}
}
Here are the CashBalance attributes of CATransfer Dac:
#region CashBalanceIn
public abstract class cashBalanceIn : PX.Data.IBqlField
{
}
protected Decimal? _CashBalanceIn;
[PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
[PXCury(typeof(CATransfer.inCuryID))]
[PXUIField(DisplayName = "Available Balance", Enabled = false)]
[CashBalance(typeof(CATransfer.inAccountID))]
public virtual Decimal? CashBalanceIn
{
get
{
return this._CashBalanceIn;
}
set
{
this._CashBalanceIn = value;
}
}
#endregion
#region CashBalanceOut
public abstract class cashBalanceOut : PX.Data.IBqlField
{
}
protected Decimal? _CashBalanceOut;
[PXDefault(TypeCode.Decimal, "0.0", PersistingCheck = PXPersistingCheck.Nothing)]
[PXCury(typeof(CATransfer.outCuryID))]
[PXUIField(DisplayName = "Available Balance", Enabled = false)]
[CashBalance(typeof(CATransfer.outAccountID))]
public virtual Decimal? CashBalanceOut
{
get
{
return this._CashBalanceOut;
}
set
{
this._CashBalanceOut = value;
}
}
#endregion
And the CashBalanceAttribute class FieldSelecting event where the value is calculated:
public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
CASetup caSetup = PXSelect<CASetup>.Select(sender.Graph);
decimal? result = 0m;
object CashAccountID = sender.GetValue(e.Row, _CashAccount);
CADailySummary caBalance = PXSelectGroupBy<CADailySummary,
Where<CADailySummary.cashAccountID, Equal<Required<CADailySummary.cashAccountID>>>,
Aggregate<Sum<CADailySummary.amtReleasedClearedCr,
Sum<CADailySummary.amtReleasedClearedDr,
Sum<CADailySummary.amtReleasedUnclearedCr,
Sum<CADailySummary.amtReleasedUnclearedDr,
Sum<CADailySummary.amtUnreleasedClearedCr,
Sum<CADailySummary.amtUnreleasedClearedDr,
Sum<CADailySummary.amtUnreleasedUnclearedCr,
Sum<CADailySummary.amtUnreleasedUnclearedDr>>>>>>>>>>.
Select(sender.Graph, CashAccountID);
if ((caBalance != null) && (caBalance.CashAccountID != null))
{
result = caBalance.AmtReleasedClearedDr - caBalance.AmtReleasedClearedCr;
if ((bool)caSetup.CalcBalDebitClearedUnreleased)
result += caBalance.AmtUnreleasedClearedDr;
if ((bool)caSetup.CalcBalCreditClearedUnreleased)
result -= caBalance.AmtUnreleasedClearedCr;
if ((bool)caSetup.CalcBalDebitUnclearedReleased)
result += caBalance.AmtReleasedUnclearedDr;
if ((bool)caSetup.CalcBalCreditUnclearedReleased)
result -= caBalance.AmtReleasedUnclearedCr;
if ((bool)caSetup.CalcBalDebitUnclearedUnreleased)
result += caBalance.AmtUnreleasedUnclearedDr;
if ((bool)caSetup.CalcBalCreditUnclearedUnreleased)
result -= caBalance.AmtUnreleasedUnclearedCr;
}
e.ReturnValue = result;
e.Cancel = true;
}
}
I am trying to take a constructor(string, string, double) and set the value in it with a scanner input. any help is appreciated. The code is list below.
My programs can assign the values that i put in, but I want to be able to assign them from the keyboard and I would like to use only one constructor method to accomplish this. Thanks
I have it broken up into two classes:
import java.util.Scanner;
public class EmployeeTest
{
public static void main(String [] args)
{
Scanner input = new Scanner(System.in);
Employee employee1 = new Employee("james", "ry", 3200);
Employee employee2 = new Employee("jim" , "bob" , 2500.56 );
System.out.println("What is employyee 1's first name? ");
employee1.setFname(input.nextLine());
}
}
class Employee
{
private String fname;
private String lname;
private double pay;
public Employee(String fname, String lname, double pay)
{
this.setFname(fname);
this.lname = lname;
this.pay = pay;
System.out.println("Employee " + fname +" "+ lname + " makes $" +
+ pay + " this month and with a 10% raise, their new pay is $" + (pay * .10 + pay));
}
void setfname(String fn)
{
setFname(fn);
}
void setlname(String ln)
{
lname = ln;
}
void setpay (double sal)
{
pay = sal;
}
String getfname()
{
return getFname();
}
String getlname()
{
return lname;
}
double getpay()
{
if (pay < 0.00)
{
return pay = 0.0;
}
return pay;
}
public String getFname() {
return fname;
}
public void setFname(String fname)
{
this.fname = fname;
}
}
You can modify you EmployeeTest class something like
class EmployeeTest {
public static void main (String...arg) {
Scanner s = new Scanner(System.in);
String[] elements = null;
while (s.hasNextLine()) {
elements = s.nextLine().split("\\s+");
//To make sure that we have all the three values
//using which we want to construct the object
if (elements.length == 3) {
//call to the method which creates the object needed
//createObject(elements[0], elements[1], Double.parseDouble(elements[2]))
//or, directly use these values to instantiate Employee object
} else {
System.out.println("Wrong values passed");
break;
}
}
s.close();
}
}
I am using the jsmpp lib for sending sms. The SMSC center returns negative response like 61,62 which are Invalid scheduled delivery time and Invalid Validty Period value. After talking with SMSC support, they require to set a default timeout for the message to be delivered, after some search on jsmpp site, didn't find it. Thanks for any suggestions ?
According to SMPP standard it should be possible to leave both of these null, but if Validity Period is required, this can be either an absolute date or a relative one.
The format should be YYMMDDhhmmsstnnp, where
YY is a two digit year (00-99)
MM is month (01-12)
DD is day (01-31)
hh is hours (00-23)
mm is minutes (00-59)
ss is seconds (00-59)
t is tenths of second (00-59)
nn is the time difference in quarter hours between local time and UTC (00-48)
p can be one of the following :-
'+' local time is ahead of UTC.
'-' local time is behind UTC.
'R' This is a relative time.
So to make the validity period 1 hour using a relative time use the following: "000000010000000R"
In my project I didn't have business requirement to schedule delivery time and set validity Period, so I set them null and it's work fine :-)
I use this class to load smpp config from properties file. Code that will using it will looks more readable and simple :-)
SMPPConfigManager is an interface for this class. It's possible to read this config not only from properties file. For example from Db and you can then implement this interface in new class.
package ru.rodin.denis.smpp;
import java.util.Properties;
import org.jsmpp.bean.*;
/**
*
* #author Denis Rodin
*/
public class SMPPFileConfig implements SMPPConfigManager {
private String host;
private int port;
private String systemId;
private String password;
private String systemType;
private TypeOfNumber sourceAddrTon;
private TypeOfNumber destAddrTon;
private NumberingPlanIndicator sourceAddrNpi;
private NumberingPlanIndicator destAddrNpi;
private String addressRange;
private int connectTimeout;
private long reconnectInterval;
private String sourceAddr;
private String destinationAddr;
private SMSCDeliveryReceipt deliveryReceipt;
private RegisteredDelivery registeredDelivery;
private BindType bindType;
private ESMClass esmClass;
private byte protocolId;
private byte priorityFlag;
private String scheduleDeliveryTime;
private String validityPeriod;
private byte replaceIfPresentFlag;
private GeneralDataCoding generalDataCoding;
private boolean generalDataCoding_compressed = true;
private boolean generalDataCoding_containMessageClass = true;
private MessageClass generalDataCoding_messageClass = MessageClass.CLASS1;
private Alphabet generalDataCoding_alphabet = Alphabet.ALPHA_DEFAULT;
private byte smDefaultMsgId;
private long transactionTimer;
private int enquireLinkTimer;
public SMPPFileConfig(Properties prop) {
this.host = prop.getProperty("smpp.host");
this.port = Integer.parseInt(prop.getProperty("smpp.port"));
this.systemId = prop.getProperty("smpp.systemId");
this.password = prop.getProperty("smpp.password");
this.systemType = prop.getProperty("smpp.systemType");
this.sourceAddrTon = getTypeOfNumber(SMPPConfigManager.AddrTon.SOURCE, prop);
this.destAddrTon = getTypeOfNumber(SMPPConfigManager.AddrTon.DEST, prop);
this.sourceAddrNpi = getNumberingPlanIndicator(SMPPConfigManager.AddrNpi.SOURCE, prop);
this.destAddrNpi = getNumberingPlanIndicator(SMPPConfigManager.AddrNpi.DEST, prop);
this.addressRange = prop.getProperty("smpp.addressRange");
this.connectTimeout = Integer.parseInt(prop.getProperty("smpp.connect.timeout"));
this.reconnectInterval = Long.parseLong(prop.getProperty("smpp.reconnect.interval"));
this.sourceAddr = prop.getProperty("smpp.sourceAddr");
this.destinationAddr = null;
this.deliveryReceipt = getSMSCDeliveryReceipt(prop.getProperty("smpp.SMSC.delivery.receipt"));
this.registeredDelivery = new RegisteredDelivery(deliveryReceipt);
this.bindType = getBindTypeFromProp(prop.getProperty("smpp.bindType"));
this.esmClass = createESMClass(prop.getProperty("smpp.ESMClass.MessageMode"), prop.getProperty("smpp.ESMClass.MessageType"), prop.getProperty("smpp.ESMClass.GSMSpecificFeature"));
this.protocolId = new Byte(prop.getProperty("smpp.protocolId"));
this.priorityFlag = new Byte(prop.getProperty("smpp.priorityFlag"));
this.scheduleDeliveryTime = prop.getProperty("smpp.scheduleDeliveryTime");
this.validityPeriod = prop.getProperty("smpp.validityPeriod");
this.replaceIfPresentFlag = new Byte(prop.getProperty("smpp.replaceIfPresentFlag"));
this.generalDataCoding = new GeneralDataCoding(generalDataCoding_compressed, generalDataCoding_containMessageClass, generalDataCoding_messageClass, generalDataCoding_alphabet);
this.smDefaultMsgId = new Byte(prop.getProperty("smpp.smDefaultMsgId"));
this.transactionTimer = Long.parseLong(prop.getProperty("smpp.transactionTimer"));
this.enquireLinkTimer = Integer.parseInt(prop.getProperty("smpp.enquireLinkTimer"));
}
#Override
public String toString() {
return "SMPPFileConfig{" + "host=" + host + ", port=" + port + ", systemId=" + systemId + ", password=" + password + ", systemType=" + systemType + ", sourceAddrTon=" + sourceAddrTon + ", destAddrTon=" + destAddrTon + ", sourceAddrNpi=" + sourceAddrNpi + ", destAddrNpi=" + destAddrNpi + ", addressRange=" + addressRange + ", connectTimeout=" + connectTimeout + ", reconnectInterval=" + reconnectInterval + ", sourceAddr=" + sourceAddr + ", destinationAddr=" + destinationAddr + ", deliveryReceipt=" + deliveryReceipt + ", registeredDelivery=" + registeredDelivery + ", bindType=" + bindType + ", esmClass=" + esmClass + ", protocolId=" + protocolId + ", priorityFlag=" + priorityFlag + ", scheduleDeliveryTime=" + scheduleDeliveryTime + ", validityPeriod=" + validityPeriod + ", replaceIfPresentFlag=" + replaceIfPresentFlag + ", generalDataCoding=" + generalDataCoding + ", generalDataCoding_compressed=" + generalDataCoding_compressed + ", generalDataCoding_containMessageClass=" + generalDataCoding_containMessageClass + ", generalDataCoding_messageClass=" + generalDataCoding_messageClass + ", generalDataCoding_alphabet=" + generalDataCoding_alphabet + ", smDefaultMsgId=" + smDefaultMsgId + '}';
}
#Override
public String getAddressRange() {
return addressRange;
}
#Override
public int getConnectTimeout() {
return connectTimeout;
}
#Override
public SMSCDeliveryReceipt getDeliveryReceipt() {
return deliveryReceipt;
}
#Override
public RegisteredDelivery getRegisteredDelivery() {
return registeredDelivery;
}
#Override
public NumberingPlanIndicator getDestAddrNpi() {
return destAddrNpi;
}
#Override
public TypeOfNumber getDestAddrTon() {
return destAddrTon;
}
#Override
public void setDestinationAddr(String destinationAddr) {
this.destinationAddr = destinationAddr;
}
#Override
public String getDestinationAddr() {
return destinationAddr;
}
#Override
public String getHost() {
return host;
}
#Override
public String getPassword() {
return password;
}
#Override
public int getPort() {
return port;
}
#Override
public long getReconnectInterval() {
return reconnectInterval;
}
#Override
public String getSourceAddr() {
return sourceAddr;
}
#Override
public NumberingPlanIndicator getSourceAddrNpi() {
return sourceAddrNpi;
}
#Override
public TypeOfNumber getSourceAddrTon() {
return sourceAddrTon;
}
#Override
public String getSystemId() {
return systemId;
}
#Override
public String getSystemType() {
return systemType;
}
#Override
public BindType getBindType() {
return bindType;
}
#Override
public ESMClass getESMClass() {
return esmClass;
}
#Override
public void setESMClass(ESMClass esmClass) {
this.esmClass = esmClass;
}
#Override
public byte getProtocolId() {
return protocolId;
}
#Override
public byte getPriorityFlag() {
return priorityFlag;
}
#Override
public String getScheduleDeliveryTime() {
return scheduleDeliveryTime;
}
#Override
public String getValidityPeriod() {
return validityPeriod;
}
#Override
public byte getReplaceIfPresentFlag() {
return replaceIfPresentFlag;
}
#Override
public GeneralDataCoding getGeneralDataCoding() {
return generalDataCoding;
}
#Override
public byte getsmDefaultMsgId(){
return smDefaultMsgId;
}
#Override
public long getTransactionTimer()
{
return transactionTimer;
}
#Override
public int getEnquireLinkTimer()
{
return enquireLinkTimer;
}
private ESMClass createESMClass(String messageMode, String messageType, String GSMSpecificFeature) {
return new ESMClass(getESMClassMessageMode(messageMode), getESMMessageType(messageType), getESMGSMSpecificFeature(GSMSpecificFeature));
}
private MessageMode getESMClassMessageMode(String type) {
if (type.equals("DEFAULT")) {
return MessageMode.DEFAULT;
} else if (type.equals("DATAGRAM")) {
return MessageMode.DATAGRAM;
} else if (type.equals("STORE_AND_FORWARD")) {
return MessageMode.STORE_AND_FORWARD;
} else if (type.equals("TRANSACTION")) {
return MessageMode.TRANSACTION;
} else {
return null;
}
}
private MessageType getESMMessageType(String type) {
if (type.equals("DEFAULT")) {
return MessageType.DEFAULT;
} else if (type.equals("CONV_ABORT")) {
return MessageType.CONV_ABORT;
} else if (type.equals("ESME_DEL_ACK")) {
return MessageType.ESME_DEL_ACK;
} else if (type.equals("ESME_MAN_ACK")) {
return MessageType.ESME_MAN_ACK;
} else if (type.equals("INTER_DEL_NOTIF")) {
return MessageType.INTER_DEL_NOTIF;
} else if (type.equals("SME_DEL_ACK")) {
return MessageType.SME_DEL_ACK;
} else if (type.equals("SME_MAN_ACK")) {
return MessageType.SME_MAN_ACK;
} else if (type.equals("SMSC_DEL_RECEIPT")) {
return MessageType.SMSC_DEL_RECEIPT;
} else {
return null;
}
}
private GSMSpecificFeature getESMGSMSpecificFeature(String type) {
if (type.equals("DEFAULT")) {
return GSMSpecificFeature.DEFAULT;
} else if (type.equals("REPLYPATH")) {
return GSMSpecificFeature.REPLYPATH;
} else if (type.equals("UDHI")) {
return GSMSpecificFeature.UDHI;
} else if (type.equals("UDHI_REPLYPATH")) {
return GSMSpecificFeature.UDHI_REPLYPATH;
} else {
return null;
}
}
private BindType getBindTypeFromProp(String type) {
//String type = prop.getProperty("smpp.bindType");
if (type.equals("BIND_RX")) {
return BindType.BIND_RX;
} else if (type.equals("BIND_TX")) {
return BindType.BIND_TX;
} else if (type.equals("BIND_TRX")) {
return BindType.BIND_TRX;
} else {
return null;
}
}
private TypeOfNumber getTypeOfNumber(SMPPConfigManager.AddrTon ton, Properties prop) {
String type;
if (ton == SMPPConfigManager.AddrTon.SOURCE) {
type = prop.getProperty("smpp.sourceAddrTon");
} else {
type = prop.getProperty("smpp.destAddrTon");
}
if (type.equals("ABBREVIATED")) {
return TypeOfNumber.ABBREVIATED;
} else if (type.equals("ALPHANUMERIC")) {
return TypeOfNumber.ALPHANUMERIC;
} else if (type.equals("INTERNATIONAL")) {
return TypeOfNumber.INTERNATIONAL;
} else if (type.equals("NATIONAL")) {
return TypeOfNumber.NATIONAL;
} else if (type.equals("NETWORK_SPECIFIC")) {
return TypeOfNumber.NETWORK_SPECIFIC;
} else if (type.equals("SUBSCRIBER_NUMBER")) {
return TypeOfNumber.SUBSCRIBER_NUMBER;
} else if (type.equals("UNKNOWN")) {
return TypeOfNumber.UNKNOWN;
} else {
return null;
}
}
private SMSCDeliveryReceipt getSMSCDeliveryReceipt(String type) {
//String type = prop.getProperty("smpp.SMSC.delivery.receipt");
if (type.equals("DEFAULT")) {
return SMSCDeliveryReceipt.DEFAULT;
} else if (type.equals("SUCCESS")) {
return SMSCDeliveryReceipt.SUCCESS;
} else if (type.equals("SUCCESS_FAILURE")) {
return SMSCDeliveryReceipt.SUCCESS_FAILURE;
} else {
return null;
}
}
private NumberingPlanIndicator getNumberingPlanIndicator(SMPPConfigManager.AddrNpi npi, Properties prop) {
String type;
if (npi == SMPPConfigManager.AddrNpi.SOURCE) {
type = prop.getProperty("smpp.sourceAddrNpi");
} else {
type = prop.getProperty("smpp.destAddrNpi");
}
if (type.equals("DATA")) {
return NumberingPlanIndicator.DATA;
} else if (type.equals("ERMES")) {
return NumberingPlanIndicator.ERMES;
} else if (type.equals("INTERNET")) {
return NumberingPlanIndicator.INTERNET;
} else if (type.equals("ISDN")) {
return NumberingPlanIndicator.ISDN;
} else if (type.equals("LAND_MOBILE")) {
return NumberingPlanIndicator.LAND_MOBILE;
} else if (type.equals("NATIONAL")) {
return NumberingPlanIndicator.NATIONAL;
} else if (type.equals("PRIVATE")) {
return NumberingPlanIndicator.PRIVATE;
} else if (type.equals("TELEX")) {
return NumberingPlanIndicator.TELEX;
} else if (type.equals("WAP")) {
return NumberingPlanIndicator.WAP;
} else if (type.equals("UNKNOWN")) {
return NumberingPlanIndicator.UNKNOWN;
} else {
return null;
}
}
}
when you submit current time as scheduled delivery time this error may occur.because it takes some time to send request. so the time you mentioned might be in past .so set the scheduled delivery time to (current time + 10 seconds )
long TEN_SECONDS=10000;//millisecs
Calendar date = Calendar.getInstance();
long t= date.getTimeInMillis();
Date scheduleDeliveryTime=new Date(t + ( TEN_SECONDS));