{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modifying record link groups\n",
    "\n",
    "Create a record link between two records in a Granta MI database.\n",
    "\n",
    "This example demonstrates:\n",
    "\n",
    "- Retrieve a list of record groups within a Granta MI database\n",
    "- Import a new record\n",
    "- Create a link between the new record and another record"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prerequisites\n",
    "Import required Python packages, and define two custom functions. The functions will:\n",
    "\n",
    "1. Format the current time (used to set the record name)\n",
    "2. Perform a record name search"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime\n",
    "\n",
    "def NowString():\n",
    "    return datetime.datetime.now().strftime(\"%d/%m/%Y %H:%M:%S\")\n",
    "\n",
    "def FindRecord(gdlSession, dbKey, tableName, recordName):\n",
    "    \"\"\" \n",
    "    Finds a record by name\n",
    "    :returns: :py:mod:`SearchResult <GRANTA_MIScriptingToolkit.SearchResult>`\n",
    "    \"\"\"\n",
    "    req = gdl.RecordNameSearchRequest(caseSensitiveNames=False, recordName=recordName, populateGUIDs=True, searchShortNames=True, searchFullNames=True)\n",
    "    req.table = gdl.TableReference(DBKey=dbKey, name=tableName)\n",
    "    resp = gdlSession.searchService.RecordNameSearch(req)\n",
    "    return resp.searchResults[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a Granta MI session\n",
    "Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import GRANTA_MIScriptingToolkit as gdl\n",
    "\n",
    "session = gdl.GRANTA_MISession('http://localhost/mi_servicelayer', autoLogon=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Create a link between a current record and a new record\n",
    "Find the record link groups that can be created within MaterialUniverse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training Exercise: id=116\n"
     ]
    }
   ],
   "source": [
    "dbkey = \"MI_Training\"\n",
    "tableName = \"MaterialUniverse\"\n",
    "\n",
    "req = gdl.GetRecordLinkGroups(DBKey=dbkey)\n",
    "\n",
    "grlg_resp = session.browseService.GetRecordLinkGroups(req)\n",
    "\n",
    "groups = {}\n",
    "for r in grlg_resp.recordLinkGroups:\n",
    "    if r.fromTable.name == tableName:\n",
    "        print(\"{0}: id={1}\".format(r.name, r.reference.recordLinkGroupIdentity))\n",
    "        groups[r.name] = r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Import a new record into the \"Training Exercise for Import\" table, with the current time as the record name. This will be the target record to create a link to later."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "grn_req = gdl.GetRootNode(table=groups[u'Training Exercise'].toTable)\n",
    "grn_resp = session.browseService.GetRootNode(grn_req)\n",
    "\n",
    "ir = gdl.ImportRecord(recordName=NowString(),\n",
    "                      existingRecord=grn_resp.rootNode.recordReference)\n",
    "req = gdl.SetRecordAttributesRequest(importRecords=[ir], importErrorMode=gdl.GRANTA_Constants.ImportErrorMode.Fault)\n",
    "resp = session.dataImportService.SetRecordAttributes(req)\n",
    "target = resp.recordsImported[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Set \"PMMA (cast sheet)\" in MaterialUniverse as the source record to create a link from."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "sourceResult = FindRecord(session, dbkey, \"MaterialUniverse\", \"PMMA (cast sheet)\")\n",
    "source = sourceResult.recordReference"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the ModifyRecordLinks operation to create a link called \"Training Exercise\" from \"PMMA (cast sheet)\" to the new imported record."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "destinationRec = gdl.NotatedTargetRecord(record=target.recordReference, notes=\"This will work\")\n",
    "mySourceRec = gdl.NotatedTargetedSourceRecord(sourceRecord=source,\n",
    "                                              targetRecords=[destinationRec])\n",
    "linkThisRecord = gdl.LinkRecords(sourceRecords=[mySourceRec])\n",
    "recordLinksMod = gdl.RecordLinkModifications(linkRecords=[linkThisRecord])\n",
    "\n",
    "req = gdl.ModifyRecordLinksRequest(recordLinkGroupReference=groups[u'Training Exercise'].reference,\n",
    "                                   recordLinkModifications=recordLinksMod,\n",
    "                                   importErrorMode=gdl.GRANTA_Constants.ImportErrorMode.Fault)\n",
    "mrlresp = session.dataImportService.ModifyRecordLinks(req)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print the record names and GUIDs for the newly-linked records. You can also check this new link in MI Viewer, by viewing the link on the \"PMMA (cast sheet)\" datasheet."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created 1 link(s)\n",
      "000016f6-000e-4fff-8fff-dd92ffff0000 (Cast sheet) -> b13dc2e3-eaa8-4f25-812b-a61fa9476db8 (23/03/2021 16:55:43)\n"
     ]
    }
   ],
   "source": [
    "print(\"Created {0} link(s)\".format(len(mrlresp.recordLinkChanges.linked)))\n",
    "\n",
    "change = mrlresp.recordLinkChanges.linked[0]\n",
    "print(\"{0} ({1}) -> {2} ({3})\".format(change.record.recordReference.recordGUID,\n",
    "                                      sourceResult.shortName,\n",
    "                                      change.targetRecords[0].recordReference.recordGUID,\n",
    "                                      ir.recordName))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
