Chargify how can get total transactions of between two dates? - asp.net

Currently, i am getting only 20 transactions per pages and can be extends only 200 but i need all transaction between that dates no paging.
Or if it possible to get count of transactions.?
How can i archive?
Thanks

I would use the following to retrieve all transactions for a subscription:
bool isFinished = false;
int counter = 1;
var results = new Dictionary<int, ITransaction>();
while (!isFinished)
{
// Get results
var transactions = chargify.GetTransactionsForSubscription(activeSubscription.SubscriptionID, counter++, 20);
// Check condition
if (transactions.Count == 0) { isFinished = true; continue; }
// Merge results
transactions.ToList().ForEach(x => results.Add(x.Key, x.Value));
}
That should get all the transactions and merge them all into the single dictionary. :) If need to use dates, then just switch the data retrieval line to something like this:
var transactions = chargify.GetTransactionsForSubscription(activeSubscription.SubscriptionID, counter++, 20, null, int.MinValue, int.MinValue, DateTime.Today, DateTime.Now); (just switch to your dates).

Related

TransactionResult.Success does not update my mutableData (Firebase)

I have copied the code from Save Data.
which is like this:
void addScoreToLeaders(string name, int score ,string
key,Dictionary<string,object> childUpdates){
reference.Child ("leaders").KeepSynced (true);
reference.Child ("leaders").RunTransaction(mutableData =>{
List<Dictionary<string,object>> leaders = mutableData.Value as
List<Dictionary<string,object>>;
if(leaders == null){
leaders = new List<Dictionary<string,object>>();
} else if(mutableData.ChildrenCount >= MAX_SCORE){
int minScore = int.MaxValue;
Dictionary<string,object> minValue = null;
foreach(var child in leaders){
if(!(child is Dictionary<string,object>)) continue;
int childScore = (int)((Dictionary<string,object>)child)
["score"];
if(childScore < minScore){
minScore = childScore;
minValue = child;
}
}
if(minScore > score){
return TransactionResult.Abort ();
}
leaders.Remove (minValue);
}
//Add the new high score
Dictionary<string ,object> newScoreMap = new
Dictionary<string,object> ();
LeaderBoardEntry entry = new LeaderBoardEntry (name, score);
newScoreMap = entry.ToDictionary ();
leaders.Add (newScoreMap);
mutableData.Value = leaders;
return TransactionResult.Success (mutableData);
});
}
okay, there's two things not happens correctly :
TransactionResult.Success(mutableData) does not store the new data at the location
Return mutableData null for every first time i call the method
[Solved] after examining the code and several attempts of testing found the solution .
line number five (5) of the code causing problem which is :
List<Dictionary<string,object>> leaders = mutableData.Value as
List<Dictionary<string,object>>;
replace with :
Dictionary<string,object> leaders = mutableData.Value as
Dictionary<string,object>;
because mutableData.Value returned the data contained in this instance as native types, and i saved the data like Dictionary<.string,object>;

How to perform Firebase Mutable Transaction Data with Flutter?

I have Swift code where I reduce or increase an int value for certain conditions. How can I replicate this with Flutter? Here is my Swift code..
// 2. Decrease Value -= from NumberOnes
let decreaseRef = self.ref.child("NumberOnes/\(myfav1)/Value")
decreaseRef.runTransactionBlock { (currentData: FIRMutableData) -> FIRTransactionResult in
if var data = currentData.value as? Int
{
var count = data
count -= 1
data = count
currentData.value = data
return FIRTransactionResult.success(withValue: currentData)
}
return FIRTransactionResult.success(withValue: currentData)
}
Also, if there's documentation/tutorials for this out there, please point me to it.
* UPDATE *
Here is my Flutter code...
fb.child('UserVideo/${userid}/Vid1').onValue.listen((Event event){
if (event.snapshot != null){
final vidID = event.snapshot.value["videoID"];
fb.child('NumberOnes/${vidID}/Value').onValue.listen((Event newEvent){
int vidValue = newEvent.snapshot.value;
vidValue;
print(vidValue);
//vidValue = value;
final value = vidValue--;
fb.child('NumberOnes/${vidID}').update({
'Value': value,
});
});
The problem with my Flutter code is that it doesn't stop decreasing. Is there a way around this?
Here is my solution. I worked it out from this answer here... Flutter Firebase update will not stop updating node?
Basically, I'm isolating the value once, manipulating it, then updating node with new info. I think this is much less efficient than the runTransactionBlock from the Firebase Swift SDK that brings back snapshot value as MutableData. If anyone finds a work around for this in the future please add answer.
if (vidRank == 1) {
var event = await fb.child('UserVideo/${userid}/Vid1').once();
if (event.snapshot != null){
var vid1id = event.snapshot.value['videoID'].toString();
var onesEvent = await fb.child('NumberOnes/${vid1id}').once();
if (onesEvent.snapshot != null){
var onesValue = (onesEvent.snapshot.value['Value'] as int);
final vidValue = onesValue - 1;
print("Inside ${vidValue}");
fb.child('NumberOnes/${vid1id}').update({
'Value': vidValue
});
}
}
}

Dictionary and condition

I have been working on an assignment in which I have to upload some records from a file to Dictionary and manipulate.
Actually file have number of record with same invoice number and different tax values and I have to add all those values and make it only one invoice
what I'm trying to do
I'm passing values from a foreach loop to a function which check if the dictionary is empty so it will simply add first record and on second call it will check weather any record in dictionary have same invoice number so it will sum and update current tax value to one already added,
what I'm getting
when I pass 2nd value (and so on) the previous value of last entry in dictionary some how update itself with current value before even comparing which I don't want.
public jd_records jd = new jd_records();
Dictionary<int, jd_records> jdValues = new Dictionary<int, jd_records>();
//Calling values with loop while jd is a publicly declared object of class jd_records
foreach (DataRow dr in jddt.Rows)
{
//jd_records jdPass = new jd_records();
jd.supplierName = dr["Supplier"].ToString();
jd.supplierNTN = dr["Supplier NTN"].ToString();
jd.invoiceNo = dr["JDE Invoice Number"].ToString();
jd.invoiceDate = DateTime.Parse(dr["JDE Invoice Date"].ToString());
if (dr["Taxable Amount"].ToString().Equals(""))
{ jd.taxable = 0; }
else
{ jd.taxable = float.Parse(dr["Taxable Amount"].ToString()); }
if (dr["Tax To Pay"].ToString().Equals(""))
{ jd.tax = 0; }
else
{ jd.tax = float.Parse(dr["Tax To Pay"].ToString()); }
jdRecordCheck();
}
called function
public void jdRecordCheck()
{
if (jdValues.Count < 1)
{
jdValues.Add(0, jd);
}
else //previous record values (at key 0) changes to new jd value when come to this else part on execution
{
foreach (KeyValuePair<int,jd_records> jdVal in jdValues)
{
if ((jdVal.Value.supplierNTN.Equals(jd.supplierNTN)) && (jdVal.Value.invoiceNo.Equals(jd.invoiceNo)))
{
jdVal.Value.tax = jdVal.Value.tax + jd.tax;
jdVal.Value.taxable = jdVal.Value.taxable + jd.taxable;
jdValues[jdVal.Key] = jdVal.Value;
}
else
{
jdValues.Add(jdVal.Key + 1, jd);
}
}
}
}
I'll be very thankful if anyone helps.
Seems to me this would be much easier to do with Linq, which contains functions for grouping and summing.
List<jd_records> result = jddt.Rows
.GroupBy(jd => jd.invoiceNo)
.Select(jd => new jd_records
{
invoiceNo = jd.invoiceNo,
totalTax = jd.Sum(d => d.tax)
}).ToList();

dynamodb scan: filter all records where attribute does not exist

I can't seem to get this right.
I want to do a scan of a table and only return records where a particular field does not exist.
I've tried the following two things:
HashMap<String, Condition> scanFilter = new HashMap();
Condition scanFilterCondition = new Condition().withComparisonOperator(ComparisonOperator.NULL.toString());
scanFilter.put("field", scanFilterCondition);
ScanRequest scan = new ScanRequest()
.withTableName("table name")
.withScanFilter(scanFilter)
etc
and
ScanRequest scan = new ScanRequest()
.withTableName("table")
.withFilterExpression("attribute_not_exists(attributeName)")
.withLimit(100)
etc
However they return no records (and most records are missing this field). Note, that if I remove the filter the scan does return and process all records as expected so the basic query is correct.
How do I do this?
EDIT added full method in case it helps
// Get information on the table so that we can set the read capacity for the operation.
List<String> tables = client.listTables().getTableNames();
String tableName = tables.stream().filter(table -> table.equals(configuration.getTableName())).findFirst().get();
if(Strings.isNullOrEmpty(tableName))
return 0;
TableDescription table = client.describeTable(tableName).getTable();
//Set the rate limit to a third of the provisioned read capacity.
int rateLimit = (int) (table.getProvisionedThroughput().getReadCapacityUnits() / 3);
RateLimiter rateLimiter = RateLimiter.create(rateLimit);
// Track how much throughput we consume on each page
int permitsToConsume = 1;
// Initialize the pagination token
Map<String, AttributeValue> exclusiveStartKey = null;
int count = 1;
int writtenCount = 0;
do {
// Let the rate limiter wait until our desired throughput "recharges"
rateLimiter.acquire(permitsToConsume);
//We only want to process records that don't have the field key set.
HashMap<String, Condition> scanFilter = new HashMap<>();
Condition scanFilterCondition = new Condition().withComparisonOperator(ComparisonOperator.NULL.toString());
scanFilter.put("field", scanFilterCondition);
ScanRequest scan = new ScanRequest()
.withTableName(configuration.getNotificationsTableName())
.withScanFilter(scanFilter)
.withLimit(100)
.withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.withExclusiveStartKey(exclusiveStartKey);
ScanResult result = client.scan(scan);
exclusiveStartKey = result.getLastEvaluatedKey();
// Account for the rest of the throughput we consumed,
// now that we know how much that scan request cost
double consumedCapacity = result.getConsumedCapacity().getCapacityUnits();
permitsToConsume = (int)(consumedCapacity - 1.0);
if(permitsToConsume <= 0) {
permitsToConsume = 1;
}
// Process results here
} while (exclusiveStartKey != null);
The NULL condition seems to be fine. You need to do recursive search using Scan. The Dynamodb scan doesn't scan the whole database in one go. It scans the data based on the amount of consumed provisioned throughput.
Sample code to perform scan in loop based on LastEvaluatedKey:-
ScanResult result = null;
do {
HashMap<String, Condition> scanFilter = new HashMap<>();
Condition scanFilterCondition = new Condition().withComparisonOperator(ComparisonOperator.NULL);
scanFilter.put("title", scanFilterCondition);
ScanRequest scanRequest = new ScanRequest().withTableName(tableName).withScanFilter(scanFilter);
if (result != null) {
scanRequest.setExclusiveStartKey(result.getLastEvaluatedKey());
}
result = dynamoDBClient.scan(scanRequest);
LOGGER.info("Number of records ==============>" + result.getItems().size());
for (Map<String, AttributeValue> item : result.getItems()) {
LOGGER.info("Movies ==================>" + item.get("title"));
}
} while (result.getLastEvaluatedKey() != null);
NULL : The attribute does not exist. NULL is supported for all data
types, including lists and maps. Note This operator tests for the
nonexistence of an attribute, not its data type. If the data type of
attribute "a" is null, and you evaluate it using NULL, the result is a
Boolean false. This is because the attribute "a" exists; its data type
is not relevant to the NULL comparison operator.
LastEvaluatedKey The primary key of the item where the operation
stopped, inclusive of the previous result set. Use this value to start
a new operation, excluding this value in the new request.
If LastEvaluatedKey is empty, then the "last page" of results has been
processed and there is no more data to be retrieved.
If LastEvaluatedKey is not empty, it does not necessarily mean that
there is more data in the result set. The only way to know when you
have reached the end of the result set is when LastEvaluatedKey is
empty.
var expr = new Expression();
expr.ExpressionStatement = "contains(#Name, :Name) and attribute_not_exists(#FullName) or #FullName = :FullName";
expr.ExpressionAttributeNames["#FullName"] = "FullName";
expr.ExpressionAttributeValues[":FullName"] = "sumit singh";
expr.ExpressionAttributeNames["#Name"] = "Name";
expr.ExpressionAttributeValues[":Name"] = "sumit singh";
ScanOperationConfig config = new ScanOperationConfig()
{
Limit = 2,
PaginationToken = "{}",
//Filter = filter,
FilterExpression = expr,
//AttributesToGet = attributesToGet,
//Select = SelectValues.SpecificAttributes,
TotalSegments = 1
};
var item = _tableContext.FromScanTableAsync(config);
do
{
documentList.AddRange(await item.GetNextSetAsync());
} while (!item.IsDone);

Does running a query inside a transaction guarantee the uniqueness of the generated number?

When I change an OnlinePayment I want to create a unique InvoiceNumber for the record. This code will generate a unique id:
int newId = db.OnlinePayments.Max(op => op.InvoiceNumber) + 1;
However, this will fail if another record is being added at the same time. Using an Identity column is not an option since the InvoiceNumber should change whenever I change the database. Would the following code guarantee the uniqueness of the generated InvoiceNumber?
using (var transaction = db.Database.BeginTransaction())
{
try
{
int newId = db.OnlinePayments.Max(op => op.InvoiceNumber) + 1;
opi.InvoiceNumber = newId;
await db.SaveChangesAsync();
transaction.Commit();
}
catch
{
transaction.Rollback();
}
}
No, since two transactions can both read the same max value and then both use that value plus one.

Resources