This commit is contained in:
@@ -208,7 +208,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async System.Threading.Tasks.Task<long> Getv7v8IdMap(Guid id, RootObjectTypes desiredType, bool allowPatch = true, bool doNotFail = true)
|
private async System.Threading.Tasks.Task<long> Getv7v8IdMap(Guid id, RootObjectTypes desiredType, bool allowPatch = true, bool doNotFail = true, long? extraV8Id=null)
|
||||||
{
|
{
|
||||||
if (!V7ToV8IdMap.ContainsKey(id))
|
if (!V7ToV8IdMap.ContainsKey(id))
|
||||||
{
|
{
|
||||||
@@ -218,15 +218,15 @@ namespace AyaNova.PlugIn.V8
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//not found, patch allowed, create a substitute record for it and put it in the map
|
//not found, patch allowed, create a substitute record for it and put it in the map
|
||||||
await CreateSubstitute(id, desiredType);
|
await CreateSubstitute(id, desiredType, extraV8Id);
|
||||||
}
|
}
|
||||||
return V7ToV8IdMap[id];
|
return V7ToV8IdMap[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
private async System.Threading.Tasks.Task<long?> Getv7v8IdMapNullOk(Guid id, RootObjectTypes desiredType, bool allowPatch = true, bool doNotFail = false)
|
private async System.Threading.Tasks.Task<long?> Getv7v8IdMapNullOk(Guid id, RootObjectTypes desiredType, bool allowPatch = true, bool doNotFail = false, long? extraV8Id=null)
|
||||||
{
|
{
|
||||||
if (id == Guid.Empty) return null;
|
if (id == Guid.Empty) return null;
|
||||||
long l = await Getv7v8IdMap(id, desiredType, allowPatch, doNotFail);
|
long l = await Getv7v8IdMap(id, desiredType, allowPatch, doNotFail, extraV8Id);
|
||||||
if (l == 0) return null;//this is the no patch no fail path
|
if (l == 0) return null;//this is the no patch no fail path
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -237,26 +237,26 @@ namespace AyaNova.PlugIn.V8
|
|||||||
private string MissingDataNamePrefix = "zV8migrate_substitute";//append guid to ensure uniqueness
|
private string MissingDataNamePrefix = "zV8migrate_substitute";//append guid to ensure uniqueness
|
||||||
|
|
||||||
|
|
||||||
private async System.Threading.Tasks.Task CreateSubstitute(Guid id, RootObjectTypes desiredType)
|
private async System.Threading.Tasks.Task CreateSubstitute(Guid id, RootObjectTypes desiredType, long? extraV8Id=null)
|
||||||
{
|
{
|
||||||
//create the simplest possible version of this object desired
|
//create the simplest possible version of this object desired
|
||||||
dynamic d = new JObject();
|
dynamic d = new JObject();
|
||||||
string sName = MissingDataNamePrefix + " " + id.ToString();
|
string sName = MissingDataNamePrefix + " " + id.ToString();
|
||||||
d.name = sName;//usually this will suffice, for the rare cases it doesn't add to the correct property below, the name property will be ignored if it's not applicable
|
d.name = sName;//usually this will suffice, for the rare cases it doesn't add to the correct property below, the name property will be ignored if it's not applicable
|
||||||
|
d.active=false;
|
||||||
|
d.notes="This object created during v8 migrate as a substitute for a missing linked record in v7";
|
||||||
string route = "";
|
string route = "";
|
||||||
switch (desiredType)
|
switch (desiredType)
|
||||||
{
|
{
|
||||||
|
|
||||||
//I guess go through export* and find everything exported and if it can have any of the above then it needs to be here for docs/wiki/attachments
|
|
||||||
//set route and make dynamic object
|
|
||||||
case RootObjectTypes.Part:
|
case RootObjectTypes.Part:
|
||||||
{
|
{
|
||||||
|
route = "part";
|
||||||
|
d.partNumber = sName;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.PartWarehouse:
|
case RootObjectTypes.PartWarehouse:
|
||||||
{
|
{
|
||||||
|
route = "part-warehouse";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.Client:
|
case RootObjectTypes.Client:
|
||||||
@@ -267,27 +267,16 @@ namespace AyaNova.PlugIn.V8
|
|||||||
case RootObjectTypes.Vendor:
|
case RootObjectTypes.Vendor:
|
||||||
{
|
{
|
||||||
route = "vendor";
|
route = "vendor";
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.HeadOffice:
|
case RootObjectTypes.HeadOffice:
|
||||||
{
|
{
|
||||||
route = "headoffice";
|
route = "head-office";
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.User:
|
case RootObjectTypes.User:
|
||||||
{
|
{
|
||||||
route = "user";
|
route = "user";
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RootObjectTypes.Contract:
|
|
||||||
{
|
|
||||||
//needs expiry date as well and I guess inactive
|
|
||||||
route = "contract";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.Project:
|
case RootObjectTypes.Project:
|
||||||
@@ -297,7 +286,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
break;
|
break;
|
||||||
case RootObjectTypes.TaxCode:
|
case RootObjectTypes.TaxCode:
|
||||||
{
|
{
|
||||||
route = "taxcode";
|
route = "tax-code";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.UnitModel:
|
case RootObjectTypes.UnitModel:
|
||||||
@@ -308,193 +297,27 @@ namespace AyaNova.PlugIn.V8
|
|||||||
case RootObjectTypes.Unit:
|
case RootObjectTypes.Unit:
|
||||||
{
|
{
|
||||||
route = "unit";
|
route = "unit";
|
||||||
|
d.serial=sName;
|
||||||
|
d.customerId=extraV8Id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.WorkOrderStatus:???????
|
case RootObjectTypes.WorkOrderStatus:
|
||||||
{
|
{
|
||||||
route = "work-order-status";???
|
route = "work-order-status";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.WorkOrderItemPriority:???
|
case RootObjectTypes.WorkOrderItemPriority:
|
||||||
{
|
{
|
||||||
route = "work-order-item-priority";???
|
route = "work-order-item-priority";
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.PurchaseOrder:
|
|
||||||
{
|
|
||||||
route = "purchase-order";
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RootObjectTypes.LoanUnit:
|
case RootObjectTypes.LoanUnit:
|
||||||
{
|
{
|
||||||
route = "loan-unit";
|
route = "loan-unit";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RootObjectTypes.XXXX:
|
|
||||||
{
|
|
||||||
route = "YYYYYYY";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Error: CreateSubstitute (source id: " + id.ToString() + " for type: " + desiredType.ToString() + ") THIS TYPE NOT CODED YET");
|
throw new Exception("Error: CreateSubstitute (source id: " + id.ToString() + " for type: " + desiredType.ToString() + ") THIS TYPE NOT CODED YET");
|
||||||
}
|
}
|
||||||
@@ -1295,8 +1118,13 @@ namespace AyaNova.PlugIn.V8
|
|||||||
|
|
||||||
if (c.ContractID != Guid.Empty)
|
if (c.ContractID != Guid.Empty)
|
||||||
{
|
{
|
||||||
d.contractId = Getv7v8IdMap(c.ContractID, RootObjectTypes.Contract);
|
long? ctId = Getv7v8IdMapNullOk(c.ContractID, RootObjectTypes.Contract, false, true);
|
||||||
d.contractExpires = c.ContractExpires;
|
if (ctId != 0 && ctId != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
d.contractId = ctId;
|
||||||
|
d.contractExpires = c.ContractExpires;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1500,8 +1328,13 @@ namespace AyaNova.PlugIn.V8
|
|||||||
|
|
||||||
if (c.ContractID != Guid.Empty)
|
if (c.ContractID != Guid.Empty)
|
||||||
{
|
{
|
||||||
d.contractId = Getv7v8IdMap(c.ContractID, RootObjectTypes.Contract);
|
long? ctId = Getv7v8IdMapNullOk(c.ContractID, RootObjectTypes.Contract, false, true);
|
||||||
d.contractExpires = c.ContractExpires;
|
if (ctId != 0 && ctId != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
d.contractId = ctId;
|
||||||
|
d.contractExpires = c.ContractExpires;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3188,7 +3021,9 @@ namespace AyaNova.PlugIn.V8
|
|||||||
d.completeByDate = util.DateToV8(c.WorkorderService.CloseByDate);
|
d.completeByDate = util.DateToV8(c.WorkorderService.CloseByDate);
|
||||||
d.invoiceNumber = c.WorkorderService.InvoiceNumber;
|
d.invoiceNumber = c.WorkorderService.InvoiceNumber;
|
||||||
d.onsite = c.Onsite;
|
d.onsite = c.Onsite;
|
||||||
d.contractId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract);
|
long? ctId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract, false, true);
|
||||||
|
if (ctId == 0) ctId = null;
|
||||||
|
d.contractId = ctId;
|
||||||
d.lastStatusId = Getv7v8IdMapNullOk(c.WorkorderService.WorkorderStatusID, RootObjectTypes.WorkOrderStatus);//workorder status is in regular map, only item status is special
|
d.lastStatusId = Getv7v8IdMapNullOk(c.WorkorderService.WorkorderStatusID, RootObjectTypes.WorkOrderStatus);//workorder status is in regular map, only item status is special
|
||||||
|
|
||||||
var client = c.uiClient;
|
var client = c.uiClient;
|
||||||
@@ -3325,7 +3160,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
{
|
{
|
||||||
|
|
||||||
//make sure we have a matching unit already
|
//make sure we have a matching unit already
|
||||||
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit);
|
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit, true,false,Getv7v8IdMap(c.ClientID, RootObjectTypes.Client));
|
||||||
if (ravUnitId != null)
|
if (ravUnitId != null)
|
||||||
{
|
{
|
||||||
//we have a legit unit record, make it for v8
|
//we have a legit unit record, make it for v8
|
||||||
@@ -3568,7 +3403,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
{
|
{
|
||||||
|
|
||||||
//make sure we have a matching unit already
|
//make sure we have a matching unit already
|
||||||
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit);
|
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit,true,false,Getv7v8IdMap(c.ClientID, RootObjectTypes.Client));
|
||||||
if (ravUnitId != null)
|
if (ravUnitId != null)
|
||||||
{
|
{
|
||||||
//we have a legit unit record, make it for v8
|
//we have a legit unit record, make it for v8
|
||||||
@@ -3741,8 +3576,9 @@ namespace AyaNova.PlugIn.V8
|
|||||||
d.validUntil = util.DateToV8(c.WorkorderQuote.ValidUntilDate);
|
d.validUntil = util.DateToV8(c.WorkorderQuote.ValidUntilDate);
|
||||||
d.submitted = util.DateToV8(c.WorkorderQuote.DateSubmitted);
|
d.submitted = util.DateToV8(c.WorkorderQuote.DateSubmitted);
|
||||||
d.approved = util.DateToV8(c.WorkorderQuote.DateApproved);
|
d.approved = util.DateToV8(c.WorkorderQuote.DateApproved);
|
||||||
|
long? ctId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract, false, true);
|
||||||
d.contractId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract);
|
if (ctId == 0) ctId = null;
|
||||||
|
d.contractId = ctId;
|
||||||
d.lastStatusId = (int)c.WorkorderQuote.QuoteStatus;
|
d.lastStatusId = (int)c.WorkorderQuote.QuoteStatus;
|
||||||
|
|
||||||
var client = c.uiClient;
|
var client = c.uiClient;
|
||||||
@@ -3847,7 +3683,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
{
|
{
|
||||||
|
|
||||||
//make sure we have a matching unit already
|
//make sure we have a matching unit already
|
||||||
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit);
|
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit,true,false,Getv7v8IdMap(c.ClientID, RootObjectTypes.Client));
|
||||||
if (ravUnitId != null)
|
if (ravUnitId != null)
|
||||||
{
|
{
|
||||||
//we have a legit unit record, make it for v8
|
//we have a legit unit record, make it for v8
|
||||||
@@ -4041,7 +3877,9 @@ namespace AyaNova.PlugIn.V8
|
|||||||
d.customerReferenceNumber = c.CustomerReferenceNumber;
|
d.customerReferenceNumber = c.CustomerReferenceNumber;
|
||||||
d.customerContactName = c.CustomerContactName;
|
d.customerContactName = c.CustomerContactName;
|
||||||
d.createdDate = util.DateToV8(c.Created, true);
|
d.createdDate = util.DateToV8(c.Created, true);
|
||||||
d.contractId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract);
|
long? ctId = Getv7v8IdMapNullOk(c.ContractIDResolved(), RootObjectTypes.Contract, false, true);
|
||||||
|
if (ctId == 0) ctId = null;
|
||||||
|
d.contractId = ctId;
|
||||||
|
|
||||||
//PM specific fields
|
//PM specific fields
|
||||||
d.copyWiki = false;
|
d.copyWiki = false;
|
||||||
@@ -4196,7 +4034,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
{
|
{
|
||||||
|
|
||||||
//make sure we have a matching unit already
|
//make sure we have a matching unit already
|
||||||
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit);
|
var ravUnitId = Getv7v8IdMapNullOk(wi.UnitID, RootObjectTypes.Unit,true,false,Getv7v8IdMap(c.ClientID, RootObjectTypes.Client));
|
||||||
if (ravUnitId != null)
|
if (ravUnitId != null)
|
||||||
{
|
{
|
||||||
//we have a legit unit record, make it for v8
|
//we have a legit unit record, make it for v8
|
||||||
@@ -4580,7 +4418,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
d.notes = c.Details;
|
d.notes = c.Details;
|
||||||
d.dateRequested = util.DateToV8(c.Created, true);
|
d.dateRequested = util.DateToV8(c.Created, true);
|
||||||
d.customerId = Getv7v8IdMap(c.ClientID, RootObjectTypes.Customer);
|
d.customerId = Getv7v8IdMap(c.ClientID, RootObjectTypes.Customer);
|
||||||
d.unitId = Getv7v8IdMapNullOk(c.UnitID, RootObjectTypes.Unit);
|
d.unitId = Getv7v8IdMapNullOk(c.UnitID, RootObjectTypes.Unit,true,false,Getv7v8IdMap(c.ClientID, RootObjectTypes.Client));
|
||||||
d.workOrderItemId = Getv7v8IdMapNullOk(c.WorkorderItemID, RootObjectTypes.WorkOrderItem, false, false);
|
d.workOrderItemId = Getv7v8IdMapNullOk(c.WorkorderItemID, RootObjectTypes.WorkOrderItem, false, false);
|
||||||
d.requestedByUserId = SafeGetUserMap(c.Creator);//creator should always be a 'outside' user account
|
d.requestedByUserId = SafeGetUserMap(c.Creator);//creator should always be a 'outside' user account
|
||||||
d.customerReferenceNumber = c.ClientRef;
|
d.customerReferenceNumber = c.ClientRef;
|
||||||
@@ -5597,7 +5435,7 @@ namespace AyaNova.PlugIn.V8
|
|||||||
//Form data like the bizobject type and id
|
//Form data like the bizobject type and id
|
||||||
|
|
||||||
|
|
||||||
string RavenTypeAsString = "";
|
string RavenTypeAsString = "";
|
||||||
int ravenType = 0;//notype is default for orphaned objects
|
int ravenType = 0;//notype is default for orphaned objects
|
||||||
long v8Id = Getv7v8IdMap(tid.ID, tid.RootObjectType, false, true);//default to 0 id if no match which is good for raven as it puts it into a list users can deal with in UI
|
long v8Id = Getv7v8IdMap(tid.ID, tid.RootObjectType, false, true);//default to 0 id if no match which is good for raven as it puts it into a list users can deal with in UI
|
||||||
if (v8Id != 0)
|
if (v8Id != 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user