Files
caliverse_server/ServerCommon/Helper/CurrencyControlHelper.cs
2025-05-01 07:20:41 +09:00

245 lines
9.6 KiB
C#

using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using Amazon.DynamoDBv2.Model;
using Amazon.S3.Model;
using ServerCore;
using ServerBase;
using DYNAMO_DB_TABLE_NAME = System.String;
using DYNAMO_DB_TABLE_FULL_NAME = System.String;
using USER_GUID = System.String;
namespace ServerCommon;
public static class CurrencyControlHelper
{
private static DynamoDbClient? m_db_connector = null;
//=============================================================================================
// 단위당 금전량을 quantity 만큼 계산하여 Round 보정후 반환 한다.
//=============================================================================================
public static double calculateRoundedMoneyByCurrency(this double reqUnitMoney, CurrencyType currencyType, int quantity = 1)
{
var result = new Result();
if (ServerCore.TypeHelper.NumericSignType.Positive == ServerCore.TypeHelper.checkNumericSignType<double>(reqUnitMoney))
{
reqUnitMoney *= -1;
}
var req_money = reqUnitMoney * quantity;
return roundMoneyByCurrencyType(currencyType, req_money);
}
//=============================================================================================
// 금전량을 보정 한다.
//=============================================================================================
public static double roundMoneyByCurrencyType(CurrencyType currencyType, double delta)
{
// CurrencyType.Calium 이 아닌 모든 재화는 소숫점을 올림 처리 한다 !!!
if (currencyType != CurrencyType.Calium)
{
delta = MathHelper.roundUpOrDown(delta);
}
return delta;
}
//=============================================================================================
// delta 만큼 금전을 쓴다.
//=============================================================================================
public static async Task<(Result, double)> spendMoneyByUserGuid( USER_GUID userGuid, CurrencyType currencyType, double delta )
{
var result = new Result();
if (ServerCore.TypeHelper.NumericSignType.Positive == ServerCore.TypeHelper.checkNumericSignType<double>(delta))
{
delta *= -1;
}
return await changeMoneyByUserGuid(userGuid, currencyType, delta);
}
//=============================================================================================
// delta 만큼 금전을 얻는다.
//=============================================================================================
public static async Task<(Result, double)> earnMoneyByUserGuid(USER_GUID userGuid, CurrencyType currencyType, double delta)
{
var result = new Result();
if (ServerCore.TypeHelper.NumericSignType.Negative == ServerCore.TypeHelper.checkNumericSignType<double>(delta))
{
delta *= -1;
}
if (0 < delta)
{
return await changeMoneyByUserGuid(userGuid, currencyType, delta);
}
return (result, 0);
}
public static async Task<(Result, double)> getMoneyByUserGuid(USER_GUID userGuid, CurrencyType type)
{
var result = new Result();
string err_msg;
var error_code = hasDbConnector();
if (error_code.isFail())
{
err_msg = $"Not available DynamoDB connector !!! : userGuid:{userGuid}";
result.setFail(error_code, err_msg);
return (result, 0);
}
var db_connector = getDbConnector();
(result, var found_money_doc) = await findMoneyDocByUserGuid(db_connector, userGuid);
if (null == found_money_doc)
{
err_msg = $"Not found MoneyDoc !!! : userGuid:{userGuid}";
result.setFail(ServerErrorCode.MoneyDocIsNull, err_msg);
return (result, 0);
}
var attrib = found_money_doc.getAttrib<MoneyAttrib>();
NullReferenceCheckHelper.throwIfNull(attrib, () => $"attrib is null !!!");
return (result, attrib.getCurrencyFromType(type));
}
public static async Task<(Result, double)> changeMoneyByUserGuid(USER_GUID userGuid, CurrencyType type, double delta)
{
var result = new Result();
var err_msg = string.Empty;
var error_code = hasDbConnector();
if (error_code.isFail())
{
err_msg = $"Not available DynamoDB connector !!! : userGuid:{userGuid}";
result.setFail(error_code, err_msg);
return (result, 0);
}
var db_connector = getDbConnector();
var table = db_connector.getTableByDoc<MoneyDoc>();
(result, var make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<MoneyDoc>(userGuid);
if (result.isFail())
{
return (result, 0);
}
NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - userGuid:{userGuid}");
(result, var request) = makeUpdateItemRequest( table.TableName
, make_primary_key.toKeyWithAttributeValue(), MoneyAttribExtensions.getKeyNameFromType(type)
, delta);
if (result.isFail() || request == null) return (result, 0);
(result, var changed_money_doc) = await db_connector.simpleQueryDocTypesWithUpdateItemRequest<MoneyDoc>(request);
if (result.isFail() || changed_money_doc == null) return (result, 0);
var money_attrib = changed_money_doc.getAttrib<MoneyAttrib>();
NullReferenceCheckHelper.throwIfNull(money_attrib, () => $"money_attrib is null !!! - userGuid:{userGuid}");
return (result, money_attrib.getCurrencyFromType(type));
}
public static async Task<(Result, MoneyDoc?)> findMoneyDocByUserGuid(DynamoDbClient dynamoDbClient, USER_GUID userGuid)
{
var result = new Result();
var money_doc = new MoneyDoc();
money_doc.setCombinationKeyForPK(userGuid);
money_doc.onApplyPKSK();
var query_config = dynamoDbClient.makeQueryConfigForReadByPKOnly(money_doc.getPK());
return await dynamoDbClient.simpleQueryDocTypeWithQueryOperationConfig<MoneyDoc>(query_config);
}
private static (Result, UpdateItemRequest?) makeUpdateItemRequest( DYNAMO_DB_TABLE_FULL_NAME tableFullName
, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
, string targetAttribName
, double deltaCount )
{
var result = new Result();
var err_msg = string.Empty;
var error_code = hasDbConnector();
if (error_code.isFail())
{
err_msg = $"Not available DynamoDb connector !!!";
result.setFail(error_code, err_msg);
return (result, null);
}
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(tableFullName);
query_builder.withKeys(attributeValueWithPrimaryKey);
var target_doc = new MoneyDoc();
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
var target_key = JsonHelper.getJsonPropertyName<MoneyAttrib>(targetAttribName);
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
if (false == is_success)
{
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
query_builder.withExpressionAttributeNames(DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key));
var update_expression = (deltaCount >= 0)
? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
: $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
query_builder.withUpdateExpression(update_expression);
var expression_attribute_values = new Dictionary<string, AttributeValue>
{
{ ":changeValue", new AttributeValue { N = Math.Abs(deltaCount).ToString() } },
{ ":start", new AttributeValue { N = "0" } }
};
query_builder.withExpressionAttributeValues(expression_attribute_values);
query_builder.withReturnValues(ReturnValue.ALL_NEW);
return query_builder.build();
}
private static ServerErrorCode hasDbConnector()
{
if(null == m_db_connector)
{
return ServerErrorCode.DynamoDbConnectorIsNull;
}
return ServerErrorCode.Success;
}
public static DynamoDbClient getDbConnector()
{
NullReferenceCheckHelper.throwIfNull(m_db_connector, () => $"m_db_connector is null !!!");
return m_db_connector;
}
//=============================================================================================
// CurrencyControlHelper <= DynamoDbClient 설정
//=============================================================================================
public static Result setDbConnector(DynamoDbClient dbConnector)
{
var result = new Result();
m_db_connector = dbConnector;
return result;
}
}