Cannot edit a record - Record already exists

I’m trying to copy purch setup from another record but I’m getting a duplicate key error. I cannot comprehend why that is.

void CopyPurchSalesSetup()
{
InventItemPurchSetup NewPurchSetup;
RefRecId NewPurchSetupRecId;
;

NewPurchSetup = NewInventTable.inventItemPurchSetup(InventDim::inventDimIdBlank(), true);
NewPurchSetupRecId = NewPurchSetup.RecId;
NewPurchSetup.data(InventTable.inventItemPurchSetup(InventDim::inventDimIdBlank()));
NewPurchSetup.ItemId = NewInventTable.ItemId;
NewPurchSetup.RecId = NewPurchSetupRecId;
NewPurchSetup.write();

}

Your code looks very strange. If the first line returns a record, your code doesn’t create a copy. It tries to change an existing record to match another record. And of course, trying to use the same field values in the primary key is a bug and database will reject this invalid data (with duplicate key error).
And if the first line isn’t supposed to create a record, why do you have such code there?

A new item is created in NewInventTable as a duplicate of InventTable but with a new unique Item ID. InventItemPurchSetup should also be duplicated with a new Item ID. It is already duplicated at this point in the code so the first line does return a record. I have verified that in this case the write metoden initiates update method.

I find the existing purch setup. Copy over all fields from the purch setup from the old item ID. Then I change the item ID to the new item ID (because otherwise I definitely WOULD have a duplicate record). And then I call write, which calls update. The key is item ID and invent dim which both remain unchanged.

EDIT: Just to be clear, my requirement is simply to copy over all setup fields from one InventItemPurchSetup to another.

Okay, now I understand your intention. Let me it a bit easier to understand:

InventItemPurchSetup newPurchSetup = newInventTable.inventItemPurchSetup(InventDim::inventDimIdBlank(), true);
InventItemPurchSetup oldPurchSetup = oldInventTable.inventItemPurchSetup(InventDim::inventDimIdBlank());

// Remeber current RecId
RecId newPurchSetupRecId = newPurchSetup.RecId;

// Copy all field values to newPurchSetup
newPurchSetup.data(oldPurchSetup);

// Put original values of ItemId and PurchId back
newPurchSetup.ItemId = newInventTable.ItemId;
newPurchSetup.RecId = newPurchSetupRecId;
newPurchSetup.update();

What exactly does the error message say? Is it thown by super() of InventItemPurchSetup.update()? (There is other code in update() that could be the reason.) Does the debugger show the expected values when saving the record? Don’t you have any other unique index on the table?

I suspect the problem is in using data(). What if you use buf2buf() instead?

Error message (translated from Danish - I can change language to be sure but it is fairly standard):
Cannot edit a record in Item purchase order settings (InventItemPurchSetup). Item number: Newly created ID, blank Invent Dim ID. The record already exists.
Item ID and Rec ID are set as expected (and also Invent Dim ID).
Error thrown by update super call. No overridden code. No customization to the table at all. No other index.

I do recall reading a recommendation to use buf2buf. I’ll try that.

buf2buf did the trick. It neatly avoids all system fields - including SequenceNum which I couldn’t change. Could that be the issue? The mystery of code that does not perform as expected annoys me but problem is solved. Thank you!