Answers.Body: <p>You can do a shallow clone with <code>cv</code> (and a little stripping of the original ID).</p>
  
  <pre><code>cv api Contact.getsingle id=203 | sed -e 's#"id"#"foo"#g' | sed -e 's#"contact_id"#"bar"#g' | cv api Contact.create --in=json
  </code></pre>
  
  <p>For the rest, you'd really need to specify the outcomes. Should the spouse be a clone too, or the original? The event registrations are for a cloned event or the original? The employer and other relationships?</p>
  
  <p>1980s movie hijinks will abound as you explore the philosophical implications of cloning, in a time before it was a hellish near-reality.</p>
  
  <hr>
  
  <p>OK, it's sprint, here's some JS to clone a contact:</p>
  
  <pre><code>// Go find a contact
  CRM.api3('Contact', 'get', {
    "sequential": 1,
    "id": 361
  }).done(function(res_old) {
    // Grab contact out and remove their ID.
    var contact_params = res_old.values[0];
    // Remove existing ID so we create a new contact.
    delete contact_params.id;
    delete contact_params.contact_id;
    // Create our new contact.
    CRM.api3('Contact', 'create', contact_params);
  });
  </code></pre>
  
  <p>And, to clone a contact and related contributions:</p>
  
  <pre><code>// Cloning a full contact + related contributions (+ ...)
  CRM.api3('Contact', 'get', {
    "sequential": 1,
    "id": 361
  }).done(function(res_old) {
    // Grab contact out and remove their ID.
    var contact_params = res_old.values[0];
    // Remove existing ID so we create a new contact.
    delete contact_params.id;
    delete contact_params.contact_id;
    // Create our new contact.
    CRM.api3('Contact', 'create', contact_params)
      .done(function (res_new) {
        // Now handle related entities, one by one.
        // Contributions only as an example below.
        CRM.api3('Contribution', 'get', {contact_id: res_old.id})
          .done(function(res_contrib) {
            for (var key in res_contrib.values) {
              var new_contrib = res_contrib.values[key];
              // Returned values need to be adjusted so we create a new contribution.
              // Remove link(s) with previous contribution.
              delete new_contrib.id;
              delete new_contrib.contribution_id;
              // Associate with the new contact.
              new_contrib.contact_id = res_new.id;
              // Contribution.create requires financial_type_id, not provided by
              // Contribution.get. That's a whole other topic. Random ID here.
              // You'd actually need to use api "return" to get all fields.
              new_contrib.financial_type_id = 1;
              CRM.api3('Contribution', 'create', new_contrib)
                .done(function (res_newcontrib) {
                  // console.log(res_newcontrib, 'rnc');
                }); //
            }
          });
          // Repeat as above for other related entities you wish to clone.
      });
  });
  </code></pre>
  
  <p>And so on to clone Contact with related Participant, Contribution &amp; Relationship records ... Some thoughts on this:</p>
  
  <ul>
  <li>Cloning a contact or other simple entity is straightforward here.</li>
  <li>Cloning related entities got verbose fast!</li>
  <li>It's kinda weird that you have to remove both contribution.contribution_id and contribution.id, both contact.id and contact.contact_id ...</li>
  <li>It's also kinda weird that you can't pipe a <code>contribution.get</code> back into a <code>contribution.create</code> because <code>contribution.get</code> does not return the (required) <code>financial_type_id</code> field.</li>
  <li>Sounds like to handle this last point, the current approach would require using <code>return</code> with the API to specify all the fields on an entity, including the required ones not returned by default.</li>
  </ul>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T20:43:08.453Z
Answers.Text: in the scenario i was thinking around, the Contact and any Participant, Contribution, Relationship records would be cloned. I was not requiring or even considering cloning spouses or Events.
Answers.UserDisplayName: petednz - fuzion
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T11:02:03.480Z
Answers.LastActivityDate: 2017-05-11T04:22:30.777Z
Answers.LastEditDate: 2017-05-11T04:22:30.777Z
Answers.UserDisplayName: Chris Burgess
Answers.Body: <p>You can clone by creating a new contact and merging with the old one. </p>
  
  <p>Once merged you can pull the old one back by searching in deleted contacts and restoring the deleted one.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-28T01:18:37.320Z
Answers.Text: hmm. interesting concept. i will give it a try
Answers.UserDisplayName: petednz - fuzion
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-06-05T15:03:45.253Z
Answers.Text: This is quite hacky but it quite works!
  But that way you can copy only the basic contact information. Things like event registrations or contributions are all only in 1 contact (they was moved (not copied) form one to the other).
Answers.UserDisplayName: KuboF Hromoslav
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-27T19:49:27.837Z
Answers.LastActivityDate: 2020-02-27T19:49:27.837Z
Answers.UserDisplayName: Interlated
Answers.Body: <p>Interesting idea Pete! Not looking at doing this. I would certainly limit to basic contact data and custom fields on contact level as a start. Perhaps relationships would make sense but hard to determine if they all need cloning (for example case relationships probably not)....</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T10:34:30.157Z
Answers.Text: Yep, my sense is the interdependency of CiviCRM entities would mean you'd need to specify what should happen with each related civi-thing your contact is connected to. The API calls will be the easy part!
Answers.UserDisplayName: Chris Burgess
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T10:43:53.203Z
Answers.Text: Paul B wants to know [How to clone a contribution?](https://civicrm.stackexchange.com/questions/18394/copy-duplicate-a-contribution) - maybe there's demand for an entity clone tool.
Answers.UserDisplayName: Chris Burgess
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T10:49:40.420Z
Answers.Text: Excellent. Clone me a Burgess when you have it up and running ;-)
Answers.UserDisplayName: petednz - fuzion
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-02T06:28:00.697Z
Answers.LastActivityDate: 2017-05-02T06:28:00.697Z
Answers.UserDisplayName: ErikH - CiviCooP
Body: <p>Just hit a few cases where it would be great to have a contact with exact same status eg event, member, relationship, contribution, and of course custom fields on contact and those other entities etc so we can 'test' a fix on. </p>
  
  <p>Might not need to clone 'everything' eg Activities, since I can see complexity bursting forth.</p>
  
  <p>Anyone else looked at doing this? Any thoughts about (im)possibility of doing this?</p>
  
Tags: <contacts>
Title: How to clone a contact?
ThreadText: # How to clone a contact?
  
  (Asked by: username_0 on 2017-05-02)
  
  Just hit a few cases where it would be great to have a contact with exact same status eg event, member, relationship, contribution, and of course custom fields on contact and those other entities etc so we can 'test' a fix on.
  
  Might not need to clone 'everything' eg Activities, since I can see complexity bursting forth.
  
  Anyone else looked at doing this? Any thoughts about (im)possibility of doing this?
  
  **Tags:** contacts
  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_1 on 2017-05-02. Score: 3
  
  You can do a shallow clone with cv (and a little stripping of the original ID).
  cv api Contact.getsingle id=203 | sed -e 's#"id"#"foo"#g' | sed -e 's#"contact_id"#"bar"#g' | cv api Contact.create --in=json
  
  For the rest, you'd really need to specify the outcomes. Should the spouse be a clone too, or the original? The event registrations are for a cloned event or the original? The employer and other relationships?
  1980s movie hijinks will abound as you explore the philosophical implications of cloning, in a time before it was a hellish near-reality.
  
  OK, it's sprint, here's some JS to clone a contact:
  // Go find a contact
  CRM.api3('Contact', 'get', {
    "sequential": 1,
    "id": 361
  }).done(function(res_old) {
    // Grab contact out and remove their ID.
    var contact_params = res_old.values[0];
    // Remove existing ID so we create a new contact.
    delete contact_params.id;
    delete contact_params.contact_id;
    // Create our new contact.
    CRM.api3('Contact', 'create', contact_params);
  });
  
  And, to clone a contact and related contributions:
  // Cloning a full contact + related contributions (+ ...)
  CRM.api3('Contact', 'get', {
    "sequential": 1,
    "id": 361
  }).done(function(res_old) {
    // Grab contact out and remove their ID.
    var contact_params = res_old.values[0];
    // Remove existing ID so we create a new contact.
    delete contact_params.id;
    delete contact_params.contact_id;
    // Create our new contact.
    CRM.api3('Contact', 'create', contact_params)
      .done(function (res_new) {
        // Now handle related entities, one by one.
        // Contributions only as an example below.
        CRM.api3('Contribution', 'get', {contact_id: res_old.id})
          .done(function(res_contrib) {
            for (var key in res_contrib.values) {
              var new_contrib = res_contrib.values[key];
              // Returned values need to be adjusted so we create a new contribution.
              // Remove link(s) with previous contribution.
              delete new_contrib.id;
              delete new_contrib.contribution_id;
              // Associate with the new contact.
              new_contrib.contact_id = res_new.id;
              // Contribution.create requires financial_type_id, not provided by
              // Contribution.get. That's a whole other topic. Random ID here.
              // You'd actually need to use api "return" to get all fields.
              new_contrib.financial_type_id = 1;
              CRM.api3('Contribution', 'create', new_contrib)
                .done(function (res_newcontrib) {
                  // console.log(res_newcontrib, 'rnc');
                }); //
            }
          });
          // Repeat as above for other related entities you wish to clone.
      });
  });
  
  And so on to clone Contact with related Participant, Contribution & Relationship records ... Some thoughts on this:
  
  Cloning a contact or other simple entity is straightforward here.
  Cloning related entities got verbose fast!
  It's kinda weird that you have to remove both contribution.contribution_id and contribution.id, both contact.id and contact.contact_id ...
  It's also kinda weird that you can't pipe a contribution.get back into a contribution.create because contribution.get does not return the (required) financial_type_id field.
  Sounds like to handle this last point, the current approach would require using return with the API to specify all the fields on an entity, including the required ones not returned by default.
  
  > **Comments:**
  > **username_0**: in the scenario i was thinking around, the Contact and any Participant, Contribution, Relationship records would be cloned. I was not requiring or even considering cloning spouses or Events.  
  
  ---
  
  ### Answer by username_2 on 2020-02-27. Score: 2
  
  You can clone by creating a new contact and merging with the old one.
  
  Once merged you can pull the old one back by searching in deleted contacts and restoring the deleted one.
  
  > **Comments:**
  > **username_0**: hmm. interesting concept. i will give it a try  
  > **username_3**: This is quite hacky but it quite works! But that way you can copy only the basic contact information. Things like event registrations or contributions are all only in 1 contact (they was moved (not copied) form one to the other).  
  
  ---
  
  ### Answer by username_4 on 2017-05-02. Score: 1
  
  Interesting idea Pete! Not looking at doing this. I would certainly limit to basic contact data and custom fields on contact level as a start. Perhaps relationships would make sense but hard to determine if they all need cloning (for example case relationships probably not)....
  
  > **Comments:**
  > **username_1**: Yep, my sense is the interdependency of CiviCRM entities would mean you'd need to specify what should happen with each related civi-thing your contact is connected to. The API calls will be the easy part!  
  > **username_1**: Paul B wants to know [How to clone a contribution?](https://civicrm.stackexchange.com/questions/18394/copy-duplicate-a-contribution) - maybe there's demand for an entity clone tool.  
  > **username_0**: Excellent. Clone me a Burgess when you have it up and running ;-)  
  
  ---
  
  