{"action":"created","comment":{"url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments/60026038","id":60026038,"diff_hunk":"@@ -29,68 +29,102 @@ class LedgerProcessorSQL(LedgerProcessorInterface):\n     Ledger processor for new SQL-based code.\n     \"\"\"\n \n-    def get_models_to_update(self, stock_report_helper, ledger_db=None):\n+    def get_models_to_update(self, form_id, stock_report_helpers, deprecated_helpers, ledger_db=None):\n         ledger_db = ledger_db or LedgerDBSQL()\n-        latest_values = {}\n-        to_save = []\n-        for stock_trans in stock_report_helper.transactions:\n-            def _lazy_original_balance():\n-                # needs to be in closures because it's zero-argument.\n-                # see compute_ledger_values for more information\n-                reference = stock_trans.ledger_reference\n-                if reference not in latest_values:\n-                    latest_values[reference] = ledger_db.get_current_ledger_value(reference)\n-                return latest_values[reference]\n-\n-            new_ledger_values = compute_ledger_values(\n-                _lazy_original_balance, stock_report_helper.report_type, stock_trans.relative_quantity\n-            )\n-\n-            ledger_value = ledger_db.get_ledger(stock_trans.ledger_reference)\n-            if not ledger_value:\n-                ledger_value = LedgerValue(**stock_trans.ledger_reference._asdict())\n-\n-            transaction = _get_ledger_transaction(\n-                _lazy_original_balance,\n-                stock_report_helper,\n-                stock_trans,\n-                new_ledger_values.balance\n-            )\n-            ledger_value.track_create(transaction)\n-\n-            # only do this after we've created the transaction otherwise we'll get the wrong delta\n-            ledger_value.balance = new_ledger_values.balance\n-            latest_values[stock_trans.ledger_reference] = new_ledger_values.balance\n-            to_save.append(ledger_value)\n-\n-        return StockModelUpdateResult(to_save=to_save)\n+        result = StockModelUpdateResult()\n+\n+        ledgers_needing_rebuild = {\n+            deprecated_transaction.ledger_reference\n+            for deprecated_helper in deprecated_helpers\n+            for deprecated_transaction in deprecated_helper.transactions\n+        }\n+\n+        updated_ledgers = []\n+        for helper in stock_report_helpers:\n+            for stock_trans in helper.transactions:\n+                ledger_value = self._process_transaction(helper, stock_trans, ledger_db)\n+                updated_ledgers.append(ledger_value)\n+\n+        for ledger_value in updated_ledgers:\n+            if ledger_value.ledger_reference in ledgers_needing_rebuild:\n+                rebuilt_ledger_value = self._rebuild_ledger(form_id, ledger_value)\n+                result.to_save.append(rebuilt_ledger_value)\n+            else:\n+                result.to_save.append(ledger_value)\n+\n+        return result\n+\n+    @staticmethod\n+    def _process_transaction(stock_report_helper, stock_trans, ledger_db):\n+        def _lazy_original_balance():\n+            # needs to be in closures because it's zero-argument.\n+            # see compute_ledger_values for more information\n+            reference = stock_trans.ledger_reference\n+            return ledger_db.get_current_ledger_value(reference)\n+\n+        new_ledger_values = compute_ledger_values(\n+            _lazy_original_balance, stock_report_helper.report_type, stock_trans.relative_quantity\n+        )\n+        ledger_value = ledger_db.get_ledger(stock_trans.ledger_reference)\n+        if not ledger_value:\n+            ledger_value = LedgerValue(**stock_trans.ledger_reference._asdict())\n+        transaction = _get_ledger_transaction(\n+            _lazy_original_balance,\n+            stock_report_helper,\n+            stock_trans,\n+            new_ledger_values.balance\n+        )\n+        ledger_value.track_create(transaction)\n+        # only do this after we've created the transaction otherwise we'll get the wrong delta\n+        ledger_value.balance = new_ledger_values.balance\n+        return ledger_value\n+\n+    def _rebuild_ledger(self, form_id, ledger_value):\n+        \"\"\"\n+        Rebuild a LedgerValue and its associated transactions during a form edit workflow.\n+\n+        :param form_id: ID of edited form\n+        :param ledger_value: LedgerValue to rebuild with transactions from new form tracked on the model\n+        :return: updated LedgerValue object\n+        \"\"\"\n+        transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(**ledger_value.ledger_reference._asdict())","path":"corehq/form_processor/backends/sql/ledger.py","position":96,"original_position":96,"commit_id":"6e65a2e92cee972f8cbdf9bdcab272c90ec38379","original_commit_id":"6e65a2e92cee972f8cbdf9bdcab272c90ec38379","user":{"login":"dimagimon","id":1179034,"avatar_url":"https://avatars.githubusercontent.com/u/1179034?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagimon","html_url":"https://github.com/dimagimon","followers_url":"https://api.github.com/users/dimagimon/followers","following_url":"https://api.github.com/users/dimagimon/following{/other_user}","gists_url":"https://api.github.com/users/dimagimon/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagimon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagimon/subscriptions","organizations_url":"https://api.github.com/users/dimagimon/orgs","repos_url":"https://api.github.com/users/dimagimon/repos","events_url":"https://api.github.com/users/dimagimon/events{/privacy}","received_events_url":"https://api.github.com/users/dimagimon/received_events","type":"User","site_admin":false},"body":"E501 line too long (116 > 115 characters)","created_at":"2016-04-18T09:03:15Z","updated_at":"2016-04-18T09:03:15Z","html_url":"https://github.com/dimagi/commcare-hq/pull/11298#discussion_r60026038","pull_request_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298","_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments/60026038"},"html":{"href":"https://github.com/dimagi/commcare-hq/pull/11298#discussion_r60026038"},"pull_request":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298"}}},"pull_request":{"url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298","id":66819316,"html_url":"https://github.com/dimagi/commcare-hq/pull/11298","diff_url":"https://github.com/dimagi/commcare-hq/pull/11298.diff","patch_url":"https://github.com/dimagi/commcare-hq/pull/11298.patch","issue_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/11298","number":11298,"state":"open","locked":false,"title":"Ledger rebuild for form edit workflow","user":{"login":"snopoke","id":249606,"avatar_url":"https://avatars.githubusercontent.com/u/249606?v=3","gravatar_id":"","url":"https://api.github.com/users/snopoke","html_url":"https://github.com/snopoke","followers_url":"https://api.github.com/users/snopoke/followers","following_url":"https://api.github.com/users/snopoke/following{/other_user}","gists_url":"https://api.github.com/users/snopoke/gists{/gist_id}","starred_url":"https://api.github.com/users/snopoke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snopoke/subscriptions","organizations_url":"https://api.github.com/users/snopoke/orgs","repos_url":"https://api.github.com/users/snopoke/repos","events_url":"https://api.github.com/users/snopoke/events{/privacy}","received_events_url":"https://api.github.com/users/snopoke/received_events","type":"User","site_admin":false},"body":"@dannyroberts @dimagi/scale-team ","created_at":"2016-04-18T09:02:42Z","updated_at":"2016-04-18T09:03:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298/commits","review_comments_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298/comments","review_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/11298/comments","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/6e65a2e92cee972f8cbdf9bdcab272c90ec38379","head":{"label":"dimagi:ledger-rebuild","ref":"ledger-rebuild","sha":"6e65a2e92cee972f8cbdf9bdcab272c90ec38379","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":247278,"name":"commcare-hq","full_name":"dimagi/commcare-hq","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-hq","description":"A server-side tool to help manage community health workers, written in Django","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-hq","forks_url":"https://api.github.com/repos/dimagi/commcare-hq/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-hq/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-hq/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-hq/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-hq/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-hq/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-hq/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-hq/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-hq/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-hq/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-hq/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-hq/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-hq/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-hq/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-hq/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-hq/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-hq/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-hq/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-hq/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-hq/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-hq/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-hq/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-hq/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-hq/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-hq/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-hq/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-hq/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-hq/releases{/id}","deployments_url":"https://api.github.com/repos/dimagi/commcare-hq/deployments","created_at":"2009-07-09T17:00:07Z","updated_at":"2016-04-17T02:02:01Z","pushed_at":"2016-04-18T09:02:42Z","git_url":"git://github.com/dimagi/commcare-hq.git","ssh_url":"git@github.com:dimagi/commcare-hq.git","clone_url":"https://github.com/dimagi/commcare-hq.git","svn_url":"https://github.com/dimagi/commcare-hq","homepage":"http://www.commcarehq.org","size":287391,"stargazers_count":69,"watchers_count":69,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":68,"mirror_url":null,"open_issues_count":54,"forks":68,"open_issues":54,"watchers":69,"default_branch":"master"}},"base":{"label":"dimagi:master","ref":"master","sha":"d20bff25cc2d1c512e5c82a3bc06bbae06704e4c","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":247278,"name":"commcare-hq","full_name":"dimagi/commcare-hq","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-hq","description":"A server-side tool to help manage community health workers, written in Django","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-hq","forks_url":"https://api.github.com/repos/dimagi/commcare-hq/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-hq/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-hq/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-hq/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-hq/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-hq/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-hq/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-hq/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-hq/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-hq/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-hq/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-hq/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-hq/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-hq/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-hq/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-hq/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-hq/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-hq/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-hq/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-hq/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-hq/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-hq/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-hq/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-hq/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-hq/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-hq/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-hq/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-hq/releases{/id}","deployments_url":"https://api.github.com/repos/dimagi/commcare-hq/deployments","created_at":"2009-07-09T17:00:07Z","updated_at":"2016-04-17T02:02:01Z","pushed_at":"2016-04-18T09:02:42Z","git_url":"git://github.com/dimagi/commcare-hq.git","ssh_url":"git@github.com:dimagi/commcare-hq.git","clone_url":"https://github.com/dimagi/commcare-hq.git","svn_url":"https://github.com/dimagi/commcare-hq","homepage":"http://www.commcarehq.org","size":287391,"stargazers_count":69,"watchers_count":69,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":68,"mirror_url":null,"open_issues_count":54,"forks":68,"open_issues":54,"watchers":69,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298"},"html":{"href":"https://github.com/dimagi/commcare-hq/pull/11298"},"issue":{"href":"https://api.github.com/repos/dimagi/commcare-hq/issues/11298"},"comments":{"href":"https://api.github.com/repos/dimagi/commcare-hq/issues/11298/comments"},"review_comments":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298/comments"},"review_comment":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/11298/commits"},"statuses":{"href":"https://api.github.com/repos/dimagi/commcare-hq/statuses/6e65a2e92cee972f8cbdf9bdcab272c90ec38379"}}}}