358 lines
14 KiB
C#
358 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Google.Protobuf.WellKnownTypes;
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using ServerCore; using ServerBase;
|
|
using ServerCommon.BusinessLogDomain;
|
|
|
|
|
|
using USER_GUID = System.String;
|
|
using Amazon.S3.Model;
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
namespace ServerCommon
|
|
{
|
|
public class ShopProductTradingMeterSubAttribute
|
|
{
|
|
[JsonProperty("product_id")]
|
|
public int ProductId { get; set; }
|
|
|
|
[JsonProperty("left_count")]
|
|
public double LeftCount { get; set; }
|
|
}
|
|
|
|
public class ShopProductTradingMeterAttribute : EntityAttributeBase, ICopyEntityAttributeFromDoc, IMergeWithEntityAttribute
|
|
{
|
|
private readonly USER_GUID m_user_guid;
|
|
|
|
[JsonProperty]
|
|
public int ShopId { get; set; }
|
|
|
|
[JsonProperty] public Timestamp EndTime { get; set; } = DateTimeHelper.MinTime.ToTimestamp();
|
|
|
|
[JsonProperty]
|
|
public List<ShopProductTradingMeterSubAttribute> ShopProductTradingMeterSubs { get; private set; } = new();
|
|
|
|
[JsonProperty] public Int32 CurrentRenewalCount { get; private set; } = 0;
|
|
|
|
public ShopProductTradingMeterAttribute( EntityBase owner, USER_GUID user_guid
|
|
, EntityBase entityOfOwnerEntityType )
|
|
: base(owner, entityOfOwnerEntityType)
|
|
{
|
|
m_user_guid = user_guid;
|
|
}
|
|
|
|
public override void onClear()
|
|
{
|
|
ShopId = 0;
|
|
EndTime = DateTimeHelper.MinTime.ToTimestamp();
|
|
ShopProductTradingMeterSubs.Clear();
|
|
CurrentRenewalCount = 0;
|
|
|
|
getAttributeState().reset();
|
|
}
|
|
|
|
public override EntityAttributeBase onCloned()
|
|
{
|
|
var owner_entity_type = getEntityOfOwnerEntityType();
|
|
NullReferenceCheckHelper.throwIfNull(owner_entity_type, () => $"owner_entity_type is null !!!");
|
|
|
|
var cloned = new ShopProductTradingMeterAttribute( getOwner()
|
|
, m_user_guid, owner_entity_type)
|
|
{
|
|
ShopId = ShopId,
|
|
EndTime = EndTime,
|
|
CurrentRenewalCount = CurrentRenewalCount
|
|
};
|
|
|
|
foreach (var sub in ShopProductTradingMeterSubs)
|
|
{
|
|
var data = new ShopProductTradingMeterSubAttribute
|
|
{
|
|
ProductId = sub.ProductId,
|
|
LeftCount = sub.LeftCount
|
|
};
|
|
|
|
cloned.ShopProductTradingMeterSubs.Add(data);
|
|
}
|
|
|
|
return cloned;
|
|
}
|
|
|
|
public override IEntityAttributeTransactor onNewEntityAttributeTransactor()
|
|
{
|
|
return new ShopProductTradingMeterAttributeTransactor(getOwner());
|
|
}
|
|
|
|
public override async Task<(Result, DynamoDbDocBase?)> toDocBase(bool isForQuery = true)
|
|
{
|
|
var result = new Result();
|
|
|
|
|
|
//=====================================================================================
|
|
// Attribute => try pending Doc
|
|
//=====================================================================================
|
|
var try_pending_doc = getTryPendingDocBase() as ShopProductTradingMeterDoc;
|
|
if (null == try_pending_doc)
|
|
{
|
|
var to_copy_doc = new ShopProductTradingMeterDoc(m_user_guid, ShopId);
|
|
|
|
var origin_doc = getOriginDocBase<ShopProductTradingMeterAttribute>();
|
|
if (null != origin_doc)
|
|
{
|
|
to_copy_doc.copyTimestampsFromOriginDocBase(origin_doc);
|
|
}
|
|
|
|
to_copy_doc.onApplyPKSK();
|
|
|
|
try_pending_doc = to_copy_doc;
|
|
|
|
setTryPendingDocBase(try_pending_doc);
|
|
}
|
|
|
|
var to_copy_doc_attrib = try_pending_doc.getAttrib<ShopProductTradingMeterAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(to_copy_doc_attrib, () => $"to_copy_doc_attrib is null !!!");
|
|
|
|
to_copy_doc_attrib.onClear();
|
|
to_copy_doc_attrib.ShopId = ShopId;
|
|
to_copy_doc_attrib.EndTime = EndTime;
|
|
to_copy_doc_attrib.CurrentRenewalCount = CurrentRenewalCount;
|
|
foreach (var sub in ShopProductTradingMeterSubs)
|
|
{
|
|
to_copy_doc_attrib.ShopProductTradingMeterSubs.Add(new ShopProductTradingMeterSubAttrib
|
|
{
|
|
ProductId = sub.ProductId,
|
|
LeftCount = sub.LeftCount
|
|
});
|
|
}
|
|
|
|
if (false == isForQuery)
|
|
{
|
|
return (result, try_pending_doc);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// Doc QueryType 반영
|
|
//=====================================================================================
|
|
(result, var to_query_doc) = await applyDoc4Query(try_pending_doc);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, to_query_doc);
|
|
}
|
|
|
|
public Result onMerge(EntityAttributeBase otherEntityAttribute)
|
|
{
|
|
var owner = getOwner();
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
|
|
var result = new Result();
|
|
string err_msg;
|
|
|
|
//=====================================================================================
|
|
// OtherAttribute => Attribute
|
|
//=====================================================================================
|
|
var other_shop_product_trading_meter_attribute = otherEntityAttribute as ShopProductTradingMeterAttribute;
|
|
if (null == other_shop_product_trading_meter_attribute)
|
|
{
|
|
err_msg = $"Failed to cast ShopProductTradingMeterAttribute !!!, other_shop_product_trading_meter_attribute is null";
|
|
result.setFail(ServerErrorCode.ClassTypeCastIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
|
|
onClear();
|
|
|
|
ShopId = other_shop_product_trading_meter_attribute.ShopId;
|
|
EndTime = other_shop_product_trading_meter_attribute.EndTime;
|
|
CurrentRenewalCount = other_shop_product_trading_meter_attribute.CurrentRenewalCount;
|
|
foreach (var subAttribute in other_shop_product_trading_meter_attribute.ShopProductTradingMeterSubs)
|
|
{
|
|
var data = new ShopProductTradingMeterSubAttribute();
|
|
data.ProductId = subAttribute.ProductId;
|
|
data.LeftCount = subAttribute.LeftCount;
|
|
ShopProductTradingMeterSubs.Add(data);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// Attribute Try Pending Doc => Origin Doc
|
|
//=====================================================================================
|
|
var try_pending_doc = other_shop_product_trading_meter_attribute.getTryPendingDocBase() as ShopProductTradingMeterDoc;
|
|
if (null != try_pending_doc)
|
|
{
|
|
other_shop_product_trading_meter_attribute.resetTryPendingDocBase();
|
|
|
|
syncOriginDocBaseWithNewDoc<ShopProductTradingMeterAttribute>(try_pending_doc);
|
|
}
|
|
|
|
var origin_doc_base = getOriginDocBase<ShopProductTradingMeterAttribute>();
|
|
if (null == origin_doc_base)
|
|
{
|
|
// DB 에 저장되어 있지 않는 경우 OriginDoc은 null 이다 !!!
|
|
return result;
|
|
}
|
|
|
|
var shop_product_trading_meter_attrib = origin_doc_base.getAttrib<ShopProductTradingMeterAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(shop_product_trading_meter_attrib, () => $"shop_product_trading_meter_attrib is null !!! - {owner.toBasicString()}");
|
|
|
|
shop_product_trading_meter_attrib.ShopId = ShopId;
|
|
shop_product_trading_meter_attrib.EndTime = EndTime;
|
|
shop_product_trading_meter_attrib.CurrentRenewalCount = CurrentRenewalCount;
|
|
|
|
foreach(var sub in ShopProductTradingMeterSubs)
|
|
{
|
|
var data = new ShopProductTradingMeterSubAttrib();
|
|
data.ProductId = sub.ProductId;
|
|
data.LeftCount = sub.LeftCount;
|
|
|
|
shop_product_trading_meter_attrib.ShopProductTradingMeterSubs.Add(data);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public bool copyEntityAttributeFromDoc(DynamoDbDocBase? docBase)
|
|
{
|
|
if (docBase is not ShopProductTradingMeterDoc meterDoc)
|
|
{
|
|
var err_msg = $"Failed to copyEntityAttributeFromDoc() !!!, shop_product_trading_meter_doc is null :{nameof(ShopProductTradingMeterDoc)}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// New Doc => Origin Doc
|
|
//=====================================================================================
|
|
syncOriginDocBaseWithNewDoc<ShopProductTradingMeterAttribute>(meterDoc);
|
|
|
|
//=====================================================================================
|
|
// Doc => Attribute
|
|
//=====================================================================================
|
|
var attr = meterDoc.getAttrib<ShopProductTradingMeterAttrib>();
|
|
if (null == attr)
|
|
{
|
|
var err_msg = $"Failed to copyEntityAttributeFromDocs() !!!, not found doc attrib !!! :{toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
onClear();
|
|
ShopId = attr.ShopId;
|
|
EndTime = attr.EndTime;
|
|
CurrentRenewalCount = attr.CurrentRenewalCount;
|
|
foreach (var meter in attr.ShopProductTradingMeterSubs)
|
|
{
|
|
var info = new ShopProductTradingMeterSubAttribute
|
|
{
|
|
ProductId = meter.ProductId,
|
|
LeftCount = meter.LeftCount
|
|
};
|
|
|
|
ShopProductTradingMeterSubs.Add(info);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public Result changeProductTradingMeter(int product_id, int delta)
|
|
{
|
|
var result = new Result();
|
|
string err_msg;
|
|
|
|
var meter = findMeter(product_id);
|
|
if (null == meter)
|
|
{
|
|
err_msg = $"Failed to found product id: {product_id}";
|
|
result.setFail(ServerErrorCode.NotFoundProductId, err_msg);
|
|
Log.getLogger().error(err_msg);
|
|
return result;
|
|
}
|
|
|
|
var change = meter.LeftCount + delta;
|
|
if (change < 0)
|
|
{
|
|
err_msg = $"Failed to change shop meter !!! : Invalid count - {meter.LeftCount} / {delta}";
|
|
result.setFail(ServerErrorCode.InvalidArgument, err_msg);
|
|
return result;
|
|
}
|
|
|
|
meter.LeftCount += delta;
|
|
return result;
|
|
}
|
|
|
|
public ShopProductTradingMeterSubAttribute? getMeterSubAttribute(int product_id)
|
|
=> ShopProductTradingMeterSubs.FirstOrDefault(sub => sub.ProductId == product_id);
|
|
|
|
public void initEndTime() => EndTime = Timestamp.FromDateTime(DateTime.UtcNow);
|
|
|
|
public void initRenewalCount() => CurrentRenewalCount = 0;
|
|
|
|
public void increaseRenewalCount(Int32 increaseCount = 1)
|
|
{
|
|
CurrentRenewalCount += increaseCount;
|
|
}
|
|
|
|
public void setCurrentRenewalCount(Int32 currenctRenewalCount)
|
|
{
|
|
CurrentRenewalCount = currenctRenewalCount;
|
|
}
|
|
|
|
private ShopProductTradingMeterSubAttribute? findMeter(int product_id) =>
|
|
ShopProductTradingMeterSubs.FirstOrDefault(meter => meter.ProductId == product_id);
|
|
}
|
|
|
|
public class ShopProductTradingMeterAttributeTransactor : EntityAttributeTransactorBase<ShopProductTradingMeterAttribute>, ICopyEntityAttributeTransactorFromEntityAttribute
|
|
{
|
|
public ShopProductTradingMeterAttributeTransactor(EntityBase owner)
|
|
: base(owner)
|
|
{
|
|
}
|
|
|
|
public bool copyEntityAttributeTransactorFromEntityAttribute(EntityAttributeBase entityAttributeBase)
|
|
{
|
|
string err_msg;
|
|
|
|
var copy_from_shop_product_trading_meter_attribute = entityAttributeBase as ShopProductTradingMeterAttribute;
|
|
if (null == copy_from_shop_product_trading_meter_attribute)
|
|
{
|
|
err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_from_shop_product_trading_meter_attribute is null :{nameof(ShopProductTradingMeterAttribute)}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
var copy_to_shop_product_trading_meter_attribute = getClonedEntityAttribute() as ShopProductTradingMeterAttribute;
|
|
if (null == copy_to_shop_product_trading_meter_attribute)
|
|
{
|
|
err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_to_shop_product_trading_meter_attribute is null :{nameof(ShopProductTradingMeterAttribute)}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
copy_to_shop_product_trading_meter_attribute.onClear();
|
|
copy_to_shop_product_trading_meter_attribute.ShopId = copy_from_shop_product_trading_meter_attribute.ShopId;
|
|
copy_to_shop_product_trading_meter_attribute.EndTime = copy_from_shop_product_trading_meter_attribute.EndTime;
|
|
copy_to_shop_product_trading_meter_attribute.setCurrentRenewalCount(copy_from_shop_product_trading_meter_attribute.CurrentRenewalCount);
|
|
foreach (var subAttribute in copy_from_shop_product_trading_meter_attribute.ShopProductTradingMeterSubs)
|
|
{
|
|
var data = new ShopProductTradingMeterSubAttribute();
|
|
data.ProductId = subAttribute.ProductId;
|
|
data.LeftCount = subAttribute.LeftCount;
|
|
copy_to_shop_product_trading_meter_attribute.ShopProductTradingMeterSubs.Add(data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
} |