@rajeshvemunoori31 , please find the code which copies the appointment to a new one (with appointment details, but without creation of a new service order) upon the Complete action
public class VanDykAppointmentEntry_Extension : PXGraphExtension<AppointmentEntry>
{
#region COmplete Action
public virtual void CopyAppointmentBeforeCompletion()
{
AppointmentEntry graph = PXGraph.CreateInstance<AppointmentEntry>();
string sourceOrderType = Base.AppointmentRecords.Current?.SrvOrdType;
string sourceOrderNbr = Base.AppointmentRecords.Current?.RefNbr;
string newOrderType = "MRO ";
string newApptNbr = " <NEW>";
FSAppointment record = (FSAppointment)graph.AppointmentRecords.Cache.CreateCopy(Base.AppointmentRecords.Current);
try
{
graph.SkipLotSerialFieldVerifying = true;
graph.IsCloningAppointment = true;
record.SrvOrdType = newOrderType;
record.RefNbr = null;
record.NoteID = null;
record.AppointmentID = null;
record.SORefNbr = Base.AppointmentRecords.Current.SORefNbr;
record.SOID = Base.AppointmentRecords.Current.SOID;
record = (FSAppointment)graph.AppointmentRecords.Cache.Insert(record); //autosave happens here for some reason
//copy appointment details
PXResultset<FSAppointmentDet> sourceFSApptLines =
PXSelectReadonly<FSAppointmentDet,
Where<FSAppointmentDet.srvOrdType, Equal<Required<FSAppointmentDet.srvOrdType>>,
And<FSAppointmentDet.refNbr, Equal<Required<FSAppointmentDet.refNbr>>>>>
.Select(graph, sourceOrderType, sourceOrderNbr);
foreach (FSAppointmentDet sourceAppointmentDet in sourceFSApptLines)
{
FSAppointmentDet targetAppointmentDet = PXCache<FSAppointmentDet>.CreateCopy(sourceAppointmentDet);
targetAppointmentDet.SrvOrdType = graph.AppointmentRecords.Current.SrvOrdType;
targetAppointmentDet.RefNbr = graph.AppointmentRecords.Current.RefNbr;
// targetAppointmentDet.LineNbr = null;
targetAppointmentDet.AppointmentID = graph.AppointmentRecords.Current.AppointmentID;
targetAppointmentDet.AppDetID = null;
targetAppointmentDet.NoteID = null;
// targetAppointmentDet.EstimatedQty = 0;
graph.Caches[typeof(FSAppointmentDet)].SetValueExt<FSAppointmentDet.estimatedQty>(targetAppointmentDet, 0m);
graph.Caches[typeof(FSAppointmentDet)].SetValueExt<FSAppointmentDet.actualQty>(targetAppointmentDet, 0m);
//targetAppointmentDet = Base.AppointmentDetails.Insert(targetAppointmentDet);
targetAppointmentDet = (FSAppointmentDet)graph.AppointmentDetails.Cache.Insert(targetAppointmentDet);
}
var stamp = PXDatabase.SelectTimeStamp();
PXTimeStampScope.PutPersisted(graph.Caches[typeof(FSAppointment)], graph.AppointmentRecords.Current, stamp);
graph.Save.Press();
}
finally
{
graph.SkipLotSerialFieldVerifying = false;
graph.IsCloningAppointment = false;
}
}
public delegate IEnumerable CompleteAppointmentDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable CompleteAppointment(PXAdapter adapter, CompleteAppointmentDelegate baseMethod)
{
if (Base.AppointmentSelected.Current != null)
{
CopyAppointmentBeforeCompletion();
}
return baseMethod(adapter);
}
#endregion
}
Notice that this code assigns the key fields values (SrvOrdType and Refnbr) to the appointment details created (instead of leaving them blank and relying on PXDbDefault)
This happens because the insert operation into the primary (FSAppointment) cache launched during the workflow action inherits the auto-saving behavior for the existing record. Because the Complete Appointment action auto-persists an existing FSAppointment record, this auto-persisting is applied to all other FSAppointment records we operate on during this action.
This reason might explain why you get the error trying t use the ‘generic copy-paste mechanism’ though I did not investigate it deep